summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-03-02 02:10:37 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-03-02 02:10:37 +0000
commit48f49e60427617866e082c89e5d38c9d8253b78b (patch)
tree458a8ec35befc478d59282e5c51c5a87dc94d858
parentf4832e39aeede40721b96e11124603ab09d1c862 (diff)
parent7ebd7233f5cd4f46fe103d4a5efed9f19f22aea8 (diff)
downloadcts-android13-mainline-networking-release.tar.gz
Snap for 9671667 from 7ebd7233f5cd4f46fe103d4a5efed9f19f22aea8 to mainline-networking-releaseaml_net_331812010aml_net_331710000android13-mainline-networking-release
Change-Id: I5ee4396518401054b0f239a99ccffbe666788e7a
-rw-r--r--apps/CameraITS/config.yml3
-rw-r--r--apps/CameraITS/tests/scene1_2/test_param_tonemap_mode.py3
-rw-r--r--apps/CameraITS/tests/scene3/test_3a_consistency.py2
-rw-r--r--apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py32
-rw-r--r--apps/CameraITS/tests/scene4/test_video_aspect_ratio_and_crop.py26
-rw-r--r--apps/CameraITS/tests/scene6/test_zoom.py11
-rwxr-xr-xapps/CameraITS/tools/run_all_tests.py188
-rw-r--r--apps/CameraITS/utils/camera_properties_utils.py14
-rw-r--r--apps/CameraITS/utils/its_session_utils.py15
-rw-r--r--apps/CtsVerifier/AndroidManifest.xml5
-rw-r--r--apps/CtsVerifier/res/layout-port/OWNERS5
-rw-r--r--apps/CtsVerifier/res/layout-port/cb_main.xml114
-rw-r--r--apps/CtsVerifier/res/layout/OWNERS7
-rw-r--r--apps/CtsVerifier/res/layout/co_main.xml3
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackLatencyActivity.java6
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/audio/RingerModeActivity.java11
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/camera/bokeh/CameraBokehActivity.java192
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java95
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/camera/orientation/CameraOrientationActivity.java73
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WifiLockdownTestActivity.java25
-rw-r--r--common/device-side/util-axt/src/com/android/compatibility/common/util/DisableAnimationRule.java52
-rw-r--r--common/device-side/util-axt/src/com/android/compatibility/common/util/MediaUtils.java16
-rw-r--r--common/device-side/util-axt/src/com/android/compatibility/common/util/OverrideAnimationScaleRule.java79
-rw-r--r--hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesValidConfigTest.java13
-rw-r--r--hostsidetests/appcompat/strictjavapackages/src/android/compat/sjp/cts/StrictJavaPackagesTest.java2
-rw-r--r--hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java17
-rw-r--r--hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/EncryptionAppTest.java10
-rw-r--r--hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java14
-rw-r--r--hostsidetests/hdmicec/src/android/hdmicec/cts/CecOperand.java1
-rw-r--r--hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecGeneralProtocolTest.java2
-rw-r--r--hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecPowerStatusTest.java6
-rw-r--r--hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecStartupTest.java2
-rw-r--r--hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecVendorCommandsTest.java14
-rw-r--r--hostsidetests/incrementalinstall/appvalidator/src/android/incrementalinstall/inrementaltestappvalidation/AppValidationTest.java16
-rw-r--r--hostsidetests/incrementalinstall/src/android/incrementalinstall/cts/IncrementalInstallTest.java12
-rw-r--r--hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/ScopedStorageDeviceTest.java9
-rw-r--r--hostsidetests/security/src/android/security/cts/KernelConfigTest.java4
-rw-r--r--hostsidetests/time/host/src/android/time/cts/host/LocationTimeZoneManagerHostTest.java110
-rw-r--r--hostsidetests/time/host/src/android/time/cts/host/LocationTimeZoneManagerStatsTest.java93
-rw-r--r--libs/midi/OWNERS4
-rw-r--r--libs/webkit-shared/src/android/webkit/cts/HttpHeader.aidl19
-rw-r--r--libs/webkit-shared/src/android/webkit/cts/HttpHeader.java88
-rw-r--r--libs/webkit-shared/src/android/webkit/cts/IWebServer.aidl26
-rw-r--r--libs/webkit-shared/src/android/webkit/cts/SharedSdkWebServer.java136
-rw-r--r--libs/webkit-shared/src/android/webkit/cts/SharedWebViewTestEnvironment.java146
-rw-r--r--tests/AlarmManager/src/android/alarmmanager/cts/BackgroundRestrictedAlarmsTest.java2
-rw-r--r--tests/JobScheduler/src/android/jobscheduler/cts/NetworkingHelper.java6
-rw-r--r--tests/PhotoPicker/res/raw/lg_g4_iso_800_svg.svgbin0 -> 107689 bytes
-rw-r--r--tests/PhotoPicker/res/raw/lg_g4_iso_800_unknown_mime_type.jpgbin0 -> 107685 bytes
-rw-r--r--tests/PhotoPicker/res/raw/test_video_mj2.mp4 (renamed from tests/PhotoPicker/res/raw/test_video_dng.mp4)bin20716 -> 20717 bytes
-rw-r--r--tests/PhotoPicker/res/raw/test_video_mpeg.mpegbin0 -> 20718 bytes
-rw-r--r--tests/PhotoPicker/res/raw/test_video_unknown_mime_type.mp4bin0 -> 20717 bytes
-rw-r--r--tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerSettingsTest.java10
-rw-r--r--tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerTest.java75
-rw-r--r--tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerFilesUtils.java37
-rw-r--r--tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerUiUtils.java28
-rw-r--r--tests/PhotoPicker/src/android/photopicker/cts/util/ResultsAssertionsUtils.java32
-rw-r--r--tests/accessibilityservice/res/layout/accessibility_cache.xml8
-rw-r--r--tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityCacheTest.java104
-rw-r--r--tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java26
-rw-r--r--tests/app/app/src/android/app/stubs/CommandReceiver.java4
-rw-r--r--tests/backup/AndroidManifest.xml2
-rw-r--r--tests/backup/src/android/backup/cts/AppLocalesBackupTest.java48
-rw-r--r--tests/camera/api31test/src/android/camera/cts/api31test/SPerfClassTest.java5
-rw-r--r--tests/camera/src/android/hardware/camera2/cts/MultiResolutionImageReaderTest.java33
-rw-r--r--tests/camera/src/android/hardware/camera2/cts/RecordingTest.java8
-rw-r--r--tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java5
-rw-r--r--tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagementRoleHolderTest.java13
-rw-r--r--tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagerTest.java1
-rw-r--r--tests/devicestate/src/android/hardware/devicestate/cts/DeviceStateManagerTests.java15
-rw-r--r--tests/framework/base/windowmanager/jetpack/SecondApp/src/android/server/wm/jetpack/second/SecondActivityUnknownEmbeddingCerts.java (renamed from tests/framework/base/windowmanager/jetpack/SecondApp/src/android/server/wm/jetpack/second/SecondActivityKnownEmbeddingCerts.java)2
-rw-r--r--tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingBoundsTests.java8
-rw-r--r--tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingLifecycleTests.java10
-rw-r--r--tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingPlaceholderTests.java35
-rw-r--r--tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/WindowManagerJetpackTestBase.java5
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/ActivityMetricsLoggerTests.java1
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/KeyguardTransitionTests.java2
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/RoundedCornerTests.java2
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java3
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationTestBase.java8
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/WindowTest.java25
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/WindowUntrustedTouchTest.java3
-rw-r--r--tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java12
-rw-r--r--tests/inputmethod/AndroidTest.xml3
-rw-r--r--tests/inputmethod/src/android/view/inputmethod/cts/ImeInsetsControllerTest.java32
-rw-r--r--tests/inputmethod/src/android/view/inputmethod/cts/InputMethodServiceTest.java14
-rw-r--r--tests/inputmethod/tests32/AndroidTest.xml3
-rw-r--r--tests/location/location_none/src/android/location/cts/none/LocationDisabledAppOpsTest.java10
-rw-r--r--tests/tests/app/AndroidManifest.xml2
-rw-r--r--tests/tests/appenumeration/src/android/appenumeration/cts/AppEnumerationTests.java7
-rw-r--r--tests/tests/bluetooth/AndroidManifest.xml1
-rw-r--r--tests/tests/car/src/android/car/cts/CarServiceHelperServiceUpdatableTest.java2
-rw-r--r--tests/tests/contactsprovider/src/android/provider/cts/contacts/ContactsContractIntentsTest.java6
-rw-r--r--tests/tests/dpi/src/android/dpi/cts/ConfigurationScreenLayoutTest.java2
-rw-r--r--tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedVectorDrawableParameterizedTest.java7
-rw-r--r--tests/tests/hibernation/src/android/hibernation/cts/AppHibernationIntegrationTest.kt2
-rw-r--r--tests/tests/hibernation/src/android/hibernation/cts/AppHibernationUtils.kt14
-rw-r--r--tests/tests/hibernation/src/android/hibernation/cts/AutoRevokeTest.kt1
-rw-r--r--tests/tests/media/common/src/android/media/cts/TestUtils.java16
-rw-r--r--tests/tests/media/decoder/src/android/media/decoder/cts/DecodeAccuracyTest.java25
-rw-r--r--tests/tests/media/decoder/src/android/media/decoder/cts/DecodeAccuracyTestBase.java51
-rw-r--r--tests/tests/media/decoder/src/android/media/decoder/cts/VideoDecoderPerfTest.java2
-rw-r--r--tests/tests/media/drmframework/src/android/media/drmframework/cts/MediaDrmTest.java9
-rw-r--r--tests/tests/nfc/src/android/nfc/cts/NfcPreferredPaymentTest.java7
-rw-r--r--tests/tests/permission/AndroidTest.xml3
-rw-r--r--tests/tests/permission2/AndroidTest.xml7
-rw-r--r--tests/tests/permission2/res/raw/automotive_android_manifest.xml4
-rw-r--r--tests/tests/permission2/res/raw/wear_android_manifest.xml52
-rw-r--r--tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java31
-rw-r--r--tests/tests/permission2/src/android/permission2/cts/RuntimePermissionProperties.kt18
-rw-r--r--tests/tests/permission3/AndroidTest.xml3
-rw-r--r--[-rwxr-xr-x]tests/tests/permission3/src/android/permission3/cts/BasePermissionTest.kt1
-rw-r--r--[-rwxr-xr-x]tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt56
-rw-r--r--tests/tests/permission3/src/android/permission3/cts/MediaPermissionTest.kt56
-rw-r--r--tests/tests/permission3/src/android/permission3/cts/PermissionTest23.kt6
-rw-r--r--tests/tests/permission4/AndroidTest.xml7
-rw-r--r--tests/tests/permission5/AndroidTest.xml7
-rw-r--r--tests/tests/sdksandbox/webkit/Android.bp1
-rw-r--r--tests/tests/sdksandbox/webkit/res/raw/trustedcert.crt31
-rw-r--r--tests/tests/sdksandbox/webkit/res/raw/trustedkey.derbin0 -> 2374 bytes
-rw-r--r--tests/tests/sdksandbox/webkit/res/raw/untrustedcert.crt31
-rw-r--r--tests/tests/sdksandbox/webkit/res/raw/untrustedkey.derbin0 -> 2376 bytes
-rw-r--r--tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxCookieManagerTest.java109
-rw-r--r--tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxCookieTest.java9
-rw-r--r--tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxDateSorterTest.java9
-rw-r--r--tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxHttpAuthHandlerTest.java9
-rw-r--r--tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxPostMessageTest.java9
-rw-r--r--tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxServiceWorkerClientTest.java9
-rw-r--r--tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxURLUtilTest.java9
-rw-r--r--tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebBackForwardListTest.java9
-rw-r--r--tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebChromeClientTest.java95
-rw-r--r--tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebHistoryItemTest.java9
-rw-r--r--tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebSettingsTest.java279
-rw-r--r--tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebViewClientTest.java185
-rw-r--r--tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebViewSslTest.java9
-rw-r--r--tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebViewTest.java19
-rw-r--r--tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebViewTransportTest.java44
-rw-r--r--tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebViewZoomTest.java9
-rw-r--r--tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/WebViewSandboxTestRule.java18
-rw-r--r--tests/tests/security/AndroidManifest.xml6
-rw-r--r--tests/tests/security/src/android/security/cts/CVE_2022_20611.java63
-rw-r--r--tests/tests/security/src/android/security/cts/PackageInstallerTest.java135
-rw-r--r--tests/tests/security/src/android/security/cts/TestForegroundService.java86
-rw-r--r--tests/tests/security/testdata/packageinstallertestapp.xml1
-rw-r--r--tests/tests/security/testdata/src/android/security/cts/packageinstallertestapp/BackgroundReceiver.java123
-rw-r--r--tests/tests/settings/src/android/settings/cts/TetherProvisioningCarrierDialogActivityTest.java8
-rw-r--r--tests/tests/telecom/AndroidManifest.xml9
-rw-r--r--tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java46
-rw-r--r--tests/tests/telecom/src/android/telecom/cts/NullBindingCallScreeningService.java82
-rw-r--r--tests/tests/telecom/src/android/telecom/cts/NullBindingCallScreeningServiceTest.java145
-rw-r--r--tests/tests/telecom/src/android/telecom/cts/OutgoingCallTest.java57
-rw-r--r--tests/tests/telecom/src/android/telecom/cts/TestUtils.java18
-rw-r--r--tests/tests/telephony/current/src/android/telephony/cts/CallComposerTest.java19
-rw-r--r--tests/tests/telephony/current/src/android/telephony/cts/DataProfileTest.java3
-rw-r--r--tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java2
-rw-r--r--tests/tests/telephony/current/src/android/telephony/ims/cts/ImsCallingTest.java34
-rw-r--r--tests/tests/telephony/current/src/android/telephony/ims/cts/ImsUtils.java7
-rw-r--r--tests/tests/text/src/android/text/method/cts/BaseMovementMethodTest.java1
-rw-r--r--tests/tests/text/src/android/text/method/cts/ScrollingMovementMethodTest.java1
-rw-r--r--tests/tests/text/src/android/text/method/cts/TouchTest.java1
-rw-r--r--tests/tests/tv/src/android/media/tv/tuner/cts/TunerTest.java8
-rw-r--r--tests/tests/view/src/android/view/cts/PixelCopyTest.java591
-rw-r--r--tests/tests/view/src/android/view/cts/TextureViewTest.java58
-rw-r--r--tests/tests/view/src/android/view/cts/View_UsingViewsTest.java6
-rw-r--r--tests/tests/voiceRecognition/src/android/voicerecognition/cts/RecognitionServiceMicIndicatorTest.java2
-rw-r--r--tests/tests/voiceinteraction/src/android/voiceinteraction/cts/HotwordDetectionServiceBasicTest.java2
-rw-r--r--tests/tests/webkit/src/android/webkit/cts/CookieManagerTest.java108
-rw-r--r--tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java3
-rw-r--r--tests/tests/webkit/src/android/webkit/cts/WebBackForwardListTest.java3
-rw-r--r--tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java63
-rw-r--r--tests/tests/webkit/src/android/webkit/cts/WebHistoryItemTest.java3
-rw-r--r--tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java88
-rw-r--r--tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java211
-rw-r--r--tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java64
-rw-r--r--tests/tests/webkit/src/android/webkit/cts/WebViewTest.java54
-rw-r--r--tests/tests/webkit/src/android/webkit/cts/WebViewTransportTest.java28
-rw-r--r--tests/tests/webkit/src/android/webkit/cts/WebViewZoomTest.java3
-rw-r--r--tests/tests/widget/res/layout/horizontal_scrollview.xml98
-rw-r--r--tests/tests/widget/src/android/widget/cts/HorizontalScrollViewTest.java8
-rw-r--r--tests/tests/widget/src/android/widget/cts/TextViewTest.java29
-rw-r--r--tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java5
-rwxr-xr-xtools/cts-tradefed/etc/cts-tradefed4
-rw-r--r--tools/cts-tradefed/res/config/cts-known-failures.xml5
-rw-r--r--tools/cts-tradefed/tests/src/com/android/compatibility/common/tradefed/loading/CommonConfigLoadingTest.java6
184 files changed, 4598 insertions, 1367 deletions
diff --git a/apps/CameraITS/config.yml b/apps/CameraITS/config.yml
index b9b0ddf21ec..d1a033937fe 100644
--- a/apps/CameraITS/config.yml
+++ b/apps/CameraITS/config.yml
@@ -32,6 +32,7 @@ TestBeds:
lighting_ch: <controller-channel>
camera: <camera-id>
scene: <scene-name> # if <scene-name> left as-is runs all scenes
+ foldable_device: "False" # set to True if testing a foldable device
- Name: TEST_BED_SENSOR_FUSION # Need 'sensor_fusion' in name for SF tests
# Test configuration for sensor_fusion/test_sensor_fusion.py
@@ -48,4 +49,4 @@ TestBeds:
rotator_cntl: "arduino" # Note: only sensor fusion supports manual
rotator_ch: <controller-channel>
camera: <camera-id>
-
+ foldable_device: "False" # set to True if testing a foldable device
diff --git a/apps/CameraITS/tests/scene1_2/test_param_tonemap_mode.py b/apps/CameraITS/tests/scene1_2/test_param_tonemap_mode.py
index 257ff3e3c61..92d6f865c51 100644
--- a/apps/CameraITS/tests/scene1_2/test_param_tonemap_mode.py
+++ b/apps/CameraITS/tests/scene1_2/test_param_tonemap_mode.py
@@ -85,7 +85,8 @@ class ParamTonemapModeTest(its_base_test.ItsBaseTest):
props = cam.override_with_hidden_physical_camera_props(props)
camera_properties_utils.skip_unless(
camera_properties_utils.compute_target_exposure(props) and
- camera_properties_utils.per_frame_control(props))
+ camera_properties_utils.per_frame_control(props) and
+ camera_properties_utils.tonemap_mode(props, 0))
log_path = self.log_path
# Load chart for scene
diff --git a/apps/CameraITS/tests/scene3/test_3a_consistency.py b/apps/CameraITS/tests/scene3/test_3a_consistency.py
index 71469fed15e..1ab129d026c 100644
--- a/apps/CameraITS/tests/scene3/test_3a_consistency.py
+++ b/apps/CameraITS/tests/scene3/test_3a_consistency.py
@@ -136,7 +136,7 @@ class ConsistencyTest(its_base_test.ItsBaseTest):
fd_min = np.amin(fds)
fd_max = np.amax(fds)
if not np.isclose(fd_max, fd_min, _FD_TOL):
- raise AssertionError(f'FD min: {fd_min}, max: {fd_min} TOL: {_FD_TOL}')
+ raise AssertionError(f'FD min: {fd_min}, max: {fd_max} TOL: {_FD_TOL}')
for g in awb_gains:
if np.isnan(g):
raise AssertionError('AWB gain entry is not a number.')
diff --git a/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
index 7283f204882..184c9aa6a1e 100644
--- a/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
+++ b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
@@ -15,6 +15,7 @@
import logging
+import math
import os.path
from mobly import test_runner
import numpy as np
@@ -37,6 +38,8 @@ _PREVIEW_SIZE = (1920, 1080)
# needs to pass the test for all resolutions within these aspect ratios.
_AR_CHECKED_PRE_API_30 = ('4:3', '16:9', '18:9')
_AR_DIFF_ATOL = 0.01
+# If RAW reference capture aspect ratio is ~4:3 or ~16:9, use JPEG, else RAW
+_AR_FOR_JPEG_REFERENCE = (4/3, 16/9)
def _check_skip_conditions(first_api_level, props):
@@ -235,14 +238,34 @@ class AspectRatioAndCropTest(its_base_test.ItsBaseTest):
debug = self.debug_mode
# Converge 3A.
- cam.do_3a()
- req = capture_request_utils.auto_capture_request()
+ if camera_properties_utils.manual_sensor(props):
+ logging.debug('Manual sensor, using manual capture request')
+ s, e, _, _, f_d = cam.do_3a(get_results=True)
+ req = capture_request_utils.manual_capture_request(
+ s, e, f_distance=f_d)
+ else:
+ logging.debug('Using auto capture request')
+ cam.do_3a()
+ req = capture_request_utils.auto_capture_request()
+
+ # For main camera: if RAW available, use it as ground truth, else JPEG
+ # For physical sub-camera: if RAW available, only use if not 4:3 or 16:9
+ use_raw_fov = False
+ if raw_avlb:
+ pixel_array_w = props['android.sensor.info.pixelArraySize']['width']
+ pixel_array_h = props['android.sensor.info.pixelArraySize']['height']
+ logging.debug('Pixel array size: %dx%d', pixel_array_w, pixel_array_h)
+ raw_aspect_ratio = pixel_array_w / pixel_array_h
+ use_raw_fov = (
+ fls_physical == fls_logical or not
+ any(math.isclose(raw_aspect_ratio, jpeg_ar, abs_tol=_AR_DIFF_ATOL)
+ for jpeg_ar in _AR_FOR_JPEG_REFERENCE)
+ )
- # If raw available, use as ground truth.
ref_img_name_stem = f'{os.path.join(log_path, _NAME)}'
ref_fov, cc_ct_gt, aspect_ratio_gt = (
image_fov_utils.find_fov_reference(
- cam, req, props, raw_avlb, ref_img_name_stem))
+ cam, req, props, use_raw_fov, ref_img_name_stem))
run_crop_test = full_or_better and raw_avlb
if run_crop_test:
@@ -273,7 +296,6 @@ class AspectRatioAndCropTest(its_base_test.ItsBaseTest):
'format': fmt_iter}]
out_surface.append({'width': w_cmpr, 'height': h_cmpr,
'format': fmt_cmpr})
- cam.do_3a()
cap = cam.do_capture(req, out_surface)[0]
_check_basic_correctness(cap, fmt_iter, w_iter, h_iter)
logging.debug('Captured %s with %s %dx%d. Compared size: %dx%d',
diff --git a/apps/CameraITS/tests/scene4/test_video_aspect_ratio_and_crop.py b/apps/CameraITS/tests/scene4/test_video_aspect_ratio_and_crop.py
index 844807bfec7..592a6e6baf1 100644
--- a/apps/CameraITS/tests/scene4/test_video_aspect_ratio_and_crop.py
+++ b/apps/CameraITS/tests/scene4/test_video_aspect_ratio_and_crop.py
@@ -14,6 +14,7 @@
"""Validate video aspect ratio, crop and FoV vs format."""
import logging
+import math
import os.path
from mobly import test_runner
@@ -33,6 +34,7 @@ _VIDEO_RECORDING_DURATION_SECONDS = 3
_FOV_PERCENT_RTOL = 0.15 # Relative tolerance on circle FoV % to expected.
_AR_CHECKED_PRE_API_30 = ('4:3', '16:9', '18:9')
_AR_DIFF_ATOL = 0.01
+_AR_FOR_JPEG_REFERENCE = (4/3, 16/9)
_MAX_8BIT_IMGS = 255
_MAX_10BIT_IMGS = 1023
@@ -139,9 +141,9 @@ class VideoAspectRatioAndCropTest(its_base_test.ItsBaseTest):
logging.debug('physical available focal lengths: %s', str(fls_physical))
# Check SKIP conditions.
- vendor_api_level = its_session_utils.get_vendor_api_level(self.dut.serial)
+ first_api_level = its_session_utils.get_first_api_level(self.dut.serial)
camera_properties_utils.skip_unless(
- vendor_api_level >= its_session_utils.ANDROID13_API_LEVEL)
+ first_api_level >= its_session_utils.ANDROID13_API_LEVEL)
# Load scene.
its_session_utils.load_scene(cam, props, self.scene,
@@ -160,13 +162,27 @@ class VideoAspectRatioAndCropTest(its_base_test.ItsBaseTest):
req = capture_request_utils.auto_capture_request()
ref_img_name_stem = f'{os.path.join(self.log_path, _NAME)}'
- if raw_avlb and (fls_physical == fls_logical):
- logging.debug('RAW')
+ # For main camera: if RAW available, use it as ground truth, else JPEG
+ # For physical sub-camera: if RAW available, only use if not 4:3 or 16:9
+ if raw_avlb:
+ pixel_array_w = props['android.sensor.info.pixelArraySize']['width']
+ pixel_array_h = props['android.sensor.info.pixelArraySize']['height']
+ logging.debug('Pixel array size: %dx%d', pixel_array_w, pixel_array_h)
+ raw_aspect_ratio = pixel_array_w / pixel_array_h
+ if (fls_physical == fls_logical or not
+ any(math.isclose(raw_aspect_ratio, jpeg_ar, abs_tol=_AR_DIFF_ATOL)
+ for jpeg_ar in _AR_FOR_JPEG_REFERENCE)):
+ logging.debug('RAW')
+ use_raw_fov = True
+ else:
+ logging.debug('RAW available, but using JPEG as ground truth')
+ use_raw_fov = False
else:
logging.debug('JPEG')
+ use_raw_fov = False
ref_fov, cc_ct_gt, aspect_ratio_gt = image_fov_utils.find_fov_reference(
- cam, req, props, raw_avlb, ref_img_name_stem)
+ cam, req, props, use_raw_fov, ref_img_name_stem)
run_crop_test = full_or_better and raw_avlb
diff --git a/apps/CameraITS/tests/scene6/test_zoom.py b/apps/CameraITS/tests/scene6/test_zoom.py
index 34b2215f480..fbc882e22a7 100644
--- a/apps/CameraITS/tests/scene6/test_zoom.py
+++ b/apps/CameraITS/tests/scene6/test_zoom.py
@@ -244,11 +244,18 @@ class ZoomTest(its_base_test.ItsBaseTest):
logging.debug('test TOLs: %s', str(test_tols))
# do captures over zoom range and find circles with cv2
- req = capture_request_utils.auto_capture_request()
+ if camera_properties_utils.manual_sensor(props):
+ logging.debug('Manual sensor, using manual capture request')
+ s, e, _, _, f_d = cam.do_3a(get_results=True)
+ req = capture_request_utils.manual_capture_request(
+ s, e, f_distance=f_d)
+ else:
+ logging.debug('Using auto capture request')
+ cam.do_3a()
+ req = capture_request_utils.auto_capture_request()
for i, z in enumerate(z_list):
logging.debug('zoom ratio: %.2f', z)
req['android.control.zoomRatio'] = z
- cam.do_3a()
cap = cam.do_capture(
req, {'format': 'yuv', 'width': size[0], 'height': size[1]})
img = image_processing_utils.convert_capture_to_rgb_image(
diff --git a/apps/CameraITS/tools/run_all_tests.py b/apps/CameraITS/tools/run_all_tests.py
index dae63c3732e..a75ce5e8b17 100755
--- a/apps/CameraITS/tools/run_all_tests.py
+++ b/apps/CameraITS/tools/run_all_tests.py
@@ -55,6 +55,7 @@ TIME_KEY_START = 'start'
TIME_KEY_END = 'end'
VALID_CONTROLLERS = ('arduino', 'canakit')
_INT_STR_DICT = {'11': '1_1', '12': '1_2'} # recover replaced '_' in scene def
+_FRONT_CAMERA_ID = '1'
# All possible scenes
# Notes on scene names:
@@ -337,6 +338,74 @@ def enable_external_storage(device_id):
run(cmd)
+def get_available_cameras(device_id, camera_id):
+ """Get available camera devices in the current state.
+
+ Args:
+ device_id: Serial number of the device.
+ camera_id: Logical camera_id
+
+ Returns:
+ List of all the available camera_ids.
+ """
+ with its_session_utils.ItsSession(
+ device_id=device_id,
+ camera_id=camera_id) as cam:
+ props = cam.get_camera_properties()
+ props = cam.override_with_hidden_physical_camera_props(props)
+ unavailable_physical_cameras = cam.get_unavailable_physical_cameras(
+ camera_id)
+ unavailable_physical_ids = unavailable_physical_cameras[
+ 'unavailablePhysicalCamerasArray']
+ output = cam.get_camera_ids()
+ all_camera_ids = output['cameraIdArray']
+ # Concat camera_id, physical camera_id and sub camera separator
+ unavailable_physical_ids = [f'{camera_id}.{s}'
+ for s in unavailable_physical_ids]
+ for i in unavailable_physical_ids:
+ if i in all_camera_ids:
+ all_camera_ids.remove(i)
+ logging.debug('available camera ids: %s', all_camera_ids)
+ return all_camera_ids
+
+
+def get_unavailable_physical_cameras(device_id, camera_id):
+ """Get unavailable physical cameras in the current state.
+
+ Args:
+ device_id: Serial number of the device.
+ camera_id: Logical camera device id
+
+ Returns:
+ List of all the unavailable camera_ids.
+ """
+ with its_session_utils.ItsSession(
+ device_id=device_id,
+ camera_id=camera_id) as cam:
+ unavailable_physical_cameras = cam.get_unavailable_physical_cameras(
+ camera_id)
+ unavailable_physical_ids = unavailable_physical_cameras[
+ 'unavailablePhysicalCamerasArray']
+ unavailable_physical_ids = [f'{camera_id}.{s}'
+ for s in unavailable_physical_ids]
+ logging.debug('Unavailable physical camera ids: %s',
+ unavailable_physical_ids)
+ return unavailable_physical_ids
+
+
+def is_device_folded(device_id):
+ """Returns True if the foldable device is in folded state.
+
+ Args:
+ device_id: Serial number of the foldable device.
+ """
+ cmd = (f'adb -s {device_id} shell cmd device_state state')
+ result = subprocess.getoutput(cmd)
+ if 'CLOSED' in result:
+ return True
+ return False
+
+
def main():
"""Run all the Camera ITS automated tests.
@@ -390,6 +459,19 @@ def main():
# Enable external storage on DUT to send summary report to CtsVerifier.apk
enable_external_storage(device_id)
+ # Check whether the dut is foldable or not
+ testing_foldable_device = True if test_params_content[
+ 'foldable_device'] == 'True' else False
+ available_camera_ids_to_test_foldable = []
+ if testing_foldable_device:
+ logging.debug('Testing foldable device.')
+ # Check the state of foldable device. True if device is folded,
+ # false if the device is opened.
+ device_folded = is_device_folded(device_id)
+ # list of available camera_ids to be tested in device state
+ available_camera_ids_to_test_foldable = get_available_cameras(
+ device_id, _FRONT_CAMERA_ID)
+
config_file_test_key = config_file_contents['TestBeds'][0]['Name'].lower()
if TEST_KEY_TABLET in config_file_test_key:
tablet_id = get_device_serial_number('tablet', config_file_contents)
@@ -417,6 +499,12 @@ def main():
scenes = [_GROUPED_SCENES[s] if s in _GROUPED_SCENES else s for s in scenes]
scenes = np.hstack(scenes).tolist()
scenes = sorted(set(scenes), key=scenes.index)
+ # List of scenes to be executed in folded state will have '_folded'
+ # prefix. This will help distinguish the test results from folded vs
+ # open device state for front camera_ids.
+ folded_device_scenes = []
+ for scene in scenes:
+ folded_device_scenes.append(f'{scene}_folded')
logging.info('Running ITS on device: %s, camera(s): %s, scene(s): %s',
device_id, camera_id_combos, scenes)
@@ -428,9 +516,48 @@ def main():
auto_scene_switch = False
logging.info('No tablet: manual, sensor_fusion, or scene5 testing.')
+ folded_prompted = False
+ opened_prompted = False
for camera_id in camera_id_combos:
test_params_content['camera'] = camera_id
results = {}
+ unav_cameras = []
+ # Get the list of unavailable cameras in current device state.
+ # These camera_ids should not be tested in current device state.
+ if testing_foldable_device:
+ unav_cameras = get_unavailable_physical_cameras(
+ device_id, _FRONT_CAMERA_ID)
+
+ if testing_foldable_device:
+ device_state = 'folded' if device_folded else 'opened'
+
+ testing_folded_front_camera = (testing_foldable_device and
+ device_folded and
+ _FRONT_CAMERA_ID in camera_id)
+
+ # Raise an assertion error if there is any camera unavailable in
+ # current device state. Usually scenes with suffix 'folded' will
+ # be executed in folded state.
+ if (testing_foldable_device and
+ _FRONT_CAMERA_ID in camera_id and camera_id in unav_cameras):
+ raise AssertionError(
+ f'Camera {camera_id} is unavailable in device state {device_state}'
+ f' and cannot be tested with device {device_state}!')
+
+ if (testing_folded_front_camera and camera_id not in unav_cameras
+ and not folded_prompted):
+ folded_prompted = True
+ input('\nYou are testing a foldable device in folded state.'
+ 'Please make sure the device is folded and press <ENTER>'
+ 'after positioning properly.\n')
+
+ if (testing_foldable_device and
+ not device_folded and _FRONT_CAMERA_ID in camera_id and
+ camera_id not in unav_cameras and not opened_prompted):
+ opened_prompted = True
+ input('\nYou are testing a foldable device in opened state.'
+ 'Please make sure the device is unfolded and press <ENTER>'
+ 'after positioning properly.\n')
# Run through all scenes if user does not supply one and config file doesn't
# have specific scene name listed.
@@ -452,9 +579,35 @@ def main():
if not per_camera_scenes:
raise ValueError('No valid scene specified for this camera.')
+ # Folded state scenes will have 'folded' suffix only for
+ # front cameras since rear cameras are common in both folded
+ # and unfolded state.
+ foldable_per_camera_scenes = []
+ if testing_folded_front_camera:
+ if camera_id not in available_camera_ids_to_test_foldable:
+ raise AssertionError(f'camera {camera_id} is not available.')
+ for s in per_camera_scenes:
+ foldable_per_camera_scenes.append(f'{s}_folded')
+
+ if foldable_per_camera_scenes:
+ per_camera_scenes = foldable_per_camera_scenes
+
logging.info('camera: %s, scene(s): %s', camera_id, per_camera_scenes)
- for s in _ALL_SCENES:
+
+ if testing_folded_front_camera:
+ all_scenes = [f'{s}_folded' for s in _ALL_SCENES]
+ else:
+ all_scenes = _ALL_SCENES
+
+ for s in all_scenes:
results[s] = {RESULT_KEY: RESULT_NOT_EXECUTED}
+
+ # assert device folded testing scenes with suffix 'folded'
+ if testing_foldable_device and 'folded' in s:
+ if not device_folded:
+ raise AssertionError('Device should be folded during'
+ ' testing scenes with suffix "folded"')
+
# A subdir in topdir will be created for each camera_id. All scene test
# output logs for each camera id will be stored in this subdir.
# This output log path is a mobly param : LogPath
@@ -464,7 +617,6 @@ def main():
os.mkdir(mobly_output_logs_path)
tot_pass = 0
for s in per_camera_scenes:
- test_params_content['scene'] = s
results[s]['TEST_STATUS'] = []
results[s][METRICS_KEY] = []
@@ -473,14 +625,22 @@ def main():
scene_test_summary = f'Cam{camera_id} {s}' + '\n'
mobly_scene_output_logs_path = os.path.join(mobly_output_logs_path, s)
+ # Since test directories do not have 'folded' in the name, we need
+ # to remove that suffix for the path of the scenes to be loaded
+ # on the tablets
+ testing_scene = s
+ if 'folded' in s:
+ testing_scene = s.split('_folded')[0]
+ test_params_content['scene'] = testing_scene
if auto_scene_switch:
# Copy scene images onto the tablet
- if s not in ['scene0']:
- load_scenes_on_tablet(s, tablet_id)
+ if 'scene0' not in testing_scene:
+ load_scenes_on_tablet(testing_scene, tablet_id)
else:
# Check manual scenes for correctness
- if s not in ['scene0'] and not testing_sensor_fusion_with_controller:
- check_manual_scenes(device_id, camera_id, s, mobly_output_logs_path)
+ if 'scene0' not in testing_scene and not testing_sensor_fusion_with_controller:
+ check_manual_scenes(device_id, camera_id, testing_scene,
+ mobly_output_logs_path)
scene_test_list = []
config_file_contents['TestBeds'][0]['TestParams'] = test_params_content
@@ -497,19 +657,21 @@ def main():
logging.info('Using %s as temporary config yml file', new_yml_file_name)
if camera_id.rfind(its_session_utils.SUB_CAMERA_SEPARATOR) == -1:
scene_dir = os.listdir(
- os.path.join(os.environ['CAMERA_ITS_TOP'], 'tests', s))
+ os.path.join(os.environ['CAMERA_ITS_TOP'], 'tests', testing_scene))
for file_name in scene_dir:
if file_name.endswith('.py') and 'test' in file_name:
scene_test_list.append(file_name)
else: # sub-camera
- if SUB_CAMERA_TESTS.get(s):
- scene_test_list = [f'{test}.py' for test in SUB_CAMERA_TESTS[s]]
+ if SUB_CAMERA_TESTS.get(testing_scene):
+ scene_test_list = [f'{test}.py' for test in SUB_CAMERA_TESTS[
+ testing_scene]]
else:
scene_test_list = []
scene_test_list.sort()
# Run tests for scene
- logging.info('Running tests for %s with camera %s', s, camera_id)
+ logging.info('Running tests for %s with camera %s',
+ testing_scene, camera_id)
num_pass = 0
num_skip = 0
num_not_mandated_fail = 0
@@ -525,7 +687,8 @@ def main():
else:
cmd = [
'python3',
- os.path.join(os.environ['CAMERA_ITS_TOP'], 'tests', s, test),
+ os.path.join(os.environ['CAMERA_ITS_TOP'], 'tests',
+ testing_scene, test),
'-c',
'%s' % new_yml_file_name
]
@@ -589,7 +752,8 @@ def main():
os.remove(MOBLY_TEST_SUMMARY_TXT_FILE)
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()})
+ 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)
diff --git a/apps/CameraITS/utils/camera_properties_utils.py b/apps/CameraITS/utils/camera_properties_utils.py
index 261c03e92d2..44aa510c49c 100644
--- a/apps/CameraITS/utils/camera_properties_utils.py
+++ b/apps/CameraITS/utils/camera_properties_utils.py
@@ -557,6 +557,20 @@ def edge_mode(props, mode):
'android.edge.availableEdgeModes']
+def tonemap_mode(props, mode):
+ """Returns whether a device supports the tonemap mode.
+
+ Args:
+ props: Camera properties object.
+ mode: Integer, indicating the tonemap mode to check for availability.
+
+ Return:
+ Boolean.
+ """
+ return 'android.edge.availableToneMapModes' in props and mode in props[
+ 'android.tonemap.availableToneMapModes']
+
+
def yuv_reprocess(props):
"""Returns whether a device supports YUV reprocessing.
diff --git a/apps/CameraITS/utils/its_session_utils.py b/apps/CameraITS/utils/its_session_utils.py
index a846306dbe2..b1fb77a72c3 100644
--- a/apps/CameraITS/utils/its_session_utils.py
+++ b/apps/CameraITS/utils/its_session_utils.py
@@ -453,6 +453,21 @@ class ItsSession(object):
self.sock.settimeout(self.SOCK_TIMEOUT)
return data['objValue']
+ def get_camera_ids(self):
+ """Returns the list of all camera_ids.
+
+ Returns:
+ List of camera ids on the device.
+ """
+ cmd = {'cmdName': 'getCameraIds'}
+ self.sock.send(json.dumps(cmd).encode() + '\n'.encode())
+ timeout = self.SOCK_TIMEOUT + self.EXTRA_SOCK_TIMEOUT
+ self.sock.settimeout(timeout)
+ data, _ = self.__read_response_from_socket()
+ if data['tag'] != 'cameraIds':
+ raise error_util.CameraItsError('Invalid command response')
+ return data['objValue']
+
def get_unavailable_physical_cameras(self, camera_id):
"""Get the unavailable physical cameras ids.
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 7cd577cf7e1..6c464b1bad3 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -3026,8 +3026,7 @@
<activity android:name=".camera.bokeh.CameraBokehActivity"
android:label="@string/camera_bokeh_test"
android:configChanges="keyboardHidden|screenSize"
- android:exported="true"
- android:screenOrientation="landscape">
+ android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.cts.intent.category.MANUAL_TEST" />
@@ -5275,6 +5274,8 @@
<meta-data android:name="test_category" android:value="@string/test_category_tv"/>
<meta-data android:name="test_required_features"
android:value="android.software.leanback"/>
+ <meta-data android:name="test_required_configs"
+ android:value="config_hdmi_source"/>
<meta-data android:name="display_mode"
android:value="multi_display_mode" />
<meta-data android:name="ApiTest"
diff --git a/apps/CtsVerifier/res/layout-port/OWNERS b/apps/CtsVerifier/res/layout-port/OWNERS
new file mode 100644
index 00000000000..f4217d97594
--- /dev/null
+++ b/apps/CtsVerifier/res/layout-port/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 41727 = per-file camera_*.xml
+# Bug component: 41727 = per-file cam_*.xml
+
+per-file camera_*.xml = file:platform/frameworks/av:/camera/OWNERS
+per-file cam_*.xml = file:platform/frameworks/av:/camera/OWNERS \ No newline at end of file
diff --git a/apps/CtsVerifier/res/layout-port/cb_main.xml b/apps/CtsVerifier/res/layout-port/cb_main.xml
new file mode 100644
index 00000000000..9a3ae1fb0ad
--- /dev/null
+++ b/apps/CtsVerifier/res/layout-port/cb_main.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright (C) 2023 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.
+-->
+
+<!-- Portrait orientation layout for the Camera Bokeh activity.
+ Provides a different view of the controls than the default (landscape)
+ layout.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1" >
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="0dp"
+ android:layout_height="fill_parent"
+ android:layout_weight="2" >
+
+ <Spinner
+ android:id="@+id/cameras_selection"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"/>
+
+ <TextView
+ android:id="@+id/test_label"
+ android:layout_height="wrap_content"
+ android:layout_width="fill_parent"
+ android:padding="2dp"
+ android:textSize="16sp"
+ android:gravity="left" />
+
+ <Button
+ android:id="@+id/next_button"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:text="@string/next_button_text" />
+
+ </LinearLayout>
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1" >
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="0dp"
+ android:layout_height="fill_parent"
+ android:layout_weight="3" >
+
+ <TextureView
+ android:id="@+id/preview_view"
+ android:layout_height="0dp"
+ android:layout_width="fill_parent"
+ android:layout_weight="3" />
+ <TextView
+ android:id="@+id/preview_label"
+ android:layout_height="wrap_content"
+ android:layout_width="fill_parent"
+ android:padding="2dp"
+ android:textSize="16sp"
+ android:gravity="center" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="0dp"
+ android:layout_height="fill_parent"
+ android:layout_weight="3" >
+
+ <ImageView
+ android:id="@+id/image_view"
+ android:layout_height="0dp"
+ android:layout_width="fill_parent"
+ android:layout_weight="3" />
+ <TextView
+ android:id="@+id/image_label"
+ android:layout_height="wrap_content"
+ android:layout_width="fill_parent"
+ android:padding="2dp"
+ android:textSize="16sp"
+ android:gravity="center" />
+
+ </LinearLayout>
+
+ </LinearLayout>
+
+ <include layout="@layout/pass_fail_buttons" />
+
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/OWNERS b/apps/CtsVerifier/res/layout/OWNERS
new file mode 100644
index 00000000000..349a259b0b4
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/OWNERS
@@ -0,0 +1,7 @@
+# Bug component: 41727 = per-file camera_*.xml
+# Bug component: 41727 = per-file cam_*.xml
+# Bug component: 41727 = per-file co_main.xml,ci_main.xml,cb_main.xml,cf_main.xml
+
+per-file camera_*.xml = file:platform/frameworks/av:/camera/OWNERS
+per-file cam_*.xml = file:platform/frameworks/av:/camera/OWNERS
+per-file co_main.xml,ci_main.xml,cb_main.xml,cf_main.xml = file:platform/frameworks/av:/camera/OWNERS \ No newline at end of file
diff --git a/apps/CtsVerifier/res/layout/co_main.xml b/apps/CtsVerifier/res/layout/co_main.xml
index e3ddf491656..ad402549ee6 100644
--- a/apps/CtsVerifier/res/layout/co_main.xml
+++ b/apps/CtsVerifier/res/layout/co_main.xml
@@ -62,7 +62,8 @@
android:id="@+id/format_view"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
- android:layout_weight="4" />
+ android:layout_weight="4"
+ android:scaleType="fitCenter" />
<TextView
android:id="@+id/format_label"
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackLatencyActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackLatencyActivity.java
index 2e5046aca67..c97edc752ee 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackLatencyActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackLatencyActivity.java
@@ -744,9 +744,9 @@ public class AudioLoopbackLatencyActivity extends PassFailButtons.Activity {
class LoopbackLatencyRequirements {
public static final int MPC_NONE = 0;
- public static final int MPC_R = 1;
- public static final int MPC_S = 2;
- public static final int MPC_T = 3;
+ public static final int MPC_R = Build.VERSION_CODES.R;
+ public static final int MPC_S = Build.VERSION_CODES.S;
+ public static final int MPC_T = Build.VERSION_CODES.TIRAMISU;
String mResultsString = new String();
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/RingerModeActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/RingerModeActivity.java
index 9e27cb3e1ac..73fc7428579 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/RingerModeActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/RingerModeActivity.java
@@ -68,7 +68,9 @@ public class RingerModeActivity extends InteractiveVerifierActivity {
private final static String PKG = "com.android.cts.verifier";
private final static long TIME_TO_PLAY = 2000;
private final static int MP3_TO_PLAY = R.raw.testmp3;
- private final static int ASYNC_TIMING_TOLERANCE_MS = 50;
+ // TODO replace sleeps with blocking receiver of ACTION_VOLUME_CHANGED intent for
+ // volume operations (AudioManager.setStreamVolume and .adjustVolume)
+ private static final int ASYNC_TIMING_TOLERANCE_MS = 150;
private AudioManager mAudioManager;
private boolean mHasVibrator;
@@ -781,7 +783,7 @@ public class RingerModeActivity extends InteractiveVerifierActivity {
// 7 to 1: success
mAudioManager.setStreamVolume(
AudioManager.STREAM_SYSTEM, 1, AudioManager.FLAG_ALLOW_RINGER_MODES);
- if (1 != mAudioManager.getStreamVolume(AudioManager.STREAM_SYSTEM)) {
+ if (1 != mAudioManager.getStreamVolume(AudioManager.STREAM_SYSTEM)) {
setFailed();
return;
}
@@ -911,6 +913,11 @@ public class RingerModeActivity extends InteractiveVerifierActivity {
}
mAudioManager.adjustStreamVolume(stream, ADJUST_SAME, 0);
+ try {
+ Thread.sleep(ASYNC_TIMING_TOLERANCE_MS);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
// volume raise
mAudioManager.setStreamVolume(stream, 1, 0);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/bokeh/CameraBokehActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/bokeh/CameraBokehActivity.java
index 55791c61fdb..3a7bc72cc56 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/bokeh/CameraBokehActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/bokeh/CameraBokehActivity.java
@@ -15,16 +15,8 @@
*/
package com.android.cts.verifier.camera.bokeh;
-import com.android.cts.verifier.PassFailButtons;
-import com.android.cts.verifier.R;
-
-import com.android.ex.camera2.blocking.BlockingCameraManager;
-import com.android.ex.camera2.blocking.BlockingCameraManager.BlockingOpenException;
-import com.android.ex.camera2.blocking.BlockingStateCallback;
-import com.android.ex.camera2.blocking.BlockingSessionCallback;
-
import android.app.AlertDialog;
-import android.content.res.Configuration;
+import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
@@ -32,6 +24,7 @@ import android.graphics.ColorFilter;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
+import android.graphics.PointF;
import android.graphics.RectF;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
@@ -43,9 +36,9 @@ import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.Capability;
import android.hardware.camera2.params.StreamConfigurationMap;
-import android.hardware.camera2.TotalCaptureResult;
import android.media.Image;
import android.media.ImageReader;
import android.os.Bundle;
@@ -56,9 +49,10 @@ import android.util.Size;
import android.util.SparseArray;
import android.view.Menu;
import android.view.MenuItem;
-import android.view.View;
+import android.view.OrientationEventListener;
import android.view.Surface;
import android.view.TextureView;
+import android.view.View;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
@@ -68,14 +62,19 @@ import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
-import android.content.Context;
-import java.lang.Math;
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+import com.android.ex.camera2.blocking.BlockingCameraManager;
+import com.android.ex.camera2.blocking.BlockingCameraManager.BlockingOpenException;
+import com.android.ex.camera2.blocking.BlockingSessionCallback;
+import com.android.ex.camera2.blocking.BlockingStateCallback;
+
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.HashMap;
import java.util.Comparator;
+import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.Set;
@@ -131,6 +130,8 @@ public class CameraBokehActivity extends PassFailButtons.Activity
private HashMap<String, ArrayList<Capability>> mTestCases = new HashMap<>();
private int mCurrentCameraIndex = -1;
private String mCameraId;
+ private int mCameraSensorOrientation;
+ private int mCameraLensFacing;
private CameraCaptureSession mCaptureSession;
private CameraDevice mCameraDevice;
@@ -204,6 +205,8 @@ public class CameraBokehActivity extends PassFailButtons.Activity
}
};
+ private OrientationEventListener mOrientationEventListener = null;
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -305,6 +308,13 @@ public class CameraBokehActivity extends PassFailButtons.Activity
mBlockingCameraManager = new BlockingCameraManager(mCameraManager);
mCameraListener = new BlockingStateCallback();
+
+ mOrientationEventListener = new OrientationEventListener(getApplicationContext()) {
+ @Override
+ public void onOrientationChanged(int orientation) {
+ configurePreviewTextureTransform();
+ }
+ };
}
/**
@@ -417,6 +427,12 @@ public class CameraBokehActivity extends PassFailButtons.Activity
}
@Override
+ public void onDestroy() {
+ super.onDestroy();
+ mOrientationEventListener.disable();
+ }
+
+ @Override
public String getTestDetails() {
StringBuilder reportBuilder = new StringBuilder();
reportBuilder.append("Tested combinations:\n");
@@ -550,7 +566,11 @@ public class CameraBokehActivity extends PassFailButtons.Activity
mCurrentColorFilter = null;
mImageView.clearColorFilter();
}
+
mImageView.setImageBitmap(bitmap);
+ if (format == ImageFormat.YUV_420_888) {
+ configureImageViewTransform();
+ }
}
});
}
@@ -611,6 +631,10 @@ public class CameraBokehActivity extends PassFailButtons.Activity
// Update untested cameras
mUntestedCameras.remove("All combinations for Camera " + mCameraId);
+ mCameraSensorOrientation =
+ mCameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
+ mCameraLensFacing = mCameraCharacteristics.get(CameraCharacteristics.LENS_FACING);
+
StreamConfigurationMap config =
mCameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
Size[] jpegSizes = config.getOutputSizes(ImageFormat.JPEG);
@@ -691,9 +715,8 @@ public class CameraBokehActivity extends PassFailButtons.Activity
}
}
- private void configurePreviewTextureTransform() {
+ private int getDisplayRotation() {
int rotation = getWindowManager().getDefaultDisplay().getRotation();
- Configuration config = getResources().getConfiguration();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0: degrees = 0; break;
@@ -701,42 +724,117 @@ public class CameraBokehActivity extends PassFailButtons.Activity
case Surface.ROTATION_180: degrees = 180; break;
case Surface.ROTATION_270: degrees = 270; break;
}
- Matrix matrix = mPreviewView.getTransform(null);
- int deviceOrientation = Configuration.ORIENTATION_PORTRAIT;
- if ((degrees % 180 == 0 && config.orientation == Configuration.ORIENTATION_LANDSCAPE) ||
- (degrees % 180 == 90 && config.orientation == Configuration.ORIENTATION_PORTRAIT)) {
- deviceOrientation = Configuration.ORIENTATION_LANDSCAPE;
- }
- int effectiveWidth = mPreviewSize.getWidth();
- int effectiveHeight = mPreviewSize.getHeight();
- if (deviceOrientation == Configuration.ORIENTATION_PORTRAIT) {
- int temp = effectiveWidth;
- effectiveWidth = effectiveHeight;
- effectiveHeight = temp;
+ return degrees;
+ }
+
+ /**
+ * Calculate the matrix required to center the preview with the correct rotation, such that
+ * the image is not cropped and either the width or height perfectly fills the available space.
+ * This is to compensate for the default behavior of TextureView, which is to not rotate the
+ * image and to completely fill the texture in both dimensions.
+ */
+ private void configurePreviewTextureTransform() {
+ int displayRotation = getDisplayRotation();
+
+ Matrix matrix = new Matrix();
+
+ mPreviewView.getSurfaceTexture().setDefaultBufferSize(mPreviewSize.getWidth(),
+ mPreviewSize.getHeight());
+ RectF viewRect = new RectF(0, 0, mPreviewView.getWidth(), mPreviewView.getHeight());
+
+ float expectedPreviewWidth, expectedPreviewHeight;
+ if ((360 + mCameraSensorOrientation - displayRotation) % 180 == 0) {
+ expectedPreviewWidth = mPreviewSize.getWidth();
+ expectedPreviewHeight = mPreviewSize.getHeight();
+ } else {
+ expectedPreviewWidth = mPreviewSize.getHeight();
+ expectedPreviewHeight = mPreviewSize.getWidth();
}
- RectF viewRect = new RectF(0, 0, mPreviewTexWidth, mPreviewTexHeight);
- RectF bufferRect = new RectF(0, 0, effectiveWidth, effectiveHeight);
- float centerX = viewRect.centerX();
- float centerY = viewRect.centerY();
- bufferRect.offset(centerX - bufferRect.centerX(),
- centerY - bufferRect.centerY());
+ float viewAspectRatio = viewRect.width() / viewRect.height();
+ float imageAspectRatio = expectedPreviewWidth / expectedPreviewHeight;
+ final PointF scale;
- matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
+ if (viewAspectRatio > imageAspectRatio) {
+ scale = new PointF((viewRect.height() / viewRect.width())
+ * ((float) mPreviewSize.getHeight() / (float) mPreviewSize.getWidth()), 1f);
+ } else {
+ scale = new PointF(1f, (viewRect.width() / viewRect.height())
+ * ((float) mPreviewSize.getWidth() / (float) mPreviewSize.getHeight()));
+ }
+
+ if (displayRotation % 180 != 0) {
+ float multiplier = viewAspectRatio > imageAspectRatio
+ ? expectedPreviewWidth / expectedPreviewHeight
+ : expectedPreviewHeight / expectedPreviewWidth;
+ scale.x *= multiplier;
+ scale.y *= multiplier;
+ }
- matrix.postRotate((360 - degrees) % 360, centerX, centerY);
- if ((degrees % 180) == 90) {
- int temp = effectiveWidth;
- effectiveWidth = effectiveHeight;
- effectiveHeight = temp;
+ matrix.setScale(scale.x, scale.y, viewRect.centerX(), viewRect.centerY());
+ if (displayRotation != 0) {
+ matrix.postRotate(360 - displayRotation, viewRect.centerX(), viewRect.centerY());
}
- // Scale to fit view, avoiding any crop
- float scale = Math.min(mPreviewTexWidth / (float) effectiveWidth,
- mPreviewTexHeight / (float) effectiveHeight);
- matrix.postScale(scale, scale, centerX, centerY);
mPreviewView.setTransform(matrix);
}
+
+ /**
+ * Calculate the matrix required to center the capture with the correct rotation, such that
+ * the image is not cropped and either the width or height perfectly fills the available space.
+ * This is to compensate for the default behavior of ImageView, which is to not rotate the
+ * image and to render it in its original size, positioned at 0, 0.
+ */
+ private void configureImageViewTransform() {
+ int displayRotation = getDisplayRotation();
+ int rotation = (360 + mCameraSensorOrientation - displayRotation) % 360;
+ if (mCameraLensFacing == CameraMetadata.LENS_FACING_FRONT) {
+ rotation = (mCameraSensorOrientation + displayRotation) % 360;
+ }
+
+ Matrix matrix = new Matrix();
+
+ RectF viewRect = new RectF(0, 0, mImageView.getMeasuredWidth(),
+ mImageView.getMeasuredHeight());
+
+ float expectedPreviewWidth, expectedPreviewHeight;
+ if (rotation % 180 == 0) {
+ expectedPreviewWidth = mPreviewSize.getWidth();
+ expectedPreviewHeight = mPreviewSize.getHeight();
+ } else {
+ expectedPreviewWidth = mPreviewSize.getHeight();
+ expectedPreviewHeight = mPreviewSize.getWidth();
+ }
+
+ final PointF scale = new PointF(0, 0);
+
+ float widthRatio = expectedPreviewWidth / viewRect.width();
+ float heightRatio = expectedPreviewHeight / viewRect.height();
+ if (widthRatio / heightRatio > 1.0f) {
+ // Scale width to fit
+ scale.x = 1.0f / widthRatio;
+ scale.y = 1.0f / widthRatio;
+ } else {
+ // Scale height to fit
+ scale.x = 1.0f / heightRatio;
+ scale.y = 1.0f / heightRatio;
+ }
+
+ matrix.setScale(scale.x, scale.y, 0, 0);
+ if (rotation % 360 != 0) {
+ matrix.postRotate(rotation, 0, 0);
+ }
+
+ RectF imageRect = new RectF(0, 0, mPreviewSize.getWidth(), mPreviewSize.getHeight());
+ matrix.mapRect(imageRect, imageRect);
+ matrix.postTranslate(-imageRect.left, -imageRect.top);
+ matrix.postTranslate(viewRect.width() / 2 - imageRect.width() / 2,
+ viewRect.height() / 2 - imageRect.height() / 2);
+
+ mImageView.setScaleType(ImageView.ScaleType.MATRIX);
+ mImageView.setImageMatrix(matrix);
+ }
+
/**
* Starts a background thread and its {@link Handler}.
*/
@@ -762,6 +860,8 @@ public class CameraBokehActivity extends PassFailButtons.Activity
private void startPreview() {
try {
+ mOrientationEventListener.disable();
+
if (mPreviewSize == null || !mPreviewSize.equals(mNextCombination.mPreviewSize) ||
mYuvImageReader == null) {
mPreviewSize = mNextCombination.mPreviewSize;
@@ -800,6 +900,10 @@ public class CameraBokehActivity extends PassFailButtons.Activity
mStillCaptureRequest = mStillCaptureRequestBuilder.build();
mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback, mCameraHandler);
+
+ if (mOrientationEventListener.canDetectOrientation()) {
+ mOrientationEventListener.enable();
+ }
} catch (CameraAccessException e) {
e.printStackTrace();
}
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 703779f550d..8682dd75693 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
@@ -276,7 +276,10 @@ public class ItsService extends Service implements SensorEventListener {
private volatile boolean mNeedsLockedAWB = false;
private volatile boolean mDoAE = true;
private volatile boolean mDoAF = true;
- private Set<Pair<String, String>> mUnavailablePhysicalCameras;
+ private final LinkedBlockingQueue<String> unavailableEventQueue = new LinkedBlockingQueue<>();
+ private final LinkedBlockingQueue<Pair<String, String>> unavailablePhysicalCamEventQueue =
+ new LinkedBlockingQueue<>();
+ private Set<String> mUnavailablePhysicalCameras;
class MySensorEvent {
@@ -286,6 +289,31 @@ public class ItsService extends Service implements SensorEventListener {
public float values[];
}
+ CameraManager.AvailabilityCallback ac = new CameraManager.AvailabilityCallback() {
+ @Override
+ public void onCameraAvailable(String cameraId) {
+ super.onCameraAvailable(cameraId);
+ }
+
+ @Override
+ public void onCameraUnavailable(String cameraId) {
+ super.onCameraUnavailable(cameraId);
+ unavailableEventQueue.offer(cameraId);
+ }
+
+ @Override
+ public void onPhysicalCameraAvailable(String cameraId, String physicalCameraId) {
+ super.onPhysicalCameraAvailable(cameraId, physicalCameraId);
+ unavailablePhysicalCamEventQueue.remove(new Pair<>(cameraId, physicalCameraId));
+ }
+
+ @Override
+ public void onPhysicalCameraUnavailable(String cameraId, String physicalCameraId) {
+ super.onPhysicalCameraUnavailable(cameraId, physicalCameraId);
+ unavailablePhysicalCamEventQueue.offer(new Pair<>(cameraId, physicalCameraId));
+ }
+ };
+
static class VideoRecordingObject {
private static final int INVALID_FRAME_RATE = -1;
@@ -470,6 +498,9 @@ public class ItsService extends Service implements SensorEventListener {
public void openCameraDevice(String cameraId) throws ItsException {
Logt.i(TAG, String.format("Opening camera %s", cameraId));
+ // Get initial physical unavailable callbacks without opening camera
+ mCameraManager.registerAvailabilityCallback(ac, mCameraHandler);
+
try {
if (mMemoryQuota == -1) {
// Initialize memory quota on this device
@@ -495,15 +526,22 @@ public class ItsService extends Service implements SensorEventListener {
}
try {
- mUnavailablePhysicalCameras = getUnavailablePhysicalCameras();
+ mUnavailablePhysicalCameras = getUnavailablePhysicalCameras(
+ unavailablePhysicalCamEventQueue, cameraId);
+ Log.i(TAG, "Unavailable cameras:" + Arrays.asList(mUnavailablePhysicalCameras.toString()));
mCamera = mBlockingCameraManager.openCamera(cameraId, mCameraListener, mCameraHandler);
mCameraCharacteristics = mCameraManager.getCameraCharacteristics(cameraId);
-
+ // The camera should be in available->unavailable state.
+ unavailableEventQueue.clear();
boolean isLogicalCamera = hasCapability(
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA);
if (isLogicalCamera) {
Set<String> physicalCameraIds = mCameraCharacteristics.getPhysicalCameraIds();
for (String id : physicalCameraIds) {
+ if (mUnavailablePhysicalCameras.contains(id)) {
+ Log.i(TAG, "Physical camera id not available: " + id);
+ continue;
+ }
mPhysicalCameraChars.put(id, mCameraManager.getCameraCharacteristics(id));
}
}
@@ -512,6 +550,8 @@ public class ItsService extends Service implements SensorEventListener {
throw new ItsException("Failed to open camera", e);
} catch (BlockingOpenException e) {
throw new ItsException("Failed to open camera (after blocking)", e);
+ } catch (Exception e) {
+ throw new ItsException("Failed to get unavailable physical cameras", e);
}
mSocketRunnableObj.sendResponse("cameraOpened", "");
}
@@ -522,6 +562,7 @@ public class ItsService extends Service implements SensorEventListener {
Logt.i(TAG, "Closing camera");
mCamera.close();
mCamera = null;
+ mCameraManager.unregisterAvailabilityCallback(ac);
}
} catch (Exception e) {
throw new ItsException("Failed to close device");
@@ -861,6 +902,8 @@ public class ItsService extends Service implements SensorEventListener {
} else if ("getMaxCamcorderProfileSize".equals(cmdObj.getString("cmdName"))) {
String cameraId = cmdObj.getString("cameraId");
doGetMaxCamcorderProfileSize(cameraId);
+ } else if ("getAvailablePhysicalCameraProperties".equals(cmdObj.getString("cmdName"))) {
+ doGetAvailablePhysicalCameraProperties();
} else {
throw new ItsException("Unknown command: " + cmd);
}
@@ -961,6 +1004,25 @@ public class ItsService extends Service implements SensorEventListener {
}
}
+ public void sendResponse(String tag, HashMap<String, CameraCharacteristics> props)
+ throws ItsException {
+ try {
+ JSONArray jsonSurfaces = new JSONArray();
+ int n = props.size();
+ for (String s : props.keySet()) {
+ JSONObject jsonSurface = new JSONObject();
+ jsonSurface.put(s, ItsSerializer.serialize(props.get(s)));
+ jsonSurfaces.put(jsonSurface);
+ }
+ Object objs[] = new Object[2];
+ objs[0] = "availablePhysicalCameraProperties";
+ objs[1] = jsonSurfaces;
+ mSerializerQueue.put(objs);
+ } catch (Exception e) {
+ throw new ItsException("Interrupted: ", e);
+ }
+ }
+
public void sendVideoRecordingObject(VideoRecordingObject obj)
throws ItsException {
try {
@@ -1139,6 +1201,27 @@ public class ItsService extends Service implements SensorEventListener {
}
}
+ private void doGetAvailablePhysicalCameraProperties() throws ItsException {
+ mSocketRunnableObj.sendResponse("availablePhysicalCameraProperties", mPhysicalCameraChars);
+ }
+
+ private Set<String> getUnavailablePhysicalCameras(
+ LinkedBlockingQueue<Pair<String, String>> queue, String cameraId) throws Exception {
+ Set<String> unavailablePhysicalCameras = new HashSet<String>();
+ while (true) {
+ Pair<String, String> unavailableIdCombo = queue.poll(
+ AVAILABILITY_TIMEOUT_MS, java.util.concurrent.TimeUnit.MILLISECONDS);
+ if (unavailableIdCombo == null) {
+ // No more entries in the queue. Break out of the loop and return.
+ break;
+ }
+ if (cameraId.equals(unavailableIdCombo.first)) {
+ unavailablePhysicalCameras.add(unavailableIdCombo.second);
+ }
+ };
+ return unavailablePhysicalCameras;
+ }
+
private void doGetCameraIds() throws ItsException {
if (mItsCameraIdList == null) {
mItsCameraIdList = ItsUtils.getItsCompatibleCameraIds(mCameraManager);
@@ -1223,10 +1306,8 @@ public class ItsService extends Service implements SensorEventListener {
try {
JSONArray cameras = new JSONArray();
JSONObject jsonObj = new JSONObject();
- for (Pair<String, String> p : mUnavailablePhysicalCameras) {
- if (cameraId.equals(p.first)) {
- cameras.put(p.second);
- }
+ for (String p : mUnavailablePhysicalCameras) {
+ cameras.put(p);
}
jsonObj.put("unavailablePhysicalCamerasArray", cameras);
Log.i(TAG, "unavailablePhysicalCameras : " +
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/orientation/CameraOrientationActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/orientation/CameraOrientationActivity.java
index 66e632b8ee8..88cd7d4b160 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/orientation/CameraOrientationActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/orientation/CameraOrientationActivity.java
@@ -18,10 +18,13 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
+import android.graphics.RectF;
import android.hardware.Camera;
+import android.hardware.Camera.CameraInfo;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
+import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
@@ -78,6 +81,9 @@ implements OnClickListener, SurfaceHolder.Callback {
private int mState = STATE_OFF;
private boolean mSizeAdjusted;
+ private int mPreviewRotation;
+ private int mPictureRotation;
+
private StringBuilder mReportBuilder = new StringBuilder();
private final TreeSet<String> mTestedCombinations = new TreeSet<String>();
private final TreeSet<String> mUntestedCombinations = new TreeSet<String>();
@@ -287,11 +293,27 @@ implements OnClickListener, SurfaceHolder.Callback {
// set preview orientation
int degrees = mPreviewOrientations.get(mNextPreviewOrientation);
- mCamera.setDisplayOrientation(degrees);
- android.hardware.Camera.CameraInfo info =
- new android.hardware.Camera.CameraInfo();
- android.hardware.Camera.getCameraInfo(mCurrentCameraId, info);
+ CameraInfo info = new CameraInfo();
+ Camera.getCameraInfo(mCurrentCameraId, info);
+ int displayRotation = getWindowManager().getDefaultDisplay().getRotation();
+ switch (displayRotation) {
+ case Surface.ROTATION_90: degrees += 90; break;
+ case Surface.ROTATION_180: degrees += 180; break;
+ case Surface.ROTATION_270: degrees += 270; break;
+ }
+ degrees %= 360;
+
+ if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
+ mPictureRotation = (info.orientation + degrees) % 360;
+ mPreviewRotation = (360 - mPictureRotation) % 360; // compensate the mirror
+ } else { // back-facing
+ mPictureRotation = (info.orientation - degrees + 360) % 360;
+ mPreviewRotation = mPictureRotation;
+ }
+
+ mCamera.setDisplayOrientation(mPreviewRotation);
+
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
TextView cameraExtraLabel =
(TextView) findViewById(R.id.instruction_extra_text);
@@ -484,30 +506,31 @@ implements OnClickListener, SurfaceHolder.Callback {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
// adjust camera preview to match output image's aspect ratio
- if(!mSizeAdjusted && mState == STATE_PREVIEW) {
- int viewWidth = mFormatView.getWidth();
- int viewHeight = mFormatView.getHeight();
- int newWidth, newHeight;
+ if (!mSizeAdjusted && mState == STATE_PREVIEW) {
+ int viewWidth = mFormatView.getMeasuredWidth();
+ int viewHeight = mFormatView.getMeasuredHeight();
- if (viewWidth == 0 || viewHeight == 0){
+ if (viewWidth == 0 || viewHeight == 0) {
return;
}
- if (mPreviewOrientations.get(mNextPreviewOrientation) == 0
- || mPreviewOrientations.get(mNextPreviewOrientation) == 180) {
- // make preview width same as output image width,
- // then calculate height using output image's height/width ratio
- newWidth = viewWidth;
- newHeight = (int) (viewWidth * ((double) mOptimalPreviewSize.height /
- (double) mOptimalPreviewSize.width));
- }
- else {
- newHeight = viewHeight;
- newWidth = (int) (viewHeight * ((double) mOptimalPreviewSize.height /
- (double) mOptimalPreviewSize.width));
+ Matrix m = new Matrix(Matrix.IDENTITY_MATRIX);
+ RectF previewRect;
+ if (mPreviewRotation == 0 || mPreviewRotation == 180) {
+ previewRect = new RectF(0, 0, mOptimalPreviewSize.width,
+ mOptimalPreviewSize.height);
+ } else {
+ previewRect = new RectF(0, 0, mOptimalPreviewSize.height,
+ mOptimalPreviewSize.width);
}
-
- LayoutParams layoutParams = new LayoutParams(newWidth, newHeight);
+ m.setRectToRect(previewRect,
+ new RectF(0, 0, viewWidth, viewHeight),
+ Matrix.ScaleToFit.CENTER);
+ RectF dstRect = new RectF();
+ m.mapRect(dstRect, previewRect);
+
+ LayoutParams layoutParams =
+ new LayoutParams((int) dstRect.width(), (int) dstRect.height());
mCameraView.setLayoutParams(layoutParams);
mSizeAdjusted = true;
mTakePictureButton.setEnabled(true);
@@ -523,7 +546,6 @@ implements OnClickListener, SurfaceHolder.Callback {
Bitmap inputImage;
inputImage = BitmapFactory.decodeByteArray(data, 0, data.length);
- int degrees = mPreviewOrientations.get(mNextPreviewOrientation);
android.hardware.Camera.CameraInfo info =
new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(mCurrentCameraId, info);
@@ -531,7 +553,6 @@ implements OnClickListener, SurfaceHolder.Callback {
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
// mirror the image along vertical axis
mirrorX = new float[] {-1, 0, 0, 0, 1, 1, 0, 0, 1};
- degrees = (360 - degrees) % 360; // compensate the mirror
} else {
// leave image the same via identity matrix
mirrorX = new float[] {1, 0, 0, 0, 1, 0, 0, 0, 1};
@@ -541,7 +562,7 @@ implements OnClickListener, SurfaceHolder.Callback {
Matrix matrixMirrorX = new Matrix();
matrixMirrorX.setValues(mirrorX);
Matrix mat = new Matrix();
- mat.postRotate(degrees);
+ mat.postRotate(mPictureRotation);
mat.postConcat(matrixMirrorX);
Bitmap inputImageAdjusted = Bitmap.createBitmap(inputImage,
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WifiLockdownTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WifiLockdownTestActivity.java
index 26be3212b57..e258c132e7d 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WifiLockdownTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WifiLockdownTestActivity.java
@@ -57,6 +57,7 @@ public class WifiLockdownTestActivity extends PassFailButtons.TestListActivity {
private static final String DISALLOW_SHARING_ADMIN_CONFIGURED_WIFI_ID =
"DISALLOW_SHARING_ADMIN_CONFIGURED_WIFI";
+ private WifiManager mWifiManager;
private WifiConfigCreator mConfigCreator;
private ButtonInfo[] mSwitchLockdownOffButtonInfos;
private ButtonInfo[] mSwitchLockdownOnButtonInfos;
@@ -64,9 +65,9 @@ public class WifiLockdownTestActivity extends PassFailButtons.TestListActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- WifiManager wifiManager = TestAppSystemServiceFactory.getWifiManager(this,
+ mWifiManager = TestAppSystemServiceFactory.getWifiManager(this,
DeviceAdminTestReceiver.class);
- mConfigCreator = new WifiConfigCreator(this, wifiManager);
+ mConfigCreator = new WifiConfigCreator(this, mWifiManager);
setContentView(R.layout.wifi_lockdown);
setInfoResources(R.string.device_owner_wifi_lockdown_test,
R.string.device_owner_wifi_lockdown_info, 0);
@@ -159,23 +160,27 @@ public class WifiLockdownTestActivity extends PassFailButtons.TestListActivity {
R.string.device_owner_wifi_config_unlocked_removal_test,
R.string.device_owner_wifi_config_unlocked_removal_test_info,
mSwitchLockdownOffButtonInfos));
- adapter.add(Utils.createInteractiveTestItem(this,
- DISALLOW_SHARING_ADMIN_CONFIGURED_WIFI_ID,
- R.string.device_owner_disallow_sharing_admin_configure_wifi,
- R.string.device_owner_disallow_sharing_admin_configure_wifi_info,
- new ButtonInfo[] {
+
+ boolean isDppSupported = mWifiManager.isEasyConnectSupported();
+ if (isDppSupported) {
+ adapter.add(Utils.createInteractiveTestItem(this,
+ DISALLOW_SHARING_ADMIN_CONFIGURED_WIFI_ID,
+ R.string.device_owner_disallow_sharing_admin_configure_wifi,
+ R.string.device_owner_disallow_sharing_admin_configure_wifi_info,
+ new ButtonInfo[] {
new ButtonInfo(
R.string.device_owner_user_restriction_set,
CommandReceiverActivity.createSetCurrentUserRestrictionIntent(
- UserManager.DISALLOW_SHARING_ADMIN_CONFIGURED_WIFI, true)),
+ UserManager.DISALLOW_SHARING_ADMIN_CONFIGURED_WIFI, true)),
new ButtonInfo(
R.string.device_owner_settings_go,
new Intent(Settings.ACTION_WIFI_SETTINGS)),
new ButtonInfo(
R.string.device_owner_user_restriction_unset,
CommandReceiverActivity.createSetCurrentUserRestrictionIntent(
- UserManager.DISALLOW_SHARING_ADMIN_CONFIGURED_WIFI, false))
- }));
+ UserManager.DISALLOW_SHARING_ADMIN_CONFIGURED_WIFI, false))
+ }));
+ }
}
private int convertKeyManagement(int radioButtonId) {
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/DisableAnimationRule.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/DisableAnimationRule.java
index dcf0a960a10..ae1684f6a78 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/DisableAnimationRule.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/DisableAnimationRule.java
@@ -16,55 +16,9 @@
package com.android.compatibility.common.util;
-import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
+public class DisableAnimationRule extends OverrideAnimationScaleRule {
-import androidx.annotation.NonNull;
-
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-
-public class DisableAnimationRule extends BeforeAfterRule {
- @NonNull
- private final GlobalSetting mWindowAnimationScaleSetting = new GlobalSetting(
- "window_animation_scale");
- @NonNull
- private final GlobalSetting mTransitionAnimationScaleSetting = new GlobalSetting(
- "transition_animation_scale");
- @NonNull
- private final GlobalSetting mAnimatorDurationScaleSetting = new GlobalSetting(
- "animator_duration_scale");
-
- @Override
- protected void onBefore(Statement base, Description description) throws Throwable {
- mWindowAnimationScaleSetting.put("0");
- mTransitionAnimationScaleSetting.put("0");
- mAnimatorDurationScaleSetting.put("0");
- }
-
- @Override
- protected void onAfter(Statement base, Description description) throws Throwable {
- mWindowAnimationScaleSetting.restore();
- mTransitionAnimationScaleSetting.restore();
- mAnimatorDurationScaleSetting.restore();
- }
-
- private static class GlobalSetting {
- @NonNull
- private final String mName;
-
- private String mInitialValue;
-
- public GlobalSetting(@NonNull String name) {
- mName = name;
- }
-
- public void put(@NonNull String value) {
- mInitialValue = runShellCommand("settings get global " + mName);
- runShellCommand("settings put global " + mName + " " + value);
- }
-
- public void restore() {
- runShellCommand("settings put global " + mName + " " + mInitialValue);
- }
+ public DisableAnimationRule() {
+ super(0);
}
}
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/MediaUtils.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/MediaUtils.java
index c3b6900c64e..e8ed8c7e7a1 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/MediaUtils.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/MediaUtils.java
@@ -1479,6 +1479,14 @@ public class MediaUtils {
if (screenSize < (FIRST_SDK_IS_AT_LEAST_R ? 3.3 : 2.5)) return false;
if (screenSize > 8.0) return false;
if (!hasDeviceGotBattery()) return false;
+ // handheld nature is not exposed to package manager, so for now,
+ // in addition to physical screen size, the following checks are
+ // also required:
+ if (!pm.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)) return false;
+ if (isWatch()) return false;
+ if (isTv()) return false;
+ if (isAutomotive()) return false;
+ if (isPc()) return false;
return true;
}
@@ -1487,6 +1495,14 @@ public class MediaUtils {
if (screenSize < 7.0) return false;
if (screenSize > 18.0) return false;
if (!hasDeviceGotBattery()) return false;
+ // tablet nature is not exposed to package manager, so for now,
+ // in addition to physical screen size, the following checks are
+ // also required:
+ if (!pm.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)) return false;
+ if (isWatch()) return false;
+ if (isTv()) return false;
+ if (isAutomotive()) return false;
+ if (isPc()) return false;
return true;
}
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/OverrideAnimationScaleRule.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/OverrideAnimationScaleRule.java
new file mode 100644
index 00000000000..2d50bfa91cd
--- /dev/null
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/OverrideAnimationScaleRule.java
@@ -0,0 +1,79 @@
+/*
+ * 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.compatibility.common.util;
+
+import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
+
+import androidx.annotation.NonNull;
+
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+
+public class OverrideAnimationScaleRule extends BeforeAfterRule {
+
+ @NonNull
+ private final GlobalSetting mWindowAnimationScaleSetting = new GlobalSetting(
+ "window_animation_scale");
+ @NonNull
+ private final GlobalSetting mTransitionAnimationScaleSetting = new GlobalSetting(
+ "transition_animation_scale");
+ @NonNull
+ private final GlobalSetting mAnimatorDurationScaleSetting = new GlobalSetting(
+ "animator_duration_scale");
+
+ private final float mAnimationScale;
+
+ public OverrideAnimationScaleRule(float animationScale) {
+ mAnimationScale = animationScale;
+ }
+
+ @Override
+ protected void onBefore(Statement base, Description description) {
+ var value = Float.toString(mAnimationScale);
+ mWindowAnimationScaleSetting.put(value);
+ mTransitionAnimationScaleSetting.put(value);
+ mAnimatorDurationScaleSetting.put(value);
+ }
+
+ @Override
+ protected void onAfter(Statement base, Description description) {
+ mWindowAnimationScaleSetting.restore();
+ mTransitionAnimationScaleSetting.restore();
+ mAnimatorDurationScaleSetting.restore();
+ }
+
+ private static class GlobalSetting {
+ @NonNull
+ private final String mName;
+
+ private String mInitialValue;
+
+ public GlobalSetting(@NonNull String name) {
+ mName = name;
+ }
+
+ public void put(@NonNull String value) {
+ mInitialValue = runShellCommand("settings get global " + mName);
+ runShellCommand("settings put global " + mName + " " + value);
+ }
+
+ public void restore() {
+ runShellCommand("settings put global " + mName + " " + mInitialValue);
+ }
+ }
+}
diff --git a/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesValidConfigTest.java b/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesValidConfigTest.java
index c0dfae1b9b2..5d792d93789 100644
--- a/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesValidConfigTest.java
+++ b/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesValidConfigTest.java
@@ -29,6 +29,7 @@ import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
import java.util.Set;
@@ -37,6 +38,9 @@ import javax.xml.parsers.DocumentBuilderFactory;
public final class CompatChangesValidConfigTest extends CompatChangeGatingTestCase {
+ private static final long RESTRICT_STORAGE_ACCESS_FRAMEWORK = 141600225L;
+ private static final String FEATURE_WATCH = "android.hardware.type.watch";
+
private static final Set<String> OVERRIDES_ALLOWLIST = ImmutableSet.of(
// This change id will sometimes remain enabled if an instrumentation test fails.
"ALLOW_TEST_API_ACCESS"
@@ -114,6 +118,15 @@ public final class CompatChangesValidConfigTest extends CompatChangeGatingTestCa
changes.add(change);
}
}
+
+ // RESTRICT_STORAGE_ACCESS_FRAMEWORK not supported on wear
+ if (getDevice().hasFeature(FEATURE_WATCH)) {
+ for (Iterator<Change> it = changes.iterator(); it.hasNext();) {
+ if (it.next().changeId == RESTRICT_STORAGE_ACCESS_FRAMEWORK) {
+ it.remove();
+ }
+ }
+ }
return changes;
}
diff --git a/hostsidetests/appcompat/strictjavapackages/src/android/compat/sjp/cts/StrictJavaPackagesTest.java b/hostsidetests/appcompat/strictjavapackages/src/android/compat/sjp/cts/StrictJavaPackagesTest.java
index 478cde28351..46f1b478230 100644
--- a/hostsidetests/appcompat/strictjavapackages/src/android/compat/sjp/cts/StrictJavaPackagesTest.java
+++ b/hostsidetests/appcompat/strictjavapackages/src/android/compat/sjp/cts/StrictJavaPackagesTest.java
@@ -758,6 +758,8 @@ public class StrictJavaPackagesTest extends BaseHostJUnit4Test {
new ImmutableMap.Builder<String, ImmutableSet<String>>()
.put("/apex/com.android.btservices/app/Bluetooth/Bluetooth.apk",
BLUETOOTH_APK_IN_APEX_BURNDOWN_LIST)
+ .put("/apex/com.android.btservices/app/BluetoothArc/BluetoothArc.apk",
+ BLUETOOTH_APK_IN_APEX_BURNDOWN_LIST)
.put("/apex/com.android.btservices/app/BluetoothGoogle/BluetoothGoogle.apk",
BLUETOOTH_APK_IN_APEX_BURNDOWN_LIST)
.put("/apex/com.android.bluetooth/app/BluetoothGoogle/BluetoothGoogle.apk",
diff --git a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
index 9e12ad04492..a31088616c3 100644
--- a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
+++ b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
@@ -35,6 +35,7 @@ import android.provider.DocumentsContract.Document;
import android.provider.DocumentsContract.Path;
import android.provider.DocumentsProvider;
import android.provider.Settings;
+import android.support.test.uiautomator.Configurator;
import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiObjectNotFoundException;
import android.support.test.uiautomator.UiScrollable;
@@ -50,6 +51,7 @@ import androidx.core.os.BuildCompat;
import com.android.cts.documentclient.MyActivity.Result;
import java.io.File;
+import java.time.Duration;
import java.util.List;
/**
@@ -73,6 +75,9 @@ public class DocumentsClientTest extends DocumentsClientTestCase {
private static final String STORAGE_AUTHORITY = "com.android.externalstorage.documents";
private static final String DEFAULT_DEVICE_NAME = "Internal storage";
+ private static final Duration SCROLL_ACKNOWLEDGEMENT_TIMEOUT = Duration.ofMillis(500);
+ private long mOriginalScrollAcknowledgementTimeout;
+
private UiSelector findRootListSelector() throws UiObjectNotFoundException {
return new UiSelector().resourceId(
getDocumentsUiPackageId() + ":id/container_roots").childSelector(
@@ -193,12 +198,24 @@ public class DocumentsClientTest extends DocumentsClientTestCase {
public void setUp() throws Exception {
super.setUp();
deleteTestDirectory();
+
+ // Extending ScrollAcknowledgmentTimeout so that we can avoid a bug in ui automator
+ // (b/266374704) and stabilize scrolling with UiScrollable.
+ mOriginalScrollAcknowledgementTimeout =
+ Configurator.getInstance().getScrollAcknowledgmentTimeout();
+ if (SCROLL_ACKNOWLEDGEMENT_TIMEOUT.toMillis() > mOriginalScrollAcknowledgementTimeout) {
+ Configurator.getInstance()
+ .setScrollAcknowledgmentTimeout(SCROLL_ACKNOWLEDGEMENT_TIMEOUT.toMillis());
+ }
}
@Override
public void tearDown() throws Exception {
super.tearDown();
deleteTestDirectory();
+
+ Configurator.getInstance()
+ .setScrollAcknowledgmentTimeout(mOriginalScrollAcknowledgementTimeout);
}
public void testOpenSimple() throws Exception {
diff --git a/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/EncryptionAppTest.java b/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/EncryptionAppTest.java
index 92f53ac21b8..a41c4b9f084 100644
--- a/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/EncryptionAppTest.java
+++ b/hostsidetests/appsecurity/test-apps/EncryptionApp/src/com/android/cts/encryptionapp/EncryptionAppTest.java
@@ -337,6 +337,7 @@ public class EncryptionAppTest extends InstrumentationTestCase {
assertQuery(2, MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
if (Environment.isExternalStorageEmulated()) {
+ pollForExternalStorageMountedState();
assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
final File expected = new File(
@@ -360,6 +361,15 @@ public class EncryptionAppTest extends InstrumentationTestCase {
ceFile::exists);
}
+ private void pollForExternalStorageMountedState() {
+ for (int i = 0; i < 10; i++) {
+ if (Environment.getExternalStorageState().equalsIgnoreCase(Environment.MEDIA_MOUNTED)) {
+ break;
+ }
+ SystemClock.sleep(500);
+ }
+ }
+
private void assertQuery(int count, int flags) throws Exception {
final Intent intent = new Intent(TEST_ACTION);
assertEquals("activity", count, mPm.queryIntentActivities(intent, flags).size());
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index 2ec37fdc71f..c1fa58b3410 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -602,7 +602,7 @@ public class ManagedProfileTest extends BaseManagedProfileTest {
assertActivityInForeground("android/com.android.internal.app.ResolverActivity", userId);
} catch (AssertionError e) {
CLog.v("ResolverActivity is not the default: " + e);
- assertActivityInForeground(resolveActivity("android.intent.action.SEND"), userId);
+ assertActivityInForeground(getCustomResolverActivity(), userId);
}
}
@@ -647,4 +647,16 @@ public class ManagedProfileTest extends BaseManagedProfileTest {
return outputs[1];
}
+
+ private String getCustomResolverActivity() throws Exception {
+ final String[] outputs = getDevice().executeShellCommand(
+ "cmd overlay lookup android android:string/config_customResolverActivity")
+ .split("\n");
+
+ String customResolverActivity = resolveActivity("android.intent.action.SEND");
+ if (outputs != null && outputs.length >= 1 && outputs[0] != null && !outputs[0].isEmpty()) {
+ customResolverActivity = outputs[0];
+ }
+ return customResolverActivity;
+ }
}
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/CecOperand.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/CecOperand.java
index a5be8bfe4c4..38765c2fb28 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/CecOperand.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/CecOperand.java
@@ -56,6 +56,7 @@ public enum CecOperand {
VENDOR_COMMAND(0x89),
GIVE_DEVICE_VENDOR_ID(0x8c),
MENU_REQUEST(0x8d),
+ MENU_STATUS(0x8e),
GIVE_POWER_STATUS(0x8f),
REPORT_POWER_STATUS(0x90),
GET_MENU_LANGUAGE(0x91),
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecGeneralProtocolTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecGeneralProtocolTest.java
index 19d2c757d0e..e1d9216f7e2 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecGeneralProtocolTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecGeneralProtocolTest.java
@@ -95,10 +95,12 @@ public final class HdmiCecGeneralProtocolTest extends BaseHdmiCecCtsTest {
throws Exception {
// DeviceDiscoveryAction will send GIVE_OSD_NAME and GIVE_DEVICE_VENDOR_ID
// HotplugDetectionAction will send GIVE_PHYSICAL_ADDRESS
+ // PowerStatusMonitorAction will send GIVE_POWER_STATUS
List<CecOperand> excludeOperands = new ArrayList<>();
excludeOperands.add(CecOperand.GIVE_PHYSICAL_ADDRESS);
excludeOperands.add(CecOperand.GIVE_DEVICE_VENDOR_ID);
excludeOperands.add(CecOperand.GIVE_OSD_NAME);
+ excludeOperands.add(CecOperand.GIVE_POWER_STATUS);
hdmiCecClient.sendCecMessage(message, params);
// Default timeout for the incoming command to arrive in response to a request is 2 secs
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecPowerStatusTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecPowerStatusTest.java
index cf9ea396177..3ca4ee0e277 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecPowerStatusTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecPowerStatusTest.java
@@ -461,10 +461,12 @@ public final class HdmiCecPowerStatusTest extends BaseHdmiCecCtsTest {
TimeUnit.SECONDS.sleep(waitSeconds);
waitForTransitionTo(HdmiCecConstants.CEC_POWER_STATUS_ON);
- // Send <UCP> [Power]. DUT should go to standby.
+ // Send <UCP> [Power]. DUT should remain in ON state.
hdmiCecClient.sendUserControlPressAndRelease(
source, HdmiCecConstants.CEC_KEYCODE_POWER, false);
- waitForTransitionTo(HdmiCecConstants.CEC_POWER_STATUS_STANDBY);
+ waitForTransitionTo(HdmiCecConstants.CEC_POWER_STATUS_ON);
+
+ sendDeviceToSleep();
// Send <UCP> [Power]. DUT should wakeup.
hdmiCecClient.sendUserControlPressAndRelease(
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecStartupTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecStartupTest.java
index 93d81003e30..7cd2e1f87ba 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecStartupTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecStartupTest.java
@@ -66,7 +66,7 @@ public final class HdmiCecStartupTest extends BaseHdmiCecCtsTest {
CecOperand.DEVICE_VENDOR_ID, CecOperand.GIVE_POWER_STATUS,
CecOperand.GET_MENU_LANGUAGE, CecOperand.ACTIVE_SOURCE,
CecOperand.REQUEST_ACTIVE_SOURCE, CecOperand.GIVE_PHYSICAL_ADDRESS,
- CecOperand.GIVE_SYSTEM_AUDIO_MODE_STATUS));
+ CecOperand.REPORT_POWER_STATUS, CecOperand.GIVE_SYSTEM_AUDIO_MODE_STATUS));
allowedMessages.addAll(expectedMessages);
device.reboot();
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecVendorCommandsTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecVendorCommandsTest.java
index 96e026dc196..d44f44ccaaa 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecVendorCommandsTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecVendorCommandsTest.java
@@ -22,8 +22,8 @@ import android.hdmicec.cts.BaseHdmiCecCtsTest;
import android.hdmicec.cts.CecMessage;
import android.hdmicec.cts.CecOperand;
import android.hdmicec.cts.HdmiControlManagerUtility;
-import android.hdmicec.cts.LogicalAddress;
import android.hdmicec.cts.LogHelper;
+import android.hdmicec.cts.LogicalAddress;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
@@ -31,9 +31,9 @@ import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import org.junit.Rule;
+import org.junit.Test;
import org.junit.rules.RuleChain;
import org.junit.runner.RunWith;
-import org.junit.Test;
/** HDMI CEC test to verify device vendor specific commands (Section 11.2.9) */
@RunWith(DeviceJUnit4ClassRunner.class)
@@ -157,7 +157,7 @@ public final class HdmiCecVendorCommandsTest extends BaseHdmiCecCtsTest {
String params = CecMessage.formatParams(VENDOR_ID);
params += CecMessage.formatParams("010203");
hdmiCecClient.sendCecMessage(
- LogicalAddress.TV, CecOperand.VENDOR_COMMAND_WITH_ID, params);
+ hdmiCecClient.getSelfDevice(), CecOperand.VENDOR_COMMAND_WITH_ID, params);
LogHelper.assertLog(
device, TEST_LOG_TAG, "Received vendor command with correct vendor ID");
@@ -176,7 +176,8 @@ public final class HdmiCecVendorCommandsTest extends BaseHdmiCecCtsTest {
LogHelper.waitForLog(getDevice(), TEST_LOG_TAG, 10, REGISTERED_LISTENER);
String params = CecMessage.formatParams("010203");
- hdmiCecClient.sendCecMessage(LogicalAddress.TV, CecOperand.VENDOR_COMMAND, params);
+ hdmiCecClient.sendCecMessage(
+ hdmiCecClient.getSelfDevice(), CecOperand.VENDOR_COMMAND, params);
LogHelper.assertLog(device, TEST_LOG_TAG, "Received vendor command without vendor ID");
} finally {
@@ -194,7 +195,8 @@ public final class HdmiCecVendorCommandsTest extends BaseHdmiCecCtsTest {
LogHelper.waitForLog(getDevice(), TEST_LOG_TAG, 10, REGISTERED_LISTENER);
String params = CecMessage.formatParams("010203");
- hdmiCecClient.sendCecMessage(LogicalAddress.TV, CecOperand.VENDOR_COMMAND, params);
+ hdmiCecClient.sendCecMessage(
+ hdmiCecClient.getSelfDevice(), CecOperand.VENDOR_COMMAND, params);
LogHelper.assertLog(device, TEST_LOG_TAG, "Received vendor command without vendor ID");
} finally {
@@ -214,7 +216,7 @@ public final class HdmiCecVendorCommandsTest extends BaseHdmiCecCtsTest {
String params = CecMessage.formatParams(VENDOR_ID);
params += CecMessage.formatParams("010203");
hdmiCecClient.sendCecMessage(
- LogicalAddress.TV, CecOperand.VENDOR_COMMAND_WITH_ID, params);
+ hdmiCecClient.getSelfDevice(), CecOperand.VENDOR_COMMAND_WITH_ID, params);
LogHelper.assertLogDoesNotContain(
device, TEST_LOG_TAG, "Received vendor command with correct vendor ID");
diff --git a/hostsidetests/incrementalinstall/appvalidator/src/android/incrementalinstall/inrementaltestappvalidation/AppValidationTest.java b/hostsidetests/incrementalinstall/appvalidator/src/android/incrementalinstall/inrementaltestappvalidation/AppValidationTest.java
index 6654d5b7ff7..5dc7dd8d320 100644
--- a/hostsidetests/incrementalinstall/appvalidator/src/android/incrementalinstall/inrementaltestappvalidation/AppValidationTest.java
+++ b/hostsidetests/incrementalinstall/appvalidator/src/android/incrementalinstall/inrementaltestappvalidation/AppValidationTest.java
@@ -39,6 +39,11 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
@RunWith(AndroidJUnit4.class)
@AppModeFull
public class AppValidationTest {
@@ -87,6 +92,17 @@ public class AppValidationTest {
assertEquals(isIncfsInstallation,
new PathChecker().isIncFsPath(installedAppInfo.installationPath));
assertEquals(versionCode, installedAppInfo.versionCode);
+ // Read the whole file to make sure it's streamed.
+ readFullFile(new File(installedAppInfo.installationPath, "base.apk"));
+ }
+
+ private static void readFullFile(File file) throws IOException {
+ try (InputStream inputStream = new FileInputStream(file)) {
+ byte[] buffer = new byte[1024];
+ while (inputStream.read(buffer) != -1) {
+ // ignore
+ }
+ }
}
private void launchTestApp() throws Exception {
diff --git a/hostsidetests/incrementalinstall/src/android/incrementalinstall/cts/IncrementalInstallTest.java b/hostsidetests/incrementalinstall/src/android/incrementalinstall/cts/IncrementalInstallTest.java
index 81e3304a849..c050b2cf2ea 100644
--- a/hostsidetests/incrementalinstall/src/android/incrementalinstall/cts/IncrementalInstallTest.java
+++ b/hostsidetests/incrementalinstall/src/android/incrementalinstall/cts/IncrementalInstallTest.java
@@ -23,6 +23,7 @@ import static android.incrementalinstall.common.Consts.SupportedComponents.ON_CR
import static android.incrementalinstall.common.Consts.SupportedComponents.ON_CREATE_COMPONENT_2;
import static android.incrementalinstall.common.Consts.SupportedComponents.UNCOMPRESSED_NATIVE_COMPONENT;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
@@ -32,6 +33,7 @@ import android.platform.test.annotations.LargeTest;
import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
import com.android.ddmlib.Log;
+import com.android.tradefed.device.TestDeviceOptions;
import com.android.tradefed.log.LogUtil;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
@@ -95,12 +97,18 @@ public class IncrementalInstallTest extends BaseHostJUnit4Test {
private static final String INSTALL_SUCCESS_OUTPUT = "Success";
private static final long DEFAULT_TEST_TIMEOUT_MS = 60 * 1000L;
private static final long DEFAULT_MAX_TIMEOUT_TO_OUTPUT_MS = 60 * 1000L; // 1min
+ private static final long DEFAULT_ADB_TIMEOUT_MS = 5 * 60 * 1000L; // 5mins
private final int TEST_APP_V1_VERSION = 1;
private final int TEST_APP_V2_VERSION = 2;
private CompatibilityBuildHelper mBuildHelper;
@Before
public void setup() throws Exception {
+ // Increase default timeout to 5 mins to accommodate for slow restarting devices.
+ TestDeviceOptions options = new TestDeviceOptions();
+ options.setAdbCommandTimeout(DEFAULT_ADB_TIMEOUT_MS);
+ getDevice().setOptions(options);
+
assumeTrue(hasIncrementalFeature());
mBuildHelper = new CompatibilityBuildHelper(getBuild());
assumeTrue(adbBinarySupportsIncremental());
@@ -254,9 +262,9 @@ public class IncrementalInstallTest extends BaseHostJUnit4Test {
getDevice().executeAdbCommand("push",
getFilePathFromBuildInfo(TEST_APP_DYNAMIC_CODE_NAME + SIG_SUFFIX),
deviceLocalPath);
- getDevice().executeShellCommand(
+ assertEquals("Success\n", getDevice().executeShellCommand(
String.format("pm install-incremental -p %s %s", TEST_APP_PACKAGE_NAME,
- deviceLocalPath + TEST_APP_DYNAMIC_CODE_NAME));
+ deviceLocalPath + TEST_APP_DYNAMIC_CODE_NAME)));
// Verify still on Incremental.
verifyInstallationTypeAndVersion(TEST_APP_PACKAGE_NAME, /* isIncfs= */ true,
TEST_APP_V1_VERSION);
diff --git a/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/ScopedStorageDeviceTest.java b/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/ScopedStorageDeviceTest.java
index 55c431cb092..351b2d074ba 100644
--- a/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/ScopedStorageDeviceTest.java
+++ b/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/ScopedStorageDeviceTest.java
@@ -79,6 +79,7 @@ import static android.scopedstorage.cts.lib.TestUtils.installAppWithStoragePermi
import static android.scopedstorage.cts.lib.TestUtils.isAppInstalled;
import static android.scopedstorage.cts.lib.TestUtils.listAs;
import static android.scopedstorage.cts.lib.TestUtils.openWithMediaProvider;
+import static android.scopedstorage.cts.lib.TestUtils.pollForPermission;
import static android.scopedstorage.cts.lib.TestUtils.queryAudioFile;
import static android.scopedstorage.cts.lib.TestUtils.queryFile;
import static android.scopedstorage.cts.lib.TestUtils.queryFileExcludingPending;
@@ -1321,7 +1322,7 @@ public class ScopedStorageDeviceTest extends ScopedStorageBaseDeviceTest {
getExifMetadataFromRawResource(R.raw.img_with_metadata);
try (InputStream in =
getContext().getResources().openRawResource(R.raw.img_with_metadata);
- FileOutputStream out = new FileOutputStream(imgFile)) {
+ FileOutputStream out = new FileOutputStream(imgFile)) {
// Dump the image we have to external storage
FileUtils.copy(in, out);
// Sync file to disk to ensure file is fully written to the lower fs.
@@ -1335,6 +1336,8 @@ public class ScopedStorageDeviceTest extends ScopedStorageBaseDeviceTest {
// Grant A_M_L and verify access to sensitive data
grantPermission(APP_C.getPackageName(), Manifest.permission.ACCESS_MEDIA_LOCATION);
+ pollForPermission(APP_C.getPackageName(),
+ Manifest.permission.ACCESS_MEDIA_LOCATION, /* granted */ true);
HashMap<String, String> exifFromTestApp =
readExifMetadataFromTestApp(APP_C, imgFile.getPath());
assertExifMetadataMatch(exifFromTestApp, originalExif);
@@ -1344,6 +1347,8 @@ public class ScopedStorageDeviceTest extends ScopedStorageBaseDeviceTest {
APP_C.getPackageName(), Manifest.permission.ACCESS_MEDIA_LOCATION);
// revokePermission waits for permission status to be updated, but MediaProvider still
// needs to get permission change callback and clear its permission cache.
+ pollForPermission(APP_C.getPackageName(),
+ Manifest.permission.ACCESS_MEDIA_LOCATION, /* granted */ false);
Thread.sleep(500);
exifFromTestApp = readExifMetadataFromTestApp(APP_C, imgFile.getPath());
assertExifMetadataMismatch(exifFromTestApp, originalExif);
@@ -1352,6 +1357,8 @@ public class ScopedStorageDeviceTest extends ScopedStorageBaseDeviceTest {
grantPermission(APP_C.getPackageName(), Manifest.permission.ACCESS_MEDIA_LOCATION);
// grantPermission waits for permission status to be updated, but MediaProvider still
// needs to get permission change callback and clear its permission cache.
+ pollForPermission(APP_C.getPackageName(),
+ Manifest.permission.ACCESS_MEDIA_LOCATION, /* granted */ true);
Thread.sleep(500);
exifFromTestApp = readExifMetadataFromTestApp(APP_C, imgFile.getPath());
assertExifMetadataMatch(exifFromTestApp, originalExif);
diff --git a/hostsidetests/security/src/android/security/cts/KernelConfigTest.java b/hostsidetests/security/src/android/security/cts/KernelConfigTest.java
index 814363d7e56..44e616dfccc 100644
--- a/hostsidetests/security/src/android/security/cts/KernelConfigTest.java
+++ b/hostsidetests/security/src/android/security/cts/KernelConfigTest.java
@@ -207,7 +207,7 @@ public class KernelConfigTest extends BaseHostJUnit4Test {
break;
}
/* Samsung Exynos SoCs */
- else if (line.startsWith("EXYNOS") || line.startsWith("S5E")) {
+ else if (line.startsWith("EXYNOS")) {
hardware = line;
break;
}
@@ -237,8 +237,6 @@ public class KernelConfigTest extends BaseHostJUnit4Test {
put("EXYNOS7872", null);
put("EXYNOS7885", null);
put("EXYNOS9610", null);
- put("S5E8825", null);
- put("S5E9925", null);
put("Kirin980", null);
put("Kirin970", null);
put("Kirin810", null);
diff --git a/hostsidetests/time/host/src/android/time/cts/host/LocationTimeZoneManagerHostTest.java b/hostsidetests/time/host/src/android/time/cts/host/LocationTimeZoneManagerHostTest.java
index b71617405ca..5d2beb3c41b 100644
--- a/hostsidetests/time/host/src/android/time/cts/host/LocationTimeZoneManagerHostTest.java
+++ b/hostsidetests/time/host/src/android/time/cts/host/LocationTimeZoneManagerHostTest.java
@@ -59,10 +59,24 @@ import java.time.Duration;
import java.util.Arrays;
import java.util.List;
-/** Host-side CTS tests for the location time zone manager service. */
+/**
+ * Host-side CTS tests for the location time zone manager service. There are plenty of unit tests
+ * for individual components but manufacturers don't have to run them. This test is intended to
+ * provide confidence that the specific device configuration is likely to work as it should, i.e.
+ * this tests the actual location_time_zone_manager service on a given device.
+ *
+ * <p>Because there are a large set of possibilities, this test has to handle them all:
+ * <ul>
+ * <li>location_time_zone_manager service disabled</li>
+ * <li>location_time_zone_manager service enabled, but no LTZPs configured</li>
+ * <li>location_time_zone_manager service enabled, with LTZPs configured</li>
+ * </ul>
+ */
@RunWith(DeviceJUnit4ClassRunner.class)
public class LocationTimeZoneManagerHostTest extends BaseHostJUnit4Test {
+ private static final String NON_EXISTENT_TZPS_APP_PACKAGE = "foobar";
+
private boolean mOriginalLocationEnabled;
private boolean mOriginalAutoDetectionEnabled;
private boolean mOriginalGeoDetectionEnabled;
@@ -80,8 +94,8 @@ public class LocationTimeZoneManagerHostTest extends BaseHostJUnit4Test {
mLocationTimeZoneManagerShellHelper =
new LocationTimeZoneManagerShellHelper(shellCommandExecutor);
- // Confirm the service being tested is present. It can be turned off, in which case there's
- // nothing to test.
+ // Confirm the service being tested is present. It can be turned off permanently in config,
+ // in which case there's nothing about it to test.
mLocationTimeZoneManagerShellHelper.assumeLocationTimeZoneManagerIsPresent();
// Install the app that hosts the fake providers.
@@ -96,28 +110,50 @@ public class LocationTimeZoneManagerHostTest extends BaseHostJUnit4Test {
mDeviceConfigPreTestState = mDeviceConfigShellHelper.setSyncModeForTest(
SYNC_DISABLED_MODE_UNTIL_REBOOT, NAMESPACE_SYSTEM_TIME);
- // All tests start with the location_time_zone_manager disabled so that providers can be
- // configured.
+ // These original values try to record the raw value of the settings before the test ran:
+ // they may be ignored by the location_time_zone_manager service when they have no meaning.
+ // Unfortunately, we cannot tell if the value returned is the result of setting defaults or
+ // real values, which means we may not return things exactly as they were. To do better
+ // would require looking at raw settings values and use internal knowledge of settings keys.
+ mOriginalAutoDetectionEnabled = mTimeZoneDetectorShellHelper.isAutoDetectionEnabled();
+ mOriginalGeoDetectionEnabled = mTimeZoneDetectorShellHelper.isGeoDetectionEnabled();
+
mLocationTimeZoneManagerShellHelper.stop();
- // Make sure locations is enabled, otherwise the geo detection feature will be disabled
- // whatever the geolocation detection setting is set to.
+ // Make sure location is enabled, otherwise the geo detection feature cannot operate.
mOriginalLocationEnabled = mLocationShellHelper.isLocationEnabledForCurrentUser();
if (!mOriginalLocationEnabled) {
mLocationShellHelper.setLocationEnabledForCurrentUser(true);
}
- // Make sure automatic time zone detection is enabled, otherwise the geo detection feature
- // will be disabled whatever the geolocation detection setting is set to.
- mOriginalAutoDetectionEnabled = mTimeZoneDetectorShellHelper.isAutoDetectionEnabled();
- if (!mOriginalAutoDetectionEnabled) {
- mTimeZoneDetectorShellHelper.setAutoDetectionEnabled(true);
+ // Restart the location_time_zone_manager with a do-nothing test config; some settings
+ // values cannot be set when the service knows that the settings won't be used. Devices
+ // can be encountered with the location_time_zone_manager enabled but with no providers
+ // installed. Starting the service with a valid-looking test provider config means we know
+ // settings changes will be accepted regardless of the real config.
+ String testPrimaryLocationTimeZoneProviderPackageName = NON_EXISTENT_TZPS_APP_PACKAGE;
+ String testSecondaryLocationTimeZoneProviderPackageName = null;
+ mLocationTimeZoneManagerShellHelper.startWithTestProviders(
+ testPrimaryLocationTimeZoneProviderPackageName,
+ testSecondaryLocationTimeZoneProviderPackageName,
+ false /* recordProviderStates */);
+
+ // Begin all tests with auto detection turned off.
+ if (mOriginalAutoDetectionEnabled) {
+ mTimeZoneDetectorShellHelper.setAutoDetectionEnabled(false);
}
- // On devices with no location time zone providers (e.g. AOSP), we cannot turn geo detection
- // on until the test LTZPs are configured as the time_zone_detector will refuse.
- mOriginalGeoDetectionEnabled = mTimeZoneDetectorShellHelper.isGeoDetectionEnabled();
+ // We set the device settings so that location detection will be used.
+ if (!mOriginalGeoDetectionEnabled) {
+ mTimeZoneDetectorShellHelper.setGeoDetectionEnabled(true);
+ }
+ // All tests begin with the location_time_zone_manager stopped so that fake providers can be
+ // configured.
+ mLocationTimeZoneManagerShellHelper.stop();
+
+ // Make sure the fake provider APK install started above has completed before tests try to
+ // use the fake providers.
FakeTimeZoneProviderAppShellHelper fakeTimeZoneProviderAppShellHelper =
new FakeTimeZoneProviderAppShellHelper(shellCommandExecutor);
// Delay until the fake TZPS app can be found.
@@ -135,24 +171,33 @@ public class LocationTimeZoneManagerHostTest extends BaseHostJUnit4Test {
return;
}
- // Reset the geoDetectionEnabled state while there is at least one LTZP configured: this
- // setting cannot be modified if there are no LTZPs on the device, e.g. on AOSP.
- mTimeZoneDetectorShellHelper.setGeoDetectionEnabled(mOriginalGeoDetectionEnabled);
-
- // Turn off the service before we reset configuration, otherwise it will restart itself
- // repeatedly.
+ // Restart the location_time_zone_manager with a test config so that the device can be set
+ // back to the starting state regardless of how the test left things.
mLocationTimeZoneManagerShellHelper.stop();
+ String testPrimaryLocationTimeZoneProviderPackageName = NON_EXISTENT_TZPS_APP_PACKAGE;
+ String testSecondaryLocationTimeZoneProviderPackageName = null;
+ mLocationTimeZoneManagerShellHelper.startWithTestProviders(
+ testPrimaryLocationTimeZoneProviderPackageName,
+ testSecondaryLocationTimeZoneProviderPackageName,
+ false /* recordProviderStates */);
+
+ if (mTimeZoneDetectorShellHelper.isGeoDetectionEnabled() != mOriginalGeoDetectionEnabled) {
+ mTimeZoneDetectorShellHelper.setGeoDetectionEnabled(mOriginalGeoDetectionEnabled);
+ }
- // Reset settings and server flags as best we can.
if (mTimeZoneDetectorShellHelper.isAutoDetectionEnabled()
!= mOriginalAutoDetectionEnabled) {
mTimeZoneDetectorShellHelper.setAutoDetectionEnabled(mOriginalAutoDetectionEnabled);
}
+
+ // Everything else can be reset without worrying about the providers.
+ mLocationTimeZoneManagerShellHelper.stop();
+
mLocationShellHelper.setLocationEnabledForCurrentUser(mOriginalLocationEnabled);
mDeviceConfigShellHelper.restoreDeviceConfigStateForTest(mDeviceConfigPreTestState);
- // Attempt to start the service. It may not start if there are no providers configured,
- // but that is ok.
+ // Attempt to start the service without test providers. It may not start if there are no
+ // providers configured, but that is ok.
mLocationTimeZoneManagerShellHelper.start();
}
@@ -165,7 +210,10 @@ public class LocationTimeZoneManagerHostTest extends BaseHostJUnit4Test {
testPrimaryLocationTimeZoneProviderPackageName,
testSecondaryLocationTimeZoneProviderPackageName,
true /* recordProviderStates */);
- mTimeZoneDetectorShellHelper.setGeoDetectionEnabled(true);
+
+ // Turn on auto detection, which should activate the location time zone algorithm.
+ mTimeZoneDetectorShellHelper.setAutoDetectionEnabled(true);
+
mPrimaryFakeTimeZoneProviderShellHelper.assertCreated();
mSecondaryFakeTimeZoneProviderShellHelper.assertNotCreated();
@@ -219,7 +267,8 @@ public class LocationTimeZoneManagerHostTest extends BaseHostJUnit4Test {
testPrimaryLocationTimeZoneProviderPackageName,
testSecondaryLocationTimeZoneProviderPackageName,
true /* recordProviderStates */);
- mTimeZoneDetectorShellHelper.setGeoDetectionEnabled(true);
+ // Turn on auto detection, which should activate the location time zone algorithm.
+ mTimeZoneDetectorShellHelper.setAutoDetectionEnabled(true);
mPrimaryFakeTimeZoneProviderShellHelper.assertCreated();
mSecondaryFakeTimeZoneProviderShellHelper.assertNotCreated();
@@ -280,7 +329,8 @@ public class LocationTimeZoneManagerHostTest extends BaseHostJUnit4Test {
testPrimaryLocationTimeZoneProviderPackageName,
testSecondaryLocationTimeZoneProviderPackageName,
true /* recordProviderStates */);
- mTimeZoneDetectorShellHelper.setGeoDetectionEnabled(true);
+ // Turn on auto detection, which should activate the location time zone algorithm.
+ mTimeZoneDetectorShellHelper.setAutoDetectionEnabled(true);
mPrimaryFakeTimeZoneProviderShellHelper.assertCreated();
mSecondaryFakeTimeZoneProviderShellHelper.assertNotCreated();
@@ -333,7 +383,8 @@ public class LocationTimeZoneManagerHostTest extends BaseHostJUnit4Test {
testPrimaryLocationTimeZoneProviderPackageName,
testSecondaryLocationTimeZoneProviderPackageName,
true /* recordProviderStates */);
- mTimeZoneDetectorShellHelper.setGeoDetectionEnabled(true);
+ // Turn on auto detection, which should activate the location time zone algorithm.
+ mTimeZoneDetectorShellHelper.setAutoDetectionEnabled(true);
mPrimaryFakeTimeZoneProviderShellHelper.assertNotCreated();
mSecondaryFakeTimeZoneProviderShellHelper.assertCreated();
@@ -382,7 +433,8 @@ public class LocationTimeZoneManagerHostTest extends BaseHostJUnit4Test {
testPrimaryLocationTimeZoneProviderPackageName,
testSecondaryLocationTimeZoneProviderPackageName,
true /* recordProviderStates*/);
- mTimeZoneDetectorShellHelper.setGeoDetectionEnabled(true);
+ // Turn on auto detection, which should activate the location time zone algorithm.
+ mTimeZoneDetectorShellHelper.setAutoDetectionEnabled(true);
mPrimaryFakeTimeZoneProviderShellHelper.assertCreated();
mSecondaryFakeTimeZoneProviderShellHelper.assertCreated();
diff --git a/hostsidetests/time/host/src/android/time/cts/host/LocationTimeZoneManagerStatsTest.java b/hostsidetests/time/host/src/android/time/cts/host/LocationTimeZoneManagerStatsTest.java
index e591d2d1a9f..9ab524d9dc1 100644
--- a/hostsidetests/time/host/src/android/time/cts/host/LocationTimeZoneManagerStatsTest.java
+++ b/hostsidetests/time/host/src/android/time/cts/host/LocationTimeZoneManagerStatsTest.java
@@ -53,10 +53,15 @@ import java.util.List;
import java.util.Set;
import java.util.function.Function;
-/** Host-side CTS tests for the location time zone manager service stats logging. */
+/**
+ * Host-side CTS tests for the location time zone manager service stats logging. Very similar to
+ * {@link LocationTimeZoneManagerHostTest} but focused on stats logging.
+ */
@RunWith(DeviceJUnit4ClassRunner.class)
public class LocationTimeZoneManagerStatsTest extends BaseHostJUnit4Test {
+ private static final String NON_EXISTENT_TZPS_APP_PACKAGE = "foobar";
+
private static final int PRIMARY_PROVIDER_INDEX = 0;
private static final int SECONDARY_PROVIDER_INDEX = 1;
@@ -80,8 +85,8 @@ public class LocationTimeZoneManagerStatsTest extends BaseHostJUnit4Test {
mLocationTimeZoneManagerShellHelper =
new LocationTimeZoneManagerShellHelper(shellCommandExecutor);
- // Confirm the service being tested is present. It can be turned off, in which case there's
- // nothing to test.
+ // Confirm the service being tested is present. It can be turned off permanently in config,
+ // in which case there's nothing about it to test.
mLocationTimeZoneManagerShellHelper.assumeLocationTimeZoneManagerIsPresent();
// Install the app that hosts the fake providers.
@@ -92,34 +97,57 @@ public class LocationTimeZoneManagerStatsTest extends BaseHostJUnit4Test {
mLocationShellHelper = new LocationShellHelper(shellCommandExecutor);
mDeviceConfigShellHelper = new DeviceConfigShellHelper(shellCommandExecutor);
+ // Stop device_config updates for the duration of the test.
mDeviceConfigPreTestState = mDeviceConfigShellHelper.setSyncModeForTest(
SYNC_DISABLED_MODE_UNTIL_REBOOT, NAMESPACE_SYSTEM_TIME);
- // All tests start with the location_time_zone_manager disabled so that providers can be
- // configured.
+ // These original values try to record the raw value of the settings before the test ran:
+ // they may be ignored by the location_time_zone_manager service when they have no meaning.
+ // Unfortunately, we cannot tell if the value returned is the result of setting defaults or
+ // real values, which means we may not return things exactly as they were. To do better
+ // would require looking at raw settings values and use internal knowledge of settings keys.
+ mOriginalAutoDetectionEnabled = mTimeZoneDetectorShellHelper.isAutoDetectionEnabled();
+ mOriginalGeoDetectionEnabled = mTimeZoneDetectorShellHelper.isGeoDetectionEnabled();
+
mLocationTimeZoneManagerShellHelper.stop();
- // Make sure locations is enabled, otherwise the geo detection feature will be disabled
- // whatever the geolocation detection setting is set to.
+ // Make sure location is enabled, otherwise the geo detection feature cannot operate.
mOriginalLocationEnabled = mLocationShellHelper.isLocationEnabledForCurrentUser();
if (!mOriginalLocationEnabled) {
mLocationShellHelper.setLocationEnabledForCurrentUser(true);
}
- // Make sure automatic time zone detection is enabled, otherwise the geo detection feature
- // will be disabled whatever the geolocation detection setting is set to
- mOriginalAutoDetectionEnabled = mTimeZoneDetectorShellHelper.isAutoDetectionEnabled();
- if (!mOriginalAutoDetectionEnabled) {
- mTimeZoneDetectorShellHelper.setAutoDetectionEnabled(true);
+ // Restart the location_time_zone_manager with a do-nothing test config; some settings
+ // values cannot be set when the service knows that the settings won't be used. Devices
+ // can be encountered with the location_time_zone_manager enabled but with no providers
+ // installed. Starting the service with a valid-looking test provider config means we know
+ // settings changes will be accepted regardless of the real config.
+ String testPrimaryLocationTimeZoneProviderPackageName = NON_EXISTENT_TZPS_APP_PACKAGE;
+ String testSecondaryLocationTimeZoneProviderPackageName = null;
+ mLocationTimeZoneManagerShellHelper.startWithTestProviders(
+ testPrimaryLocationTimeZoneProviderPackageName,
+ testSecondaryLocationTimeZoneProviderPackageName,
+ false /* recordProviderStates */);
+
+ // Begin all tests with auto detection turned off.
+ if (mOriginalAutoDetectionEnabled) {
+ mTimeZoneDetectorShellHelper.setAutoDetectionEnabled(false);
}
- // On devices with no location time zone providers (e.g. AOSP), we cannot turn geo detection
- // on until the test LTZPs are configured as the time_zone_detector will refuse.
- mOriginalGeoDetectionEnabled = mTimeZoneDetectorShellHelper.isGeoDetectionEnabled();
+ // We set the device settings so that location detection will be used.
+ if (!mOriginalGeoDetectionEnabled) {
+ mTimeZoneDetectorShellHelper.setGeoDetectionEnabled(true);
+ }
- // Make sure that the fake providers used in the tests are available.
+ // All tests begin with the location_time_zone_manager stopped so that fake providers can be
+ // configured.
+ mLocationTimeZoneManagerShellHelper.stop();
+
+ // Make sure the fake provider APK install started above has completed before tests try to
+ // use the fake providers.
FakeTimeZoneProviderAppShellHelper fakeTimeZoneProviderAppShellHelper =
new FakeTimeZoneProviderAppShellHelper(shellCommandExecutor);
+ // Delay until the fake TZPS app can be found.
fakeTimeZoneProviderAppShellHelper.waitForInstallation();
ConfigUtils.removeConfig(device);
@@ -133,27 +161,36 @@ public class LocationTimeZoneManagerStatsTest extends BaseHostJUnit4Test {
return;
}
- // Reset the geoDetectionEnabled state while there is at least one LTZP configured: this
- // setting cannot be modified if there are no LTZPs on the device, e.g. on AOSP.
- mTimeZoneDetectorShellHelper.setGeoDetectionEnabled(mOriginalGeoDetectionEnabled);
-
- // Turn off the service before we reset configuration, otherwise it will restart itself
- // repeatedly.
+ // Restart the location_time_zone_manager with a test config so that the device can be set
+ // back to the starting state regardless of how the test left things.
mLocationTimeZoneManagerShellHelper.stop();
+ String testPrimaryLocationTimeZoneProviderPackageName = NON_EXISTENT_TZPS_APP_PACKAGE;
+ String testSecondaryLocationTimeZoneProviderPackageName = null;
+ mLocationTimeZoneManagerShellHelper.startWithTestProviders(
+ testPrimaryLocationTimeZoneProviderPackageName,
+ testSecondaryLocationTimeZoneProviderPackageName,
+ false /* recordProviderStates */);
+
+ if (mTimeZoneDetectorShellHelper.isGeoDetectionEnabled() != mOriginalGeoDetectionEnabled) {
+ mTimeZoneDetectorShellHelper.setGeoDetectionEnabled(mOriginalGeoDetectionEnabled);
+ }
- // Reset settings and server flags as best we can.
if (mTimeZoneDetectorShellHelper.isAutoDetectionEnabled()
!= mOriginalAutoDetectionEnabled) {
mTimeZoneDetectorShellHelper.setAutoDetectionEnabled(mOriginalAutoDetectionEnabled);
}
+
+ // Everything else can be reset without worrying about the providers.
+ mLocationTimeZoneManagerShellHelper.stop();
+
mLocationShellHelper.setLocationEnabledForCurrentUser(mOriginalLocationEnabled);
ConfigUtils.removeConfig(getDevice());
ReportUtils.clearReports(getDevice());
mDeviceConfigShellHelper.restoreDeviceConfigStateForTest(mDeviceConfigPreTestState);
- // Attempt to start the service. It may not start if there are no providers configured,
- // but that is ok.
+ // Attempt to start the service without test providers. It may not start if there are no
+ // providers configured, but that is ok.
mLocationTimeZoneManagerShellHelper.start();
}
@@ -169,12 +206,12 @@ public class LocationTimeZoneManagerStatsTest extends BaseHostJUnit4Test {
testSecondaryLocationTimeZoneProviderPackageName,
true /* recordProviderStates */);
- // Turn geo detection on and off, twice.
+ // Turn the location detection algorithm on and off, twice.
for (int i = 0; i < 2; i++) {
Thread.sleep(AtomTestUtils.WAIT_TIME_SHORT);
- mTimeZoneDetectorShellHelper.setGeoDetectionEnabled(true);
+ mTimeZoneDetectorShellHelper.setAutoDetectionEnabled(true);
Thread.sleep(AtomTestUtils.WAIT_TIME_SHORT);
- mTimeZoneDetectorShellHelper.setGeoDetectionEnabled(false);
+ mTimeZoneDetectorShellHelper.setAutoDetectionEnabled(false);
}
// Sorted list of events in order in which they occurred.
diff --git a/libs/midi/OWNERS b/libs/midi/OWNERS
new file mode 100644
index 00000000000..0808c5acacc
--- /dev/null
+++ b/libs/midi/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 48436
+philburk@google.com
+pmclean@google.com
+robertwu@google.com
diff --git a/libs/webkit-shared/src/android/webkit/cts/HttpHeader.aidl b/libs/webkit-shared/src/android/webkit/cts/HttpHeader.aidl
new file mode 100644
index 00000000000..644be025b65
--- /dev/null
+++ b/libs/webkit-shared/src/android/webkit/cts/HttpHeader.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2023 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.webkit.cts;
+
+parcelable HttpHeader;
diff --git a/libs/webkit-shared/src/android/webkit/cts/HttpHeader.java b/libs/webkit-shared/src/android/webkit/cts/HttpHeader.java
new file mode 100644
index 00000000000..26e01543a41
--- /dev/null
+++ b/libs/webkit-shared/src/android/webkit/cts/HttpHeader.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2023 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.webkit.cts;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Pair;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class attempts to match the Apache HttpRequest as close as possible so that it can be used
+ * in place of it. The apache HttpRequest is not parcelable.
+ */
+public class HttpHeader implements Parcelable {
+ private final String mHeader;
+ private final String mValue;
+
+ public static final Parcelable.Creator<HttpHeader> CREATOR =
+ new Parcelable.Creator<HttpHeader>() {
+ public HttpHeader createFromParcel(Parcel in) {
+ return new HttpHeader(in);
+ }
+
+ public HttpHeader[] newArray(int size) {
+ return new HttpHeader[size];
+ }
+ };
+
+ /** Create a new HttpHeader from a header name and value string. */
+ public static HttpHeader create(String header, String value) {
+ return new HttpHeader(header, value);
+ }
+
+ /** Convert a list of HttpHeaders to a List of pairs to be used with CtsTestServer. */
+ public static List<Pair<String, String>> asPairList(List<HttpHeader> headers) {
+ List<Pair<String, String>> pairList = new ArrayList<>();
+ if (headers != null) {
+ for (HttpHeader header : headers) {
+ pairList.add(header.getPair());
+ }
+ }
+ return pairList;
+ }
+
+ HttpHeader(Parcel in) {
+ // Note: This must be read in the same order we write
+ // to the parcel in {@link #wroteToParcel(Parcel out, int flags)}.
+ this(in.readString(), in.readString());
+ }
+
+ HttpHeader(String header, String value) {
+ mHeader = header;
+ mValue = value;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ // Note: This must be written in the same order we read
+ // from the parcel in {@link #HttpRequest(Parcel in)}.
+ out.writeString(mHeader);
+ out.writeString(mValue);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ private Pair<String, String> getPair() {
+ return Pair.create(mHeader, mValue);
+ }
+}
diff --git a/libs/webkit-shared/src/android/webkit/cts/IWebServer.aidl b/libs/webkit-shared/src/android/webkit/cts/IWebServer.aidl
index f74f935c31e..77cde38bf83 100644
--- a/libs/webkit-shared/src/android/webkit/cts/IWebServer.aidl
+++ b/libs/webkit-shared/src/android/webkit/cts/IWebServer.aidl
@@ -17,14 +17,24 @@
package android.webkit.cts;
import android.webkit.cts.HttpRequest;
+import android.webkit.cts.HttpHeader;
+
+import java.util.List;
interface IWebServer {
- void start(int sslMode, in @nullable byte[] acceptedIssuerDer);
+ void start(int sslMode, in @nullable byte[] acceptedIssuerDer, int keyResId, int certResId);
void shutdown();
void resetRequestState();
+ String setResponse(
+ String path, String responseString, in List<HttpHeader> responseHeaders);
+
+ String getAbsoluteUrl(String path);
+
+ String getUserAgentUrl();
+
String getDelayedAssetUrl(String path);
String getRedirectingAssetUrl(String path);
@@ -35,7 +45,21 @@ interface IWebServer {
String getBinaryUrl(String mimeType, int contentLength);
+ String getAppCacheUrl();
+
+ int getRequestCount();
+
+ int getRequestCountWithPath(String path);
+
boolean wasResourceRequested(String url);
+ HttpRequest getLastRequest(String path);
+
HttpRequest getLastAssetRequest(String url);
+
+ String getCookieUrl(String path);
+
+ String getSetCookieUrl(String path, String key, String value, String attributes);
+
+ String getLinkedScriptUrl(String path, String url);
} \ No newline at end of file
diff --git a/libs/webkit-shared/src/android/webkit/cts/SharedSdkWebServer.java b/libs/webkit-shared/src/android/webkit/cts/SharedSdkWebServer.java
index 4852f5aa33d..c3ceaf8c84a 100644
--- a/libs/webkit-shared/src/android/webkit/cts/SharedSdkWebServer.java
+++ b/libs/webkit-shared/src/android/webkit/cts/SharedSdkWebServer.java
@@ -20,6 +20,9 @@ import android.os.RemoteException;
import androidx.annotation.Nullable;
+import java.util.Collections;
+import java.util.List;
+
/**
* This class serves as the public fronting API for tests to interact with the CtsTestServer.
*
@@ -34,15 +37,11 @@ public final class SharedSdkWebServer {
mWebServer = webServer;
}
- /** Starts the web server. */
- public void start(@SslMode int sslMode) {
- start(new Config().setSslMode(sslMode));
- }
-
- /** Starts the web server using the provided {@link Config}. */
- public void start(Config config) {
+ /** Starts the web server using the provided parameters}. */
+ public void start(@SslMode int sslMode, @Nullable byte[] acceptedIssuerDer,
+ int keyResId, int certResId) {
try {
- mWebServer.start(config.mSslMode, config.mAcceptedIssuerDer);
+ mWebServer.start(sslMode, acceptedIssuerDer, keyResId, certResId);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
@@ -66,6 +65,42 @@ public final class SharedSdkWebServer {
}
}
+ /**
+ * Sets a response to be returned when a particular request path is passed in (with the option
+ * to specify additional headers).
+ */
+ public String setResponse(
+ String path, String responseString, List<HttpHeader> responseHeaders) {
+ // We can't send a null value as a list
+ // so default to an empty list if null was provided.
+ if (responseHeaders == null) {
+ responseHeaders = Collections.emptyList();
+ }
+ try {
+ return mWebServer.setResponse(path, responseString, responseHeaders);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /** Return the absolute URL that refers to a path. */
+ public String getAbsoluteUrl(String path) {
+ try {
+ return mWebServer.getAbsoluteUrl(path);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /** Returns a url that will contain the user agent in the header and in the body. */
+ public String getUserAgentUrl() {
+ try {
+ return mWebServer.getUserAgentUrl();
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
/** Get a delayed assert url for an asset path. */
public String getDelayedAssetUrl(String path) {
try {
@@ -78,7 +113,7 @@ public final class SharedSdkWebServer {
/** Get a url that will redirect for a path. */
public String getRedirectingAssetUrl(String path) {
try {
- return mWebServer.getAssetUrl(path);
+ return mWebServer.getRedirectingAssetUrl(path);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
@@ -111,6 +146,33 @@ public final class SharedSdkWebServer {
}
}
+ /** Returns the url to the app cache. */
+ public String getAppCacheUrl() {
+ try {
+ return mWebServer.getAppCacheUrl();
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /** Returns how many requests have been made. */
+ public int getRequestCount() {
+ try {
+ return mWebServer.getRequestCount();
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /** Returns the request count for a particular path */
+ public int getRequestCount(String path) {
+ try {
+ return mWebServer.getRequestCountWithPath(path);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
/** Verify if a resource was requested. */
public boolean wasResourceRequested(String url) {
try {
@@ -121,6 +183,15 @@ public final class SharedSdkWebServer {
}
/** Retrieve the last request to be made on a url. */
+ public HttpRequest getLastRequest(String path) {
+ try {
+ return mWebServer.getLastRequest(path);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /** Retrieve the last request for an asset path to be made on a url. */
public HttpRequest getLastAssetRequest(String url) {
try {
return mWebServer.getLastAssetRequest(url);
@@ -129,34 +200,33 @@ public final class SharedSdkWebServer {
}
}
- /** Configuration options for starting a SharedSdkWebServer */
- public static class Config {
- private @SslMode int mSslMode;
- private @Nullable byte[] mAcceptedIssuerDer;
-
- public Config() {
- mSslMode = SslMode.INSECURE;
- mAcceptedIssuerDer = null;
+ /** Returns a url that will contain the path as a cookie. */
+ public String getCookieUrl(String path) {
+ try {
+ return mWebServer.getCookieUrl(path);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
}
+ }
- /** Set the server's SslMode */
- public Config setSslMode(@SslMode int sslMode) {
- mSslMode = sslMode;
- return this;
+ /**
+ * Returns a URL that attempts to set the cookie
+ * "key=value" with the given list of attributes when fetched.
+ */
+ public String getSetCookieUrl(String path, String key, String value, String attributes) {
+ try {
+ return mWebServer.getSetCookieUrl(path, key, value, attributes);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
}
+ }
- /**
- * Configures the server's TrustManager to contain a given accepted issuer certificate
- * (specified as DER bytes).
- *
- * Note that this does not enforce that certificates are issued from this issuer - as with
- * the default CTS trust manager, all certificates are always considered valid. Supplying an
- * acceptedIssuer merely affects the issuer DNs contained in the certificate request sent to
- * the client in the TLS handshake.
- */
- public Config setAcceptedIssuer(@Nullable byte[] acceptedIssuerDer) {
- mAcceptedIssuerDer = acceptedIssuerDer;
- return this;
+ /** Returns a URL for a page with a script tag where src equals the URL passed in. */
+ public String getLinkedScriptUrl(String path, String url) {
+ try {
+ return mWebServer.getLinkedScriptUrl(path, url);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
}
}
}
diff --git a/libs/webkit-shared/src/android/webkit/cts/SharedWebViewTestEnvironment.java b/libs/webkit-shared/src/android/webkit/cts/SharedWebViewTestEnvironment.java
index c590e9c9686..eb43397fad6 100644
--- a/libs/webkit-shared/src/android/webkit/cts/SharedWebViewTestEnvironment.java
+++ b/libs/webkit-shared/src/android/webkit/cts/SharedWebViewTestEnvironment.java
@@ -19,6 +19,7 @@ package android.webkit.cts;
import static org.junit.Assert.*;
import android.app.Instrumentation;
+import android.app.UiAutomation;
import android.content.Context;
import android.os.RemoteException;
import android.os.StrictMode;
@@ -39,6 +40,7 @@ import java.io.ByteArrayInputStream;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
+import java.util.List;
import javax.net.ssl.X509TrustManager;
@@ -131,6 +133,25 @@ public final class SharedWebViewTestEnvironment {
}
}
+ /** Returns a web server that has been started and can be used
+ * for web based testing. */
+ public SharedSdkWebServer getSetupWebServer(@SslMode int sslMode) {
+ return getSetupWebServer(sslMode, null, 0, 0);
+ }
+
+ /** Returns a web server that has been started and can be used
+ * for web based testing. */
+ public SharedSdkWebServer getSetupWebServer(@SslMode int sslMode,
+ @Nullable byte[] acceptedIssuerDer, int keyResId, int certResId) {
+ try {
+ SharedSdkWebServer webServer = getWebServer();
+ webServer.start(sslMode, acceptedIssuerDer, keyResId, certResId);
+ return webServer;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
/**
* Use this builder to create a {@link SharedWebViewTestEnvironment}. The {@link
* SharedWebViewTestEnvironment} can not be built directly.
@@ -183,12 +204,27 @@ public final class SharedWebViewTestEnvironment {
}
/**
+ * UiAutomation sends events at device level which lets us get around issues with sending
+ * instrumented events to the SDK Runtime but we don't want this for the regular tests. If
+ * something like a dialog pops up while an input event is being sent, the instrumentation would
+ * treat that as an issue while the UiAutomation input event would just send it through.
+ *
+ * <p>So by default, we disable this use and only use it in the SDK Sandbox.
+ *
+ * <p>This API is used for regular activity based tests.
+ */
+ public static IHostAppInvoker.Stub createHostAppInvoker(Context applicationContext) {
+ return createHostAppInvoker(applicationContext, false);
+ }
+ /**
* This will generate a new {@link IHostAppInvoker} binder node. This should be called from
* wherever the activity exists for test cases.
*/
- public static IHostAppInvoker.Stub createHostAppInvoker(Context applicationContext) {
+ public static IHostAppInvoker.Stub createHostAppInvoker(
+ Context applicationContext, boolean allowUiAutomation) {
return new IHostAppInvoker.Stub() {
private Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
+ private UiAutomation mUiAutomation;
public void waitForIdleSync() {
mInstrumentation.waitForIdleSync();
@@ -199,7 +235,11 @@ public final class SharedWebViewTestEnvironment {
}
public void sendPointerSync(MotionEvent event) {
- mInstrumentation.sendPointerSync(event);
+ if (allowUiAutomation) {
+ sendPointerSyncWithUiAutomation(event);
+ } else {
+ sendPointerSyncWithInstrumentation(event);
+ }
}
public byte[] getEncodingBytes(String data, String charset) {
@@ -210,16 +250,21 @@ public final class SharedWebViewTestEnvironment {
return new IWebServer.Stub() {
private CtsTestServer mWebServer;
- public void start(@SslMode int sslMode, @Nullable byte[] acceptedIssuerDer) {
+ public void start(@SslMode int sslMode, @Nullable byte[] acceptedIssuerDer,
+ int keyResId, int certResId) {
assertNull(mWebServer);
final X509Certificate[] acceptedIssuerCerts;
if (acceptedIssuerDer != null) {
try {
- CertificateFactory certFactory = CertificateFactory.getInstance(
- "X.509");
- acceptedIssuerCerts = new X509Certificate[]{
- (X509Certificate) certFactory.generateCertificate(
- new ByteArrayInputStream(acceptedIssuerDer))};
+ CertificateFactory certFactory =
+ CertificateFactory.getInstance("X.509");
+ acceptedIssuerCerts =
+ new X509Certificate[] {
+ (X509Certificate)
+ certFactory.generateCertificate(
+ new ByteArrayInputStream(
+ acceptedIssuerDer))
+ };
} catch (CertificateException e) {
// Throw manually, because compiler does not understand that fail()
// does not return.
@@ -237,9 +282,9 @@ public final class SharedWebViewTestEnvironment {
}
};
mWebServer = new CtsTestServer(applicationContext, sslMode,
- trustManager);
+ trustManager, keyResId, certResId);
} catch (Exception e) {
- fail("Failed to launch CtsTestServer");
+ fail(" Failed to launch CtsTestServer: " + e);
}
}
@@ -261,6 +306,23 @@ public final class SharedWebViewTestEnvironment {
mWebServer.resetRequestState();
}
+ public String setResponse(
+ String path, String responseString, List<HttpHeader> responseHeaders) {
+ assertNotNull("The WebServer needs to be started", mWebServer);
+ return mWebServer.setResponse(
+ path, responseString, HttpHeader.asPairList(responseHeaders));
+ }
+
+ public String getAbsoluteUrl(String path) {
+ assertNotNull("The WebServer needs to be started", mWebServer);
+ return mWebServer.getAbsoluteUrl(path);
+ }
+
+ public String getUserAgentUrl() {
+ assertNotNull("The WebServer needs to be started", mWebServer);
+ return mWebServer.getUserAgentUrl();
+ }
+
public String getDelayedAssetUrl(String path) {
assertNotNull("The WebServer needs to be started", mWebServer);
return mWebServer.getDelayedAssetUrl(path);
@@ -286,22 +348,80 @@ public final class SharedWebViewTestEnvironment {
return mWebServer.getBinaryUrl(mimeType, contentLength);
}
+ public String getAppCacheUrl() {
+ assertNotNull("The WebServer needs to be started", mWebServer);
+ return mWebServer.getAppCacheUrl();
+ }
+
+ public int getRequestCount() {
+ assertNotNull("The WebServer needs to be started", mWebServer);
+ return mWebServer.getRequestCount();
+ }
+
+ public int getRequestCountWithPath(String path) {
+ assertNotNull("The WebServer needs to be started", mWebServer);
+ return mWebServer.getRequestCount(path);
+ }
+
public boolean wasResourceRequested(String url) {
assertNotNull("The WebServer needs to be started", mWebServer);
return mWebServer.wasResourceRequested(url);
}
+ public HttpRequest getLastRequest(String path) {
+ assertNotNull("The WebServer needs to be started", mWebServer);
+ return toHttpRequest(path, mWebServer.getLastRequest(path));
+ }
+
public HttpRequest getLastAssetRequest(String url) {
assertNotNull("The WebServer needs to be started", mWebServer);
- org.apache.http.HttpRequest request = mWebServer.getLastAssetRequest(url);
- if (request == null) {
+ return toHttpRequest(url, mWebServer.getLastAssetRequest(url));
+ }
+
+ public String getCookieUrl(String path) {
+ assertNotNull("The WebServer needs to be started", mWebServer);
+ return mWebServer.getCookieUrl(path);
+ }
+
+ public String getSetCookieUrl(String path, String key, String value,
+ String attributes) {
+ assertNotNull("The WebServer needs to be started", mWebServer);
+ return mWebServer.getSetCookieUrl(path, key, value, attributes);
+ }
+
+ public String getLinkedScriptUrl(String path, String url) {
+ assertNotNull("The WebServer needs to be started", mWebServer);
+ return mWebServer.getLinkedScriptUrl(path, url);
+ }
+
+ private HttpRequest toHttpRequest(
+ String url, org.apache.http.HttpRequest apacheRequest) {
+ if (apacheRequest == null) {
return null;
}
- return new HttpRequest(url, request);
+ return new HttpRequest(url, apacheRequest);
}
};
}
+
+ private void sendPointerSyncWithInstrumentation(MotionEvent event) {
+ mInstrumentation.sendPointerSync(event);
+ }
+
+ private void sendPointerSyncWithUiAutomation(MotionEvent event) {
+ if (mUiAutomation == null) {
+ mUiAutomation = mInstrumentation.getUiAutomation();
+
+ if (mUiAutomation == null) {
+ fail("Could not retrieve UI automation");
+ }
+ }
+
+ if (!mUiAutomation.injectInputEvent(event, true)) {
+ fail("Could not inject motion event");
+ }
+ }
};
}
}
diff --git a/tests/AlarmManager/src/android/alarmmanager/cts/BackgroundRestrictedAlarmsTest.java b/tests/AlarmManager/src/android/alarmmanager/cts/BackgroundRestrictedAlarmsTest.java
index c51ed92d40d..d19831751e0 100644
--- a/tests/AlarmManager/src/android/alarmmanager/cts/BackgroundRestrictedAlarmsTest.java
+++ b/tests/AlarmManager/src/android/alarmmanager/cts/BackgroundRestrictedAlarmsTest.java
@@ -51,6 +51,7 @@ import com.android.compatibility.common.util.SystemUtil;
import org.junit.After;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -155,6 +156,7 @@ public class BackgroundRestrictedAlarmsTest {
+ " times when restrictions were lifted", waitForAlarms(minCount, DEFAULT_WAIT));
}
+ @Ignore("Feature auto_restricted_bucket_on_bg_restricted is disabled right now")
@Test
public void testRepeatingAlarmAllowedWhenAutoRestrictedBucketFeatureOn() throws Exception {
final long interval = MIN_REPEATING_INTERVAL;
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/NetworkingHelper.java b/tests/JobScheduler/src/android/jobscheduler/cts/NetworkingHelper.java
index 1402975cfe6..6177592cde3 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/NetworkingHelper.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/NetworkingHelper.java
@@ -16,6 +16,7 @@
package android.jobscheduler.cts;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
@@ -193,7 +194,9 @@ public class NetworkingHelper {
}
final NetworkCapabilities networkCapabilities =
mConnectivityManager.getNetworkCapabilities(network);
- return networkCapabilities != null && networkCapabilities.hasTransport(TRANSPORT_WIFI);
+ return networkCapabilities != null
+ && networkCapabilities.hasTransport(TRANSPORT_WIFI)
+ && networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED);
}
boolean isWifiEnabled() {
@@ -300,6 +303,7 @@ public class NetworkingHelper {
NetworkRequest nr = new NetworkRequest.Builder().clearCapabilities().build();
NetworkCapabilities nc = new NetworkCapabilities.Builder()
.addTransportType(TRANSPORT_WIFI)
+ .addCapability(NET_CAPABILITY_VALIDATED)
.build();
NetworkTracker tracker = new NetworkTracker(nc, enable, mConnectivityManager);
mConnectivityManager.registerNetworkCallback(nr, tracker);
diff --git a/tests/PhotoPicker/res/raw/lg_g4_iso_800_svg.svg b/tests/PhotoPicker/res/raw/lg_g4_iso_800_svg.svg
new file mode 100644
index 00000000000..55b3d2e8874
--- /dev/null
+++ b/tests/PhotoPicker/res/raw/lg_g4_iso_800_svg.svg
Binary files differ
diff --git a/tests/PhotoPicker/res/raw/lg_g4_iso_800_unknown_mime_type.jpg b/tests/PhotoPicker/res/raw/lg_g4_iso_800_unknown_mime_type.jpg
new file mode 100644
index 00000000000..c988c573fab
--- /dev/null
+++ b/tests/PhotoPicker/res/raw/lg_g4_iso_800_unknown_mime_type.jpg
Binary files differ
diff --git a/tests/PhotoPicker/res/raw/test_video_dng.mp4 b/tests/PhotoPicker/res/raw/test_video_mj2.mp4
index 9b38f0e8e7d..2b7decd215b 100644
--- a/tests/PhotoPicker/res/raw/test_video_dng.mp4
+++ b/tests/PhotoPicker/res/raw/test_video_mj2.mp4
Binary files differ
diff --git a/tests/PhotoPicker/res/raw/test_video_mpeg.mpeg b/tests/PhotoPicker/res/raw/test_video_mpeg.mpeg
new file mode 100644
index 00000000000..27b288ed028
--- /dev/null
+++ b/tests/PhotoPicker/res/raw/test_video_mpeg.mpeg
Binary files differ
diff --git a/tests/PhotoPicker/res/raw/test_video_unknown_mime_type.mp4 b/tests/PhotoPicker/res/raw/test_video_unknown_mime_type.mp4
new file mode 100644
index 00000000000..5a2e7b56d00
--- /dev/null
+++ b/tests/PhotoPicker/res/raw/test_video_unknown_mime_type.mp4
Binary files differ
diff --git a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerSettingsTest.java b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerSettingsTest.java
index d0715e3f699..f818c10baaf 100644
--- a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerSettingsTest.java
+++ b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerSettingsTest.java
@@ -17,8 +17,11 @@
package android.photopicker.cts;
import static android.photopicker.cts.util.PhotoPickerUiUtils.isPhotoPickerVisible;
-import static android.photopicker.cts.util.PhotoPickerUiUtils.verifyActionBarExists;
+import static android.photopicker.cts.util.PhotoPickerUiUtils.verifySettingsActionBarIsVisible;
import static android.photopicker.cts.util.PhotoPickerUiUtils.verifySettingsActivityIsVisible;
+import static android.photopicker.cts.util.PhotoPickerUiUtils.verifySettingsDescriptionIsVisible;
+import static android.photopicker.cts.util.PhotoPickerUiUtils.verifySettingsFragmentContainerExists;
+import static android.photopicker.cts.util.PhotoPickerUiUtils.verifySettingsTitleIsVisible;
import android.content.Intent;
import android.os.Build;
@@ -91,7 +94,10 @@ public class PhotoPickerSettingsTest extends PhotoPickerBaseTest {
// Verify PhotoPickerSettingsActivity is launched and visible.
verifySettingsActivityIsVisible(sDevice);
- verifyActionBarExists();
+ verifySettingsActionBarIsVisible();
+ verifySettingsTitleIsVisible();
+ verifySettingsDescriptionIsVisible();
+ verifySettingsFragmentContainerExists();
}
private static String getAllowedProvidersDeviceConfig() throws IOException {
diff --git a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerTest.java b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerTest.java
index 11d99d1ed41..293cbacd05c 100644
--- a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerTest.java
+++ b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerTest.java
@@ -18,8 +18,12 @@ package android.photopicker.cts;
import static android.photopicker.cts.util.GetContentActivityAliasUtils.clearPackageData;
import static android.photopicker.cts.util.GetContentActivityAliasUtils.getDocumentsUiPackageName;
-import static android.photopicker.cts.util.PhotoPickerFilesUtils.createDNGVideosAndGetUris;
+import static android.photopicker.cts.util.PhotoPickerFilesUtils.createImageWithUnknownMimeType;
import static android.photopicker.cts.util.PhotoPickerFilesUtils.createImagesAndGetUris;
+import static android.photopicker.cts.util.PhotoPickerFilesUtils.createMj2VideosAndGetUris;
+import static android.photopicker.cts.util.PhotoPickerFilesUtils.createMpegVideo;
+import static android.photopicker.cts.util.PhotoPickerFilesUtils.createSvgImage;
+import static android.photopicker.cts.util.PhotoPickerFilesUtils.createVideoWithUnknownMimeType;
import static android.photopicker.cts.util.PhotoPickerFilesUtils.createVideosAndGetUris;
import static android.photopicker.cts.util.PhotoPickerFilesUtils.deleteMedia;
import static android.photopicker.cts.util.PhotoPickerUiUtils.REGEX_PACKAGE_NAME;
@@ -30,6 +34,7 @@ import static android.photopicker.cts.util.PhotoPickerUiUtils.findItemList;
import static android.photopicker.cts.util.PhotoPickerUiUtils.findPreviewAddButton;
import static android.photopicker.cts.util.PhotoPickerUiUtils.findPreviewAddOrSelectButton;
import static android.photopicker.cts.util.ResultsAssertionsUtils.assertContainsMimeType;
+import static android.photopicker.cts.util.ResultsAssertionsUtils.assertExtension;
import static android.photopicker.cts.util.ResultsAssertionsUtils.assertMimeType;
import static android.photopicker.cts.util.ResultsAssertionsUtils.assertPersistedGrant;
import static android.photopicker.cts.util.ResultsAssertionsUtils.assertPickerUriFormat;
@@ -63,6 +68,7 @@ import org.junit.runners.Parameterized.Parameters;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Map;
/**
* Photo Picker Device only tests for common flows.
@@ -229,7 +235,7 @@ public class PhotoPickerTest extends PhotoPickerBaseTest {
@Test
public void testMultiSelect_longPress() throws Exception {
final int videoCount = 3;
- mUriList.addAll(createDNGVideosAndGetUris(videoCount, mContext.getUserId()));
+ mUriList.addAll(createMj2VideosAndGetUris(videoCount, mContext.getUserId()));
Intent intent = new Intent(mAction);
intent.setType("video/*");
@@ -544,11 +550,11 @@ public class PhotoPickerTest extends PhotoPickerBaseTest {
@Test
public void testMimeTypeFilter() throws Exception {
final int videoCount = 2;
- mUriList.addAll(createDNGVideosAndGetUris(videoCount, mContext.getUserId()));
+ mUriList.addAll(createMj2VideosAndGetUris(videoCount, mContext.getUserId()));
final int imageCount = 1;
mUriList.addAll(createImagesAndGetUris(imageCount, mContext.getUserId()));
- final String mimeType = "video/dng";
+ final String mimeType = "video/mj2";
Intent intent = new Intent(mAction);
addMultipleSelectionFlag(intent);
@@ -579,9 +585,9 @@ public class PhotoPickerTest extends PhotoPickerBaseTest {
@Test
public void testExtraMimeTypeFilter() throws Exception {
- final int dngVideoCount = 2;
- // Creates 2 videos with mime type: "video/dng"
- mUriList.addAll(createDNGVideosAndGetUris(dngVideoCount, mContext.getUserId()));
+ final int mj2VideoCount = 2;
+ // Creates 2 videos with mime type: "video/mj2"
+ mUriList.addAll(createMj2VideosAndGetUris(mj2VideoCount, mContext.getUserId()));
final int mp4VideoCount = 3;
// Creates 3 videos with mime type: "video/mp4"
@@ -597,11 +603,11 @@ public class PhotoPickerTest extends PhotoPickerBaseTest {
if (Intent.ACTION_GET_CONTENT.equals(intent.getAction())) {
intent.setType("*/*");
}
- final String[] mimeTypes = new String[]{"video/dng", "image/dng"};
+ final String[] mimeTypes = new String[]{"video/mj2", "image/dng"};
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
launchPhotoPickerForIntent(intent);
- final int totalCount = dngVideoCount + imageCount;
+ final int totalCount = mj2VideoCount + imageCount;
final List<UiObject> itemList = findItemList(totalCount);
final int itemCount = itemList.size();
assertThat(itemCount).isAtLeast(totalCount);
@@ -626,7 +632,7 @@ public class PhotoPickerTest extends PhotoPickerBaseTest {
@Test
public void testMimeTypeFilterPriority() throws Exception {
final int videoCount = 2;
- mUriList.addAll(createDNGVideosAndGetUris(videoCount, mContext.getUserId()));
+ mUriList.addAll(createMj2VideosAndGetUris(videoCount, mContext.getUserId()));
final int imageCount = 1;
mUriList.addAll(createImagesAndGetUris(imageCount, mContext.getUserId()));
@@ -634,7 +640,7 @@ public class PhotoPickerTest extends PhotoPickerBaseTest {
addMultipleSelectionFlag(intent);
// setType has lower priority than EXTRA_MIME_TYPES filters.
intent.setType("image/*");
- final String mimeType = "video/dng";
+ final String mimeType = "video/mj2";
intent.putExtra(Intent.EXTRA_MIME_TYPES, new String[] {mimeType});
launchPhotoPickerForIntent(intent);
@@ -660,6 +666,53 @@ public class PhotoPickerTest extends PhotoPickerBaseTest {
}
}
+ @Test
+ public void testPickerUriFileExtensions() throws Exception {
+ // 1. Create test media items
+ mUriList.add(createSvgImage(mContext.getUserId()));
+ mUriList.add(createImageWithUnknownMimeType(mContext.getUserId()));
+ mUriList.add(createMpegVideo(mContext.getUserId()));
+ mUriList.add(createVideoWithUnknownMimeType(mContext.getUserId()));
+
+ final int expectedItemCount = mUriList.size();
+
+ final Map<String, String> mimeTypeToExpectedExtensionMap = Map.of(
+ "image/svg+xml", "svg",
+ "image/foo", "jpg",
+ "video/mpeg", "mpeg",
+ "video/foo", "mp4"
+ );
+
+ // 2. Launch Picker in multi-select mode for the test mime types
+ final Intent intent = new Intent(mAction);
+ addMultipleSelectionFlag(intent);
+ launchPhotoPickerForIntent(intent);
+
+ // 3. Add all items
+ final List<UiObject> itemList = findItemList(expectedItemCount);
+ final int itemCount = itemList.size();
+ assertWithMessage("Unexpected number of media items found in the picker ui")
+ .that(itemCount)
+ .isEqualTo(expectedItemCount);
+
+ for (UiObject item : itemList) {
+ clickAndWait(sDevice, item);
+ }
+ clickAndWait(sDevice, findAddButton());
+
+ // 4. Get the activity result data to extract the picker uris
+ final ClipData clipData = mActivity.getResult().data.getClipData();
+ assertWithMessage("Unexpected number of items returned from the picker activity")
+ .that(clipData.getItemCount())
+ .isEqualTo(itemCount);
+
+ // 5. Assert the picker uri file extension as expected for each item
+ for (int i = 0; i < itemCount; i++) {
+ final Uri uri = clipData.getItemAt(i).getUri();
+ assertExtension(uri, mimeTypeToExpectedExtensionMap);
+ }
+ }
+
private void assertMuteButtonState(UiObject muteButton, boolean isMuted)
throws UiObjectNotFoundException {
// We use content description to assert the state of the mute button, there is no other way
diff --git a/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerFilesUtils.java b/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerFilesUtils.java
index 2732df71762..9a39a4006cc 100644
--- a/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerFilesUtils.java
+++ b/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerFilesUtils.java
@@ -28,6 +28,7 @@ import android.provider.cts.ProviderTestUtils;
import android.provider.cts.media.MediaStoreUtils;
import android.util.Pair;
+import androidx.annotation.NonNull;
import androidx.test.InstrumentationRegistry;
import com.android.compatibility.common.util.ShellUtils;
@@ -91,10 +92,10 @@ public class PhotoPickerFilesUtils {
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/jpeg", userId, isFavorite);
}
- public static List<Uri> createDNGVideosAndGetUris(int count, int userId) throws Exception {
+ public static List<Uri> createMj2VideosAndGetUris(int count, int userId) throws Exception {
List<Uri> uriList = new ArrayList<>();
for (int i = 0; i < count; i++) {
- final Uri uri = createDNGVideo(userId);
+ final Uri uri = createMj2Video(userId);
uriList.add(uri);
clearMediaOwner(uri, userId);
}
@@ -131,8 +132,8 @@ public class PhotoPickerFilesUtils {
ShellUtils.runShellCommand(cmd);
}
- private static Uri createDNGVideo(int userId) throws Exception {
- return getPermissionAndStageMedia(R.raw.test_video_dng,
+ private static Uri createMj2Video(int userId) throws Exception {
+ return getPermissionAndStageMedia(R.raw.test_video_mj2,
MediaStore.Video.Media.EXTERNAL_CONTENT_URI, "video/mp4", userId,
/* isFavorite */ false).first;
}
@@ -176,4 +177,32 @@ public class PhotoPickerFilesUtils {
return new Pair(session.publish(), displayName);
}
}
+
+ @NonNull
+ public static Uri createSvgImage(int userId) throws Exception {
+ return getPermissionAndStageMedia(R.raw.lg_g4_iso_800_svg,
+ MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/svg+xml", userId,
+ /* isFavorite */ false).first;
+ }
+
+ @NonNull
+ public static Uri createImageWithUnknownMimeType(int userId) throws Exception {
+ return getPermissionAndStageMedia(R.raw.lg_g4_iso_800_unknown_mime_type,
+ MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/jpeg", userId,
+ /* isFavorite */ false).first;
+ }
+
+ @NonNull
+ public static Uri createMpegVideo(int userId) throws Exception {
+ return getPermissionAndStageMedia(R.raw.test_video_mpeg,
+ MediaStore.Video.Media.EXTERNAL_CONTENT_URI, "video/mpeg", userId,
+ /* isFavorite */ false).first;
+ }
+
+ @NonNull
+ public static Uri createVideoWithUnknownMimeType(int userId) throws Exception {
+ return getPermissionAndStageMedia(R.raw.test_video_unknown_mime_type,
+ MediaStore.Video.Media.EXTERNAL_CONTENT_URI, "video/mp4", userId,
+ /* isFavorite */ false).first;
+ }
}
diff --git a/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerUiUtils.java b/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerUiUtils.java
index 49a4eb40e1a..85b0e89fefd 100644
--- a/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerUiUtils.java
+++ b/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerUiUtils.java
@@ -119,10 +119,34 @@ public class PhotoPickerUiUtils {
PhotoPickerUiUtils.REGEX_PACKAGE_NAME + ":id/bottom_sheet")).waitForExists(TIMEOUT);
}
- public static void verifyActionBarExists() {
+ public static void verifySettingsActionBarIsVisible() {
assertWithMessage("Timed out waiting for action bar to appear")
.that(new UiObject(new UiSelector()
- .resourceIdMatches(REGEX_PACKAGE_NAME + ":id/action_bar"))
+ .resourceIdMatches(REGEX_PACKAGE_NAME + ":id/picker_settings_toolbar"))
+ .waitForExists(TIMEOUT))
+ .isTrue();
+ }
+
+ public static void verifySettingsTitleIsVisible() {
+ assertWithMessage("Timed out waiting for settings page title to appear")
+ .that(new UiObject(new UiSelector()
+ .resourceIdMatches(REGEX_PACKAGE_NAME + ":id/picker_settings_title"))
+ .waitForExists(TIMEOUT))
+ .isTrue();
+ }
+
+ public static void verifySettingsDescriptionIsVisible() {
+ assertWithMessage("Timed out waiting for settings page description to appear")
+ .that(new UiObject(new UiSelector()
+ .resourceIdMatches(REGEX_PACKAGE_NAME + ":id/picker_settings_description"))
+ .waitForExists(TIMEOUT))
+ .isTrue();
+ }
+
+ public static void verifySettingsFragmentContainerExists() {
+ assertWithMessage("Timed out waiting for settings fragment container to appear")
+ .that(new UiObject(new UiSelector()
+ .resourceIdMatches(REGEX_PACKAGE_NAME + ":id/settings_fragment_container"))
.waitForExists(TIMEOUT))
.isTrue();
}
diff --git a/tests/PhotoPicker/src/android/photopicker/cts/util/ResultsAssertionsUtils.java b/tests/PhotoPicker/src/android/photopicker/cts/util/ResultsAssertionsUtils.java
index e08dd2a1e2e..2f346770215 100644
--- a/tests/PhotoPicker/src/android/photopicker/cts/util/ResultsAssertionsUtils.java
+++ b/tests/PhotoPicker/src/android/photopicker/cts/util/ResultsAssertionsUtils.java
@@ -33,6 +33,7 @@ import android.net.Uri;
import android.os.FileUtils;
import android.os.ParcelFileDescriptor;
+import androidx.annotation.NonNull;
import androidx.test.InstrumentationRegistry;
import java.io.ByteArrayOutputStream;
@@ -44,6 +45,7 @@ import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Map;
/**
* Photo Picker Utility methods for PhotoPicker result assertions.
@@ -107,11 +109,39 @@ public class ResultsAssertionsUtils {
}
}
+ public static void assertExtension(@NonNull Uri uri,
+ @NonNull Map<String, String> mimeTypeToExpectedExtensionMap) {
+ assertThat(uri).isNotNull();
+
+ final ContentResolver resolver =
+ InstrumentationRegistry.getTargetContext().getContentResolver();
+ final String[] projection =
+ new String[]{ PickerMediaColumns.MIME_TYPE, PickerMediaColumns.DISPLAY_NAME };
+
+ try (Cursor c = resolver.query(
+ uri, projection, /* queryArgs */ null, /* cancellationSignal */ null)) {
+ assertThat(c).isNotNull();
+ assertThat(c.moveToFirst()).isTrue();
+
+ final String mimeType = c.getString(c.getColumnIndex(PickerMediaColumns.MIME_TYPE));
+ final String expectedExtension = mimeTypeToExpectedExtensionMap.get(mimeType);
+
+ final String displayName =
+ c.getString(c.getColumnIndex(PickerMediaColumns.DISPLAY_NAME));
+ final String[] displayNameParts = displayName.split("\\.");
+ final String resultExtension = displayNameParts[displayNameParts.length - 1];
+
+ assertWithMessage("Unexpected picker file extension")
+ .that(resultExtension)
+ .isEqualTo(expectedExtension);
+ }
+ }
+
private static void assertVideoRedactedReadOnlyAccess(Uri uri, ContentResolver resolver)
throws Exception {
// The location is redacted
// TODO(b/201505595): Make this method work for test_video.mp4. Currently it works only for
- // test_video_dng.mp4
+ // test_video_mj2.mp4
try (InputStream in = resolver.openInputStream(uri);
ByteArrayOutputStream out = new ByteArrayOutputStream()) {
FileUtils.copy(in, out);
diff --git a/tests/accessibilityservice/res/layout/accessibility_cache.xml b/tests/accessibilityservice/res/layout/accessibility_cache.xml
index 0a7839c72b0..2bfd467c0d0 100644
--- a/tests/accessibilityservice/res/layout/accessibility_cache.xml
+++ b/tests/accessibilityservice/res/layout/accessibility_cache.xml
@@ -21,11 +21,15 @@
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
+ android:focusable="true"
+ android:id="@+id/subtreeRoot"
+ android:contentDescription="Subtree root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<TextView
+ android:contentDescription="Text view"
android:text="textView"
android:layout_width="60dp"
android:layout_height="60dp"
@@ -33,12 +37,12 @@
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:contentDescription="child layout"
-
+ android:contentDescription="Child layout"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="@+id/text"
+ android:contentDescription="Text view 2"
android:text="textView2"
android:layout_width="60dp"
android:layout_height="60dp"
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityCacheTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityCacheTest.java
index 89a874ec21f..c8ef56e6392 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityCacheTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityCacheTest.java
@@ -20,7 +20,6 @@ import static android.accessibilityservice.cts.utils.ActivityLaunchUtils.launchA
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
@@ -50,6 +49,7 @@ import org.junit.Test;
import org.junit.rules.RuleChain;
import org.junit.runner.RunWith;
+import java.util.ArrayList;
import java.util.List;
@AppModeFull
@@ -71,6 +71,8 @@ public class AccessibilityCacheTest {
mInstrumentedAccessibilityServiceRule = new InstrumentedAccessibilityServiceTestRule<>(
InstrumentedAccessibilityService.class, false);
+ private static final String SUBTREE_ROOT_ID = "android.accessibilityservice.cts:id/subtreeRoot";
+
@Rule
public final RuleChain mRuleChain = RuleChain
.outerRule(mActivityRule)
@@ -128,9 +130,10 @@ public class AccessibilityCacheTest {
@Test
public void invalidateNode_subtreeInCacheInvalidated() {
- // Tree is FrameLayout with TextView and LinearLayout children.
+ // Subtree is FrameLayout with TextView and LinearLayout children.
// The LinearLayout has a TextView child.
- AccessibilityNodeInfo root = mService.getRootInActiveWindow();
+ AccessibilityNodeInfo root = mService.getRootInActiveWindow()
+ .findAccessibilityNodeInfosByViewId(SUBTREE_ROOT_ID).get(0);
assertThat(root.getChildCount(), is(2));
AccessibilityNodeInfo child0 = root.getChild(0);
AccessibilityNodeInfo child1 = root.getChild(1);
@@ -146,27 +149,26 @@ public class AccessibilityCacheTest {
@Test
public void clear_cacheInvalidated() {
- // Tree is FrameLayout with TextView and LinearLayout children.
- // The LinearLayout has a TextView child.
AccessibilityNodeInfo root = mService.getRootInActiveWindow();
- assertThat(root.getChildCount(), is(2));
- AccessibilityNodeInfo child0 = root.getChild(0);
- AccessibilityNodeInfo child1 = root.getChild(1);
- AccessibilityNodeInfo grandChild = child1.getChild(0);
+
+ List<AccessibilityNodeInfo> allNodes = new ArrayList<>();
+ allNodes.add(root);
+ getNodes(allNodes, root);
assertTrue(mService.clearCache());
- assertFalse("Root is in cache", mService.isNodeInCache(root));
- assertFalse("Child0 is in cache", mService.isNodeInCache(child0));
- assertFalse("Child1 is in cache", mService.isNodeInCache(child1));
- assertFalse("Grandchild is in cache", mService.isNodeInCache(grandChild));
+ for (AccessibilityNodeInfo node : allNodes) {
+ assertFalse("Node " + node.getContentDescription() + " is in cache",
+ mService.isNodeInCache(node));
+ }
}
@Test
public void getChild_descendantNotPrefetched() {
- // Tree is FrameLayout with TextView and LinearLayout children.
+ // Subtree is FrameLayout with TextView and LinearLayout children.
// The LinearLayout has a TextView child.
- AccessibilityNodeInfo frameRoot = mService.getRootInActiveWindow();
+ AccessibilityNodeInfo frameRoot = mService.getRootInActiveWindow()
+ .findAccessibilityNodeInfosByViewId(SUBTREE_ROOT_ID).get(0);
assertThat(frameRoot.getChildCount(), is(2));
AccessibilityNodeInfo textViewChild = frameRoot.getChild(0);
AccessibilityNodeInfo linearLayoutChild = frameRoot.getChild(1);
@@ -185,9 +187,10 @@ public class AccessibilityCacheTest {
@Test
public void getChild_descendantPrefetched() {
- // Tree is FrameLayout with TextView and LinearLayout children.
+ // Subtree is FrameLayout with TextView and LinearLayout children.
// The LinearLayout has a TextView child.
- AccessibilityNodeInfo frameRoot = mService.getRootInActiveWindow();
+ AccessibilityNodeInfo frameRoot = mService.getRootInActiveWindow()
+ .findAccessibilityNodeInfosByViewId(SUBTREE_ROOT_ID).get(0);
assertThat(frameRoot.getChildCount(), is(2));
AccessibilityNodeInfo textViewChild = frameRoot.getChild(0);
AccessibilityNodeInfo linearLayoutChild = frameRoot.getChild(1);
@@ -208,9 +211,10 @@ public class AccessibilityCacheTest {
@Test
public void getParent_ancestorsPrefetched() {
- // Tree is FrameLayout with TextView and LinearLayout children.
+ // Subtree is FrameLayout with TextView and LinearLayout children.
// The LinearLayout has a TextView child.
- AccessibilityNodeInfo frameRoot = mService.getRootInActiveWindow();
+ AccessibilityNodeInfo frameRoot = mService.getRootInActiveWindow()
+ .findAccessibilityNodeInfosByViewId(SUBTREE_ROOT_ID).get(0);
assertThat(frameRoot.getChildCount(), is(2));
AccessibilityNodeInfo textViewChild = frameRoot.getChild(0);
AccessibilityNodeInfo linearLayoutChild = frameRoot.getChild(1);
@@ -235,9 +239,10 @@ public class AccessibilityCacheTest {
*/
@Test
public void testRequest_withMultiplePrefetchingStrategies_throwsException() {
- // Tree is FrameLayout with TextView and LinearLayout children.
+ // Subtree is FrameLayout with TextView and LinearLayout children.
// The LinearLayout has a TextView child.
- AccessibilityNodeInfo root = mService.getRootInActiveWindow();
+ AccessibilityNodeInfo root = mService.getRootInActiveWindow()
+ .findAccessibilityNodeInfosByViewId(SUBTREE_ROOT_ID).get(0);
assertThat(root.getChildCount(), is(2));
// Clear cache.
@@ -264,46 +269,47 @@ public class AccessibilityCacheTest {
assertNotNull(activityWindowInfo);
AccessibilityNodeInfo windowRoot = activityWindowInfo.getRoot();
- assertThat(windowRoot.getChildCount(), is(2));
- AccessibilityNodeInfo textViewChild = windowRoot.getChild(0);
- AccessibilityNodeInfo linearLayoutChild = windowRoot.getChild(1);
- AccessibilityNodeInfo frameGrandChild = linearLayoutChild.getChild(0);
+ List<AccessibilityNodeInfo> allNodes = new ArrayList<>();
+ allNodes.add(windowRoot); // root should not be in the cache after clearing
+ getNodes(allNodes, windowRoot);
// Clear cache.
assertTrue(mService.clearCachedSubtree(windowRoot));
- AccessibilityNodeInfo windowRoot2 = activityWindowInfo.getRoot(
- AccessibilityNodeInfo.FLAG_PREFETCH_SIBLINGS
- | AccessibilityNodeInfo.FLAG_PREFETCH_UNINTERRUPTIBLE);
- // Confirm roots are the same.
- assertEquals(windowRoot, windowRoot2);
- assertFalse("Root is in cache", mService.isNodeInCache(windowRoot));
- assertFalse("TextView is in cache", mService.isNodeInCache(textViewChild));
- assertFalse("LinearLayout is in cache", mService.isNodeInCache(linearLayoutChild));
- assertFalse("Root grandchild is in cache", mService.isNodeInCache(frameGrandChild));
+ for (AccessibilityNodeInfo node : allNodes) {
+ assertFalse("Node " + node.getContentDescription() + " is in cache",
+ mService.isNodeInCache(node));
+ }
}
@Test
public void testRequest_prefetchWithRootInActiveWindow() {
- // Tree is FrameLayout with TextView and LinearLayout children.
- // The LinearLayout has a TextView child.
- AccessibilityNodeInfo frameRoot = mService.getRootInActiveWindow();
- assertThat(frameRoot.getChildCount(), is(2));
- AccessibilityNodeInfo textViewChild = frameRoot.getChild(0);
- AccessibilityNodeInfo linearLayoutChild = frameRoot.getChild(1);
- AccessibilityNodeInfo frameGrandChild = linearLayoutChild.getChild(0);
+ AccessibilityNodeInfo windowRoot = mService.getRootInActiveWindow();
+
+ List<AccessibilityNodeInfo> allNodesExceptRoot = new ArrayList<>();
+ getNodes(allNodesExceptRoot, windowRoot);
// Clear cache.
- assertTrue(mService.clearCachedSubtree(frameRoot));
+ assertTrue(mService.clearCachedSubtree(windowRoot));
- AccessibilityNodeInfo frameRoot2 = mService.getRootInActiveWindow(
+ AccessibilityNodeInfo windowRoot2 = mService.getRootInActiveWindow(
AccessibilityNodeInfo.FLAG_PREFETCH_SIBLINGS
| AccessibilityNodeInfo.FLAG_PREFETCH_UNINTERRUPTIBLE);
- // Confirm roots are the same.
- assertEquals(frameRoot, frameRoot2);
- assertTrue("Root is in cache", mService.isNodeInCache(frameRoot2));
- assertFalse("TextView is in cache", mService.isNodeInCache(textViewChild));
- assertFalse("LinearLayout is in cache", mService.isNodeInCache(linearLayoutChild));
- assertFalse("Root grandchild is in cache", mService.isNodeInCache(frameGrandChild));
+
+ assertTrue("Root is in cache", mService.isNodeInCache(windowRoot2));
+ for (AccessibilityNodeInfo node : allNodesExceptRoot) {
+ assertFalse("Node " + node.getContentDescription() + " is in cache",
+ mService.isNodeInCache(node));
+ }
+ }
+
+ private void getNodes(List<AccessibilityNodeInfo> nodesList, AccessibilityNodeInfo node) {
+ // Explicitly not prefetching to avoid a race condition where the cache may be populated
+ // after calling clearCachedSubtree
+ final int noPrefetchingStrategy = 0;
+ for (int i = 0; i < node.getChildCount(); i++) {
+ nodesList.add(node.getChild(i, noPrefetchingStrategy));
+ getNodes(nodesList, node.getChild(i));
+ }
}
}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java
index 01d1659f95b..7312c26da0a 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java
@@ -16,18 +16,26 @@
package android.accessibilityservice.cts;
+import static android.accessibilityservice.cts.utils.CtsTestUtils.assertThrows;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
+import android.accessibility.cts.common.InstrumentedAccessibilityService;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.os.Parcel;
+import android.platform.test.annotations.AsbSecurityTest;
import android.platform.test.annotations.Presubmit;
import android.view.accessibility.AccessibilityEvent;
import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import com.google.common.base.Strings;
+
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -37,7 +45,7 @@ import org.junit.runner.RunWith;
*/
@Presubmit
@RunWith(AndroidJUnit4.class)
-public class AccessibilityServiceInfoTest {
+public class AccessibilityServiceInfoTest extends StsExtraBusinessLogicTestCase {
@Rule
public final AccessibilityDumpOnFailureRule mDumpOnFailureRule =
@@ -131,6 +139,22 @@ public class AccessibilityServiceInfoTest {
}
+ @Test
+ @AsbSecurityTest(cveBugId = {261589597})
+ public void testSetServiceInfo_throwsForLargeServiceInfo() {
+ try {
+ final InstrumentedAccessibilityService service =
+ InstrumentedAccessibilityService.enableService(
+ InstrumentedAccessibilityService.class);
+ final AccessibilityServiceInfo info = service.getServiceInfo();
+ info.packageNames = new String[]{Strings.repeat("A", 1024 * 507)};
+
+ assertThrows(IllegalStateException.class, () -> service.setServiceInfo(info));
+ } finally {
+ InstrumentedAccessibilityService.disableAllServices();
+ }
+ }
+
/**
* Fully populates the {@link AccessibilityServiceInfo} to marshal.
*
diff --git a/tests/app/app/src/android/app/stubs/CommandReceiver.java b/tests/app/app/src/android/app/stubs/CommandReceiver.java
index 26ab62bb330..d5cfb39410d 100644
--- a/tests/app/app/src/android/app/stubs/CommandReceiver.java
+++ b/tests/app/app/src/android/app/stubs/CommandReceiver.java
@@ -464,7 +464,9 @@ public class CommandReceiver extends BroadcastReceiver {
private static Intent makeIntent(int command, String sourcePackage,
String targetPackage, int flags, Bundle extras) {
Intent intent = new Intent();
- if (command == COMMAND_BIND_SERVICE || command == COMMAND_START_FOREGROUND_SERVICE) {
+ if (command == COMMAND_BIND_SERVICE || command == COMMAND_START_FOREGROUND_SERVICE
+ || command == COMMAND_STOP_FOREGROUND_SERVICE || command == COMMAND_START_ACTIVITY
+ || command == COMMAND_START_FOREGROUND_SERVICE_LOCATION || command == COMMAND_UNBIND_SERVICE) {
intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
}
intent.setComponent(new ComponentName(sourcePackage, "android.app.stubs.CommandReceiver"));
diff --git a/tests/backup/AndroidManifest.xml b/tests/backup/AndroidManifest.xml
index 22c253102a1..71a0925dd19 100644
--- a/tests/backup/AndroidManifest.xml
+++ b/tests/backup/AndroidManifest.xml
@@ -19,6 +19,8 @@
package="android.backup.cts">
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
+ <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+
<application>
<uses-library android:name="android.test.runner" />
<uses-library android:name="org.apache.http.legacy" />
diff --git a/tests/backup/src/android/backup/cts/AppLocalesBackupTest.java b/tests/backup/src/android/backup/cts/AppLocalesBackupTest.java
index aab41595553..d51b7ae0af5 100644
--- a/tests/backup/src/android/backup/cts/AppLocalesBackupTest.java
+++ b/tests/backup/src/android/backup/cts/AppLocalesBackupTest.java
@@ -23,7 +23,6 @@ import static com.android.compatibility.common.util.SystemUtil.callWithShellPerm
import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
import android.Manifest;
-import android.app.Instrumentation;
import android.app.LocaleManager;
import android.app.time.ExternalTimeSuggestion;
import android.app.time.TimeManager;
@@ -38,6 +37,7 @@ import android.content.IntentFilter;
import android.os.LocaleList;
import android.os.SystemClock;
import android.platform.test.annotations.AppModeFull;
+import android.provider.Settings;
import androidx.test.InstrumentationRegistry;
@@ -72,8 +72,13 @@ public class AppLocalesBackupTest extends BaseBackupCtsTest {
private static final Duration RETENTION_PERIOD = Duration.ofDays(3);
+ private static final String SHELL_COMMAND_IS_AUTO_DETECTION_ENABLED =
+ "cmd time_detector is_auto_detection_enabled";
+
private Context mContext;
private LocaleManager mLocaleManager;
+ private boolean mOriginalAutoTime;
+ private DeviceShellCommandExecutor mShellCommandExecutor;
@Before
@Override
@@ -82,6 +87,14 @@ public class AppLocalesBackupTest extends BaseBackupCtsTest {
mContext = InstrumentationRegistry.getTargetContext();
mLocaleManager = mContext.getSystemService(LocaleManager.class);
+ mShellCommandExecutor = new InstrumentationShellCommandExecutor(
+ InstrumentationRegistry.getInstrumentation().getUiAutomation());
+
+ mOriginalAutoTime = isAutoDetectionEnabled(mShellCommandExecutor);
+ // Auto time needs to be enabled to be able to suggest external time
+ if (!mOriginalAutoTime) {
+ assertTrue(setAutoTimeEnabled(/*enabled*/ true, mShellCommandExecutor));
+ }
install(TEST_APP_APK_1);
install(TEST_APP_APK_2);
@@ -89,6 +102,11 @@ public class AppLocalesBackupTest extends BaseBackupCtsTest {
@After
public void tearDown() throws Exception {
+ // reset auto time to its original value
+ if (!mOriginalAutoTime) {
+ setAutoTimeEnabled(/*enabled*/ false, mShellCommandExecutor);
+ }
+
uninstall(TEST_APP_PACKAGE_1);
uninstall(TEST_APP_PACKAGE_2);
}
@@ -239,11 +257,8 @@ public class AppLocalesBackupTest extends BaseBackupCtsTest {
// Locales for App1 should be restored immediately since that's present already.
assertLocalesForApp(TEST_APP_PACKAGE_1, DEFAULT_LOCALES_1);
- Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
- DeviceShellCommandExecutor shellCommandExecutor = new InstrumentationShellCommandExecutor(
- instrumentation.getUiAutomation());
DeviceConfigShellHelper deviceConfigShellHelper = new DeviceConfigShellHelper(
- shellCommandExecutor);
+ mShellCommandExecutor);
// This anticipates a future state where a generally applied target preparer may disable
// device_config sync for all CTS tests: only suspend syncing if it isn't already suspended,
@@ -337,11 +352,9 @@ public class AppLocalesBackupTest extends BaseBackupCtsTest {
getBackupUtils().restoreAndAssertSuccess(RESTORE_TOKEN, SYSTEM_PACKAGE);
- Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
- DeviceShellCommandExecutor shellCommandExecutor = new InstrumentationShellCommandExecutor(
- instrumentation.getUiAutomation());
+
DeviceConfigShellHelper deviceConfigShellHelper = new DeviceConfigShellHelper(
- shellCommandExecutor);
+ mShellCommandExecutor);
// This anticipates a future state where a generally applied target preparer may disable
// device_config sync for all CTS tests: only suspend syncing if it isn't already suspended,
@@ -482,6 +495,23 @@ public class AppLocalesBackupTest extends BaseBackupCtsTest {
setApplicationLocalesAndVerify(TEST_APP_PACKAGE_2, EMPTY_LOCALES);
}
+ private boolean isAutoDetectionEnabled(
+ DeviceShellCommandExecutor shellCommandExecutor) throws Exception {
+ return shellCommandExecutor.executeToBoolean(SHELL_COMMAND_IS_AUTO_DETECTION_ENABLED);
+ }
+
+ private boolean setAutoTimeEnabled(
+ boolean enabled, DeviceShellCommandExecutor shellCommandExecutor) throws Exception {
+ // Android T does not have a dedicated shell command or API to change time auto detection
+ // setting, so direct Settings changes are used.
+ Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AUTO_TIME,
+ enabled ? 1 : 0);
+
+ sleepForAsyncOperation();
+
+ return isAutoDetectionEnabled(shellCommandExecutor) == enabled;
+ }
+
private static final class BlockingBroadcastReceiver extends BroadcastReceiver {
private CountDownLatch mLatch = new CountDownLatch(1);
private String mPackageName;
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 772e7a599cb..7e88b27b560 100644
--- a/tests/camera/api31test/src/android/camera/cts/api31test/SPerfClassTest.java
+++ b/tests/camera/api31test/src/android/camera/cts/api31test/SPerfClassTest.java
@@ -125,9 +125,8 @@ public class SPerfClassTest extends AndroidTestCase {
for (Size jpegSize : jpegSizes) {
mCollector.expectTrue(
"Primary camera's JPEG size must be at least 1080p, but is " +
- jpegSize,
- jpegSize.getWidth() >= FULLHD.getWidth() &&
- jpegSize.getHeight() >= FULLHD.getHeight());
+ jpegSize, jpegSize.getWidth() * jpegSize.getHeight()
+ >= FULLHD.getWidth() * FULLHD.getHeight());
}
CameraDevice camera = null;
diff --git a/tests/camera/src/android/hardware/camera2/cts/MultiResolutionImageReaderTest.java b/tests/camera/src/android/hardware/camera2/cts/MultiResolutionImageReaderTest.java
index 35edd778854..e7cb07a5698 100644
--- a/tests/camera/src/android/hardware/camera2/cts/MultiResolutionImageReaderTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/MultiResolutionImageReaderTest.java
@@ -18,8 +18,8 @@ package android.hardware.camera2.cts;
import android.graphics.ImageFormat;
import android.hardware.HardwareBuffer;
-import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CaptureFailure;
import android.hardware.camera2.CaptureRequest;
@@ -28,41 +28,37 @@ import android.hardware.camera2.MultiResolutionImageReader;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.cts.CameraTestUtils.HandlerExecutor;
import android.hardware.camera2.cts.CameraTestUtils.SimpleCaptureCallback;
-import android.hardware.camera2.cts.testcases.Camera2AndroidTestCase;
import android.hardware.camera2.cts.helpers.StaticMetadata;
+import android.hardware.camera2.cts.testcases.Camera2AndroidTestCase;
import android.hardware.camera2.params.MandatoryStreamCombination;
-import android.hardware.camera2.params.MandatoryStreamCombination.MandatoryStreamInformation;
import android.hardware.camera2.params.MultiResolutionStreamConfigurationMap;
import android.hardware.camera2.params.MultiResolutionStreamInfo;
import android.hardware.camera2.params.OutputConfiguration;
import android.hardware.camera2.params.SessionConfiguration;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.Image;
-import android.media.ImageReader;
import android.util.Log;
-import android.util.Range;
import android.util.Size;
import android.view.Surface;
-import java.util.Arrays;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Set;
-import java.util.concurrent.LinkedBlockingQueue;
+import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
-import org.junit.Test;
-import static android.hardware.camera2.cts.CameraTestUtils.checkSessionConfigurationSupported;
import static android.hardware.camera2.cts.CameraTestUtils.ImageAndMultiResStreamInfo;
-import static android.hardware.camera2.cts.CameraTestUtils.StreamCombinationTargets;
import static android.hardware.camera2.cts.CameraTestUtils.SimpleMultiResolutionImageReaderListener;
+import static android.hardware.camera2.cts.CameraTestUtils.StreamCombinationTargets;
+import static android.hardware.camera2.cts.CameraTestUtils.checkSessionConfigurationSupported;
+
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
+
import static org.mockito.Mockito.*;
/**
@@ -128,9 +124,15 @@ public class MultiResolutionImageReaderTest extends Camera2AndroidTestCase {
isLogicalCamera || isUltraHighResCamera);
for (int format : multiResolutionOutputFormats) {
- assertTrue(String.format("Camera %s: multi-resolution output format %d "
- + "isn't a supported format", id, format),
- CameraTestUtils.contains(outputFormats, format));
+ // Multi-resolution output format must be one of the supports stream configuration
+ // map formats, with the exception of RAW. It's valid for the camera device not to
+ // support RAW, but the multi-resolution ImageReader does.
+ if (format != ImageFormat.RAW_SENSOR && format != ImageFormat.RAW10
+ && format != ImageFormat.RAW12 && format != ImageFormat.RAW_PRIVATE) {
+ assertTrue(String.format("Camera %s: multi-resolution output format %d "
+ + "isn't a supported format", id, format),
+ CameraTestUtils.contains(outputFormats, format));
+ }
Collection<MultiResolutionStreamInfo> multiResolutionStreams =
multiResolutionMap.getOutputInfo(format);
@@ -522,6 +524,7 @@ public class MultiResolutionImageReaderTest extends Camera2AndroidTestCase {
img.close();
numImageVerified++;
+ retryCount = 0;
}
}
}
diff --git a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
index df85f466b9e..49614f2260c 100644
--- a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
@@ -1218,6 +1218,10 @@ public class RecordingTest extends Camera2SurfaceViewTestCase {
previewFrameRate = previewRateMap.get(captureRate);
Log.v(TAG, "previewFrameRate: " + previewFrameRate + " captureRate: " +
captureRate);
+
+ Range<Integer> previewfpsRange =
+ new Range<Integer>(previewFrameRate, captureRate);
+
// Skip the test if the highest recording FPS supported by CamcorderProfile
if (fpsRange.getUpper() > getFpsFromHighSpeedProfileForSize(size)) {
Log.w(TAG, "high speed recording " + size + "@" + captureRate + "fps"
@@ -1230,7 +1234,7 @@ public class RecordingTest extends Camera2SurfaceViewTestCase {
// prepare preview surface by using video size.
updatePreviewSurfaceWithVideo(size, captureRate);
- startConstrainedPreview(fpsRange, previewResultListener);
+ startConstrainedPreview(previewfpsRange, previewResultListener);
mOutMediaFileName = mDebugFileNameBase + "/test_cslowMo_video_" +
captureRate + "fps_" + id + "_" + size.toString() + ".mp4";
@@ -1278,7 +1282,7 @@ public class RecordingTest extends Camera2SurfaceViewTestCase {
// Stop recording and preview
stopRecording(/*useMediaRecorder*/true);
- startConstrainedPreview(fpsRange, previewResultListener);
+ startConstrainedPreview(previewfpsRange, previewResultListener);
// Convert number of frames camera produced into the duration in unit of ms.
float frameDurationMs = 1000.0f / videoFrameRate;
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 37f6fa43c97..282269cd69a 100644
--- a/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
+++ b/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
@@ -761,9 +761,6 @@ public class CameraTestUtils extends Assert {
image = mLastReader.acquireLatestImage();
if (VERBOSE) Log.v(TAG, "acquireLatestImage from "
+ mLastReader.toString() + " produces " + image);
- if (image == null) {
- return null;
- }
} else {
fail("invalid image reader");
}
@@ -772,7 +769,7 @@ public class CameraTestUtils extends Assert {
} else {
fail("wait for image available time out after " + timeoutMs + "ms");
}
- return new ImageAndMultiResStreamInfo(image,
+ return image == null ? null : new ImageAndMultiResStreamInfo(image,
mOwner.getStreamInfoForImageReader(mLastReader));
} else {
ImageAndMultiResStreamInfo imageAndInfo = mQueue.poll(timeoutMs,
diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagementRoleHolderTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagementRoleHolderTest.java
index f85d895d643..31eaebecfd8 100644
--- a/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagementRoleHolderTest.java
+++ b/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagementRoleHolderTest.java
@@ -71,13 +71,14 @@ import com.android.eventlib.truth.EventLogsSubject;
import com.android.queryable.queries.ActivityQuery;
import org.junit.ClassRule;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
// TODO(b/228016400): replace usages of createAndProvisionManagedProfile with a nene API
@RunWith(BedsteadJUnit4.class)
-public class DevicePolicyManagementRoleHolderTest {
+public class DevicePolicyManagementRoleHolderTest { // TODO: This is crashing on non-headless - figure it out - on headless it d't run with btest so follow up....
@ClassRule
@Rule
public static final DeviceState sDeviceState = new DeviceState();
@@ -135,6 +136,7 @@ public class DevicePolicyManagementRoleHolderTest {
+ ".TestAppAccountAuthenticatorService"))
.get();
+ @Ignore("b/268616097 fix issue with pre-existing accounts on the device")
@Postsubmit(reason = "new test")
@RequireFeature(FEATURE_MANAGED_USERS)
@EnsureHasPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS)
@@ -174,6 +176,7 @@ public class DevicePolicyManagementRoleHolderTest {
}
}
+ @Ignore("b/268616097 fix issue with pre-existing accounts on the device")
@Postsubmit(reason = "new test")
@RequireFeature(FEATURE_MANAGED_USERS)
@EnsureHasDeviceOwner
@@ -216,6 +219,7 @@ public class DevicePolicyManagementRoleHolderTest {
}
}
+ @Ignore("b/268616097 fix issue with pre-existing accounts on the device")
@Postsubmit(reason = "new test")
@RequireFeature(FEATURE_MANAGED_USERS)
@EnsureHasPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS)
@@ -246,6 +250,7 @@ public class DevicePolicyManagementRoleHolderTest {
}
}
+ @Ignore("b/268616097 fix issue with pre-existing accounts on the device")
@Postsubmit(reason = "new test")
@RequireFeature(FEATURE_MANAGED_USERS)
@EnsureHasPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS)
@@ -277,6 +282,7 @@ public class DevicePolicyManagementRoleHolderTest {
}
}
+ @Ignore("b/268616097 fix issue with pre-existing accounts on the device")
@Postsubmit(reason = "new test")
@RequireFeature(FEATURE_MANAGED_USERS)
@EnsureHasPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS)
@@ -308,6 +314,7 @@ public class DevicePolicyManagementRoleHolderTest {
}
}
+ @Ignore("b/268616097 fix issue with pre-existing accounts on the device")
@Postsubmit(reason = "New test")
@Test
@EnsureHasPermission(MANAGE_ROLE_HOLDERS)
@@ -326,6 +333,7 @@ public class DevicePolicyManagementRoleHolderTest {
}
// TODO(b/222669810): add ensureHasNoAccounts annotation
+ @Ignore("b/268616097 fix issue with pre-existing accounts on the device")
@Postsubmit(reason = "New test")
@Test
@EnsureHasPermission(MANAGE_ROLE_HOLDERS)
@@ -350,6 +358,7 @@ public class DevicePolicyManagementRoleHolderTest {
}
// TODO(b/222669810): add ensureHasNoAccounts annotation
+ @Ignore("b/268616097 fix issue with pre-existing accounts on the device")
@Postsubmit(reason = "New test")
@Test
@RequireFeature(FEATURE_MANAGED_USERS)
@@ -373,6 +382,7 @@ public class DevicePolicyManagementRoleHolderTest {
.isFalse();
}
+ @Ignore("b/268616097 fix issue with pre-existing accounts on the device")
@Postsubmit(reason = "New test")
@Test
@EnsureHasPermission(MANAGE_ROLE_HOLDERS)
@@ -393,6 +403,7 @@ public class DevicePolicyManagementRoleHolderTest {
}
}
+ @Ignore("b/268616097 fix issue with pre-existing accounts on the device")
@Postsubmit(reason = "New test")
@Test
@EnsureDoesNotHavePermission(MANAGE_ROLE_HOLDERS)
diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagerTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagerTest.java
index ae9ced5fd3a..7a056ded5c0 100644
--- a/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagerTest.java
+++ b/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagerTest.java
@@ -1150,6 +1150,7 @@ public final class DevicePolicyManagerTest {
@Postsubmit(reason = "New test")
@Test
@EnsureHasPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS)
+ @RequireFeature(FEATURE_MANAGED_USERS)
@RequireDoesNotHaveFeature(FEATURE_DEVICE_ADMIN)
public void checkProvisioningPreCondition_withoutDeviceAdminFeature_returnsDeviceAdminNotSupported() {
assertThat(
diff --git a/tests/devicestate/src/android/hardware/devicestate/cts/DeviceStateManagerTests.java b/tests/devicestate/src/android/hardware/devicestate/cts/DeviceStateManagerTests.java
index 230b75a44a8..f6ff30302d6 100644
--- a/tests/devicestate/src/android/hardware/devicestate/cts/DeviceStateManagerTests.java
+++ b/tests/devicestate/src/android/hardware/devicestate/cts/DeviceStateManagerTests.java
@@ -176,7 +176,8 @@ public class DeviceStateManagerTests extends DeviceStateManagerTestBase {
* triggered with a value equal to the requested state.
*/
@Test
- public void testRequestStateSucceedsAsTopApp_ifStateDefinedAsAvailableForAppsToRequest() {
+ public void testRequestStateSucceedsAsTopApp_ifStateDefinedAsAvailableForAppsToRequest()
+ throws Throwable {
final DeviceStateManager manager = getDeviceStateManager();
final int[] supportedStates = manager.getSupportedStates();
@@ -209,7 +210,7 @@ public class DeviceStateManagerTests extends DeviceStateManagerTestBase {
// checks that we were able to find a valid state to request.
assumeTrue(nextState != INVALID_DEVICE_STATE);
- activity.requestDeviceStateChange(nextState);
+ runWithControlDeviceStatePermission(() -> activity.requestDeviceStateChange(nextState));
PollingCheck.waitFor(TIMEOUT, () -> callback.mCurrentState == nextState);
@@ -269,7 +270,7 @@ public class DeviceStateManagerTests extends DeviceStateManagerTestBase {
* in a registered callback being triggered with a value equal to the base state.
*/
@Test
- public void testCancelStateRequestFromNewActivity() throws IllegalArgumentException {
+ public void testCancelStateRequestFromNewActivity() throws Throwable {
final DeviceStateManager manager = getDeviceStateManager();
final int[] supportedStates = manager.getSupportedStates();
// We want to verify that the app can change device state
@@ -292,7 +293,7 @@ public class DeviceStateManagerTests extends DeviceStateManagerTestBase {
DEFAULT_DISPLAY
);
- DeviceStateTestActivity activity = activitySession.getActivity();
+ final DeviceStateTestActivity activity = activitySession.getActivity();
int originalState = callback.mCurrentState;
@@ -303,7 +304,7 @@ public class DeviceStateManagerTests extends DeviceStateManagerTestBase {
// checks that we were able to find a valid state to request.
assumeTrue(nextState != INVALID_DEVICE_STATE);
- activity.requestDeviceStateChange(nextState);
+ runWithControlDeviceStatePermission(() -> activity.requestDeviceStateChange(nextState));
PollingCheck.waitFor(TIMEOUT, () -> callback.mCurrentState == nextState);
@@ -322,8 +323,8 @@ public class DeviceStateManagerTests extends DeviceStateManagerTestBase {
// and launching the second activity.
assertEquals(nextState, callback.mCurrentState);
- activity = secondActivitySession.getActivity();
- activity.cancelOverriddenState();
+ final DeviceStateTestActivity activity2 = secondActivitySession.getActivity();
+ activity2.cancelOverriddenState();
PollingCheck.waitFor(TIMEOUT, () -> callback.mCurrentState == originalState);
diff --git a/tests/framework/base/windowmanager/jetpack/SecondApp/src/android/server/wm/jetpack/second/SecondActivityKnownEmbeddingCerts.java b/tests/framework/base/windowmanager/jetpack/SecondApp/src/android/server/wm/jetpack/second/SecondActivityUnknownEmbeddingCerts.java
index 9bf28dc730b..c6a7c9b45b7 100644
--- a/tests/framework/base/windowmanager/jetpack/SecondApp/src/android/server/wm/jetpack/second/SecondActivityKnownEmbeddingCerts.java
+++ b/tests/framework/base/windowmanager/jetpack/SecondApp/src/android/server/wm/jetpack/second/SecondActivityUnknownEmbeddingCerts.java
@@ -22,5 +22,5 @@ import android.app.Activity;
* A test activity that requests trusted host certificates for embedding that does not match the
* certificate of the host in CTS tests from 'android.server.wm.jetpack'.
*/
-public class SecondActivityKnownEmbeddingCerts extends Activity {
+public class SecondActivityUnknownEmbeddingCerts extends Activity {
}
diff --git a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingBoundsTests.java b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingBoundsTests.java
index 18fe90ec6b9..57a9fd56093 100644
--- a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingBoundsTests.java
+++ b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingBoundsTests.java
@@ -69,13 +69,15 @@ public class ActivityEmbeddingBoundsTests extends ActivityEmbeddingTestBase {
final Activity primaryActivity = startActivityNewTask(
TestConfigChangeHandlingActivity.class);
- // Set split pair rule such that if the parent width is any smaller than it is now, then
+ // Set split pair rule such that if the parent bounds is any smaller than it is now, then
// the parent cannot support a split.
final int originalTaskWidth = getTaskWidth();
+ final int originalTaskHeight = getTaskHeight();
final SplitPairRule splitPairRule = createSplitPairRuleBuilderWithJava8Predicate(
activityActivityPair -> true /* activityPairPredicate */,
activityIntentPair -> true /* activityIntentPredicate */,
- parentWindowMetrics -> parentWindowMetrics.getBounds().width() >= originalTaskWidth)
+ parentWindowMetrics -> parentWindowMetrics.getBounds().width() >= originalTaskWidth
+ && parentWindowMetrics.getBounds().height() >= originalTaskHeight)
.setSplitRatio(DEFAULT_SPLIT_RATIO).build();
mActivityEmbeddingComponent.setEmbeddingRules(Collections.singleton(splitPairRule));
@@ -93,7 +95,7 @@ public class ActivityEmbeddingBoundsTests extends ActivityEmbeddingTestBase {
for (int i = 0; i < numTimesToResize; i++) {
// Shrink the display by 10% to make the activities stacked
mReportedDisplayMetrics.setSize(new Size((int) (originalDisplaySize.getWidth() * 0.9),
- originalDisplaySize.getHeight()));
+ (int) (originalDisplaySize.getHeight() * 0.9)));
waitForFillsTask(secondaryActivity);
waitAndAssertNotVisible(primaryActivity);
diff --git a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingLifecycleTests.java b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingLifecycleTests.java
index 967f776792d..7e72571cee8 100644
--- a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingLifecycleTests.java
+++ b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingLifecycleTests.java
@@ -22,6 +22,7 @@ import static android.server.wm.jetpack.utils.ActivityEmbeddingUtil.createWildca
import static android.server.wm.jetpack.utils.ActivityEmbeddingUtil.startActivityAndVerifySplit;
import static android.server.wm.jetpack.utils.ActivityEmbeddingUtil.waitAndAssertNotVisible;
import static android.server.wm.jetpack.utils.ActivityEmbeddingUtil.waitAndAssertResumed;
+import static android.server.wm.jetpack.utils.ExtensionUtil.getWindowExtensions;
import static android.server.wm.lifecycle.LifecycleConstants.ON_CREATE;
import static android.server.wm.lifecycle.LifecycleConstants.ON_DESTROY;
import static android.server.wm.lifecycle.LifecycleConstants.ON_PAUSE;
@@ -40,6 +41,7 @@ import android.app.Activity;
import android.app.Application;
import android.net.Uri;
import android.os.Bundle;
+import android.server.wm.jetpack.utils.JavaConsumerAdapter;
import android.server.wm.jetpack.utils.TestActivityWithId;
import android.server.wm.jetpack.utils.TestActivityWithId2;
import android.server.wm.jetpack.utils.TestConfigChangeHandlingActivity;
@@ -80,7 +82,13 @@ public class ActivityEmbeddingLifecycleTests extends ActivityEmbeddingTestBase {
public void setUp() {
super.setUp();
mSplitInfoConsumer = new SplitInfoLifecycleConsumer<>();
- mActivityEmbeddingComponent.setSplitInfoCallback(mSplitInfoConsumer);
+ if (getWindowExtensions().getVendorApiLevel() >= 2) {
+ mActivityEmbeddingComponent.setSplitInfoCallback(mSplitInfoConsumer);
+ } else {
+ mActivityEmbeddingComponent.setSplitInfoCallback(
+ new JavaConsumerAdapter<>(mSplitInfoConsumer)
+ );
+ }
mEventLogClient = EventLogClient.create(TEST_OWNER, mInstrumentation.getTargetContext(),
Uri.parse("content://android.server.wm.jetpack.logprovider"));
diff --git a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingPlaceholderTests.java b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingPlaceholderTests.java
index e7235a2a4d0..0a105cf7742 100644
--- a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingPlaceholderTests.java
+++ b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/ActivityEmbeddingPlaceholderTests.java
@@ -172,14 +172,16 @@ public class ActivityEmbeddingPlaceholderTests extends ActivityEmbeddingTestBase
@Test
public void testPlaceholderFinishedWhenTaskWidthDecreased() {
final int taskWidth = getTaskWidth();
+ final int taskHeight = getTaskHeight();
// Set embedding rules with the parent window metrics only allowing side-by-side activities
- // on a task width at least the current width.
+ // on a task bounds at least the current bounds.
final SplitPlaceholderRule splitPlaceholderRule =
new SplitPlaceholderRuleBuilderWithDefaults(PRIMARY_ACTIVITY_ID,
PLACEHOLDER_ACTIVITY_ID)
- .setParentWindowMetrics(
- windowMetrics -> windowMetrics.getBounds().width() >= taskWidth)
+ .setParentWindowMetrics(windowMetrics ->
+ windowMetrics.getBounds().width() >= taskWidth
+ && windowMetrics.getBounds().height() >= taskHeight)
.build();
mActivityEmbeddingComponent.setEmbeddingRules(Collections.singleton(splitPlaceholderRule));
@@ -189,11 +191,11 @@ public class ActivityEmbeddingPlaceholderTests extends ActivityEmbeddingTestBase
final TestActivity primaryActivity = (TestActivity) activityPair.first;
final Activity placeholderActivity = activityPair.second;
- // Shrink display width by 10% so that the primary and placeholder activities are stacked
+ // Shrink display size by 10% so that the primary and placeholder activities are stacked
primaryActivity.resetBoundsChangeCounter();
final Size currentSize = mReportedDisplayMetrics.getSize();
mReportedDisplayMetrics.setSize(new Size((int) (currentSize.getWidth() * 0.9),
- currentSize.getHeight()));
+ (int) (currentSize.getHeight() * 0.9)));
// Verify that the placeholder activity was finished and that the primary activity now
// fills the task.
@@ -208,16 +210,17 @@ public class ActivityEmbeddingPlaceholderTests extends ActivityEmbeddingTestBase
*/
@Test
public void testPlaceholderLaunchedWhenTaskWidthIncreased() {
- final int taskWidth = getTaskWidth();
+ final double splitTaskWidth = getTaskWidth() * 1.05;
+ final double splitTaskHeight = getTaskHeight() * 1.05;
// Set embedding rules with the parent window metrics only allowing side-by-side activities
- // on a task width 5% wider than the current task width.
+ // on a task bounds 5% larger than the current task bounds.
final SplitPlaceholderRule splitPlaceholderRule =
new SplitPlaceholderRuleBuilderWithDefaults(PRIMARY_ACTIVITY_ID,
PLACEHOLDER_ACTIVITY_ID)
- .setParentWindowMetrics(
- windowMetrics ->
- windowMetrics.getBounds().width() >= taskWidth * 1.05)
+ .setParentWindowMetrics(windowMetrics ->
+ windowMetrics.getBounds().width() >= splitTaskWidth
+ && windowMetrics.getBounds().height() >= splitTaskHeight)
.build();
mActivityEmbeddingComponent.setEmbeddingRules(Collections.singleton(splitPlaceholderRule));
@@ -228,10 +231,10 @@ public class ActivityEmbeddingPlaceholderTests extends ActivityEmbeddingTestBase
verifyFillsTask(primaryActivity);
waitAndAssertNotResumed(PLACEHOLDER_ACTIVITY_ID);
- // Increase display width by 10% so that the primary and placeholder activities are stacked
+ // Increase display size by 10% so that the primary and placeholder activities are stacked
final Size currentSize = mReportedDisplayMetrics.getSize();
mReportedDisplayMetrics.setSize(new Size((int) (currentSize.getWidth() * 1.1),
- currentSize.getHeight()));
+ (int) (currentSize.getHeight() * 1.1)));
// Verify that the placeholder activity is launched into a split with the primary activity
waitAndAssertResumed(PLACEHOLDER_ACTIVITY_ID);
@@ -247,14 +250,16 @@ public class ActivityEmbeddingPlaceholderTests extends ActivityEmbeddingTestBase
@Test
public void testStickyPlaceholder() {
final int taskWidth = getTaskWidth();
+ final int taskHeight = getTaskHeight();
// Set embedding rules with isSticky set to true and the parent window metrics only allowing
// side-by-side activities on a task width at least the current width.
final SplitPlaceholderRule splitPlaceholderRule =
new SplitPlaceholderRuleBuilderWithDefaults(PRIMARY_ACTIVITY_ID,
PLACEHOLDER_ACTIVITY_ID).setIsSticky(true)
- .setParentWindowMetrics(
- windowMetrics -> windowMetrics.getBounds().width() >= taskWidth)
+ .setParentWindowMetrics(windowMetrics ->
+ windowMetrics.getBounds().width() >= taskWidth
+ && windowMetrics.getBounds().height() >= taskHeight)
.build();
mActivityEmbeddingComponent.setEmbeddingRules(Collections.singleton(splitPlaceholderRule));
@@ -267,7 +272,7 @@ public class ActivityEmbeddingPlaceholderTests extends ActivityEmbeddingTestBase
placeholderActivity.resetBoundsChangeCounter();
final Size currentSize = mReportedDisplayMetrics.getSize();
mReportedDisplayMetrics.setSize(new Size((int) (currentSize.getWidth() * 0.9),
- currentSize.getHeight()));
+ (int) (currentSize.getHeight() * 0.9)));
// Verify that the placeholder was not finished and fills the task
assertTrue(placeholderActivity.waitForBoundsChange());
diff --git a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/WindowManagerJetpackTestBase.java b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/WindowManagerJetpackTestBase.java
index fb9f5e8ccb5..2c8c843bb79 100644
--- a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/WindowManagerJetpackTestBase.java
+++ b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/WindowManagerJetpackTestBase.java
@@ -186,6 +186,11 @@ public class WindowManagerJetpackTestBase {
.width();
}
+ public int getTaskHeight() {
+ return mContext.getSystemService(WindowManager.class).getMaximumWindowMetrics().getBounds()
+ .height();
+ }
+
public static void setActivityOrientationActivityHandlesOrientationChanges(
TestActivity activity, int orientation) {
// Make sure that the provided orientation is a fixed orientation
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/ActivityMetricsLoggerTests.java b/tests/framework/base/windowmanager/src/android/server/wm/ActivityMetricsLoggerTests.java
index 9293ed96f74..ff195a14530 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/ActivityMetricsLoggerTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/ActivityMetricsLoggerTests.java
@@ -162,6 +162,7 @@ public class ActivityMetricsLoggerTests extends ActivityManagerTestBase {
}
private void assertTransitionIsStartingWindow(LogMaker log) {
+ if (isLeanBack()) return;
assertEquals("transition should be started because of starting window",
1 /* APP_TRANSITION_STARTING_WINDOW */, log.getSubtype());
assertNotNull("log should have starting window delay",
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/KeyguardTransitionTests.java b/tests/framework/base/windowmanager/src/android/server/wm/KeyguardTransitionTests.java
index b585c048c4b..4463efe0b3b 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/KeyguardTransitionTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/KeyguardTransitionTests.java
@@ -155,7 +155,7 @@ public class KeyguardTransitionTests extends ActivityManagerTestBase {
@Test
public void testNewActivityDuringOccludedWithAttr() {
final LockScreenSession lockScreenSession = createManagedLockScreenSession();
- launchActivity(SHOW_WHEN_LOCKED_ATTR_NO_PREVIEW_ACTIVITY);
+ launchActivityInFullscreen(SHOW_WHEN_LOCKED_ATTR_NO_PREVIEW_ACTIVITY);
lockScreenSession.gotoKeyguard(SHOW_WHEN_LOCKED_ATTR_NO_PREVIEW_ACTIVITY);
launchActivity(SHOW_WHEN_LOCKED_WITH_DIALOG_NO_PREVIEW_ACTIVITY);
mWmState.computeState(SHOW_WHEN_LOCKED_WITH_DIALOG_NO_PREVIEW_ACTIVITY);
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 5f96dd32241..1a452c05b4d 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/RoundedCornerTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/RoundedCornerTests.java
@@ -136,8 +136,6 @@ public class RoundedCornerTests extends ActivityManagerTestBase {
});
// Make sure the child window has been laid out.
- final View childWindowRoot = activity.getChildWindowRoot();
- PollingCheck.waitFor(TIMEOUT, () -> childWindowRoot.getWidth() > 0);
PollingCheck.waitFor(TIMEOUT, () -> activity.getDispatchedInsets() != null);
final WindowInsets insets = activity.getDispatchedInsets();
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 4958cc1bf9c..f6c13120b67 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java
@@ -167,6 +167,7 @@ public class SplashscreenTests extends ActivityManagerTestBase {
// TODO(b/192431448): Allow Automotive to skip this test until Splash Screen is properly
// applied insets by system bars in AAOS.
assumeFalse(isCar());
+ assumeFalse(isLeanBack());
final CommandSession.ActivitySession starter = prepareTestStarter();
final ActivityOptions noIconOptions = ActivityOptions.makeBasic()
@@ -438,6 +439,7 @@ public class SplashscreenTests extends ActivityManagerTestBase {
// TODO(b/192431448): Allow Automotive to skip this test until Splash Screen is properly
// applied insets by system bars in AAOS.
assumeFalse(isCar());
+ assumeFalse(isLeanBack());
final CommandSession.ActivitySession starter = prepareTestStarter();
final ActivityOptions noIconOptions = ActivityOptions.makeBasic()
@@ -506,6 +508,7 @@ public class SplashscreenTests extends ActivityManagerTestBase {
// TODO(b/192431448): Allow Automotive to skip this test until Splash Screen is properly
// applied insets by system bars in AAOS.
assumeFalse(isCar());
+ assumeFalse(isLeanBack());
final LauncherApps launcherApps = mContext.getSystemService(LauncherApps.class);
final ShortcutManager shortcutManager = mContext.getSystemService(ShortcutManager.class);
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationTestBase.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationTestBase.java
index 74d06b943f6..ddc1411c3dc 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationTestBase.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationTestBase.java
@@ -49,7 +49,11 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
+import com.android.compatibility.common.util.OverrideAnimationScaleRule;
+
import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.rules.TestRule;
import org.mockito.InOrder;
import java.util.ArrayList;
@@ -63,6 +67,10 @@ import java.util.function.Predicate;
*/
public class WindowInsetsAnimationTestBase extends WindowManagerTestBase {
+ @Rule
+ public final OverrideAnimationScaleRule mOverrideAnimationScaleRule =
+ new OverrideAnimationScaleRule(1.0f);
+
protected TestActivity mActivity;
protected View mRootView;
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowTest.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowTest.java
index f3ed79f804e..0c376ae6e49 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowTest.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowTest.java
@@ -676,17 +676,20 @@ public class WindowTest {
@Test
public void testSetFitsContentForInsets_displayCutoutInsets_areApplied()
throws Throwable {
- setMayAffectDisplayRotation();
- mActivityRule.runOnUiThread(() -> {
- mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
- mWindow.setDecorFitsSystemWindows(true);
- WindowManager.LayoutParams attrs = mWindow.getAttributes();
- attrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
- mWindow.setAttributes(attrs);
- });
- mInstrumentation.waitForIdleSync();
- assertEquals(mActivity.getContentView().getRootWindowInsets().getSystemWindowInsets(),
- mActivity.getAppliedInsets());
+ try (IgnoreOrientationRequestSession session =
+ new IgnoreOrientationRequestSession(false /* enable */)) {
+ setMayAffectDisplayRotation();
+ mActivityRule.runOnUiThread(() -> {
+ mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+ mWindow.setDecorFitsSystemWindows(true);
+ WindowManager.LayoutParams attrs = mWindow.getAttributes();
+ attrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+ mWindow.setAttributes(attrs);
+ });
+ mInstrumentation.waitForIdleSync();
+ assertEquals(mActivity.getContentView().getRootWindowInsets().getSystemWindowInsets(),
+ mActivity.getAppliedInsets());
+ }
}
@Test
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 cc4552decff..04d18faa595 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowUntrustedTouchTest.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowUntrustedTouchTest.java
@@ -33,6 +33,7 @@ import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;
+import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
import android.app.Activity;
@@ -76,6 +77,7 @@ import androidx.annotation.Nullable;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import com.android.compatibility.common.util.AppOpsUtils;
+import com.android.compatibility.common.util.FeatureUtil;
import com.android.compatibility.common.util.SystemUtil;
import org.junit.After;
@@ -805,6 +807,7 @@ public class WindowUntrustedTouchTest {
@Test
public void testWhenTextToastWindow_allowsTouch() throws Throwable {
+ assumeFalse("Watch does not support new Toast behavior yet.", FeatureUtil.isWatch());
addToastOverlay(APP_A, /* custom */ false);
Rect toast = mWmState.waitForResult("toast bounds",
state -> state.findFirstWindowWithType(LayoutParams.TYPE_TOAST).getFrame());
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 03988ea28af..46081611198 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
@@ -23,6 +23,7 @@ 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.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.Intent.ACTION_MAIN;
import static android.content.Intent.CATEGORY_HOME;
@@ -348,6 +349,11 @@ public abstract class ActivityManagerTestBase {
extras);
}
+ protected static String getAmStartCmdWithWindowingMode(
+ final ComponentName activityName, int windowingMode) {
+ return getAmStartCmdInNewTask(activityName) + " --windowingMode " + windowingMode;
+ }
+
protected WindowManagerStateHelper mWmState = new WindowManagerStateHelper();
protected TouchHelper mTouchHelper = new TouchHelper(mInstrumentation, mWmState);
// Initialized in setUp to execute with proper permission, such as MANAGE_ACTIVITY_TASKS
@@ -829,6 +835,12 @@ public abstract class ActivityManagerTestBase {
mWmState.waitForValidState(activityName);
}
+ protected void launchActivityInFullscreen(final ComponentName activityName) {
+ executeShellCommand(
+ getAmStartCmdWithWindowingMode(activityName, WINDOWING_MODE_FULLSCREEN));
+ mWmState.waitForValidState(activityName);
+ }
+
protected static void waitForIdle() {
getInstrumentation().waitForIdleSync();
}
diff --git a/tests/inputmethod/AndroidTest.xml b/tests/inputmethod/AndroidTest.xml
index 78d878bdef7..8f2225294aa 100644
--- a/tests/inputmethod/AndroidTest.xml
+++ b/tests/inputmethod/AndroidTest.xml
@@ -116,6 +116,9 @@
<option name="teardown-command" value="am compat reset ALLOW_TEST_API_ACCESS com.android.cts.mocka11yime" />
<option name="run-command" value="am compat enable ALLOW_TEST_API_ACCESS android.view.inputmethod.ctstestapp" />
<option name="teardown-command" value="am compat reset ALLOW_TEST_API_ACCESS android.view.inputmethod.ctstestapp" />
+
+ <!-- Wait for PACKAGE_ADDED broadcasts to be delivered to InputMethodManagerService. -->
+ <option name="run-command" value="am wait-for-broadcast-idle" />
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.view.inputmethod.cts" />
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/ImeInsetsControllerTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/ImeInsetsControllerTest.java
index 0fa03072b1c..4d4bdef8134 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/ImeInsetsControllerTest.java
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/ImeInsetsControllerTest.java
@@ -18,6 +18,7 @@ package android.view.inputmethod.cts;
import static android.view.WindowInsets.CONSUMED;
import static android.view.WindowInsets.Type.ime;
+import static android.view.WindowInsets.Type.navigationBars;
import static com.android.cts.mockime.ImeEventStreamTestUtils.expectBindInput;
import static com.android.cts.mockime.ImeEventStreamTestUtils.expectCommand;
@@ -26,7 +27,6 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import android.app.WindowConfiguration;
-import android.graphics.Point;
import android.os.Process;
import android.os.SystemClock;
import android.util.Pair;
@@ -91,7 +91,7 @@ public class ImeInsetsControllerTest extends EndToEndImeTestBase {
}
private static final int INITIAL_KEYBOARD_HEIGHT = 200;
- private static final int NEW_KEYBOARD_HEIGHT = 300;
+ private static final int KEYBOARD_HEIGHT_INCREASE = 100;
@Test
public void testChangeSizeWhileControlling() throws Exception {
@@ -152,7 +152,9 @@ public class ImeInsetsControllerTest extends EndToEndImeTestBase {
// Change keyboard height, but make sure the insets don't change until the controlling
// is done.
- expectCommand(stream, imeSession.callSetHeight(NEW_KEYBOARD_HEIGHT), TIMEOUT);
+ final int newKeyboardHeight =
+ lastInsets[0].getInsets(ime()).bottom + KEYBOARD_HEIGHT_INCREASE;
+ expectCommand(stream, imeSession.callSetHeight(newKeyboardHeight), TIMEOUT);
SystemClock.sleep(500);
@@ -174,8 +176,8 @@ public class ImeInsetsControllerTest extends EndToEndImeTestBase {
assertEquals(0, insetsLatch.getCount());
// Verify new height
- assertEquals(getExpectedBottomInsets(NEW_KEYBOARD_HEIGHT, decorView),
- lastInsets[0].getInsets(ime()).bottom);
+ assertEquals(getExpectedBottomInsets(newKeyboardHeight, decorView),
+ lastInsets[0].getInsets(ime()).bottom);
assertFalse(cancelled[0]);
}
@@ -206,22 +208,10 @@ public class ImeInsetsControllerTest extends EndToEndImeTestBase {
};
}
- private int getDisplayHeight(View view) {
- final Point size = new Point();
- view.getDisplay().getRealSize(size);
- return size.y;
- }
-
- private int getBottomOfWindow(View decorView) {
- final int[] viewPos = new int[2];
- decorView.getLocationOnScreen(viewPos);
- return decorView.getHeight() + viewPos[1];
- }
-
private int getExpectedBottomInsets(int keyboardHeight, View decorView) {
- return Math.max(
- 0,
- keyboardHeight
- - Math.max(0, getDisplayHeight(decorView) - getBottomOfWindow(decorView)));
+ // IME window is never smaller than navigation bars.
+ final int navBarHeight = decorView.getRootWindowInsets()
+ .getInsetsIgnoringVisibility(navigationBars()).bottom;
+ return Math.max(navBarHeight, keyboardHeight);
}
}
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodServiceTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodServiceTest.java
index 8e18ec1af98..a9cec5104ef 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodServiceTest.java
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodServiceTest.java
@@ -41,10 +41,12 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
import android.app.Activity;
import android.app.Instrumentation;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.inputmethodservice.InputMethodService;
@@ -713,6 +715,8 @@ public class InputMethodServiceTest extends EndToEndImeTestBase {
@Test
public void testBatchEdit_commitAndSetComposingRegion_webView() throws Exception {
+ assumeTrue(hasFeatureWebView());
+
getCommitAndSetComposingRegionTest(TIMEOUT,
"testBatchEdit_commitAndSetComposingRegion_webView/")
.setTestTextView(false)
@@ -729,6 +733,8 @@ public class InputMethodServiceTest extends EndToEndImeTestBase {
@Test
public void testBatchEdit_commitSpaceThenSetComposingRegion_webView() throws Exception {
+ assumeTrue(hasFeatureWebView());
+
getCommitSpaceAndSetComposingRegionTest(TIMEOUT,
"testBatchEdit_commitSpaceThenSetComposingRegion_webView/")
.setTestTextView(false)
@@ -747,12 +753,20 @@ public class InputMethodServiceTest extends EndToEndImeTestBase {
@Test
public void testBatchEdit_getCommitSpaceAndSetComposingRegionTestInSelectionTest_webView()
throws Exception {
+ assumeTrue(hasFeatureWebView());
+
getCommitSpaceAndSetComposingRegionInSelectionTest(TIMEOUT,
"testBatchEdit_getCommitSpaceAndSetComposingRegionTestInSelectionTest_webView/")
.setTestTextView(false)
.runTest();
}
+ private boolean hasFeatureWebView() {
+ final PackageManager pm =
+ InstrumentationRegistry.getInstrumentation().getContext().getPackageManager();
+ return pm.hasSystemFeature(PackageManager.FEATURE_WEBVIEW);
+ }
+
@Test
public void testImeVisibleAfterRotation() throws Exception {
try (MockImeSession imeSession = MockImeSession.create(
diff --git a/tests/inputmethod/tests32/AndroidTest.xml b/tests/inputmethod/tests32/AndroidTest.xml
index 9c5b12879de..e24e28df3c3 100644
--- a/tests/inputmethod/tests32/AndroidTest.xml
+++ b/tests/inputmethod/tests32/AndroidTest.xml
@@ -71,6 +71,9 @@
<option name="teardown-command" value="am compat reset ALLOW_TEST_API_ACCESS com.android.cts.mockime" />
<option name="run-command" value="am compat enable ALLOW_TEST_API_ACCESS android.view.inputmethod.ctstestapp" />
<option name="teardown-command" value="am compat reset ALLOW_TEST_API_ACCESS android.view.inputmethod.ctstestapp" />
+
+ <!-- Wait for PACKAGE_ADDED broadcasts to be delivered to InputMethodManagerService. -->
+ <option name="run-command" value="am wait-for-broadcast-idle" />
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
<option name="package" value="android.view.inputmethod.cts.sdk32" />
diff --git a/tests/location/location_none/src/android/location/cts/none/LocationDisabledAppOpsTest.java b/tests/location/location_none/src/android/location/cts/none/LocationDisabledAppOpsTest.java
index ded4ecaffe9..b4c5c834595 100644
--- a/tests/location/location_none/src/android/location/cts/none/LocationDisabledAppOpsTest.java
+++ b/tests/location/location_none/src/android/location/cts/none/LocationDisabledAppOpsTest.java
@@ -86,13 +86,16 @@ public class LocationDisabledAppOpsTest {
List<String> bypassedCheckOps = new ArrayList<>();
for (PackageInfo pi : pkgs) {
ApplicationInfo ai = pi.applicationInfo;
- if (ai.uid != Process.SYSTEM_UID) {
+ int appId = UserHandle.getAppId(ai.uid);
+ if (appId != Process.SYSTEM_UID) {
final int[] mode = {MODE_ALLOWED};
+ final boolean[] isProvider = {false};
runWithShellPermissionIdentity(() -> {
mode[0] = mAom.noteOpNoThrow(
OPSTR_FINE_LOCATION, ai.uid, ai.packageName);
+ isProvider[0] = mLm.isProviderPackage(null, pi.packageName, null);
if (mode[0] == MODE_ALLOWED && !ignoreList.containsAll(pi.packageName)
- && !mLm.isProviderPackage(null, pi.packageName, null)) {
+ && !isProvider[0]) {
bypassedNoteOps.add(pi.packageName);
}
});
@@ -102,8 +105,9 @@ public class LocationDisabledAppOpsTest {
runWithShellPermissionIdentity(() -> {
mode[0] = mAom
.checkOpNoThrow(OPSTR_FINE_LOCATION, ai.uid, ai.packageName);
+ isProvider[0] = mLm.isProviderPackage(null, pi.packageName, null);
if (mode[0] == MODE_ALLOWED && !ignoreList.includes(pi.packageName)
- && !mLm.isProviderPackage(null, pi.packageName, null)) {
+ && !isProvider[0]) {
bypassedCheckOps.add(pi.packageName);
}
});
diff --git a/tests/tests/app/AndroidManifest.xml b/tests/tests/app/AndroidManifest.xml
index ef8c1a8271c..3eab6325f28 100644
--- a/tests/tests/app/AndroidManifest.xml
+++ b/tests/tests/app/AndroidManifest.xml
@@ -22,7 +22,7 @@
<uses-library android:name="android.test.runner" />
<activity android:name=".ApplyOverrideConfigurationActivity"
- android:configChanges="orientation|screenSize" />
+ android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout" />
<activity android:name=".PictureInPictureActivity"
android:resizeableActivity="false"
diff --git a/tests/tests/appenumeration/src/android/appenumeration/cts/AppEnumerationTests.java b/tests/tests/appenumeration/src/android/appenumeration/cts/AppEnumerationTests.java
index 755ac444f19..6ea60236a8e 100644
--- a/tests/tests/appenumeration/src/android/appenumeration/cts/AppEnumerationTests.java
+++ b/tests/tests/appenumeration/src/android/appenumeration/cts/AppEnumerationTests.java
@@ -17,6 +17,7 @@
package android.appenumeration.cts;
import static android.Manifest.permission.SET_PREFERRED_APPLICATIONS;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.appenumeration.cts.Constants.ACTION_AWAIT_LAUNCHER_APPS_CALLBACK;
import static android.appenumeration.cts.Constants.ACTION_AWAIT_LAUNCHER_APPS_SESSION_CALLBACK;
import static android.appenumeration.cts.Constants.ACTION_BIND_SERVICE;
@@ -163,6 +164,7 @@ import static org.junit.Assume.assumeTrue;
import android.Manifest;
import android.accounts.Account;
import android.accounts.AccountManager;
+import android.app.ActivityOptions;
import android.app.PendingIntent;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
@@ -2532,7 +2534,10 @@ public class AppEnumerationTests {
AmUtils.waitForBroadcastIdle();
startAndWaitForCommandReady(intent);
} else {
- InstrumentationRegistry.getInstrumentation().getContext().startActivity(intent);
+ final ActivityOptions options = ActivityOptions.makeBasic();
+ options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ InstrumentationRegistry.getInstrumentation().getContext().startActivity(
+ intent, options.toBundle());
}
return () -> {
if (!latch.block(TimeUnit.SECONDS.toMillis(10))) {
diff --git a/tests/tests/bluetooth/AndroidManifest.xml b/tests/tests/bluetooth/AndroidManifest.xml
index e624d2b2ab7..a1512005e4e 100644
--- a/tests/tests/bluetooth/AndroidManifest.xml
+++ b/tests/tests/bluetooth/AndroidManifest.xml
@@ -27,6 +27,7 @@
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<application>
<uses-library android:name="android.test.runner" />
diff --git a/tests/tests/car/src/android/car/cts/CarServiceHelperServiceUpdatableTest.java b/tests/tests/car/src/android/car/cts/CarServiceHelperServiceUpdatableTest.java
index ed42e79c06b..80229ec9638 100644
--- a/tests/tests/car/src/android/car/cts/CarServiceHelperServiceUpdatableTest.java
+++ b/tests/tests/car/src/android/car/cts/CarServiceHelperServiceUpdatableTest.java
@@ -43,6 +43,7 @@ import androidx.test.filters.FlakyTest;
import com.android.compatibility.common.util.SystemUtil;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import java.io.BufferedReader;
@@ -66,6 +67,7 @@ public final class CarServiceHelperServiceUpdatableTest extends CarApiTestBase {
}
@Test
+ @Ignore("b/234674080")
public void testCarServiceHelperServiceDump() throws Exception {
assumeThat("System_server_dumper not implemented.",
executeShellCommand("service check system_server_dumper"),
diff --git a/tests/tests/contactsprovider/src/android/provider/cts/contacts/ContactsContractIntentsTest.java b/tests/tests/contactsprovider/src/android/provider/cts/contacts/ContactsContractIntentsTest.java
index 488547d042c..9edc805da2e 100644
--- a/tests/tests/contactsprovider/src/android/provider/cts/contacts/ContactsContractIntentsTest.java
+++ b/tests/tests/contactsprovider/src/android/provider/cts/contacts/ContactsContractIntentsTest.java
@@ -56,8 +56,12 @@ public class ContactsContractIntentsTest extends AndroidTestCase {
}
public void testSetDefaultAccount() {
- Intent intent = new Intent(ContactsContract.Settings.ACTION_SET_DEFAULT_ACCOUNT);
PackageManager packageManager = getContext().getPackageManager();
+ if (packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+ return; // Skip test on watch since the intent is not required.
+ }
+
+ Intent intent = new Intent(ContactsContract.Settings.ACTION_SET_DEFAULT_ACCOUNT);
List<ResolveInfo> resolveInfoList = packageManager.queryIntentActivities(intent, 0);
assertNotNull("Missing ResolveInfo", resolveInfoList);
int handlerCount = 0;
diff --git a/tests/tests/dpi/src/android/dpi/cts/ConfigurationScreenLayoutTest.java b/tests/tests/dpi/src/android/dpi/cts/ConfigurationScreenLayoutTest.java
index 5db5f661d61..d3e4c91ad8a 100644
--- a/tests/tests/dpi/src/android/dpi/cts/ConfigurationScreenLayoutTest.java
+++ b/tests/tests/dpi/src/android/dpi/cts/ConfigurationScreenLayoutTest.java
@@ -28,6 +28,8 @@ import static android.view.WindowInsets.Type.displayCutout;
import static android.view.WindowInsets.Type.navigationBars;
import static android.view.WindowInsets.Type.systemBars;
+import static android.server.wm.ActivityManagerTestBase.isTablet;
+
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedVectorDrawableParameterizedTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedVectorDrawableParameterizedTest.java
index c0ef37498ca..dd0cc92e4a1 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedVectorDrawableParameterizedTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedVectorDrawableParameterizedTest.java
@@ -40,6 +40,7 @@ import androidx.test.filters.LargeTest;
import androidx.test.filters.SmallTest;
import androidx.test.rule.ActivityTestRule;
+import com.android.compatibility.common.util.OverrideAnimationScaleRule;
import com.android.compatibility.common.util.SynchronousPixelCopy;
import com.android.compatibility.common.util.SystemUtil;
import com.android.compatibility.common.util.WidgetTestUtils;
@@ -63,6 +64,12 @@ public class AnimatedVectorDrawableParameterizedTest {
public ActivityTestRule<DrawableStubActivity> mActivityRule =
new ActivityTestRule<>(DrawableStubActivity.class);
+ // Some of these tests require animations to work normally, which may not be the case
+ // depending on the current state of the test device
+ @Rule
+ public final OverrideAnimationScaleRule animationScaleRule =
+ new OverrideAnimationScaleRule(1f);
+
private static final int IMAGE_WIDTH = 64;
private static final int IMAGE_HEIGHT = 64;
private static final long MAX_TIMEOUT_MS = 1000;
diff --git a/tests/tests/hibernation/src/android/hibernation/cts/AppHibernationIntegrationTest.kt b/tests/tests/hibernation/src/android/hibernation/cts/AppHibernationIntegrationTest.kt
index 3a9969e11b9..a7c5f490573 100644
--- a/tests/tests/hibernation/src/android/hibernation/cts/AppHibernationIntegrationTest.kt
+++ b/tests/tests/hibernation/src/android/hibernation/cts/AppHibernationIntegrationTest.kt
@@ -64,7 +64,6 @@ import org.junit.Assert.assertTrue
import org.junit.Assume.assumeFalse
import org.junit.Before
import org.junit.BeforeClass
-import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -138,7 +137,6 @@ class AppHibernationIntegrationTest {
}
@Test
- @Ignore("b/201545116")
fun testUnusedApp_getsForceStopped() {
withUnusedThresholdMs(TEST_UNUSED_THRESHOLD) {
withApp(APK_PATH_S_APP, APK_PACKAGE_NAME_S_APP) {
diff --git a/tests/tests/hibernation/src/android/hibernation/cts/AppHibernationUtils.kt b/tests/tests/hibernation/src/android/hibernation/cts/AppHibernationUtils.kt
index 485a4efe431..b6f03c87203 100644
--- a/tests/tests/hibernation/src/android/hibernation/cts/AppHibernationUtils.kt
+++ b/tests/tests/hibernation/src/android/hibernation/cts/AppHibernationUtils.kt
@@ -328,14 +328,18 @@ fun waitFindObject(uiAutomation: UiAutomation, selector: BySelector): UiObject2
val title = ui.depthFirstSearch { node ->
node.viewIdResourceName?.contains("alertTitle") == true
}
- val okButton = ui.depthFirstSearch { node ->
- node.textAsString?.equals("OK", ignoreCase = true) ?: false
+ val okCloseButton = ui.depthFirstSearch { node ->
+ (node.textAsString?.equals("OK", ignoreCase = true) ?: false) ||
+ (node.textAsString?.equals("Close app", ignoreCase = true) ?: false)
}
-
- if (title?.text?.toString() == "Android System" && okButton != null) {
+ val titleString = title?.text?.toString()
+ if (okCloseButton != null &&
+ titleString != null &&
+ (titleString == "Android System" ||
+ titleString.endsWith("keeps stopping"))) {
// Auto dismiss occasional system dialogs to prevent interfering with the test
android.util.Log.w(AutoRevokeTest.LOG_TAG, "Ignoring exception", e)
- okButton.click()
+ okCloseButton.click()
return UiAutomatorUtils.waitFindObject(selector)
} else {
throw e
diff --git a/tests/tests/hibernation/src/android/hibernation/cts/AutoRevokeTest.kt b/tests/tests/hibernation/src/android/hibernation/cts/AutoRevokeTest.kt
index 1adc0281893..34ad254ff2f 100644
--- a/tests/tests/hibernation/src/android/hibernation/cts/AutoRevokeTest.kt
+++ b/tests/tests/hibernation/src/android/hibernation/cts/AutoRevokeTest.kt
@@ -194,7 +194,6 @@ class AutoRevokeTest {
@AppModeFull(reason = "Uses separate apps for testing")
@Test
- @Ignore("b/201545116")
fun testUnusedApp_uninstallApp() {
assumeFalse(
"Unused apps screen may be unavailable on TV",
diff --git a/tests/tests/media/common/src/android/media/cts/TestUtils.java b/tests/tests/media/common/src/android/media/cts/TestUtils.java
index 20bf143ca96..552cf65372a 100644
--- a/tests/tests/media/common/src/android/media/cts/TestUtils.java
+++ b/tests/tests/media/common/src/android/media/cts/TestUtils.java
@@ -187,13 +187,27 @@ public final class TestUtils {
return true;
}
// MTS mode, just the codecs that live in the modules
- if (name.startsWith("c2.android.")) {
+ if (isMainlineCodec(name)) {
return true;
}
Log.d(TAG, "Test mode MTS does not test codec " + name);
return false;
}
+ /*
+ * Report whether this codec is a google-supplied codec that lives within the
+ * mainline modules.
+ *
+ * @param name the name of a codec
+ * @return {@code} true if the codec is one that lives within the mainline boundaries
+ */
+ public static boolean isMainlineCodec(String name) {
+ if (name.startsWith("c2.android.")) {
+ return true;
+ }
+ return false;
+ }
+
private TestUtils() {
}
diff --git a/tests/tests/media/decoder/src/android/media/decoder/cts/DecodeAccuracyTest.java b/tests/tests/media/decoder/src/android/media/decoder/cts/DecodeAccuracyTest.java
index c9823760671..1a1280cbe90 100644
--- a/tests/tests/media/decoder/src/android/media/decoder/cts/DecodeAccuracyTest.java
+++ b/tests/tests/media/decoder/src/android/media/decoder/cts/DecodeAccuracyTest.java
@@ -27,6 +27,8 @@ import android.graphics.Bitmap;
import android.media.MediaFormat;
import android.media.cts.MediaHeavyPresubmitTest;
import android.media.cts.TestArgs;
+import android.media.cts.TestUtils;
+import android.os.Build;
import android.os.Environment;
import android.platform.test.annotations.AppModeFull;
import android.util.Log;
@@ -34,6 +36,7 @@ import android.view.View;
import androidx.test.platform.app.InstrumentationRegistry;
+import com.android.compatibility.common.util.ApiLevelUtil;
import com.android.compatibility.common.util.MediaUtils;
import java.io.File;
@@ -64,6 +67,10 @@ import org.junit.Test;
@AppModeFull(reason = "There should be no instant apps specific behavior related to accuracy")
public class DecodeAccuracyTest extends DecodeAccuracyTestBase {
+ private static final boolean IS_AT_LEAST_U = ApiLevelUtil.isAfter(Build.VERSION_CODES.TIRAMISU)
+ || ApiLevelUtil.codenameEquals("UpsideDownCake");
+ private static final boolean IS_BEFORE_U = !IS_AT_LEAST_U;
+
private static final String TAG = DecodeAccuracyTest.class.getSimpleName();
private static final Field[] fields = R.raw.class.getFields();
private static final int ALLOWED_GREATEST_PIXEL_DIFFERENCE = 90;
@@ -281,7 +288,7 @@ public class DecodeAccuracyTest extends DecodeAccuracyTestBase {
final int golden = getGoldenId(vf.getDescription(), vf.getOriginalSize());
assertTrue("No golden found.", golden != 0);
decodeVideo(vf, videoViewFactory, decoderName);
- validateResult(vf, videoViewFactory.getVideoViewSnapshot(), golden);
+ validateResult(vf, videoViewFactory.getVideoViewSnapshot(), golden, decoderName);
}
private void decodeVideo(VideoFormat videoFormat, VideoViewFactory videoViewFactory,
@@ -293,12 +300,24 @@ public class DecodeAccuracyTest extends DecodeAccuracyTestBase {
}
private void validateResult(
- VideoFormat videoFormat, VideoViewSnapshot videoViewSnapshot, int goldenId) {
+ VideoFormat videoFormat, VideoViewSnapshot videoViewSnapshot, int goldenId,
+ String decoderName) {
final Bitmap result = checkNotNull("The expected bitmap from snapshot is null",
getHelper().generateBitmapFromVideoViewSnapshot(videoViewSnapshot));
final Bitmap golden = getHelper().generateBitmapFromImageResourceId(goldenId);
+
+ int ignorePixels = 0;
+ if (IS_BEFORE_U && TestUtils.isMtsMode()) {
+ if (TestUtils.isMainlineCodec(decoderName)) {
+ // some older systems don't give proper behavior at the edges (in system code).
+ // while we can't fix the behavior at the edges, we can verify that the rest
+ // of the image is within tolerance. b/256807044
+ ignorePixels = 1;
+ }
+ }
final BitmapCompare.Difference difference = BitmapCompare.computeMinimumDifference(
- result, golden, videoFormat.getOriginalWidth(), videoFormat.getOriginalHeight());
+ result, golden, ignorePixels, videoFormat.getOriginalWidth(),
+ videoFormat.getOriginalHeight());
if (difference.greatestPixelDifference > ALLOWED_GREATEST_PIXEL_DIFFERENCE) {
/* save failing file */
diff --git a/tests/tests/media/decoder/src/android/media/decoder/cts/DecodeAccuracyTestBase.java b/tests/tests/media/decoder/src/android/media/decoder/cts/DecodeAccuracyTestBase.java
index d26c45ffd33..38fdb1858ad 100644
--- a/tests/tests/media/decoder/src/android/media/decoder/cts/DecodeAccuracyTestBase.java
+++ b/tests/tests/media/decoder/src/android/media/decoder/cts/DecodeAccuracyTestBase.java
@@ -1763,6 +1763,7 @@ class FilenameParser {
* CIE L*a*b* color space. The euclidean distance formula is used to determine pixel differences.
*/
class BitmapCompare {
+ private static final String TAG = "BitmapCompare";
private static final int RED = 0;
private static final int GREEN = 1;
@@ -1776,6 +1777,8 @@ class BitmapCompare {
/**
* Produces greatest pixel between two bitmaps. Used to determine bitmap similarity.
*
+ * This simplified variant does not ignore any edge pixels.
+ *
* @param bitmap1 A bitmap to compare to bitmap2.
* @param bitmap2 A bitmap to compare to bitmap1.
* @return A {@link Difference} with an integer describing the greatest pixel difference,
@@ -1783,7 +1786,26 @@ class BitmapCompare {
* {@link Pair<Integer, Integer>} of the (col, row) pixel coordinate where it was first found.
*/
@TargetApi(12)
- public static Difference computeDifference(Bitmap bitmap1, Bitmap bitmap2) {
+ private static Difference computeDifference(Bitmap bitmap1, Bitmap bitmap2) {
+ return computeDifference(bitmap1, bitmap2, 0);
+ }
+
+ /**
+ * Produces greatest pixel between two bitmaps. Used to determine bitmap similarity.
+ *
+ * @param bitmap1 A bitmap to compare to bitmap2.
+ * @param bitmap2 A bitmap to compare to bitmap1.
+ * @param ignorePixels number of pixels at each edge where we ignore the scoring. This
+ * is used for mainline and older base systems to bypass an edge behavior in the
+ * GPU code on those systems.
+ * @return A {@link Difference} with an integer describing the greatest pixel difference,
+ * using {@link Integer#MAX_VALUE} for completely different bitmaps, and an optional
+ * {@link Pair<Integer, Integer>} of the (col, row) pixel coordinate where it was
+ * first found.
+ */
+ @TargetApi(12)
+ private static Difference computeDifference(Bitmap bitmap1, Bitmap bitmap2, int ignorePixels) {
+ Log.i(TAG, "ignorePixels = " + ignorePixels);
if (bitmap1 == null || bitmap2 == null) {
return new Difference(Integer.MAX_VALUE);
}
@@ -1797,15 +1819,31 @@ class BitmapCompare {
// euclidean distance formula.
final double[][] pixels1 = convertRgbToCieLab(bitmap1);
final double[][] pixels2 = convertRgbToCieLab(bitmap2);
- int greatestDifference = 0;
+ int greatestDifference = -1; // forces a legal index later...
int greatestDifferenceIndex = -1;
for (int i = 0; i < pixels1.length; i++) {
+ // pixels within 'ignorePixels' of the edge are to be ignored for
+ // scoring purposes.
+ int x = i % bitmap1.getWidth();
+ int y = i / bitmap1.getWidth();
+ if (x < ignorePixels || x >= bitmap1.getWidth() - ignorePixels
+ || y < ignorePixels || y >= bitmap1.getHeight() - ignorePixels) {
+ continue;
+ }
+
final int difference = euclideanDistance(pixels1[i], pixels2[i]);
+
if (difference > greatestDifference) {
greatestDifference = difference;
greatestDifferenceIndex = i;
}
}
+
+ // huge ignorePixels values can get here without checking any pixels
+ if (greatestDifferenceIndex == -1) {
+ greatestDifferenceIndex = 0;
+ greatestDifference = 0;
+ }
return new Difference(greatestDifference, Pair.create(
greatestDifferenceIndex % bitmap1.getWidth(),
greatestDifferenceIndex / bitmap1.getWidth()));
@@ -2019,16 +2057,16 @@ class BitmapCompare {
*/
@TargetApi(12)
public static Difference computeMinimumDifference(
- Bitmap bitmap1, Bitmap bitmap2, Pair<Double, Double>[] borderCrops) {
+ Bitmap bitmap1, Bitmap bitmap2, int ignorePixels, Pair<Double, Double>[] borderCrops) {
// Compute the difference with the original image (bitmap2) first.
- Difference minDiff = computeDifference(bitmap1, bitmap2);
+ Difference minDiff = computeDifference(bitmap1, bitmap2, ignorePixels);
// Then go through the list of borderCrops.
for (Pair<Double, Double> borderCrop : borderCrops) {
// Compute the difference between bitmap1 and a transformed
// version of bitmap2.
Bitmap bitmap2s = shrinkAndScaleBilinear(bitmap2, borderCrop.first, borderCrop.second);
- Difference d = computeDifference(bitmap1, bitmap2s);
+ Difference d = computeDifference(bitmap1, bitmap2s, ignorePixels);
// Keep the minimum difference.
if (d.greatestPixelDifference < minDiff.greatestPixelDifference) {
minDiff = d;
@@ -2043,7 +2081,7 @@ class BitmapCompare {
*/
@TargetApi(12)
public static Difference computeMinimumDifference(
- Bitmap bitmap1, Bitmap bitmap2, int trueWidth, int trueHeight) {
+ Bitmap bitmap1, Bitmap bitmap2, int ignorePixels, int trueWidth, int trueHeight) {
double hBorder = (double) bitmap1.getWidth() / (double) trueWidth;
double vBorder = (double) bitmap1.getHeight() / (double) trueHeight;
@@ -2052,6 +2090,7 @@ class BitmapCompare {
return computeMinimumDifference(
bitmap1,
bitmap2,
+ ignorePixels,
new Pair[] {
Pair.create(hBorderH, 0.0),
Pair.create(hBorderH, vBorderH),
diff --git a/tests/tests/media/decoder/src/android/media/decoder/cts/VideoDecoderPerfTest.java b/tests/tests/media/decoder/src/android/media/decoder/cts/VideoDecoderPerfTest.java
index ef7646b87f6..3db3d570777 100644
--- a/tests/tests/media/decoder/src/android/media/decoder/cts/VideoDecoderPerfTest.java
+++ b/tests/tests/media/decoder/src/android/media/decoder/cts/VideoDecoderPerfTest.java
@@ -211,7 +211,7 @@ public class VideoDecoderPerfTest extends MediaTestBase {
}
// allow improvements in mainline-updated google-supplied software codecs.
- boolean fasterIsOk = mUpdatedSwCodec & name.startsWith("c2.android.");
+ boolean fasterIsOk = mUpdatedSwCodec & TestUtils.isMainlineCodec(name);
String error =
MediaPerfUtils.verifyAchievableFrameRates(name, mime, width, height,
fasterIsOk, measuredFps);
diff --git a/tests/tests/media/drmframework/src/android/media/drmframework/cts/MediaDrmTest.java b/tests/tests/media/drmframework/src/android/media/drmframework/cts/MediaDrmTest.java
index 1bb5646c781..62e2f693458 100644
--- a/tests/tests/media/drmframework/src/android/media/drmframework/cts/MediaDrmTest.java
+++ b/tests/tests/media/drmframework/src/android/media/drmframework/cts/MediaDrmTest.java
@@ -51,10 +51,7 @@ public class MediaDrmTest {
private void testSingleScheme(UUID scheme) throws Exception {
MediaDrm md = new MediaDrm(scheme);
- assertTrue(md.getOpenSessionCount() <= md.getMaxSessionCount());
- assertThrows(() -> {
- md.closeSession(null);
- });
+ // TODO(b/267460223): test properties description, vendor, version
md.close();
}
@@ -125,7 +122,9 @@ public class MediaDrmTest {
@Test
public void testPlaybackComponent() throws UnsupportedSchemeException {
- for (UUID scheme : MediaDrm.getSupportedCryptoSchemes()) {
+ final UUID CLEARKEY_UUID = new UUID(0xe2719d58a985b3c9L, 0x781ab030af78d30eL);
+ // TODO(b/267463362): move testPlaybackComponent to MediaDrmClearkeyTest
+ for (UUID scheme : new UUID[] {CLEARKEY_UUID}) {
MediaDrm drm = new MediaDrm(scheme);
byte[] sid = null;
try {
diff --git a/tests/tests/nfc/src/android/nfc/cts/NfcPreferredPaymentTest.java b/tests/tests/nfc/src/android/nfc/cts/NfcPreferredPaymentTest.java
index c769a09432b..85810eb3a3f 100644
--- a/tests/tests/nfc/src/android/nfc/cts/NfcPreferredPaymentTest.java
+++ b/tests/tests/nfc/src/android/nfc/cts/NfcPreferredPaymentTest.java
@@ -57,7 +57,12 @@ public class NfcPreferredPaymentTest {
private boolean supportsHardware() {
final PackageManager pm = InstrumentationRegistry.getContext().getPackageManager();
- return pm.hasSystemFeature(PackageManager.FEATURE_NFC);
+ boolean existAnyReqFeature =
+ pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)
+ || pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF)
+ || pm.hasSystemFeature(PackageManager.FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE)
+ || pm.hasSystemFeature(PackageManager.FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC);
+ return existAnyReqFeature;
}
@Before
diff --git a/tests/tests/permission/AndroidTest.xml b/tests/tests/permission/AndroidTest.xml
index eafc6a6389c..c50ccb424f8 100644
--- a/tests/tests/permission/AndroidTest.xml
+++ b/tests/tests/permission/AndroidTest.xml
@@ -27,7 +27,10 @@
<!-- Keep screen on for Bluetooth scanning -->
<target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
<option name="force-skip-system-props" value="true" /> <!-- avoid restarting device -->
+ <option name="set-global-setting" key="verifier_verify_adb_installs" value="0" />
+ <option name="restore-settings" value="true" />
<option name="screen-always-on" value="on" />
+ <option name="disable-device-config-sync" value="true" />
</target_preparer>
<!-- Install main test suite apk -->
diff --git a/tests/tests/permission2/AndroidTest.xml b/tests/tests/permission2/AndroidTest.xml
index 54ea94b710e..59d483d40c8 100644
--- a/tests/tests/permission2/AndroidTest.xml
+++ b/tests/tests/permission2/AndroidTest.xml
@@ -30,6 +30,13 @@
<option name="test-file-name" value="CtsPermission2TestCases.apk" />
</target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
+ <option name="force-skip-system-props" value="true" /> <!-- avoid restarting device -->
+ <option name="set-global-setting" key="verifier_verify_adb_installs" value="0" />
+ <option name="restore-settings" value="true" />
+ <option name="disable-device-config-sync" value="true" />
+ </target_preparer>
+
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="push" value="CtsLocationPermissionsUserSdk22.apk->/data/local/tmp/cts/permissions2/CtsLocationPermissionsUserSdk22.apk" />
<option name="push" value="CtsLocationPermissionsUserSdk29.apk->/data/local/tmp/cts/permissions2/CtsLocationPermissionsUserSdk29.apk" />
diff --git a/tests/tests/permission2/res/raw/automotive_android_manifest.xml b/tests/tests/permission2/res/raw/automotive_android_manifest.xml
index aa263ea65bb..d275ef4fed9 100644
--- a/tests/tests/permission2/res/raw/automotive_android_manifest.xml
+++ b/tests/tests/permission2/res/raw/automotive_android_manifest.xml
@@ -482,4 +482,8 @@
android:protectionLevel="signature|privileged"
android:label="@string/car_permission_label_manage_thread_priority"
android:description="@string/car_permission_desc_manage_thread_priority"/>
+ <permission android:name="android.car.permission.BIND_OEM_CAR_SERVICE"
+ android:protectionLevel="signature|privileged"
+ android:label="@string/car_permission_label_bind_oem_car_service"
+ android:description="@string/car_permission_desc_bind_oem_car_service"/>
</manifest>
diff --git a/tests/tests/permission2/res/raw/wear_android_manifest.xml b/tests/tests/permission2/res/raw/wear_android_manifest.xml
new file mode 100644
index 00000000000..08488bc3d72
--- /dev/null
+++ b/tests/tests/permission2/res/raw/wear_android_manifest.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 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 file contains permissions which were back ported.
+ These permissions are already present on future platform releases.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android" coreApp="true" android:sharedUserId="android.uid.system"
+ android:sharedUserLabel="@string/android_system_label">
+
+ <!-- @hide Allows an application to access wrist temperature data from the watch sensors.
+ <p class="note"><strong>Note: </strong> This permission is for Wear OS only.
+ <p>Protection level: dangerous -->
+ <permission android:name="android.permission.BODY_SENSORS_WRIST_TEMPERATURE"
+ android:permissionGroup="android.permission-group.UNDEFINED"
+ android:label="@string/permlab_bodySensorsWristTemperature"
+ android:description="@string/permdesc_bodySensorsWristTemperature"
+ android:backgroundPermission="android.permission.BODY_SENSORS_WRIST_TEMPERATURE_BACKGROUND"
+ android:protectionLevel="dangerous" />
+
+ <!-- @hide Allows an application to access wrist temperature data from the watch sensors.
+ If you're requesting this permission, you must also request
+ {@link #BODY_SENSORS_WRIST_TEMPERATURE}. Requesting this permission by itself doesn't
+ give you wrist temperature body sensors access.
+ <p class="note"><strong>Note: </strong> This permission is for Wear OS only.
+ <p>Protection level: dangerous
+
+ <p> This is a hard restricted permission which cannot be held by an app until
+ the installer on record allowlists the permission. For more details see
+ {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
+ -->
+ <permission android:name="android.permission.BODY_SENSORS_WRIST_TEMPERATURE_BACKGROUND"
+ android:permissionGroup="android.permission-group.UNDEFINED"
+ android:label="@string/permlab_bodySensors_wristTemperature_background"
+ android:description="@string/permdesc_bodySensors_wristTemperature_background"
+ android:protectionLevel="dangerous"
+ android:permissionFlags="hardRestricted" />
+
+</manifest> \ No newline at end of file
diff --git a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
index 512e3782d48..637380313a2 100644
--- a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
+++ b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
@@ -20,6 +20,8 @@ import static android.content.pm.PermissionInfo.FLAG_INSTALLED;
import static android.content.pm.PermissionInfo.PROTECTION_MASK_BASE;
import static android.os.Build.VERSION.SECURITY_PATCH;
+import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
+
import static com.google.common.truth.Truth.assertWithMessage;
import android.Manifest;
@@ -29,6 +31,7 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
+import android.os.Build;
import android.os.Process;
import android.os.SystemProperties;
import android.platform.test.annotations.AppModeFull;
@@ -74,10 +77,15 @@ public class PermissionPolicyTest {
private static final String SET_UNRESTRICTED_GESTURE_EXCLUSION
= "android.permission.SET_UNRESTRICTED_GESTURE_EXCLUSION";
+ private static final String BIND_OEM_CAR_SERVICE =
+ "android.car.permission.BIND_OEM_CAR_SERVICE";
+
private static final String RECEIVE_KEYCODE_EVENTS_PERMISSION =
"android.permission.RECEIVE_KEYCODE_EVENTS";
private static final String ACCESS_SHORTCUTS_PERMISSION = "android.permission.ACCESS_SHORTCUTS";
+ private static final String BIND_QUICK_SETTINGS_TILE =
+ "android.permission.BIND_QUICK_SETTINGS_TILE";
private static final String LOG_TAG = "PermissionProtectionTest";
@@ -168,6 +176,9 @@ public class PermissionPolicyTest {
}
declaredPermissionsMap.putAll(carServiceBuiltInPermissionsMap);
}
+ if (sContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+ expectedPermissions.addAll(loadExpectedPermissions(R.raw.wear_android_manifest));
+ }
for (ExpectedPermissionInfo expectedPermission : expectedPermissions) {
String expectedPermissionName = expectedPermission.name;
@@ -536,6 +547,8 @@ public class PermissionPolicyTest {
return parseDate(SECURITY_PATCH).before(MANAGE_COMPANION_DEVICES_PATCH_DATE);
case SET_UNRESTRICTED_GESTURE_EXCLUSION:
return true;
+ case BIND_OEM_CAR_SERVICE:
+ return shoudldSkipBindOemCarService();
case RECEIVE_KEYCODE_EVENTS_PERMISSION:
return true;
default:
@@ -543,9 +556,25 @@ public class PermissionPolicyTest {
}
}
+ /**
+ * check should be skipped only for T and T-QPR1
+ */
+ private boolean shoudldSkipBindOemCarService() {
+ if (Build.VERSION.SDK_INT > 33) {
+ return false;
+ }
+ String output = runShellCommand("dumpsys car_service --version");
+ if (output.contains("Car API minor: 0") || output.contains("Car API minor: 1")) {
+ return true;
+ }
+
+ return false;
+ }
+
private static boolean shouldAllowProtectionFlagsChange(
String permissionName, int expectedFlags, int actualFlags) {
- return ACCESS_SHORTCUTS_PERMISSION.equals(permissionName)
+ return (ACCESS_SHORTCUTS_PERMISSION.equals(permissionName)
+ || BIND_QUICK_SETTINGS_TILE.equals(permissionName))
&& ((expectedFlags | PermissionInfo.PROTECTION_FLAG_RECENTS)
== (actualFlags | PermissionInfo.PROTECTION_FLAG_RECENTS));
}
diff --git a/tests/tests/permission2/src/android/permission2/cts/RuntimePermissionProperties.kt b/tests/tests/permission2/src/android/permission2/cts/RuntimePermissionProperties.kt
index 18557bd54d5..2a9f815aec5 100644
--- a/tests/tests/permission2/src/android/permission2/cts/RuntimePermissionProperties.kt
+++ b/tests/tests/permission2/src/android/permission2/cts/RuntimePermissionProperties.kt
@@ -55,6 +55,7 @@ import android.Manifest.permission.WRITE_CONTACTS
import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
import android.Manifest.permission_group.UNDEFINED
import android.app.AppOpsManager.permissionToOp
+import android.content.pm.PackageManager
import android.content.pm.PackageManager.GET_PERMISSIONS
import android.content.pm.PermissionInfo.PROTECTION_DANGEROUS
import android.content.pm.PermissionInfo.PROTECTION_FLAG_APPOP
@@ -166,6 +167,23 @@ class RuntimePermissionProperties {
// runtime permission
expectedPerms.add(READ_MEDIA_VISUAL_USER_SELECTED)
+ // Add runtime permissions added in V (back ported from U) which were _not_ split from a
+ // previously existing runtime permission
+ if (context.packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+ expectedPerms.add(BODY_SENSORS_WRIST_TEMPERATURE)
+ expectedPerms.add(BODY_SENSORS_WRIST_TEMPERATURE_BACKGROUND)
+ }
+
assertThat(expectedPerms).containsExactlyElementsIn(platformRuntimePerms.map { it.name })
}
+
+ companion object {
+ // These permissions are back ported from Android U to tm-wear, hidden in the
+ // "core/res/AndroidManifest.xml" file of /framework/base repo. Added these 2 constants here
+ // because hidden permissions can't be imported like other imported permissions in this file
+ private const val BODY_SENSORS_WRIST_TEMPERATURE =
+ "android.permission.BODY_SENSORS_WRIST_TEMPERATURE"
+ private const val BODY_SENSORS_WRIST_TEMPERATURE_BACKGROUND =
+ "android.permission.BODY_SENSORS_WRIST_TEMPERATURE_BACKGROUND"
+ }
}
diff --git a/tests/tests/permission3/AndroidTest.xml b/tests/tests/permission3/AndroidTest.xml
index a2555ffcba3..68401e7fd3a 100644
--- a/tests/tests/permission3/AndroidTest.xml
+++ b/tests/tests/permission3/AndroidTest.xml
@@ -32,6 +32,9 @@
<!-- Keep screen on for Bluetooth scanning -->
<target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
<option name="force-skip-system-props" value="true" /> <!-- avoid restarting device -->
+ <option name="set-global-setting" key="verifier_verify_adb_installs" value="0" />
+ <option name="restore-settings" value="true" />
+ <option name="disable-device-config-sync" value="true" />
<option name="screen-always-on" value="on" />
</target_preparer>
diff --git a/tests/tests/permission3/src/android/permission3/cts/BasePermissionTest.kt b/tests/tests/permission3/src/android/permission3/cts/BasePermissionTest.kt
index 5b9db99170a..e9f6c2ab6d5 100755..100644
--- a/tests/tests/permission3/src/android/permission3/cts/BasePermissionTest.kt
+++ b/tests/tests/permission3/src/android/permission3/cts/BasePermissionTest.kt
@@ -49,6 +49,7 @@ abstract class BasePermissionTest {
companion object {
const val APK_DIRECTORY = "/data/local/tmp/cts/permission3"
+ const val QUICK_CHECK_TIMEOUT_MILLIS = 100L
const val IDLE_TIMEOUT_MILLIS: Long = 1000
const val UNEXPECTED_TIMEOUT_MILLIS = 1000
const val TIMEOUT_MILLIS: Long = 20000
diff --git a/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt b/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt
index 6d476c5d762..4443fac930a 100755..100644
--- a/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt
+++ b/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt
@@ -32,9 +32,11 @@ import android.support.test.uiautomator.UiSelector
import android.text.Spanned
import android.text.style.ClickableSpan
import android.view.View
+import com.android.compatibility.common.util.SystemUtil.callWithShellPermissionIdentity
import com.android.compatibility.common.util.SystemUtil.eventually
import com.android.modules.utils.build.SdkLevel
import org.junit.After
+import org.junit.Assert
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
@@ -113,6 +115,9 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
const val REQUEST_LOCATION_MESSAGE = "permgrouprequest_location"
+ // The highest SDK for which the system will show a "low SDK" warning when launching the app
+ const val MAX_SDK_FOR_SDK_WARNING = 27
+
val STORAGE_AND_MEDIA_PERMISSIONS = setOf(
android.Manifest.permission.READ_EXTERNAL_STORAGE,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
@@ -209,8 +214,10 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
uninstallPackage(APP_PACKAGE_NAME, requireSuccess = false)
}
- protected fun clearTargetSdkWarning() =
- click(By.res("android:id/button1"))
+ protected fun clearTargetSdkWarning(timeoutMillis: Long = TIMEOUT_MILLIS) =
+ waitFindObjectOrNull(By.res("android:id/button1"), timeoutMillis)?.click()?.also {
+ waitForIdle()
+ }
protected fun clickPermissionReviewContinue() {
if (isAutomotive || isWatch) {
@@ -231,6 +238,8 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
protected fun approvePermissionReview() {
startAppActivityAndAssertResultCode(Activity.RESULT_OK) {
clickPermissionReviewContinue()
+ waitForIdle()
+ clearTargetSdkWarning()
}
}
@@ -294,6 +303,13 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
}
)
waitForIdle()
+
+ // Clear the low target SDK warning message if it's expected
+ if (getTargetSdk() <= MAX_SDK_FOR_SDK_WARNING) {
+ clearTargetSdkWarning(timeoutMillis = QUICK_CHECK_TIMEOUT_MILLIS)
+ waitForIdle()
+ }
+
// Notification permission prompt is shown first, so get it out of the way
clickNotificationPermissionRequestAllowButtonIfAvailable()
// Perform the post-request action
@@ -421,6 +437,9 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
"com.android.permissioncontroller:id/detail_message"
)[0]
}
+ if (!node.isVisibleToUser) {
+ scrollToBottom()
+ }
assertTrue(node.isVisibleToUser)
val text = node.text as Spanned
val clickableSpan = text.getSpans(0, text.length, ClickableSpan::class.java)[0]
@@ -459,26 +478,39 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
}
}
- protected fun grantAppPermissions(vararg permissions: String, targetSdk: Int = 30) {
- setAppPermissionState(*permissions, state = PermissionState.ALLOWED, isLegacyApp = false,
- targetSdk = targetSdk)
+ protected fun grantAppPermissions(vararg permissions: String) {
+ setAppPermissionState(*permissions, state = PermissionState.ALLOWED, isLegacyApp = false)
}
protected fun revokeAppPermissions(
vararg permissions: String,
- isLegacyApp: Boolean = false,
- targetSdk: Int = 30
+ isLegacyApp: Boolean = false
) {
setAppPermissionState(*permissions, state = PermissionState.DENIED,
- isLegacyApp = isLegacyApp, targetSdk = targetSdk)
+ isLegacyApp = isLegacyApp)
+ }
+
+ protected fun getTargetSdk(packageName: String = APP_PACKAGE_NAME): Int {
+ return callWithShellPermissionIdentity {
+ try {
+ context.packageManager.getApplicationInfo(packageName, 0).targetSdkVersion
+ } catch (e: PackageManager.NameNotFoundException) {
+ Assert.fail("Package $packageName not found")
+ -1
+ }
+ }
}
private fun setAppPermissionState(
vararg permissions: String,
state: PermissionState,
- isLegacyApp: Boolean,
- targetSdk: Int
+ isLegacyApp: Boolean
) {
+ val targetSdk = getTargetSdk()
+ if (targetSdk <= MAX_SDK_FOR_SDK_WARNING) {
+ clearTargetSdkWarning(QUICK_CHECK_TIMEOUT_MILLIS)
+ }
+
if (isTv) {
// Dismiss DeprecatedTargetSdkVersionDialog, if present
if (waitFindObjectOrNull(By.text(APP_PACKAGE_NAME), 1000L) != null) {
@@ -561,7 +593,9 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
By.text(getPermissionControllerString(
ALLOW_FOREGROUND_PREFERENCE_TEXT))
} else {
- byAnyText(getPermissionControllerResString(ALLOW_BUTTON_TEXT),getPermissionControllerResString(ALLOW_ALL_FILES_BUTTON_TEXT))
+ byAnyText(getPermissionControllerResString(ALLOW_BUTTON_TEXT),
+ getPermissionControllerResString(
+ ALLOW_ALL_FILES_BUTTON_TEXT))
}
PermissionState.DENIED ->
if (!isLegacyApp && hasAskButton(permission)) {
diff --git a/tests/tests/permission3/src/android/permission3/cts/MediaPermissionTest.kt b/tests/tests/permission3/src/android/permission3/cts/MediaPermissionTest.kt
index 8bd15373101..df2810e33d9 100644
--- a/tests/tests/permission3/src/android/permission3/cts/MediaPermissionTest.kt
+++ b/tests/tests/permission3/src/android/permission3/cts/MediaPermissionTest.kt
@@ -39,9 +39,7 @@ class MediaPermissionTest : BaseUsePermissionTest() {
@Test
fun testWhenRESIsGrantedFromGrantDialogThenShouldGrantAllPermissions() {
installPackage(APP_APK_PATH_23)
- requestAppPermissionsAndAssertResult(
- android.Manifest.permission.READ_EXTERNAL_STORAGE to true
- ) {
+ requestAppPermissionsAndAssertResult(Manifest.permission.READ_EXTERNAL_STORAGE to true) {
clickPermissionRequestAllowButton()
}
assertStorageAndMediaPermissionState(true)
@@ -50,30 +48,28 @@ class MediaPermissionTest : BaseUsePermissionTest() {
@Test
fun testWhenRESIsGrantedManuallyThenShouldGrantAllPermissions() {
installPackage(APP_APK_PATH_23)
- grantAppPermissions(android.Manifest.permission.READ_EXTERNAL_STORAGE, targetSdk = 23)
+ grantAppPermissions(Manifest.permission.READ_EXTERNAL_STORAGE)
assertStorageAndMediaPermissionState(true)
}
@Test
fun testWhenAuralIsGrantedManuallyThenShouldGrantAllPermissions() {
installPackage(APP_APK_PATH_23)
- grantAppPermissions(android.Manifest.permission.READ_MEDIA_AUDIO, targetSdk = 23)
+ grantAppPermissions(Manifest.permission.READ_MEDIA_AUDIO)
assertStorageAndMediaPermissionState(true)
}
@Test
fun testWhenVisualIsGrantedManuallyThenShouldGrantAllPermissions() {
installPackage(APP_APK_PATH_23)
- grantAppPermissions(android.Manifest.permission.READ_MEDIA_VIDEO, targetSdk = 23)
+ grantAppPermissions(Manifest.permission.READ_MEDIA_VIDEO)
assertStorageAndMediaPermissionState(true)
}
@Test
fun testWhenRESIsDeniedFromGrantDialogThenShouldDenyAllPermissions() {
installPackage(APP_APK_PATH_23)
- requestAppPermissionsAndAssertResult(
- android.Manifest.permission.READ_EXTERNAL_STORAGE to false
- ) {
+ requestAppPermissionsAndAssertResult(Manifest.permission.READ_EXTERNAL_STORAGE to false) {
clickPermissionRequestDenyButton()
}
assertStorageAndMediaPermissionState(false)
@@ -82,16 +78,16 @@ class MediaPermissionTest : BaseUsePermissionTest() {
@Test
fun testWhenRESIsDeniedManuallyThenShouldDenyAllPermissions() {
installPackage(APP_APK_PATH_23)
- grantAppPermissions(android.Manifest.permission.READ_EXTERNAL_STORAGE, targetSdk = 23)
- revokeAppPermissions(android.Manifest.permission.READ_EXTERNAL_STORAGE, targetSdk = 23)
+ grantAppPermissions(Manifest.permission.READ_EXTERNAL_STORAGE)
+ revokeAppPermissions(Manifest.permission.READ_EXTERNAL_STORAGE)
assertStorageAndMediaPermissionState(false)
}
@Test
fun testWhenAuralIsDeniedManuallyThenShouldDenyAllPermissions() {
installPackage(APP_APK_PATH_23)
- grantAppPermissions(android.Manifest.permission.READ_MEDIA_AUDIO, targetSdk = 23)
- revokeAppPermissions(android.Manifest.permission.READ_MEDIA_AUDIO, targetSdk = 23)
+ grantAppPermissions(Manifest.permission.READ_MEDIA_AUDIO)
+ revokeAppPermissions(Manifest.permission.READ_MEDIA_AUDIO)
assertStorageAndMediaPermissionState(false)
}
@@ -100,8 +96,8 @@ class MediaPermissionTest : BaseUsePermissionTest() {
// TODO: Re-enable after b/239249703 is fixed
Assume.assumeFalse("skip on TV due to flaky", isTv)
installPackage(APP_APK_PATH_23)
- grantAppPermissions(android.Manifest.permission.READ_MEDIA_VIDEO, targetSdk = 23)
- revokeAppPermissions(android.Manifest.permission.READ_MEDIA_VIDEO, targetSdk = 23)
+ grantAppPermissions(Manifest.permission.READ_MEDIA_VIDEO)
+ revokeAppPermissions(Manifest.permission.READ_MEDIA_VIDEO)
assertStorageAndMediaPermissionState(false)
}
@@ -109,8 +105,8 @@ class MediaPermissionTest : BaseUsePermissionTest() {
fun testWhenA33AppRequestsStorageThenNoDialogAndNoGrant() {
installPackage(APP_APK_PATH_MEDIA_PERMISSION_33_WITH_STORAGE)
requestAppPermissions(
- android.Manifest.permission.READ_EXTERNAL_STORAGE,
- android.Manifest.permission.WRITE_EXTERNAL_STORAGE
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.WRITE_EXTERNAL_STORAGE
) {
}
assertStorageAndMediaPermissionState(false)
@@ -119,30 +115,30 @@ class MediaPermissionTest : BaseUsePermissionTest() {
@Test
fun testWhenA33AppRequestsAuralThenDialogAndGrant() {
installPackage(APP_APK_PATH_LATEST)
- requestAppPermissions(android.Manifest.permission.READ_MEDIA_AUDIO) {
+ requestAppPermissions(Manifest.permission.READ_MEDIA_AUDIO) {
clickPermissionRequestAllowButton()
}
- assertAppHasPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE, false)
- assertAppHasPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE, false)
- assertAppHasPermission(android.Manifest.permission.READ_MEDIA_AUDIO, true)
- assertAppHasPermission(android.Manifest.permission.READ_MEDIA_VIDEO, false)
- assertAppHasPermission(android.Manifest.permission.READ_MEDIA_IMAGES, false)
+ assertAppHasPermission(Manifest.permission.READ_EXTERNAL_STORAGE, false)
+ assertAppHasPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, false)
+ assertAppHasPermission(Manifest.permission.READ_MEDIA_AUDIO, true)
+ assertAppHasPermission(Manifest.permission.READ_MEDIA_VIDEO, false)
+ assertAppHasPermission(Manifest.permission.READ_MEDIA_IMAGES, false)
}
@Test
fun testWhenA33AppRequestsVisualThenDialogAndGrant() {
installPackage(APP_APK_PATH_LATEST)
requestAppPermissions(
- android.Manifest.permission.READ_MEDIA_VIDEO,
- android.Manifest.permission.READ_MEDIA_IMAGES
+ Manifest.permission.READ_MEDIA_VIDEO,
+ Manifest.permission.READ_MEDIA_IMAGES
) {
clickPermissionRequestAllowButton()
}
- assertAppHasPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE, false)
- assertAppHasPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE, false)
- assertAppHasPermission(android.Manifest.permission.READ_MEDIA_AUDIO, false)
- assertAppHasPermission(android.Manifest.permission.READ_MEDIA_VIDEO, true)
- assertAppHasPermission(android.Manifest.permission.READ_MEDIA_IMAGES, true)
+ assertAppHasPermission(Manifest.permission.READ_EXTERNAL_STORAGE, false)
+ assertAppHasPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, false)
+ assertAppHasPermission(Manifest.permission.READ_MEDIA_AUDIO, false)
+ assertAppHasPermission(Manifest.permission.READ_MEDIA_VIDEO, true)
+ assertAppHasPermission(Manifest.permission.READ_MEDIA_IMAGES, true)
}
@Test
diff --git a/tests/tests/permission3/src/android/permission3/cts/PermissionTest23.kt b/tests/tests/permission3/src/android/permission3/cts/PermissionTest23.kt
index f9c449634e2..c9cc81ae8d8 100644
--- a/tests/tests/permission3/src/android/permission3/cts/PermissionTest23.kt
+++ b/tests/tests/permission3/src/android/permission3/cts/PermissionTest23.kt
@@ -247,7 +247,7 @@ class PermissionTest23 : BaseUsePermissionTest() {
android.Manifest.permission.CALL_PHONE,
android.Manifest.permission.RECORD_AUDIO,
android.Manifest.permission.CAMERA,
- android.Manifest.permission.READ_EXTERNAL_STORAGE, targetSdk = 23
+ android.Manifest.permission.READ_EXTERNAL_STORAGE
)
// Don't use UI for granting location and sensor permissions as they show another dialog
uiAutomation.grantRuntimePermission(
@@ -307,12 +307,12 @@ class PermissionTest23 : BaseUsePermissionTest() {
Assume.assumeFalse("other form factors might not support the ask button",
isTv || isAutomotive || isWatch)
- grantAppPermissions(android.Manifest.permission.ACCESS_BACKGROUND_LOCATION, targetSdk = 23)
+ grantAppPermissions(android.Manifest.permission.ACCESS_BACKGROUND_LOCATION)
assertAppHasPermission(android.Manifest.permission.ACCESS_BACKGROUND_LOCATION, true)
assertAppHasPermission(android.Manifest.permission.ACCESS_FINE_LOCATION, true)
assertAppHasPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION, true)
- revokeAppPermissions(android.Manifest.permission.ACCESS_BACKGROUND_LOCATION, targetSdk = 23)
+ revokeAppPermissions(android.Manifest.permission.ACCESS_BACKGROUND_LOCATION)
SystemUtil.runWithShellPermissionIdentity {
val perms = listOf(android.Manifest.permission.ACCESS_BACKGROUND_LOCATION,
android.Manifest.permission.ACCESS_FINE_LOCATION,
diff --git a/tests/tests/permission4/AndroidTest.xml b/tests/tests/permission4/AndroidTest.xml
index 78fe62fdac0..3a60e8a4ed4 100644
--- a/tests/tests/permission4/AndroidTest.xml
+++ b/tests/tests/permission4/AndroidTest.xml
@@ -34,6 +34,13 @@
<option name="test-file-name" value="CtsAppThatAccessesMicAndCameraPermission.apk" />
</target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
+ <option name="force-skip-system-props" value="true" /> <!-- avoid restarting device -->
+ <option name="set-global-setting" key="verifier_verify_adb_installs" value="0" />
+ <option name="restore-settings" value="true" />
+ <option name="disable-device-config-sync" value="true" />
+ </target_preparer>
+
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.permission4.cts" />
<option name="runtime-hint" value="5m" />
diff --git a/tests/tests/permission5/AndroidTest.xml b/tests/tests/permission5/AndroidTest.xml
index 953df0de922..abc0896ca85 100644
--- a/tests/tests/permission5/AndroidTest.xml
+++ b/tests/tests/permission5/AndroidTest.xml
@@ -33,6 +33,13 @@
<option name="test-file-name" value="CtsPermission5TestCases.apk" />
</target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
+ <option name="force-skip-system-props" value="true" /> <!-- avoid restarting device -->
+ <option name="set-global-setting" key="verifier_verify_adb_installs" value="0" />
+ <option name="restore-settings" value="true" />
+ <option name="disable-device-config-sync" value="true" />
+ </target_preparer>
+
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller" >
<option name="cleanup-apks" value="true" />
<option name="test-file-name" value="CtsBlamedPermissionApp.apk" />
diff --git a/tests/tests/sdksandbox/webkit/Android.bp b/tests/tests/sdksandbox/webkit/Android.bp
index 47af4008a0b..f0ab1430c64 100644
--- a/tests/tests/sdksandbox/webkit/Android.bp
+++ b/tests/tests/sdksandbox/webkit/Android.bp
@@ -18,6 +18,7 @@ package {
android_test {
name: "CtsSdkSandboxWebkitTestCases",
+ resource_dirs: ["res"],
defaults: ["cts_defaults"],
libs: [
"android.test.runner",
diff --git a/tests/tests/sdksandbox/webkit/res/raw/trustedcert.crt b/tests/tests/sdksandbox/webkit/res/raw/trustedcert.crt
new file mode 100644
index 00000000000..d9fad3584d0
--- /dev/null
+++ b/tests/tests/sdksandbox/webkit/res/raw/trustedcert.crt
@@ -0,0 +1,31 @@
+-----BEGIN CERTIFICATE-----
+MIIFRzCCAy+gAwIBAgIUP/dGwbAus1Vf8cWLiAnyRs7duGAwDQYJKoZIhvcNAQEL
+BQAwJTEjMCEGA1UEAwwaQ3RzV2Via2l0VGVzdENhc2VzLXRydXN0ZWQwHhcNMjEw
+MjA1MTkzMTIxWhcNMzEwMjAzMTkzMTIxWjAlMSMwIQYDVQQDDBpDdHNXZWJraXRU
+ZXN0Q2FzZXMtdHJ1c3RlZDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
+ALT6mHjIXl4ZCea7eZNOEQ8WXbR/uhimTJG3YUD2l+SC9k+dnrXJPvIrKzDq/HB0
+PO/0vNOBIeLd9CIDWVhg2tZ9J542EJB02Fueotcr30SuTG4lMtuD1Iyd37LZwUEd
+3nsFOdh65hwgzuyvBUm86CQCbNdXuj9FysHynh/plBopOTAhQkVWHKgQnKGui3Cu
+7h55GFPWxBNvc9ugCee0N+CtKhTj2ngBUd46iGmL3h7gXJOwBKrEkfdZLtz6DW5L
+Rv0+LyNcJBu5bIbU/0JK9419vbzcjvVDstgIeZJCXlc4XepPy7ASyNLJNYAe9UHc
+97Hw3yxu4VlNaGK1WbbDsOgU2Wvf0j9iGFwuuJch5pnCsJuS+rKSeCUXMz71gwo1
+lplpRNWkQkx8/0hae788M74BlQWJfV795SoAOk/qq+HxqmSv43bTaMn6UOCiBAml
+BNHgi5SF3vxlebSnHENRJTAx0JI7H5uXFPQswHYu6IGy23yFeWD+9RLADivzdiYw
+YMbeO7289+CTrTX5JKtfNqrF9Q9iqMgU3gaq2t4TKwBiIp/M5q6BLjY1spIHAnc5
+WD8y7b7ymswPUxtjaOBxdzr/dzan0ziQIKfywu6mHDQl2kWwYpFMHwIp2O1wP2Gg
+5KS6jDj9LNveV5V1GytuWIxMlyeQ8we13aIe8jURloVLAgMBAAGjbzBtMB0GA1Ud
+DgQWBBRZIZS/ttjxMLfPr91mYr9yW/b4YjAfBgNVHSMEGDAWgBRZIZS/ttjxMLfP
+r91mYr9yW/b4YjAPBgNVHRMBAf8EBTADAQH/MBoGA1UdEQQTMBGCCWxvY2FsaG9z
+dIcEfwAAATANBgkqhkiG9w0BAQsFAAOCAgEAT9c+EnbGK+hpxVlwPiNCk7jWc7zb
+6aUnyI+EVHKvMhOuSzFzllW4NZIl0ZWxzVd15LRiLaNoLXCTKWnL5MYA6BZYlT2i
+gaKVO6z8ytPfRcq1ITYp75b3N0cD7X28g6GNg7hyi/KEx0X1WS8fb88KC6fl/Sy6
+wdWg1WxPaOCosKvMwLpiFoemJBFIhNGzIghRye6MV7PjMRbb0weEQUNmtsxCtq+e
+ARBL+pXznphk3nOgreI0VlIi7imre+w6KfaTP0+UBOKhZvk451kPSHRBv8+lC6tS
+EcxqJOH/UKLQNyTzmLCLrdjnkRcwLhzegoskmLWGV4Ca2MVV3d6zGRczFplEi/lW
+Sux3Pbga+fh3FL1NqnpDCWgEptq+4mNYQn6G71jVOGw3MQtWEZijG95GPC1Yody6
+/CmNzg7eHY1PluXu73aOvJLjESqK1AxZTgpjbN1vUHg8WeSli3/Zcqn12r3FQSEY
+qPV3bfWivq7H9UZqHHb9aONBPRhH1xVKf5ByJNwNgRMD4sdBHtklvF1fKnOs3sZ5
+7RhRWn2mNskAHZsVtBGcPCqzPk8oGCptxaEr2rAotb3kD/3TZc2miZUN+AWfOG+U
+QeZLno7U+INDfTQC5D8be9LviYdYK8IkolzHHFcDw0Nyyx5hzj7xNq9T4ENGbjMP
+5RiEoWyKwEGZGoY=
+-----END CERTIFICATE-----
diff --git a/tests/tests/sdksandbox/webkit/res/raw/trustedkey.der b/tests/tests/sdksandbox/webkit/res/raw/trustedkey.der
new file mode 100644
index 00000000000..5ac993a4ed1
--- /dev/null
+++ b/tests/tests/sdksandbox/webkit/res/raw/trustedkey.der
Binary files differ
diff --git a/tests/tests/sdksandbox/webkit/res/raw/untrustedcert.crt b/tests/tests/sdksandbox/webkit/res/raw/untrustedcert.crt
new file mode 100644
index 00000000000..c75e8938302
--- /dev/null
+++ b/tests/tests/sdksandbox/webkit/res/raw/untrustedcert.crt
@@ -0,0 +1,31 @@
+-----BEGIN CERTIFICATE-----
+MIIFSzCCAzOgAwIBAgIUf5q9s3tlwksxPAbNPire6b8YvQUwDQYJKoZIhvcNAQEL
+BQAwJzElMCMGA1UEAwwcQ3RzV2Via2l0VGVzdENhc2VzLXVudHJ1c3RlZDAeFw0y
+MTAyMDUxOTMxMjFaFw0zMTAyMDMxOTMxMjFaMCcxJTAjBgNVBAMMHEN0c1dlYmtp
+dFRlc3RDYXNlcy11bnRydXN0ZWQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
+AoICAQC5atc0ZDX6R5MIemlOoAwPrjN/DGazzStLE7VCxX8pgK92G7Ur2Attd8C/
+I8c8gvCcOnfF+cvxEe6DSwamLPf/qoCght8RKP8kvEE6OmbjYhL7IEp6wIsP3ER9
+D41wVbbXVOlt2DVDsV/STIoEtQSOW2apT3QIlk65uW6NUyzT94OQKqnXnzToy9/b
+j/g0ONWjmMML7TAz0qJrW89yAjuzxOMkx9VFONt+kN8SyidRdGhtFrJWDP6FCzHZ
+FtMgMpzEsQTFfDBPwnZDHMIQId5Rs4DxLF6OuTIO5gI94e4fQs0vQtudpItm11IP
+m9Nrui+A4A+ySYQ4Qd+ac7NUUw3qBTRhhtVW08gRllIlNpUe2WG3agRd+BybZgPI
+KuOPwAhPZyYCUX/TRafwaAWCcdhNVvERHe8KD9NHV/fAf0fqTvsEKzpV6n58W6oo
+TrsG45+3oFMc24akGajN4MlcYovOA+dCkKp9/dt+dAqD//oPm79gK98is78jcEcW
+Vx+ayAVdMM02YcZhhI7g44HRxHXRVEWMgTckpQZ0Y+5fGfTdvKIzPpFqGZ888TaU
+RgJTEcb2lM/GpSdFlTxsd4idLiYfbZDZ2e8LeDnCzgDxhHCaHK6nensgjA6UIGro
+wYpA+OF929zojBAHGVZzrK2RWEAmT35YXpAbbuFHRipWHeWe+QIDAQABo28wbTAd
+BgNVHQ4EFgQU89I2yAoiDmTOLQHkUpYP4KAZafgwHwYDVR0jBBgwFoAU89I2yAoi
+DmTOLQHkUpYP4KAZafgwDwYDVR0TAQH/BAUwAwEB/zAaBgNVHREEEzARgglsb2Nh
+bGhvc3SHBH8AAAEwDQYJKoZIhvcNAQELBQADggIBAB+AHqtcGsJqORIJAH9OWlmB
+3EDiNrYjjeMWcuFx4kWPGWEXjOWf7NmnWCoyL7JhQEDO71U3T/FxLhsuTHgqABh2
+TP3V8yYgsLtosQORLrbTgSMnJ6ApcvFC6A6busp6WGExeuiGvVbFlPwP7oInKkXP
+Gb6LPpwp2F6hVitNOCzzTNlZy/77faOoqGI307sFX28XJT+Oj1Zs08AgCEoYkEK0
+vYx7z0qVOvWFTMAgIMBefJBcxLlMmrkL9hyFRZN1y1dir+6zhz7nSnThtYr16tsq
+dHU4+F6gfmlerbEbAHX9h0Kx9UY+mdgtU3CywM6xufM4iK2LwE8Wzr5/ND8jnvH8
+2sPdjVMZpPPNPc6M2K7W/IdSrlEOAFopBFvFCLtsFNssp9gNiuEwSE9Ver73xE+S
+3uH0y4kfESmJVQeEdviA1qcDuSxLQoTsXJSKJdWaMfOJMVR7yGFiV6Tz89puurPP
+5Fprk4RbOcAWLHTVLOnTcwB6cvJ5FUIJEw2UOWFJQp6uQ2KkHXuIvBQjNNSuuTOg
+HGrIDhEVV1vbfEmx3X7BKE2svp+xp4o/TM8j5CytWC/D0qVGCnqGNCONyV4uNs7O
+/3NzqixCcLDz+B2bzieW3Qjb76t68ZJ7JxvB6c9fiUrlmUcdPaSWKpXonjvlI0pN
+A5+Gfe2t0uDpO1MROjkA
+-----END CERTIFICATE-----
diff --git a/tests/tests/sdksandbox/webkit/res/raw/untrustedkey.der b/tests/tests/sdksandbox/webkit/res/raw/untrustedkey.der
new file mode 100644
index 00000000000..134bef87868
--- /dev/null
+++ b/tests/tests/sdksandbox/webkit/res/raw/untrustedkey.der
Binary files differ
diff --git a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxCookieManagerTest.java b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxCookieManagerTest.java
new file mode 100644
index 00000000000..8db9cdf8a51
--- /dev/null
+++ b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxCookieManagerTest.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2023 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.sdksandbox.webkit.cts;
+
+import android.app.sdksandbox.testutils.testscenario.KeepSdkSandboxAliveRule;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.MediumTest;
+
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class SdkSandboxCookieManagerTest {
+ @ClassRule
+ public static final KeepSdkSandboxAliveRule sSdkTestSuiteSetup =
+ new KeepSdkSandboxAliveRule("com.android.emptysdkprovider");
+
+ @Rule
+ public final WebViewSandboxTestRule sdkTester =
+ new WebViewSandboxTestRule("android.webkit.cts.CookieManagerTest");
+
+ @Test
+ public void testGetInstance() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testGetInstance");
+ }
+
+ @Test
+ public void testFlush() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testFlush");
+ }
+
+ @Test
+ public void testAcceptCookie() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAcceptCookie");
+ }
+
+ @Test
+ public void testSetCookie() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testSetCookie");
+ }
+
+ @Test
+ public void testSetCookieNullCallback() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testSetCookieNullCallback");
+ }
+
+ @Test
+ public void testSetCookieCallback() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testSetCookieCallback");
+ }
+
+ @Test
+ public void testRemoveCookies() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testRemoveCookies");
+ }
+
+ @Test
+ public void testRemoveCookiesNullCallback() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testRemoveCookiesNullCallback");
+ }
+
+ @Test
+ public void testRemoveCookiesCallback() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testRemoveCookiesCallback");
+ }
+
+ @Test
+ public void testThirdPartyCookie() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testThirdPartyCookie");
+ }
+
+ @Test
+ public void testSameSiteLaxByDefault() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testSameSiteLaxByDefault");
+ }
+
+ @Test
+ public void testSameSiteNoneRequiresSecure() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testSameSiteNoneRequiresSecure");
+ }
+
+ @Test
+ public void testSchemefulSameSite() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testSchemefulSameSite");
+ }
+
+ @Test
+ public void testb3167208() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testb3167208");
+ }
+}
diff --git a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxCookieTest.java b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxCookieTest.java
index a99a7066bba..52f4daf9a58 100644
--- a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxCookieTest.java
+++ b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxCookieTest.java
@@ -22,10 +22,6 @@ import android.platform.test.annotations.Presubmit;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
-import com.android.compatibility.common.util.NullWebViewUtils;
-
-import org.junit.Assume;
-import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
@@ -42,11 +38,6 @@ public class SdkSandboxCookieTest {
public final WebViewSandboxTestRule sdkTester =
new WebViewSandboxTestRule("android.webkit.cts.CookieTest");
- @Before
- public void setUp() {
- Assume.assumeTrue("WebView is not available", NullWebViewUtils.isWebViewAvailable());
- }
-
@Presubmit
@Test
public void testDomain() throws Exception {
diff --git a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxDateSorterTest.java b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxDateSorterTest.java
index b563d808133..e83a5248961 100644
--- a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxDateSorterTest.java
+++ b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxDateSorterTest.java
@@ -22,10 +22,6 @@ import android.platform.test.annotations.AppModeFull;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.MediumTest;
-import com.android.compatibility.common.util.NullWebViewUtils;
-
-import org.junit.Assume;
-import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
@@ -43,11 +39,6 @@ public class SdkSandboxDateSorterTest {
public final WebViewSandboxTestRule sdkTester =
new WebViewSandboxTestRule("android.webkit.cts.DateSorterTest");
- @Before
- public void setUp() {
- Assume.assumeTrue("WebView is not available", NullWebViewUtils.isWebViewAvailable());
- }
-
@Test
public void testConstructor() throws Exception {
sdkTester.assertSdkTestRunPasses("testConstructor");
diff --git a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxHttpAuthHandlerTest.java b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxHttpAuthHandlerTest.java
index f44bff0f546..05e9a1ff604 100644
--- a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxHttpAuthHandlerTest.java
+++ b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxHttpAuthHandlerTest.java
@@ -22,10 +22,6 @@ import android.platform.test.annotations.AppModeFull;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.MediumTest;
-import com.android.compatibility.common.util.NullWebViewUtils;
-
-import org.junit.Assume;
-import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
@@ -43,11 +39,6 @@ public class SdkSandboxHttpAuthHandlerTest {
public final WebViewSandboxTestRule sdkTester =
new WebViewSandboxTestRule("android.webkit.cts.HttpAuthHandlerTest");
- @Before
- public void setUp() {
- Assume.assumeTrue("WebView is not available", NullWebViewUtils.isWebViewAvailable());
- }
-
@Test
public void testProceed() throws Exception {
sdkTester.assertSdkTestRunPasses("testProceed");
diff --git a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxPostMessageTest.java b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxPostMessageTest.java
index c29d806f181..214084a0484 100644
--- a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxPostMessageTest.java
+++ b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxPostMessageTest.java
@@ -22,10 +22,6 @@ import android.platform.test.annotations.AppModeFull;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.MediumTest;
-import com.android.compatibility.common.util.NullWebViewUtils;
-
-import org.junit.Assume;
-import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
@@ -43,11 +39,6 @@ public class SdkSandboxPostMessageTest {
public final WebViewSandboxTestRule sdkTester =
new WebViewSandboxTestRule("android.webkit.cts.PostMessageTest");
- @Before
- public void setUp() {
- Assume.assumeTrue("WebView is not available", NullWebViewUtils.isWebViewAvailable());
- }
-
@Test
public void testSimpleMessageToMainFrame() throws Exception {
sdkTester.assertSdkTestRunPasses("testSimpleMessageToMainFrame");
diff --git a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxServiceWorkerClientTest.java b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxServiceWorkerClientTest.java
index c3ee9b05188..39922ede210 100644
--- a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxServiceWorkerClientTest.java
+++ b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxServiceWorkerClientTest.java
@@ -21,10 +21,6 @@ import android.app.sdksandbox.testutils.testscenario.KeepSdkSandboxAliveRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
-import com.android.compatibility.common.util.NullWebViewUtils;
-
-import org.junit.Assume;
-import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
@@ -41,11 +37,6 @@ public class SdkSandboxServiceWorkerClientTest {
public final WebViewSandboxTestRule sdkTester =
new WebViewSandboxTestRule("android.webkit.cts.ServiceWorkerClientTest");
- @Before
- public void setUp() {
- Assume.assumeTrue("WebView is not available", NullWebViewUtils.isWebViewAvailable());
- }
-
@Test
public void testServiceWorkerClientInterceptCallback() throws Exception {
sdkTester.assertSdkTestRunPasses("testServiceWorkerClientInterceptCallback");
diff --git a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxURLUtilTest.java b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxURLUtilTest.java
index f2de548d944..4e047c73431 100644
--- a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxURLUtilTest.java
+++ b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxURLUtilTest.java
@@ -22,10 +22,6 @@ import android.platform.test.annotations.AppModeFull;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.MediumTest;
-import com.android.compatibility.common.util.NullWebViewUtils;
-
-import org.junit.Assume;
-import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
@@ -43,11 +39,6 @@ public class SdkSandboxURLUtilTest {
public final WebViewSandboxTestRule sdkTester =
new WebViewSandboxTestRule("android.webkit.cts.URLUtilTest");
- @Before
- public void setUp() {
- Assume.assumeTrue("WebView is not available", NullWebViewUtils.isWebViewAvailable());
- }
-
@Test
public void testIsAssetUrl() throws Exception {
sdkTester.assertSdkTestRunPasses("testIsAssetUrl");
diff --git a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebBackForwardListTest.java b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebBackForwardListTest.java
index 9940f1c9fe8..7d8c85bcc40 100644
--- a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebBackForwardListTest.java
+++ b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebBackForwardListTest.java
@@ -21,10 +21,6 @@ import android.app.sdksandbox.testutils.testscenario.KeepSdkSandboxAliveRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.MediumTest;
-import com.android.compatibility.common.util.NullWebViewUtils;
-
-import org.junit.Assume;
-import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
@@ -41,11 +37,6 @@ public class SdkSandboxWebBackForwardListTest {
public final WebViewSandboxTestRule sdkTester =
new WebViewSandboxTestRule("android.webkit.cts.WebBackForwardListTest");
- @Before
- public void setUp() {
- Assume.assumeTrue("WebView is not available", NullWebViewUtils.isWebViewAvailable());
- }
-
@Test
public void testGetCurrentItem() throws Exception {
sdkTester.assertSdkTestRunPasses("testGetCurrentItem");
diff --git a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebChromeClientTest.java b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebChromeClientTest.java
new file mode 100644
index 00000000000..95ec8dae855
--- /dev/null
+++ b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebChromeClientTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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.sdksandbox.webkit.cts;
+
+import android.app.sdksandbox.testutils.testscenario.KeepSdkSandboxAliveRule;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.MediumTest;
+
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class SdkSandboxWebChromeClientTest {
+
+ @ClassRule
+ public static final KeepSdkSandboxAliveRule sSdkTestSuiteSetup =
+ new KeepSdkSandboxAliveRule("com.android.emptysdkprovider");
+
+ @Rule
+ public final WebViewSandboxTestRule sdkTester =
+ new WebViewSandboxTestRule("android.webkit.cts.WebChromeClientTest");
+
+ @Test
+ public void testOnProgressChanged() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testOnProgressChanged");
+ }
+
+ @Test
+ public void testOnReceivedTitle() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testOnReceivedTitle");
+ }
+
+ @Test
+ public void testOnReceivedIcon() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testOnReceivedIcon");
+ }
+
+ @Test
+ public void testWindows() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testWindows");
+ }
+
+ @Test
+ public void testBlockWindowsSync() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testBlockWindowsSync");
+ }
+
+ @Test
+ public void testBlockWindowsAsync() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testBlockWindowsAsync");
+ }
+
+ @Test
+ public void testOnJsAlert() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testOnJsAlert");
+ }
+
+ @Test
+ public void testOnJsConfirm() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testOnJsConfirm");
+ }
+
+ @Test
+ public void testOnJsPrompt() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testOnJsPrompt");
+ }
+
+ @Test
+ public void testOnConsoleMessage() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testOnConsoleMessage");
+ }
+
+ @Test
+ public void testOnJsBeforeUnloadIsCalled() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testOnJsBeforeUnloadIsCalled");
+ }
+
+}
diff --git a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebHistoryItemTest.java b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebHistoryItemTest.java
index fbfd3c20e78..5eb7225e286 100644
--- a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebHistoryItemTest.java
+++ b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebHistoryItemTest.java
@@ -21,10 +21,6 @@ import android.app.sdksandbox.testutils.testscenario.KeepSdkSandboxAliveRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.MediumTest;
-import com.android.compatibility.common.util.NullWebViewUtils;
-
-import org.junit.Assume;
-import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
@@ -41,11 +37,6 @@ public class SdkSandboxWebHistoryItemTest {
public final WebViewSandboxTestRule sdkTester =
new WebViewSandboxTestRule("android.webkit.cts.WebHistoryItemTest");
- @Before
- public void setUp() {
- Assume.assumeTrue("WebView is not available", NullWebViewUtils.isWebViewAvailable());
- }
-
@Test
public void testWebHistoryItem() throws Exception {
sdkTester.assertSdkTestRunPasses("testWebHistoryItem");
diff --git a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebSettingsTest.java b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebSettingsTest.java
new file mode 100644
index 00000000000..e2112aed33d
--- /dev/null
+++ b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebSettingsTest.java
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2023 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.sdksandbox.webkit.cts;
+
+import android.app.sdksandbox.testutils.testscenario.KeepSdkSandboxAliveRule;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.MediumTest;
+
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class SdkSandboxWebSettingsTest {
+ @ClassRule
+ public static final KeepSdkSandboxAliveRule sSdkTestSuiteSetup =
+ new KeepSdkSandboxAliveRule("com.android.emptysdkprovider");
+
+ @Rule
+ public final WebViewSandboxTestRule sdkTester =
+ new WebViewSandboxTestRule("android.webkit.cts.WebSettingsTest");
+
+ @Test
+ public void testUserAgentString_default() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testUserAgentString_default");
+ }
+
+ @Test
+ public void testUserAgentStringTest() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testUserAgentStringTest");
+ }
+
+ @Test
+ public void testAccessUserAgentString() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessUserAgentString");
+ }
+
+ @Test
+ public void testAccessCacheMode_defaultValue() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessCacheMode_defaultValue");
+ }
+
+ @Test
+ public void testAccessCacheMode_cacheElseNetwork() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessCacheMode_cacheElseNetwork");
+ }
+
+ @Test
+ public void testAccessCacheMode_noCache() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessCacheMode_noCache");
+ }
+
+ @Test
+ public void testAccessCacheMode_cacheOnly() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessCacheMode_cacheOnly");
+ }
+
+ @Test
+ public void testAccessCursiveFontFamily() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessCursiveFontFamily");
+ }
+
+ @Test
+ public void testAccessFantasyFontFamily() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessFantasyFontFamily");
+ }
+
+ @Test
+ public void testAccessFixedFontFamily() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessFixedFontFamily");
+ }
+
+ @Test
+ public void testAccessSansSerifFontFamily() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessSansSerifFontFamily");
+ }
+
+ @Test
+ public void testAccessSerifFontFamily() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessSerifFontFamily");
+ }
+
+ @Test
+ public void testAccessStandardFontFamily() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessStandardFontFamily");
+ }
+
+ @Test
+ public void testAccessDefaultFontSize() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessDefaultFontSize");
+ }
+
+ @Test
+ public void testAccessDefaultFixedFontSize() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessDefaultFixedFontSize");
+ }
+
+ @Test
+ public void testAccessDefaultTextEncodingName() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessDefaultTextEncodingName");
+ }
+
+ @Test
+ public void testAccessJavaScriptCanOpenWindowsAutomatically() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessJavaScriptCanOpenWindowsAutomatically");
+ }
+
+ @Test
+ public void testAccessJavaScriptEnabled() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessJavaScriptEnabled");
+ }
+
+ @Test
+ public void testAccessLayoutAlgorithm() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessLayoutAlgorithm");
+ }
+
+ @Test
+ public void testAccessMinimumFontSize() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessMinimumFontSize");
+ }
+
+ @Test
+ public void testAccessMinimumLogicalFontSize() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessMinimumLogicalFontSize");
+ }
+
+ @Test
+ public void testAccessPluginsEnabled() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessPluginsEnabled");
+ }
+
+ @Test
+ public void testOffscreenPreRaster() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testOffscreenPreRaster");
+ }
+
+ @Test
+ public void testAccessPluginsPath() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessPluginsPath");
+ }
+
+ @Test
+ public void testAccessTextSize() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessTextSize");
+ }
+
+ @Test
+ public void testAccessUseDoubleTree() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessUseDoubleTree");
+ }
+
+ @Test
+ public void testAccessUseWideViewPort() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessUseWideViewPort");
+ }
+
+ @Test
+ public void testSetNeedInitialFocus() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testSetNeedInitialFocus");
+ }
+
+ @Test
+ public void testSetRenderPriority() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testSetRenderPriority");
+ }
+
+ @Test
+ public void testAccessSupportMultipleWindows() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessSupportMultipleWindows");
+ }
+
+ @Test
+ public void testAccessSupportZoom() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessSupportZoom");
+ }
+
+ @Test
+ public void testAccessBuiltInZoomControls() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessBuiltInZoomControls");
+ }
+
+ @Test
+ public void testAppCacheDisabled() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAppCacheDisabled");
+ }
+
+ @Test
+ public void testAppCacheEnabled() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAppCacheEnabled");
+ }
+
+ @Test
+ public void testDatabaseDisabled() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testDatabaseDisabled");
+ }
+
+ @Test
+ public void testDisabledActionModeMenuItems() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testDisabledActionModeMenuItems");
+ }
+
+ @Test
+ public void testLoadsImagesAutomatically_default() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testLoadsImagesAutomatically_default");
+ }
+
+ @Test
+ public void testLoadsImagesAutomatically_httpImagesLoaded() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testLoadsImagesAutomatically_httpImagesLoaded");
+ }
+
+ @Test
+ public void testLoadsImagesAutomatically_dataUriImagesLoaded() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testLoadsImagesAutomatically_dataUriImagesLoaded");
+ }
+
+ @Test
+ public void testLoadsImagesAutomatically_blockLoadingImages() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testLoadsImagesAutomatically_blockLoadingImages");
+ }
+
+ @Test
+ public void testLoadsImagesAutomatically_loadImagesWithoutReload() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testLoadsImagesAutomatically_loadImagesWithoutReload");
+ }
+
+ @Test
+ public void testBlockNetworkImage() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testBlockNetworkImage");
+ }
+
+ @Test
+ public void testBlockNetworkLoads() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testBlockNetworkLoads");
+ }
+
+ @Test
+ public void testIframesWhenAccessFromFileURLsDisabled() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testIframesWhenAccessFromFileURLsDisabled");
+ }
+
+ @Test
+ public void testXHRWhenAccessFromFileURLsEnabled() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testXHRWhenAccessFromFileURLsEnabled");
+ }
+
+ @Test
+ public void testXHRWhenAccessFromFileURLsDisabled() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testXHRWhenAccessFromFileURLsDisabled");
+ }
+
+ @Test
+ public void testAllowMixedMode() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAllowMixedMode");
+ }
+
+ @Test
+ public void testEnableSafeBrowsing() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testEnableSafeBrowsing");
+ }
+}
diff --git a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebViewClientTest.java b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebViewClientTest.java
new file mode 100644
index 00000000000..68b68ba8977
--- /dev/null
+++ b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebViewClientTest.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2023 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.sdksandbox.webkit.cts;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.FlakyTest;
+import androidx.test.filters.MediumTest;
+
+import org.junit.Assume;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class SdkSandboxWebViewClientTest {
+ // TODO(b/260196711): IME does not currently work correctly in the SDK RUntime. We should enable
+ // impacted tests once this is fixed.
+ // This prevents some tests from running.
+ private static final boolean CAN_INJECT_KEY_EVENTS = false;
+
+ // TODO(b/266051278): Uncomment this when we work out why preserving
+ // the SDK sandbox manager between tests cases {@link testOnRenderProcessGone}
+ // to fail.
+ //
+ // @ClassRule
+ // public static final KeepSdkSandboxAliveRule sSdkTestSuiteSetup =
+ // new KeepSdkSandboxAliveRule("com.android.emptysdkprovider");
+
+ @Rule
+ public final WebViewSandboxTestRule sdkTester =
+ new WebViewSandboxTestRule("android.webkit.cts.WebViewClientTest");
+
+ @Test
+ public void testShouldOverrideUrlLoadingDefault() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testShouldOverrideUrlLoadingDefault");
+ }
+
+ @Test
+ public void testShouldOverrideUrlLoading() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testShouldOverrideUrlLoading");
+ }
+
+ @Test
+ public void testShouldOverrideUrlLoadingOnCreateWindow() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testShouldOverrideUrlLoadingOnCreateWindow");
+ }
+
+ @Test
+ public void testLoadPage() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testLoadPage");
+ }
+
+ @Test
+ public void testOnReceivedLoginRequest() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testOnReceivedLoginRequest");
+ }
+
+ @Test
+ public void testOnReceivedError() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testOnReceivedError");
+ }
+
+ @Test
+ public void testOnReceivedErrorForSubresource() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testOnReceivedErrorForSubresource");
+ }
+
+ @Test
+ public void testOnReceivedHttpError() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testOnReceivedHttpError");
+ }
+
+ @Test
+ public void testOnFormResubmission() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testOnFormResubmission");
+ }
+
+ @Test
+ public void testDoUpdateVisitedHistory() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testDoUpdateVisitedHistory");
+ }
+
+ @Test
+ public void testOnReceivedHttpAuthRequest() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testOnReceivedHttpAuthRequest");
+ }
+
+ @Test
+ public void testShouldOverrideKeyEvent() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testShouldOverrideKeyEvent");
+ }
+
+ @Test
+ public void testOnUnhandledKeyEvent() throws Exception {
+ Assume.assumeTrue(CAN_INJECT_KEY_EVENTS);
+ sdkTester.assertSdkTestRunPasses("testOnUnhandledKeyEvent");
+ }
+
+ @Test
+ public void testOnScaleChanged() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testOnScaleChanged");
+ }
+
+ @Test
+ public void testShouldInterceptRequestParams() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testShouldInterceptRequestParams");
+ }
+
+ @Test
+ public void testShouldInterceptRequestResponse() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testShouldInterceptRequestResponse");
+ }
+
+ @Test
+ public void testOnRenderProcessGoneDefault() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testOnRenderProcessGoneDefault");
+ }
+
+ @Test
+ public void testOnRenderProcessGone() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testOnRenderProcessGone");
+ }
+
+ // TODO(crbug/1245351): Remove @FlakyTest once bug fixed
+ @FlakyTest
+ @Test
+ public void testOnSafeBrowsingHitBackToSafety() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testOnSafeBrowsingHitBackToSafety");
+ }
+
+ // TODO(crbug/1245351): Remove @FlakyTest once bug fixed
+ @FlakyTest
+ @Test
+ public void testOnSafeBrowsingHitProceed() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testOnSafeBrowsingHitProceed");
+ }
+
+ // TODO(crbug/1245351): Remove @FlakyTest once bug fixed
+ @FlakyTest
+ @Test
+ public void testOnSafeBrowsingMalwareCode() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testOnSafeBrowsingMalwareCode");
+ }
+
+ // TODO(crbug/1245351): Remove @FlakyTest once bug fixed
+ @FlakyTest
+ @Test
+ public void testOnSafeBrowsingPhishingCode() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testOnSafeBrowsingPhishingCode");
+ }
+
+ // TODO(crbug/1245351): Remove @FlakyTest once bug fixed
+ @FlakyTest
+ @Test
+ public void testOnSafeBrowsingUnwantedSoftwareCode() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testOnSafeBrowsingUnwantedSoftwareCode");
+ }
+
+ // TODO(crbug/1245351): Remove @FlakyTest once bug fixed
+ @FlakyTest
+ @Test
+ public void testOnSafeBrowsingBillingCode() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testOnSafeBrowsingBillingCode");
+ }
+
+ @Test
+ public void testOnPageCommitVisibleCalled() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testOnPageCommitVisibleCalled");
+ }
+}
diff --git a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebViewSslTest.java b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebViewSslTest.java
index b5c2bf8393c..ba5975e7d08 100644
--- a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebViewSslTest.java
+++ b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebViewSslTest.java
@@ -22,10 +22,6 @@ import android.platform.test.annotations.AppModeFull;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.MediumTest;
-import com.android.compatibility.common.util.NullWebViewUtils;
-
-import org.junit.Assume;
-import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
@@ -42,11 +38,6 @@ public class SdkSandboxWebViewSslTest {
public final WebViewSandboxTestRule sdkTester =
new WebViewSandboxTestRule("android.webkit.cts.WebViewSslTest");
- @Before
- public void checkAssumptions() throws Exception {
- Assume.assumeTrue("WebView is not available", NullWebViewUtils.isWebViewAvailable());
- }
-
@Test
@MediumTest
public void testInsecureSiteClearsCertificate() throws Exception {
diff --git a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebViewTest.java b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebViewTest.java
index 14e6592641e..e6de7e8bed5 100644
--- a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebViewTest.java
+++ b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebViewTest.java
@@ -23,10 +23,7 @@ import android.platform.test.annotations.Presubmit;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.MediumTest;
-import com.android.compatibility.common.util.NullWebViewUtils;
-
import org.junit.Assume;
-import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
@@ -36,10 +33,10 @@ import org.junit.runner.RunWith;
@AppModeFull
@RunWith(AndroidJUnit4.class)
public class SdkSandboxWebViewTest {
- // TODO(b/260196711): We are not able to inject input events
- // from the SDK Runtime.SdkSandbox
+ // TODO(b/230340812): IME does not currently work correctly in the SDK RUntime. We should enable
+ // impacted tests once this is fixed.
// This prevents some tests from running.
- private static final boolean CAN_INJECT_INPUT_EVENTS = false;
+ private static final boolean CAN_INJECT_KEY_EVENTS = false;
@ClassRule
public static final KeepSdkSandboxAliveRule sSdkTestSuiteSetup =
@@ -49,11 +46,6 @@ public class SdkSandboxWebViewTest {
public final WebViewSandboxTestRule sdkTester =
new WebViewSandboxTestRule("android.webkit.cts.WebViewTest");
- @Before
- public void setUp() {
- Assume.assumeTrue("WebView is not available", NullWebViewUtils.isWebViewAvailable());
- }
-
@Test
public void testConstructor() throws Exception {
sdkTester.assertSdkTestRunPasses("testConstructor");
@@ -394,19 +386,18 @@ public class SdkSandboxWebViewTest {
@Test
public void testRequestFocusNodeHref() throws Exception {
- Assume.assumeTrue(CAN_INJECT_INPUT_EVENTS);
+ Assume.assumeTrue(CAN_INJECT_KEY_EVENTS);
sdkTester.assertSdkTestRunPasses("testRequestFocusNodeHref");
}
@Test
public void testRequestImageRef() throws Exception {
- Assume.assumeTrue(CAN_INJECT_INPUT_EVENTS);
sdkTester.assertSdkTestRunPasses("testRequestImageRef");
}
@Test
public void testGetHitTestResult() throws Exception {
- Assume.assumeTrue(CAN_INJECT_INPUT_EVENTS);
+ Assume.assumeTrue(CAN_INJECT_KEY_EVENTS);
sdkTester.assertSdkTestRunPasses("testGetHitTestResult");
}
}
diff --git a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebViewTransportTest.java b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebViewTransportTest.java
new file mode 100644
index 00000000000..a4db755e434
--- /dev/null
+++ b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebViewTransportTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 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.sdksandbox.webkit.cts;
+
+import android.app.sdksandbox.testutils.testscenario.KeepSdkSandboxAliveRule;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.MediumTest;
+
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class SdkSandboxWebViewTransportTest {
+ @ClassRule
+ public static final KeepSdkSandboxAliveRule sSdkTestSuiteSetup =
+ new KeepSdkSandboxAliveRule("com.android.emptysdkprovider");
+
+ @Rule
+ public final WebViewSandboxTestRule sdkTester =
+ new WebViewSandboxTestRule("android.webkit.cts.WebViewTransportTest");
+
+ @Test
+ public void testAccessWebView() throws Exception {
+ sdkTester.assertSdkTestRunPasses("testAccessWebView");
+ }
+}
diff --git a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebViewZoomTest.java b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebViewZoomTest.java
index 9f13fed16d8..4afee9ca31d 100644
--- a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebViewZoomTest.java
+++ b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/SdkSandboxWebViewZoomTest.java
@@ -20,10 +20,6 @@ import android.app.sdksandbox.testutils.testscenario.KeepSdkSandboxAliveRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.MediumTest;
-import com.android.compatibility.common.util.NullWebViewUtils;
-
-import org.junit.Assume;
-import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
@@ -41,11 +37,6 @@ public class SdkSandboxWebViewZoomTest {
public final WebViewSandboxTestRule sdkTester =
new WebViewSandboxTestRule("android.webkit.cts.WebViewZoomTest");
- @Before
- public void setUp() {
- Assume.assumeTrue("WebView is not available", NullWebViewUtils.isWebViewAvailable());
- }
-
@Test
public void testZoomIn() throws Exception {
sdkTester.assertSdkTestRunPasses("testZoomIn");
diff --git a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/WebViewSandboxTestRule.java b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/WebViewSandboxTestRule.java
index c9d641fdee6..433b5cecf5a 100644
--- a/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/WebViewSandboxTestRule.java
+++ b/tests/tests/sdksandbox/webkit/src/android/sdksandbox/webkit/cts/WebViewSandboxTestRule.java
@@ -24,6 +24,12 @@ import android.webkit.cts.SharedWebViewTestEnvironment;
import androidx.test.core.app.ApplicationProvider;
+import com.android.compatibility.common.util.NullWebViewUtils;
+
+import org.junit.Assume;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
/**
* This rule is used to invoke webview tests inside a test sdk.
* This rule is a wrapper for using the
@@ -34,10 +40,11 @@ import androidx.test.core.app.ApplicationProvider;
public class WebViewSandboxTestRule extends SdkSandboxScenarioRule {
public WebViewSandboxTestRule(String webViewTestClassName) {
- super("com.android.cts.sdk.webviewsandboxtest",
+ super(
+ "com.android.cts.sdk.webviewsandboxtest",
getSetupParams(webViewTestClassName),
SharedWebViewTestEnvironment.createHostAppInvoker(
- ApplicationProvider.getApplicationContext()),
+ ApplicationProvider.getApplicationContext(), true),
ENABLE_LIFE_CYCLE_ANNOTATIONS);
}
@@ -46,4 +53,11 @@ public class WebViewSandboxTestRule extends SdkSandboxScenarioRule {
params.putString(SharedWebViewTest.WEB_VIEW_TEST_CLASS_NAME, webViewTestClassName);
return params;
}
+
+ @Override
+ public Statement apply(final Statement base, final Description description) {
+ // This will prevent shared webview tests from running if a WebView provider does not exist.
+ Assume.assumeTrue("WebView is not available", NullWebViewUtils.isWebViewAvailable());
+ return super.apply(base, description);
+ }
}
diff --git a/tests/tests/security/AndroidManifest.xml b/tests/tests/security/AndroidManifest.xml
index 7627600c97c..5487fb43bde 100644
--- a/tests/tests/security/AndroidManifest.xml
+++ b/tests/tests/security/AndroidManifest.xml
@@ -27,6 +27,7 @@
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
+ <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
@@ -217,6 +218,11 @@
<activity android:name="android.security.cts.ActivityManagerTest$ActivityOptionsActivity" />
<activity android:name="android.security.cts.ActivityManagerTest$BaseActivity" />
+ <activity android:name="android.security.cts.PackageInstallerTest$BackgroundLaunchActivity"
+ android:exported="true" />
+ <service android:name="android.security.cts.TestForegroundService"
+ android:exported="true" />
+
<provider android:name="android.security.cts.CVE_2022_20358.PocContentProvider"
android:authorities="android.security.cts.CVE_2022_20358.provider"
android:enabled="true"
diff --git a/tests/tests/security/src/android/security/cts/CVE_2022_20611.java b/tests/tests/security/src/android/security/cts/CVE_2022_20611.java
new file mode 100644
index 00000000000..02526f4b3f9
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2022_20611.java
@@ -0,0 +1,63 @@
+/**
+ * Copyright (C) 2023 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 com.android.compatibility.common.util.ShellUtils.runShellCommand;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.compatibility.common.util.SystemUtil;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+@RunWith(AndroidJUnit4.class)
+public class CVE_2022_20611 extends StsExtraBusinessLogicTestCase {
+ /**
+ * CVE-2022-20611
+ */
+ @AsbSecurityTest(cveBugId = 242996180)
+ @Test
+ public void testPocCVE_2022_20611() throws Exception {
+ Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ int provisioningAppId = context.getResources().getIdentifier(
+ "config_deviceProvisioningPackage", "string", "android");
+ assumeTrue("config_deviceProvisioningPackage not found.", provisioningAppId > 0);
+
+ String protectedPkg = context.getResources().getString(provisioningAppId);
+ assumeFalse("config_deviceProvisioningPackage is not set", protectedPkg.isEmpty());
+
+ String res = runShellCommand("pm list packages " + protectedPkg);
+ assumeTrue(protectedPkg + " is not installed.", res.contains(protectedPkg));
+
+ res = runShellCommand("pm uninstall -k --user 0 " + protectedPkg);
+ if (!res.contains("DELETE_FAILED_INTERNAL_ERROR")) {
+ runShellCommand("pm install-existing --user 0 " + protectedPkg);
+ fail(
+ "Protected package '" + protectedPkg + "' could be uninstalled. "
+ + "Vulnerable to b/242994180.");
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/PackageInstallerTest.java b/tests/tests/security/src/android/security/cts/PackageInstallerTest.java
index ddea21385d8..43124ecd847 100644
--- a/tests/tests/security/src/android/security/cts/PackageInstallerTest.java
+++ b/tests/tests/security/src/android/security/cts/PackageInstallerTest.java
@@ -16,25 +16,46 @@
package android.security.cts;
+import static android.content.Intent.EXTRA_REMOTE_CALLBACK;
+
import android.Manifest;
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.app.Instrumentation.ActivityMonitor;
+import android.app.Service;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.ConditionVariable;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.RemoteCallback;
import android.platform.test.annotations.AppModeFull;
import android.platform.test.annotations.AsbSecurityTest;
+import android.provider.Settings;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
+import com.android.compatibility.common.util.SystemUtil;
import com.android.cts.install.lib.Install;
import com.android.cts.install.lib.TestApp;
import com.android.cts.install.lib.Uninstall;
import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
import org.junit.After;
+import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.Objects;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicReference;
@RunWith(AndroidJUnit4.class)
@AppModeFull
@@ -42,10 +63,41 @@ public class PackageInstallerTest extends StsExtraBusinessLogicTestCase {
private static final String TEST_APP_NAME = "android.security.cts.packageinstallertestapp";
+ private static final String KEY_ERROR = "key_error";
+ private static final String ACTION_COMMIT_WITH_ACTIVITY_INTENT_SENDER = TEST_APP_NAME
+ + ".action.COMMIT_WITH_ACTIVITY_INTENT_SENDER";
+ private static final String ACTION_COMMIT_WITH_FG_SERVICE_INTENT_SENDER = TEST_APP_NAME
+ + ".action.COMMIT_WITH_FG_SERVICE_INTENT_SENDER";
+
+ static final long DEFAULT_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(15);
+
private static final TestApp TEST_APP = new TestApp(
"PackageInstallerTestApp", TEST_APP_NAME, 1, /*isApex*/ false,
"PackageInstallerTestApp.apk");
+ private static Context sContext = InstrumentationRegistry.getInstrumentation().getContext();
+ private static HandlerThread sResponseThread;
+ private static Handler sHandler;
+
+ private static final ComponentName BACKGROUND_RECEIVER_COMPONENT_NAME =
+ ComponentName.createRelative(TEST_APP_NAME, ".BackgroundReceiver");
+ private static final ComponentName BACKGROUND_LAUNCH_ACTIVITY_COMPONENT_NAME =
+ new ComponentName(sContext, BackgroundLaunchActivity.class);
+ private static final ComponentName FOREGROUND_SERVICE_COMPONENT_NAME =
+ new ComponentName(sContext, TestForegroundService.class);
+
+ @BeforeClass
+ public static void onBeforeClass() {
+ sResponseThread = new HandlerThread("response");
+ sResponseThread.start();
+ sHandler = new Handler(sResponseThread.getLooper());
+ }
+
+ @AfterClass
+ public static void onAfterClass() {
+ sResponseThread.quit();
+ }
+
@Before
public void setUp() {
InstrumentationRegistry
@@ -74,4 +126,87 @@ public class PackageInstallerTest extends StsExtraBusinessLogicTestCase {
Assert.assertNotNull("Did not receive broadcast", packageName);
Assert.assertEquals(TEST_APP_NAME, packageName);
}
+
+ @Test
+ @AsbSecurityTest(cveBugId = 230492955)
+ public void commitSessionInBackground_withActivityIntentSender_doesNotLaunchActivity()
+ throws Exception {
+ Install.single(TEST_APP).commit();
+ // An activity with the system uid in the foreground is necessary to this test.
+ goToSettings();
+ final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ final ActivityMonitor monitor = instrumentation.addMonitor(
+ BackgroundLaunchActivity.class.getName(), null /* result */, false /* block */);
+ try {
+ sendActionToBackgroundReceiver(
+ ACTION_COMMIT_WITH_ACTIVITY_INTENT_SENDER,
+ BACKGROUND_LAUNCH_ACTIVITY_COMPONENT_NAME);
+
+ final Activity activity = monitor.waitForActivityWithTimeout(DEFAULT_TIMEOUT_MS);
+ if (activity != null) {
+ instrumentation.runOnMainSync(() -> activity.finish());
+ }
+ Assert.assertNull(activity);
+ } finally {
+ instrumentation.removeMonitor(monitor);
+ }
+ }
+
+ @Test
+ @AsbSecurityTest(cveBugId = 243377226)
+ public void commitSessionInBackground_withForegroundServiceIntentSender_doesNotStartService()
+ throws Exception {
+ Install.single(TEST_APP).commit();
+ // An activity with the system uid in the foreground is necessary to this test.
+ goToSettings();
+
+ sendActionToBackgroundReceiver(
+ ACTION_COMMIT_WITH_FG_SERVICE_INTENT_SENDER, FOREGROUND_SERVICE_COMPONENT_NAME);
+
+ final Service service =
+ TestForegroundService.waitFor(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ if (service != null) {
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(
+ () -> service.stopSelf());
+ }
+ Assert.assertNull(service);
+ }
+
+ private void goToSettings() {
+ SystemUtil.runShellCommand(
+ "am start -W --user current -a " + Settings.ACTION_SETTINGS);
+ }
+
+ private Bundle sendActionToBackgroundReceiver(String action, ComponentName statusReceiver)
+ throws Exception {
+ final Intent intent = new Intent(action)
+ .setComponent(BACKGROUND_RECEIVER_COMPONENT_NAME);
+ if (statusReceiver != null) {
+ intent.putExtra(Intent.EXTRA_COMPONENT_NAME, statusReceiver);
+ }
+ final ConditionVariable latch = new ConditionVariable();
+ final AtomicReference<Bundle> resultReference = new AtomicReference<>();
+ final RemoteCallback remoteCallback = new RemoteCallback(
+ bundle -> {
+ resultReference.set(bundle);
+ latch.open();
+ },
+ sHandler);
+ intent.putExtra(EXTRA_REMOTE_CALLBACK, remoteCallback);
+ sContext.sendBroadcast(intent);
+
+ if (!latch.block(DEFAULT_TIMEOUT_MS)) {
+ throw new TimeoutException(
+ "Latch timed out while awaiting a response from background receiver");
+ }
+ final Bundle bundle = resultReference.get();
+ if (bundle != null && bundle.containsKey(KEY_ERROR)) {
+ throw Objects.requireNonNull(bundle.getSerializable(KEY_ERROR, Exception.class));
+ }
+ return bundle;
+ }
+
+ // An activity to receive status of a committed session
+ public static class BackgroundLaunchActivity extends Activity {
+ }
}
diff --git a/tests/tests/security/src/android/security/cts/TestForegroundService.java b/tests/tests/security/src/android/security/cts/TestForegroundService.java
new file mode 100644
index 00000000000..b09a925c01d
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/TestForegroundService.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2023 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.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.IBinder;
+
+import org.junit.Assert;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+public class TestForegroundService extends Service {
+ private static BlockingQueue<Service> sQueue = new LinkedBlockingQueue<>();
+
+ private static final int FGS_NOTIFICATION_ID = 1;
+ private static final String NOTIFICATION_CHANNEL_ID =
+ TestForegroundService.class.getSimpleName();
+
+ @Override
+ public void onCreate() {
+ createNotificationChannelId(this, NOTIFICATION_CHANNEL_ID);
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ // When this service is started, make it a foreground service
+ final Notification.Builder builder =
+ new Notification.Builder(this, NOTIFICATION_CHANNEL_ID)
+ .setSmallIcon(android.R.drawable.btn_star)
+ .setContentTitle(NOTIFICATION_CHANNEL_ID)
+ .setContentText(TestForegroundService.class.getName());
+ startForeground(FGS_NOTIFICATION_ID, builder.build());
+
+ try {
+ sQueue.put(this);
+ } catch (InterruptedException e) {
+ Assert.fail(e.toString());
+ }
+ return Service.START_NOT_STICKY;
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ /** Create a notification channel. */
+ private static void createNotificationChannelId(Context context, String id) {
+ final NotificationManager nm =
+ context.getSystemService(NotificationManager.class);
+ final CharSequence name = id;
+ final String description = TestForegroundService.class.getName();
+ final int importance = NotificationManager.IMPORTANCE_DEFAULT;
+ final NotificationChannel channel = new NotificationChannel(
+ NOTIFICATION_CHANNEL_ID, name, importance);
+ channel.setDescription(description);
+ nm.createNotificationChannel(channel);
+ }
+
+ /** Wait until the service is started */
+ public static Service waitFor(long timeout, TimeUnit unit)
+ throws InterruptedException {
+ return sQueue.poll(timeout, unit);
+ }
+}
diff --git a/tests/tests/security/testdata/packageinstallertestapp.xml b/tests/tests/security/testdata/packageinstallertestapp.xml
index 5e6e066b3af..ad39db564ae 100644
--- a/tests/tests/security/testdata/packageinstallertestapp.xml
+++ b/tests/tests/security/testdata/packageinstallertestapp.xml
@@ -34,5 +34,6 @@
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
+ <receiver android:name=".BackgroundReceiver" android:exported="true" />
</application>
</manifest>
diff --git a/tests/tests/security/testdata/src/android/security/cts/packageinstallertestapp/BackgroundReceiver.java b/tests/tests/security/testdata/src/android/security/cts/packageinstallertestapp/BackgroundReceiver.java
new file mode 100644
index 00000000000..8997082db52
--- /dev/null
+++ b/tests/tests/security/testdata/src/android/security/cts/packageinstallertestapp/BackgroundReceiver.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2023 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.packageinstallertestapp;
+
+import static android.content.Intent.EXTRA_COMPONENT_NAME;
+import static android.content.Intent.EXTRA_REMOTE_CALLBACK;
+import static android.content.pm.PackageInstaller.SessionParams.MODE_FULL_INSTALL;
+
+import android.app.ActivityManager;
+import android.app.ActivityManager.RunningAppProcessInfo;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentSender;
+import android.content.pm.PackageInstaller;
+import android.content.pm.PackageInstaller.Session;
+import android.content.pm.PackageInstaller.SessionParams;
+import android.os.Bundle;
+import android.os.RemoteCallback;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * A receiver to invoke APIs in the background.
+ */
+public class BackgroundReceiver extends BroadcastReceiver {
+ private static final String PKG_NAME = "android.security.cts.packageinstallertestapp";
+ private static final String KEY_ERROR = "key_error";
+ private static final String ACTION_COMMIT_WITH_ACTIVITY_INTENT_SENDER = PKG_NAME
+ + ".action.COMMIT_WITH_ACTIVITY_INTENT_SENDER";
+ private static final String ACTION_COMMIT_WITH_FG_SERVICE_INTENT_SENDER = PKG_NAME
+ + ".action.COMMIT_WITH_FG_SERVICE_INTENT_SENDER";
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final RemoteCallback remoteCallback = intent.getParcelableExtra(EXTRA_REMOTE_CALLBACK,
+ RemoteCallback.class);
+ final ComponentName statusReceiver = intent.getParcelableExtra(
+ EXTRA_COMPONENT_NAME, ComponentName.class);
+ final String action = intent.getAction();
+
+ if (!isAppInBackground(context)) {
+ sendError(remoteCallback,
+ new IllegalStateException("App is not in background"));
+ return;
+ }
+ try {
+ if (action.equals(ACTION_COMMIT_WITH_ACTIVITY_INTENT_SENDER)) {
+ final IntentSender intentSender = PendingIntent.getActivity(context,
+ 0 /* requestCode */,
+ new Intent().setComponent(statusReceiver),
+ PendingIntent.FLAG_IMMUTABLE)
+ .getIntentSender();
+ sendInstallCommit(context, remoteCallback, intentSender);
+ } else if (action.equals(ACTION_COMMIT_WITH_FG_SERVICE_INTENT_SENDER)) {
+ final IntentSender intentSender = PendingIntent.getForegroundService(context,
+ 0 /* requestCode */,
+ new Intent().setComponent(statusReceiver),
+ PendingIntent.FLAG_IMMUTABLE)
+ .getIntentSender();
+ sendInstallCommit(context, remoteCallback, intentSender);
+ } else {
+ sendError(remoteCallback,
+ new IllegalArgumentException("Unknown action: " + action));
+ }
+ } catch (Throwable e) {
+ sendError(remoteCallback, e);
+ }
+ }
+
+ private static boolean isAppInBackground(Context context) {
+ final ActivityManager activityManager = context.getSystemService(ActivityManager.class);
+ final List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
+ final String packageName = context.getPackageName();
+ final RunningAppProcessInfo appInfo = appProcesses.stream()
+ .filter(app -> app.processName.equals(packageName))
+ .findAny().orElse(null);
+ if (appInfo != null
+ && appInfo.importance >= RunningAppProcessInfo.IMPORTANCE_SERVICE) {
+ return true;
+ }
+ return false;
+ }
+
+ private static void sendInstallCommit(Context context, RemoteCallback remoteCallback,
+ IntentSender intentSender) throws IOException {
+ final PackageInstaller packageInstaller =
+ context.getPackageManager().getPackageInstaller();
+ final int sessionId = packageInstaller.createSession(
+ new SessionParams(MODE_FULL_INSTALL));
+ final Session session = packageInstaller.openSession(sessionId);
+ session.commit(intentSender);
+ sendSuccess(remoteCallback);
+ }
+
+ private static void sendError(RemoteCallback remoteCallback, Throwable failure) {
+ Bundle result = new Bundle();
+ result.putSerializable(KEY_ERROR, failure);
+ remoteCallback.sendResult(result);
+ }
+
+ private static void sendSuccess(RemoteCallback remoteCallback) {
+ Bundle result = new Bundle();
+ remoteCallback.sendResult(result);
+ }
+}
diff --git a/tests/tests/settings/src/android/settings/cts/TetherProvisioningCarrierDialogActivityTest.java b/tests/tests/settings/src/android/settings/cts/TetherProvisioningCarrierDialogActivityTest.java
index c47ba7a9a9e..40d2b8b4d17 100644
--- a/tests/tests/settings/src/android/settings/cts/TetherProvisioningCarrierDialogActivityTest.java
+++ b/tests/tests/settings/src/android/settings/cts/TetherProvisioningCarrierDialogActivityTest.java
@@ -16,6 +16,7 @@
package android.settings.cts;
+import static org.junit.Assume.assumeFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
@@ -44,6 +45,8 @@ public class TetherProvisioningCarrierDialogActivityTest {
final PackageManager pm =
InstrumentationRegistry.getInstrumentation().getContext().getPackageManager();
assumeTrue(pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY));
+ assumeFalse(
+ "Skipping test: Tethering is not supported in Wear OS", isWatch());
}
@Test
@@ -54,4 +57,9 @@ public class TetherProvisioningCarrierDialogActivityTest {
intent, PackageManager.MATCH_DEFAULT_ONLY);
assertTrue(ri != null);
}
+
+ private boolean isWatch() {
+ return InstrumentationRegistry.getTargetContext()
+ .getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
+ }
}
diff --git a/tests/tests/telecom/AndroidManifest.xml b/tests/tests/telecom/AndroidManifest.xml
index 1b1d48ea3a1..57d09e7bec8 100644
--- a/tests/tests/telecom/AndroidManifest.xml
+++ b/tests/tests/telecom/AndroidManifest.xml
@@ -87,6 +87,15 @@
</intent-filter>
</service>
+ <service android:name=".NullBindingCallScreeningService"
+ android:permission="android.permission.BIND_SCREENING_SERVICE"
+ android:enabled="false"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.telecom.CallScreeningService"/>
+ </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/BaseTelecomTestWithMockServices.java b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
index 439b37790d9..dbdf8518481 100644
--- a/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
+++ b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
@@ -89,6 +89,7 @@ public class BaseTelecomTestWithMockServices extends InstrumentationTestCase {
public static final int FLAG_REGISTER = 0x1;
public static final int FLAG_ENABLE = 0x2;
public static final int FLAG_SET_DEFAULT = 0x4;
+ public static final int FLAG_PHONE_ACCOUNT_HANDLES_CONTENT_SCHEME = 0x8;
// Don't accidently use emergency number.
private static int sCounter = 5553638;
@@ -360,7 +361,12 @@ public class BaseTelecomTestWithMockServices extends InstrumentationTestCase {
CtsConnectionService.setUp(this.connectionService);
if ((flags & FLAG_REGISTER) != 0) {
- mTelecomManager.registerPhoneAccount(TestUtils.TEST_PHONE_ACCOUNT);
+ if ((flags & FLAG_PHONE_ACCOUNT_HANDLES_CONTENT_SCHEME) != 0) {
+ mTelecomManager.registerPhoneAccount(
+ TestUtils.TEST_PHONE_ACCOUNT_THAT_HANDLES_CONTENT_SCHEME);
+ } else {
+ mTelecomManager.registerPhoneAccount(TestUtils.TEST_PHONE_ACCOUNT);
+ }
}
if ((flags & FLAG_ENABLE) != 0) {
TestUtils.enablePhoneAccount(getInstrumentation(), TestUtils.TEST_PHONE_ACCOUNT_HANDLE);
@@ -723,6 +729,29 @@ public class BaseTelecomTestWithMockServices extends InstrumentationTestCase {
}
/**
+ * Verifies that a call was not placed
+ */
+ void placeAndVerifyNoCall(Bundle extras) {
+ assertEquals("Lock should have no permits!", 0, mInCallCallbacks.lock.availablePermits());
+ placeNewCallWithPhoneAccount(extras, 0);
+
+ try {
+ if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S,
+ TimeUnit.SECONDS)) {
+ }
+ } catch (InterruptedException e) {
+ Log.i(TAG, "Test interrupted!");
+ }
+
+ // Make sure any procedures to disconnect existing calls (makeRoomForOutgoingCall)
+ // complete successfully
+ TestUtils.waitOnLocalMainLooper(WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+ TestUtils.waitOnAllHandlers(getInstrumentation());
+
+ assertNull("Service should be null since call should not have been placed",
+ mInCallCallbacks.getService());
+ }
+ /**
* Puts Telecom in a state where there is an active call provided by the
* {@link CtsConnectionService} which can be tested.
*/
@@ -856,6 +885,21 @@ public class BaseTelecomTestWithMockServices extends InstrumentationTestCase {
return null;
}
+ void verifyNoConnectionForOutgoingCall() {
+ try {
+ if (!connectionService.lock.tryAcquire(TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+ TimeUnit.MILLISECONDS)) {
+ //fail("No outgoing call connection requested by Telecom");
+ }
+ } catch (InterruptedException e) {
+ Log.i(TAG, "Test interrupted!");
+ }
+
+ assertThat("Telecom should not create outgoing connection for outgoing call",
+ connectionService.outgoingConnections.size(), equalTo(0));
+ return;
+ }
+
MockConnection verifyConnectionForIncomingCall() {
// Assuming only 1 connection present
return verifyConnectionForIncomingCall(0);
diff --git a/tests/tests/telecom/src/android/telecom/cts/NullBindingCallScreeningService.java b/tests/tests/telecom/src/android/telecom/cts/NullBindingCallScreeningService.java
new file mode 100644
index 00000000000..6b6e5ed9718
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/NullBindingCallScreeningService.java
@@ -0,0 +1,82 @@
+/*
+ * 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.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.IBinder;
+import android.telecom.Call;
+import android.telecom.CallScreeningService;
+import android.util.Log;
+
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * Provides a minimal CTS-test implementation of {@link CallScreeningService}.
+ * This emulates an implementation of {@link CallScreeningService} that returns a null binding.
+ * This is used to test null binding cases to ensure we unbind the service when a null binding is
+ * received from onBind.
+ */
+public class NullBindingCallScreeningService extends CallScreeningService {
+ private static final String TAG = NullBindingCallScreeningService.class.getSimpleName();
+ public static CountDownLatch sBindLatch = new CountDownLatch(1);
+ public static CountDownLatch sUnbindLatch = new CountDownLatch(1);
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ Log.i(TAG, "onBind: returning null service");
+ sUnbindLatch = new CountDownLatch(1);
+ sBindLatch.countDown();
+ return null;
+ }
+
+ @Override
+ public boolean onUnbind(Intent intent) {
+ Log.i(TAG, "onUnbind: unbinding service");
+ sBindLatch = new CountDownLatch(1);
+ sUnbindLatch.countDown();
+ return false;
+ }
+
+ @Override
+ public void onScreenCall(Call.Details callDetails) {
+ Log.i(TAG, "onScreenCall");
+ }
+
+ public static void resetBindLatches() {
+ sBindLatch = new CountDownLatch(1);
+ sUnbindLatch = new CountDownLatch(1);
+ }
+
+ public static void enableNullBindingCallScreeningService(Context context) {
+ ComponentName componentName = new ComponentName(context,
+ NullBindingCallScreeningService.class);
+ context.getPackageManager().setComponentEnabledSetting(componentName,
+ PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+ PackageManager.DONT_KILL_APP);
+ }
+
+ public static void disableNullBindingCallScreeningService(Context context) {
+ ComponentName componentName = new ComponentName(context,
+ NullBindingCallScreeningService.class);
+ context.getPackageManager().setComponentEnabledSetting(componentName,
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+ PackageManager.DONT_KILL_APP);
+ }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/NullBindingCallScreeningServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/NullBindingCallScreeningServiceTest.java
new file mode 100644
index 00000000000..b88643af46d
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/NullBindingCallScreeningServiceTest.java
@@ -0,0 +1,145 @@
+/*
+ * 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 static android.telecom.cts.TestUtils.waitOnAllHandlers;
+
+import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
+
+import android.app.role.RoleManager;
+import android.content.Context;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Process;
+import android.os.UserHandle;
+import android.telecom.TelecomManager;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+public class NullBindingCallScreeningServiceTest extends BaseTelecomTestWithMockServices {
+ private static final int ASYNC_TIMEOUT = 10000;
+ private static final String ROLE_CALL_SCREENING = RoleManager.ROLE_CALL_SCREENING;
+ private static final Uri TEST_OUTGOING_NUMBER = Uri.fromParts("tel", "6505551212", null);
+
+ private RoleManager mRoleManager;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ if (!mShouldTestTelecom) {
+ return;
+ }
+ NullBindingCallScreeningService.enableNullBindingCallScreeningService(mContext);
+ mRoleManager = (RoleManager) mContext.getSystemService(Context.ROLE_SERVICE);
+ setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE);
+ // Ensure NullBindingCallScreeningService pkg holds the call screening role.
+ addRoleHolder(ROLE_CALL_SCREENING,
+ NullBindingCallScreeningService.class.getPackage().getName());
+ NullBindingCallScreeningService.resetBindLatches();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ if (!mShouldTestTelecom) {
+ return;
+ }
+ // Remove the app from the screening role.
+ removeRoleHolder(ROLE_CALL_SCREENING,
+ NullBindingCallScreeningService.class.getPackage().getName());
+ NullBindingCallScreeningService.disableNullBindingCallScreeningService(mContext);
+ }
+
+ public void testNullBindingOnIncomingCall() throws Exception {
+ Uri testNumber = createRandomTestNumber();
+ Bundle extras = new Bundle();
+ extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, testNumber);
+
+ // Verify that binding latch counts are reset for testing
+ assertBindLatchInit();
+ // Add a new incoming call
+ mTelecomManager.addNewIncomingCall(TestUtils.TEST_PHONE_ACCOUNT_HANDLE, extras);
+ // Assert unbind after onBind return a null service
+ assertBindLatchCountDown();
+ // Wait until the new incoming call is processed. Needed for proper tear down.
+ waitOnAllHandlers(getInstrumentation());
+ }
+
+ public void testNullBindingOnOutgoingCall() throws Exception {
+ Uri testNumber = createRandomTestNumber();
+ Bundle extras = new Bundle();
+ extras.putParcelable(TestUtils.EXTRA_PHONE_NUMBER, TEST_OUTGOING_NUMBER);
+
+ // Verify that binding latch counts are reset for testing
+ assertBindLatchInit();
+ // Create a new outgoing call.
+ mTelecomManager.placeCall(testNumber, extras);
+ // Assert unbind after onBind return a null service
+ assertBindLatchCountDown();
+ }
+
+ private void assertBindLatchInit() {
+ assertTrue(NullBindingCallScreeningService.sUnbindLatch.getCount() == 1);
+ assertTrue(NullBindingCallScreeningService.sBindLatch.getCount() == 1);
+ }
+
+ private void assertBindLatchCountDown() {
+ assertTrue(TestUtils.waitForLatchCountDown(NullBindingCallScreeningService.sBindLatch));
+ assertTrue(TestUtils.waitForLatchCountDown(NullBindingCallScreeningService.sUnbindLatch));
+ }
+
+ private void addRoleHolder(String roleName, String packageName)
+ throws Exception {
+ UserHandle user = Process.myUserHandle();
+ Executor executor = mContext.getMainExecutor();
+ LinkedBlockingQueue<Boolean> queue = new LinkedBlockingQueue(1);
+
+ runWithShellPermissionIdentity(() -> mRoleManager.addRoleHolderAsUser(roleName,
+ packageName, RoleManager.MANAGE_HOLDERS_FLAG_DONT_KILL_APP, user, executor,
+ successful -> {
+ try {
+ queue.put(successful);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }));
+ boolean result = queue.poll(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS);
+ assertTrue(result);
+ }
+
+ private void removeRoleHolder(String roleName, String packageName)
+ throws Exception {
+ UserHandle user = Process.myUserHandle();
+ Executor executor = mContext.getMainExecutor();
+ LinkedBlockingQueue<Boolean> queue = new LinkedBlockingQueue(1);
+
+ runWithShellPermissionIdentity(() -> mRoleManager.removeRoleHolderAsUser(roleName,
+ packageName, RoleManager.MANAGE_HOLDERS_FLAG_DONT_KILL_APP, user, executor,
+ successful -> {
+ try {
+ queue.put(successful);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }));
+ boolean result = queue.poll(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS);
+ assertTrue(result);
+ }
+}
+
diff --git a/tests/tests/telecom/src/android/telecom/cts/OutgoingCallTest.java b/tests/tests/telecom/src/android/telecom/cts/OutgoingCallTest.java
index 5074ab9834d..90e11d1c6c4 100644
--- a/tests/tests/telecom/src/android/telecom/cts/OutgoingCallTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/OutgoingCallTest.java
@@ -19,10 +19,15 @@ package android.telecom.cts;
import static android.telecom.Call.STATE_SELECT_PHONE_ACCOUNT;
import static android.telephony.TelephonyManager.CALL_STATE_RINGING;
+import android.content.ContentValues;
import android.content.Context;
+import android.content.ContentProviderOperation;
+import android.content.ContentResolver;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
+import android.provider.Contacts;
+import android.provider.ContactsContract;
import android.telecom.Call;
import android.telecom.CallAudioState;
import android.telecom.Connection;
@@ -33,6 +38,7 @@ import android.telephony.emergency.EmergencyNumber;
import com.android.compatibility.common.util.SystemUtil;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -48,18 +54,53 @@ public class OutgoingCallTest extends BaseTelecomTestWithMockServices {
private static final String TEST_EMERGENCY_NUMBER = "9998887776655443210";
+ Uri mPersonRecord = null;
+ Uri mPhoneRecord = null;
+ private final static String TEST_PHONE_NUMBER = "+18005552871";
+
@Override
protected void setUp() throws Exception {
super.setUp();
NewOutgoingCallBroadcastReceiver.reset();
if (mShouldTestTelecom) {
- setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE);
+ setupConnectionService(null,
+ FLAG_REGISTER | FLAG_ENABLE | FLAG_PHONE_ACCOUNT_HANDLES_CONTENT_SCHEME);
+
+ try {
+ // Add a test contact
+ ContentResolver cr = getInstrumentation().getTargetContext().getContentResolver();
+ mPersonRecord = null;
+ mPhoneRecord = null;
+
+ // insert a contact with phone number
+ ContentValues values = new ContentValues();
+ values.put(Contacts.People.NAME, "CTS test contact");
+ mPersonRecord = cr.insert(Contacts.People.CONTENT_URI, values);
+ Uri phoneUri = Uri.withAppendedPath(mPersonRecord,
+ Contacts.People.Phones.CONTENT_DIRECTORY);
+ values.clear();
+ values.put(Contacts.People.Phones.TYPE, Contacts.People.Phones.TYPE_HOME);
+ values.put(Contacts.People.Phones.NUMBER, TEST_PHONE_NUMBER);
+ mPhoneRecord = cr.insert(phoneUri, values);
+
+ } catch (Exception e) {
+ assertTrue("Failed to insert test contact", false);
+ }
}
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
+ ContentResolver resolver = getInstrumentation().getTargetContext().getContentResolver();
+
+ if (mPersonRecord != null) {
+ resolver.delete(mPersonRecord, null, null);
+ }
+ if(mPhoneRecord != null) {
+ resolver.delete(mPhoneRecord, null, null);
+ }
+
TestUtils.clearSystemDialerOverride(getInstrumentation());
TestUtils.removeTestEmergencyNumber(getInstrumentation(), TEST_EMERGENCY_NUMBER);
}
@@ -73,6 +114,20 @@ public class OutgoingCallTest extends BaseTelecomTestWithMockServices {
} */
/**
+ * Verifies that providing content URI instead of tel/sip uri does not start a call
+ *
+ */
+ public void testDoNotStartCallWithContentUri() {
+ if (!mShouldTestTelecom) {
+ return;
+ }
+ final Bundle extras = new Bundle();
+ extras.putParcelable(TestUtils.EXTRA_PHONE_NUMBER, mPhoneRecord);
+ placeAndVerifyNoCall(extras);
+ verifyNoConnectionForOutgoingCall();
+ }
+
+ /**
* Verifies that providing the EXTRA_START_CALL_WITH_SPEAKERPHONE extra starts the call with
* speakerphone automatically enabled.
*
diff --git a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
index 2560b942382..59d2394dd96 100644
--- a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
+++ b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
@@ -138,6 +138,24 @@ public class TestUtils {
.addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL)
.build();
+ public static final PhoneAccount TEST_PHONE_ACCOUNT_THAT_HANDLES_CONTENT_SCHEME =
+ PhoneAccount.builder(
+ TEST_PHONE_ACCOUNT_HANDLE, ACCOUNT_LABEL)
+ .setAddress(Uri.parse("tel:555-TEST"))
+ .setSubscriptionAddress(Uri.parse("tel:555-TEST"))
+ .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
+ PhoneAccount.CAPABILITY_VIDEO_CALLING |
+ PhoneAccount.CAPABILITY_RTT |
+ PhoneAccount.CAPABILITY_CONNECTION_MANAGER |
+ PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS |
+ PhoneAccount.CAPABILITY_ADHOC_CONFERENCE_CALLING)
+ .setHighlightColor(Color.RED)
+ .setShortDescription(ACCOUNT_LABEL)
+ .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
+ .addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL)
+ .addSupportedUriScheme("content")
+ .build();
+
public static final PhoneAccount TEST_SIM_PHONE_ACCOUNT = PhoneAccount.builder(
TEST_SIM_PHONE_ACCOUNT_HANDLE, SIM_ACCOUNT_LABEL)
.setAddress(Uri.parse("tel:555-TEST"))
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/CallComposerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/CallComposerTest.java
index 4b67468083e..c4a1e0c954d 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/CallComposerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/CallComposerTest.java
@@ -26,6 +26,7 @@ import android.net.Uri;
import android.os.OutcomeReceiver;
import android.os.ParcelFileDescriptor;
import android.os.ParcelUuid;
+import android.telephony.ims.cts.ImsUtils;
import android.os.UserHandle;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -69,6 +70,9 @@ public class CallComposerTest {
@Before
public void setUp() throws Exception {
+ if (!ImsUtils.shouldTestImsCall()) {
+ return;
+ }
mContext = InstrumentationRegistry.getContext();
overrideDefaultDialer();
mPreviousTestMode = Boolean.parseBoolean(
@@ -80,6 +84,9 @@ public class CallComposerTest {
@After
public void tearDown() throws Exception {
+ if (!ImsUtils.shouldTestImsCall()) {
+ return;
+ }
restoreDefaultDialer();
TelephonyUtils.executeShellCommand(InstrumentationRegistry.getInstrumentation(),
"cmd phone callcomposer test-mode "
@@ -89,6 +96,9 @@ public class CallComposerTest {
@Test
public void testUploadPictureWithFile() throws Exception {
+ if (!ImsUtils.shouldTestImsCall()) {
+ return;
+ }
Path testFile = mContext.getFilesDir().toPath().resolve(TEST_FILE_NAME);
byte[] imageData = getSamplePictureAsBytes();
Files.write(testFile, imageData);
@@ -99,6 +109,9 @@ public class CallComposerTest {
@Test
public void testUploadPictureAsStream() throws Exception {
+ if (!ImsUtils.shouldTestImsCall()) {
+ return;
+ }
byte[] imageData = getSamplePictureAsBytes();
ByteArrayInputStream inputStream = new ByteArrayInputStream(imageData);
@@ -108,6 +121,9 @@ public class CallComposerTest {
@Test
public void testExcessivelyLargePictureAsFile() throws Exception {
+ if (!ImsUtils.shouldTestImsCall()) {
+ return;
+ }
int targetSize = (int) TelephonyManager.getMaximumCallComposerPictureSize() + 1;
byte[] imageData = getSamplePictureAsBytes();
byte[] paddedData = new byte[targetSize];
@@ -121,6 +137,9 @@ public class CallComposerTest {
@Test
public void testExcessivelyLargePictureAsStream() throws Exception {
+ if (!ImsUtils.shouldTestImsCall()) {
+ return;
+ }
int targetSize = (int) TelephonyManager.getMaximumCallComposerPictureSize() + 1;
byte[] imageData = getSamplePictureAsBytes();
byte[] paddedData = new byte[targetSize];
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/DataProfileTest.java b/tests/tests/telephony/current/src/android/telephony/cts/DataProfileTest.java
index d592e0f643c..0f52eb55fcc 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/DataProfileTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/DataProfileTest.java
@@ -316,7 +316,8 @@ public class DataProfileTest {
assertEquals(null, profile.getUserName());
assertEquals(null, profile.getPassword());
assertEquals(0, profile.getProfileId());
- assertEquals(ApnSetting.PROTOCOL_IP, profile.getProtocolType());
+ assertTrue(profile.getProtocolType() == ApnSetting.PROTOCOL_IPV4V6
+ || profile.getProtocolType() == ApnSetting.PROTOCOL_IP);
assertEquals(ApnSetting.PROTOCOL_IP, profile.getRoamingProtocolType());
assertEquals(ApnSetting.TYPE_NONE, profile.getSupportedApnTypesBitmask());
assertEquals(DataProfile.TYPE_COMMON, profile.getType());
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
index 03576df21c6..cf46203dbcb 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
@@ -2271,7 +2271,7 @@ public class TelephonyManagerTest {
List<String> plmns = mTelephonyManager.getEquivalentHomePlmns();
- if (mTelephonyManager.getPhoneType() != TelephonyManager.PHONE_TYPE_GSM) {
+ if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
assertEquals(0, plmns.size());
} else {
for (String plmn : plmns) {
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsCallingTest.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsCallingTest.java
index 1c20e9af869..4f902a2ed76 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsCallingTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsCallingTest.java
@@ -208,7 +208,7 @@ public class ImsCallingTest {
@BeforeClass
public static void beforeAllTests() throws Exception {
- if (!ImsUtils.shouldTestImsService()) {
+ if (!ImsUtils.shouldTestImsCall()) {
return;
}
@@ -272,7 +272,7 @@ public class ImsCallingTest {
@AfterClass
public static void afterAllTests() throws Exception {
- if (!ImsUtils.shouldTestImsService()) {
+ if (!ImsUtils.shouldTestImsCall()) {
return;
}
@@ -308,7 +308,7 @@ public class ImsCallingTest {
@Before
public void beforeTest() throws Exception {
- if (!ImsUtils.shouldTestImsService()) {
+ if (!ImsUtils.shouldTestImsCall()) {
return;
}
TelephonyManager tm = (TelephonyManager) InstrumentationRegistry.getInstrumentation()
@@ -365,7 +365,7 @@ public class ImsCallingTest {
@After
public void afterTest() throws Exception {
- if (!ImsUtils.shouldTestImsService()) {
+ if (!ImsUtils.shouldTestImsCall()) {
return;
}
@@ -389,7 +389,7 @@ public class ImsCallingTest {
@Test
public void testOutGoingCall() throws Exception {
- if (!ImsUtils.shouldTestImsService()) {
+ if (!ImsUtils.shouldTestImsCall()) {
return;
}
@@ -426,7 +426,7 @@ public class ImsCallingTest {
@Test
public void testOutGoingCallStartFailed() throws Exception {
- if (!ImsUtils.shouldTestImsService()) {
+ if (!ImsUtils.shouldTestImsCall()) {
return;
}
@@ -474,7 +474,7 @@ public class ImsCallingTest {
@Test
public void testIncomingCall() throws Exception {
- if (!ImsUtils.shouldTestImsService()) {
+ if (!ImsUtils.shouldTestImsCall()) {
return;
}
bindImsService();
@@ -506,7 +506,7 @@ public class ImsCallingTest {
@Test
public void testOutGoingCallForExecutor() throws Exception {
- if (!ImsUtils.shouldTestImsService()) {
+ if (!ImsUtils.shouldTestImsCall()) {
return;
}
@@ -545,7 +545,7 @@ public class ImsCallingTest {
@Test
public void testOutGoingCallHoldResume() throws Exception {
- if (!ImsUtils.shouldTestImsService()) {
+ if (!ImsUtils.shouldTestImsCall()) {
return;
}
@@ -591,7 +591,7 @@ public class ImsCallingTest {
@Test
public void testOutGoingCallHoldFailure() throws Exception {
- if (!ImsUtils.shouldTestImsService()) {
+ if (!ImsUtils.shouldTestImsCall()) {
return;
}
@@ -635,7 +635,7 @@ public class ImsCallingTest {
@Test
public void testOutGoingCallResumeFailure() throws Exception {
- if (!ImsUtils.shouldTestImsService()) {
+ if (!ImsUtils.shouldTestImsCall()) {
return;
}
@@ -685,7 +685,7 @@ public class ImsCallingTest {
@Test
public void testOutGoingIncomingMultiCall() throws Exception {
- if (!ImsUtils.shouldTestImsService()) {
+ if (!ImsUtils.shouldTestImsCall()) {
return;
}
@@ -755,7 +755,7 @@ public class ImsCallingTest {
@Test
public void testOutGoingIncomingMultiCallAcceptTerminate() throws Exception {
- if (!ImsUtils.shouldTestImsService()) {
+ if (!ImsUtils.shouldTestImsCall()) {
return;
}
@@ -826,7 +826,7 @@ public class ImsCallingTest {
@Test
public void testOutGoingCallSwap() throws Exception {
- if (!ImsUtils.shouldTestImsService()) {
+ if (!ImsUtils.shouldTestImsCall()) {
return;
}
@@ -877,7 +877,7 @@ public class ImsCallingTest {
@Test
public void testOutGoingCallSwapFail() throws Exception {
- if (!ImsUtils.shouldTestImsService()) {
+ if (!ImsUtils.shouldTestImsCall()) {
return;
}
@@ -929,7 +929,7 @@ public class ImsCallingTest {
@Test
public void testConferenceCall() throws Exception {
- if (!ImsUtils.shouldTestImsService()) {
+ if (!ImsUtils.shouldTestImsCall()) {
return;
}
Log.i(LOG_TAG, "testConference ");
@@ -973,7 +973,7 @@ public class ImsCallingTest {
@Test
public void testConferenceCallFailure() throws Exception {
- if (!ImsUtils.shouldTestImsService()) {
+ if (!ImsUtils.shouldTestImsCall()) {
return;
}
Log.i(LOG_TAG, "testConferenceCallFailure ");
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsUtils.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsUtils.java
index b386e3caecd..adae12a946e 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsUtils.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsUtils.java
@@ -67,6 +67,13 @@ public class ImsUtils {
return hasTelephony && hasIms;
}
+ public static boolean shouldTestImsCall() {
+ final PackageManager pm = InstrumentationRegistry.getInstrumentation().getContext()
+ .getPackageManager();
+ return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS)
+ && pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CALLING);
+ }
+
public static boolean shouldTestImsSingleRegistration() {
final PackageManager pm = InstrumentationRegistry.getInstrumentation().getContext()
.getPackageManager();
diff --git a/tests/tests/text/src/android/text/method/cts/BaseMovementMethodTest.java b/tests/tests/text/src/android/text/method/cts/BaseMovementMethodTest.java
index bc03371036f..2e73d038d55 100644
--- a/tests/tests/text/src/android/text/method/cts/BaseMovementMethodTest.java
+++ b/tests/tests/text/src/android/text/method/cts/BaseMovementMethodTest.java
@@ -181,6 +181,7 @@ public class BaseMovementMethodTest {
private TextView createTextView() {
final TextView textView = new TextViewNoIme(mActivityRule.getActivity());
textView.setFocusable(true);
+ textView.setEllipsize(null);
textView.setMovementMethod(mMovementMethod);
textView.setTextDirection(View.TEXT_DIRECTION_LTR);
return textView;
diff --git a/tests/tests/text/src/android/text/method/cts/ScrollingMovementMethodTest.java b/tests/tests/text/src/android/text/method/cts/ScrollingMovementMethodTest.java
index 34ffd767a99..c967b05b355 100644
--- a/tests/tests/text/src/android/text/method/cts/ScrollingMovementMethodTest.java
+++ b/tests/tests/text/src/android/text/method/cts/ScrollingMovementMethodTest.java
@@ -86,6 +86,7 @@ public class ScrollingMovementMethodTest {
mTextView = new TextViewNoIme(mActivity);
mTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12);
mTextView.setText(THREE_LINES_TEXT, BufferType.EDITABLE);
+ mTextView.setEllipsize(null);
mSpannable = (Spannable) mTextView.getText();
mScaledTouchSlop = ViewConfiguration.get(mActivity).getScaledTouchSlop();
}
diff --git a/tests/tests/text/src/android/text/method/cts/TouchTest.java b/tests/tests/text/src/android/text/method/cts/TouchTest.java
index fd078fb280d..127b87cb72b 100644
--- a/tests/tests/text/src/android/text/method/cts/TouchTest.java
+++ b/tests/tests/text/src/android/text/method/cts/TouchTest.java
@@ -70,6 +70,7 @@ public class TouchTest {
mActivity = mActivityRule.getActivity();
mTextView = new TextViewNoIme(mActivity);
mTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10);
+ mTextView.setEllipsize(null);
}
@Test
diff --git a/tests/tests/tv/src/android/media/tv/tuner/cts/TunerTest.java b/tests/tests/tv/src/android/media/tv/tuner/cts/TunerTest.java
index 84707ea0063..69d05864f5e 100644
--- a/tests/tests/tv/src/android/media/tv/tuner/cts/TunerTest.java
+++ b/tests/tests/tv/src/android/media/tv/tuner/cts/TunerTest.java
@@ -1634,11 +1634,8 @@ public class TunerTest {
mTuner.close();
mTuner = null;
- // check the sharee is also closed
- // tune() would have failed even before close() but still..
- // TODO: fix this once callback sharing is implemented
- res = sharee.tune(feSettings);
- assertEquals(Tuner.RESULT_UNAVAILABLE, res);
+ // check the frontend of sharee is also released
+ assertNull(sharee.getFrontendInfo());
sharee.close();
@@ -1660,7 +1657,6 @@ public class TunerTest {
assertNotNull(statusCapabilities);
FrontendStatus status = mTuner.getFrontendStatus(statusCapabilities);
assertNotNull(status);
-
}
@Test
diff --git a/tests/tests/view/src/android/view/cts/PixelCopyTest.java b/tests/tests/view/src/android/view/cts/PixelCopyTest.java
index 823b02873bb..379f24bece8 100644
--- a/tests/tests/view/src/android/view/cts/PixelCopyTest.java
+++ b/tests/tests/view/src/android/view/cts/PixelCopyTest.java
@@ -24,8 +24,10 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.app.Activity;
+import android.app.ActivityOptions;
import android.app.Instrumentation;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
@@ -41,10 +43,10 @@ import android.media.Image;
import android.media.ImageReader;
import android.media.ImageWriter;
import android.os.Debug;
-import android.server.wm.IgnoreOrientationRequestSession;
import android.server.wm.SetRequestedOrientationRule;
import android.util.Half;
import android.util.Log;
+import android.util.Pair;
import android.view.PixelCopy;
import android.view.Surface;
import android.view.View;
@@ -62,8 +64,10 @@ import com.android.compatibility.common.util.SynchronousPixelCopy;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExternalResource;
import org.junit.rules.TestName;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
@@ -73,6 +77,7 @@ import org.junit.runners.model.Statement;
import java.io.File;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
+import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
@@ -82,11 +87,9 @@ import java.util.function.Function;
public class PixelCopyTest {
private static final String TAG = "PixelCopyTests";
- // TODO: Use SetRequestedOrientationRule instead.
- @Rule
- public SetRequestedOrientationRule.DisableFixedToUserRotationRule
- mDisableFixedToUserRotationRule =
- new SetRequestedOrientationRule.DisableFixedToUserRotationRule();
+ @ClassRule
+ public static SetRequestedOrientationRule mSetRequestedOrientationRule =
+ new SetRequestedOrientationRule();
@Rule
public ActivityTestRule<PixelCopyGLProducerCtsActivity> mGLSurfaceViewActivityRule =
@@ -96,18 +99,31 @@ public class PixelCopyTest {
public ActivityTestRule<PixelCopyVideoSourceActivity> mVideoSourceActivityRule =
new ActivityTestRule<>(PixelCopyVideoSourceActivity.class, false, false);
- @Rule
- public ActivityTestRule<PixelCopyViewProducerActivity> mWindowSourceActivityRule =
- new ActivityTestRule<>(PixelCopyViewProducerActivity.class, false, false);
+ public static class FullscreenActivityRule extends ExternalResource {
+ private final ArrayList<Activity> mActivities = new ArrayList<>();
- @Rule
- public ActivityTestRule<PixelCopyWideGamutViewProducerActivity>
- mWideGamutWindowSourceActivityRule = new ActivityTestRule<>(
- PixelCopyWideGamutViewProducerActivity.class, false, false);
+ public <T extends Activity> T launch(Class<T> klass) {
+ final Pair<Intent, ActivityOptions> args =
+ SetRequestedOrientationRule.buildFullScreenLaunchArgs(klass);
+ final T activity = (T) InstrumentationRegistry.getInstrumentation()
+ .startActivitySync(args.first, args.second.toBundle());
+ mActivities.add(activity);
+ return activity;
+ }
+
+ @Override
+ protected void after() {
+ if (mActivities.isEmpty()) return;
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ for (final Activity activity : mActivities) {
+ activity.finish();
+ }
+ });
+ }
+ }
@Rule
- public ActivityTestRule<PixelCopyViewProducerDialogActivity> mDialogSourceActivityRule =
- new ActivityTestRule<>(PixelCopyViewProducerDialogActivity.class, false, false);
+ public FullscreenActivityRule mFullscreenActivityRule = new FullscreenActivityRule();
@Rule
public SurfaceTextureRule mSurfaceRule = new SurfaceTextureRule();
@@ -125,24 +141,6 @@ public class PixelCopyTest {
mCopyHelper = new SynchronousPixelCopy();
}
- /**
- * Helper method used to execute a runnable that enables the
- * {@link Activity#setRequestedOrientation} API.
- *
- * On Android 12L large screen devices ignore requests to the setRequestedOrientation.
- * So in order to support test cases that rely on this API, use
- * {@link IgnoreOrientationRequestSession} to temporarily enable the setRequestedOrientation API
- */
- private void withRequestedOrientationsEnabled(Runnable runnable) {
- IgnoreOrientationRequestSession session = new IgnoreOrientationRequestSession(
- false /* enable setRequestedOrientation */);
- try {
- runnable.run();
- } finally {
- session.close();
- }
- }
-
@Test(expected = IllegalArgumentException.class)
public void testNullDest() {
Bitmap dest = null;
@@ -313,370 +311,327 @@ public class PixelCopyTest {
assertNotEquals(generationId, bitmap.getGenerationId());
}
- private Window waitForWindowProducerActivity() {
- PixelCopyViewProducerActivity activity =
- mWindowSourceActivityRule.launchActivity(null);
+ private PixelCopyViewProducerActivity waitForWindowProducerActivity() {
+ PixelCopyViewProducerActivity activity = mFullscreenActivityRule.launch(
+ PixelCopyViewProducerActivity.class);
activity.waitForFirstDrawCompleted(10, TimeUnit.SECONDS);
- return activity.getWindow();
+ return activity;
}
- private Rect makeWindowRect(int left, int top, int right, int bottom) {
+ private Rect makeWindowRect(
+ PixelCopyViewProducerActivity activity, int left, int top, int right, int bottom) {
Rect r = new Rect(left, top, right, bottom);
- mWindowSourceActivityRule.getActivity().normalizedToSurface(r);
+ activity.normalizedToSurface(r);
return r;
}
@Test
public void testWindowProducer() {
- withRequestedOrientationsEnabled(() -> {
- Bitmap bitmap;
- Window window = waitForWindowProducerActivity();
- PixelCopyViewProducerActivity activity = mWindowSourceActivityRule.getActivity();
- do {
- Rect src = makeWindowRect(0, 0, 100, 100);
- bitmap = Bitmap.createBitmap(src.width(), src.height(), Config.ARGB_8888);
- int result = mCopyHelper.request(window, src, bitmap);
- assertEquals("Fullsize copy request failed", PixelCopy.SUCCESS, result);
- assertEquals(Config.ARGB_8888, bitmap.getConfig());
- assertBitmapQuadColor(bitmap,
- Color.RED, Color.GREEN, Color.BLUE, Color.BLACK);
- assertBitmapEdgeColor(bitmap, Color.YELLOW);
- } while (activity.rotate());
- });
+ PixelCopyViewProducerActivity activity = waitForWindowProducerActivity();
+ do {
+ Rect src = makeWindowRect(activity, 0, 0, 100, 100);
+ Bitmap bitmap = Bitmap.createBitmap(src.width(), src.height(), Config.ARGB_8888);
+ int result = mCopyHelper.request(activity.getWindow(), src, bitmap);
+ assertEquals("Fullsize copy request failed", PixelCopy.SUCCESS, result);
+ assertEquals(Config.ARGB_8888, bitmap.getConfig());
+ assertBitmapQuadColor(bitmap,
+ Color.RED, Color.GREEN, Color.BLUE, Color.BLACK);
+ assertBitmapEdgeColor(bitmap, Color.YELLOW);
+ } while (activity.rotate());
}
@Test
public void testWindowProducerCropTopLeft() {
- withRequestedOrientationsEnabled(() -> {
- Window window = waitForWindowProducerActivity();
- Bitmap bitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
- PixelCopyViewProducerActivity activity = mWindowSourceActivityRule.getActivity();
- do {
- int result = mCopyHelper.request(window, makeWindowRect(0, 0, 50, 50), bitmap);
- assertEquals("Scaled copy request failed", PixelCopy.SUCCESS, result);
- assertBitmapQuadColor(bitmap,
- Color.RED, Color.RED, Color.RED, Color.RED);
- } while (activity.rotate());
- });
+ PixelCopyViewProducerActivity activity = waitForWindowProducerActivity();
+ Bitmap bitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
+ do {
+ int result = mCopyHelper.request(
+ activity.getWindow(), makeWindowRect(activity, 0, 0, 50, 50), bitmap);
+ assertEquals("Scaled copy request failed", PixelCopy.SUCCESS, result);
+ assertBitmapQuadColor(bitmap,
+ Color.RED, Color.RED, Color.RED, Color.RED);
+ } while (activity.rotate());
}
@Test
public void testWindowProducerCropCenter() {
- withRequestedOrientationsEnabled(() -> {
- Window window = waitForWindowProducerActivity();
- Bitmap bitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
- PixelCopyViewProducerActivity activity = mWindowSourceActivityRule.getActivity();
- do {
- int result = mCopyHelper.request(window, makeWindowRect(25, 25, 75, 75), bitmap);
- assertEquals("Scaled copy request failed", PixelCopy.SUCCESS, result);
- assertBitmapQuadColor(bitmap,
- Color.RED, Color.GREEN, Color.BLUE, Color.BLACK);
- } while (activity.rotate());
- });
+ PixelCopyViewProducerActivity activity = waitForWindowProducerActivity();
+ Bitmap bitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
+ do {
+ int result = mCopyHelper.request(
+ activity.getWindow(), makeWindowRect(activity, 25, 25, 75, 75), bitmap);
+ assertEquals("Scaled copy request failed", PixelCopy.SUCCESS, result);
+ assertBitmapQuadColor(bitmap,
+ Color.RED, Color.GREEN, Color.BLUE, Color.BLACK);
+ } while (activity.rotate());
}
@Test
public void testWindowProducerCropBottomHalf() {
- withRequestedOrientationsEnabled(() -> {
- Window window = waitForWindowProducerActivity();
- Bitmap bitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
- PixelCopyViewProducerActivity activity = mWindowSourceActivityRule.getActivity();
- do {
- int result = mCopyHelper.request(window, makeWindowRect(0, 50, 100, 100), bitmap);
- assertEquals("Scaled copy request failed", PixelCopy.SUCCESS, result);
- assertBitmapQuadColor(bitmap,
- Color.BLUE, Color.BLACK, Color.BLUE, Color.BLACK);
- } while (activity.rotate());
- });
+ PixelCopyViewProducerActivity activity = waitForWindowProducerActivity();
+ Bitmap bitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
+ do {
+ int result = mCopyHelper.request(
+ activity.getWindow(), makeWindowRect(activity, 0, 50, 100, 100), bitmap);
+ assertEquals("Scaled copy request failed", PixelCopy.SUCCESS, result);
+ assertBitmapQuadColor(bitmap,
+ Color.BLUE, Color.BLACK, Color.BLUE, Color.BLACK);
+ } while (activity.rotate());
}
@Test
public void testWindowProducerScaling() {
- withRequestedOrientationsEnabled(() -> {
- // Since we only sample mid-pixel of each qudrant, filtering
- // quality isn't tested
- Window window = waitForWindowProducerActivity();
- Bitmap bitmap = Bitmap.createBitmap(20, 20, Config.ARGB_8888);
- PixelCopyViewProducerActivity activity = mWindowSourceActivityRule.getActivity();
- do {
- int result = mCopyHelper.request(window, bitmap);
- assertEquals("Scaled copy request failed", PixelCopy.SUCCESS, result);
- // Make sure nothing messed with the bitmap
- assertEquals(20, bitmap.getWidth());
- assertEquals(20, bitmap.getHeight());
- assertEquals(Config.ARGB_8888, bitmap.getConfig());
- assertBitmapQuadColor(bitmap,
- Color.RED, Color.GREEN, Color.BLUE, Color.BLACK);
- } while (activity.rotate());
- });
+ // Since we only sample mid-pixel of each qudrant, filtering
+ // quality isn't tested
+ PixelCopyViewProducerActivity activity = waitForWindowProducerActivity();
+ Bitmap bitmap = Bitmap.createBitmap(20, 20, Config.ARGB_8888);
+ do {
+ int result = mCopyHelper.request(activity.getWindow(), bitmap);
+ assertEquals("Scaled copy request failed", PixelCopy.SUCCESS, result);
+ // Make sure nothing messed with the bitmap
+ assertEquals(20, bitmap.getWidth());
+ assertEquals(20, bitmap.getHeight());
+ assertEquals(Config.ARGB_8888, bitmap.getConfig());
+ assertBitmapQuadColor(bitmap,
+ Color.RED, Color.GREEN, Color.BLUE, Color.BLACK);
+ } while (activity.rotate());
}
@Test
public void testWindowProducerCopyToRGBA16F() {
- withRequestedOrientationsEnabled(() -> {
- Window window = waitForWindowProducerActivity();
- PixelCopyViewProducerActivity activity = mWindowSourceActivityRule.getActivity();
-
- Bitmap bitmap;
- do {
- Rect src = makeWindowRect(0, 0, 100, 100);
- bitmap = Bitmap.createBitmap(src.width(), src.height(), Config.RGBA_F16);
- int result = mCopyHelper.request(window, src, bitmap);
- // On OpenGL ES 2.0 devices a copy to RGBA_F16 can fail because there's
- // not support for float textures
- if (result != PixelCopy.ERROR_DESTINATION_INVALID) {
- assertEquals("Fullsize copy request failed", PixelCopy.SUCCESS, result);
- assertEquals(Config.RGBA_F16, bitmap.getConfig());
- assertBitmapQuadColor(bitmap,
- Color.RED, Color.GREEN, Color.BLUE, Color.BLACK);
- assertBitmapEdgeColor(bitmap, Color.YELLOW);
- }
- } while (activity.rotate());
- });
+ PixelCopyViewProducerActivity activity = waitForWindowProducerActivity();
+ do {
+ Rect src = makeWindowRect(activity, 0, 0, 100, 100);
+ Bitmap bitmap = Bitmap.createBitmap(src.width(), src.height(), Config.RGBA_F16);
+ int result = mCopyHelper.request(activity.getWindow(), src, bitmap);
+ // On OpenGL ES 2.0 devices a copy to RGBA_F16 can fail because there's
+ // not support for float textures
+ if (result != PixelCopy.ERROR_DESTINATION_INVALID) {
+ assertEquals("Fullsize copy request failed", PixelCopy.SUCCESS, result);
+ assertEquals(Config.RGBA_F16, bitmap.getConfig());
+ assertBitmapQuadColor(bitmap,
+ Color.RED, Color.GREEN, Color.BLUE, Color.BLACK);
+ assertBitmapEdgeColor(bitmap, Color.YELLOW);
+ }
+ } while (activity.rotate());
}
- private Window waitForWideGamutWindowProducerActivity() {
- PixelCopyWideGamutViewProducerActivity activity =
- mWideGamutWindowSourceActivityRule.launchActivity(null);
+ private PixelCopyWideGamutViewProducerActivity waitForWideGamutWindowProducerActivity() {
+ PixelCopyWideGamutViewProducerActivity activity = mFullscreenActivityRule.launch(
+ PixelCopyWideGamutViewProducerActivity.class);
activity.waitForFirstDrawCompleted(10, TimeUnit.SECONDS);
- return activity.getWindow();
+ return activity;
}
- private Rect makeWideGamutWindowRect(int left, int top, int right, int bottom) {
+ private Rect makeWideGamutWindowRect(
+ PixelCopyWideGamutViewProducerActivity activity,
+ int left, int top, int right, int bottom) {
Rect r = new Rect(left, top, right, bottom);
- mWideGamutWindowSourceActivityRule.getActivity().offsetForContent(r);
+ activity.offsetForContent(r);
return r;
}
@Test
public void testWideGamutWindowProducerCopyToRGBA8888() {
- withRequestedOrientationsEnabled(() -> {
- Window window = waitForWideGamutWindowProducerActivity();
- assertEquals(
- ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT,
- window.getAttributes().getColorMode()
- );
-
- // Early out if the device does not support wide color gamut rendering
- if (!window.isWideColorGamut()) {
- return;
- }
+ PixelCopyWideGamutViewProducerActivity activity = waitForWideGamutWindowProducerActivity();
+ assertEquals(
+ ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT,
+ activity.getWindow().getAttributes().getColorMode()
+ );
+
+ // Early out if the device does not support wide color gamut rendering
+ if (!activity.getWindow().isWideColorGamut()) {
+ return;
+ }
- PixelCopyWideGamutViewProducerActivity activity =
- mWideGamutWindowSourceActivityRule.getActivity();
+ do {
+ Rect src = makeWideGamutWindowRect(activity, 0, 0, 128, 128);
+ Bitmap bitmap = Bitmap.createBitmap(src.width(), src.height(), Config.ARGB_8888);
+ int result = mCopyHelper.request(activity.getWindow(), src, bitmap);
- Bitmap bitmap;
- do {
- Rect src = makeWideGamutWindowRect(0, 0, 128, 128);
- bitmap = Bitmap.createBitmap(src.width(), src.height(), Config.ARGB_8888);
- int result = mCopyHelper.request(window, src, bitmap);
-
- assertEquals("Fullsize copy request failed", PixelCopy.SUCCESS, result);
- assertEquals(Config.ARGB_8888, bitmap.getConfig());
+ assertEquals("Fullsize copy request failed", PixelCopy.SUCCESS, result);
+ assertEquals(Config.ARGB_8888, bitmap.getConfig());
- assertEquals("Top left", Color.RED, bitmap.getPixel(32, 32));
- assertEquals("Top right", Color.GREEN, bitmap.getPixel(96, 32));
- assertEquals("Bottom left", Color.BLUE, bitmap.getPixel(32, 96));
- assertEquals("Bottom right", Color.YELLOW, bitmap.getPixel(96, 96));
- } while (activity.rotate());
- });
+ assertEquals("Top left", Color.RED, bitmap.getPixel(32, 32));
+ assertEquals("Top right", Color.GREEN, bitmap.getPixel(96, 32));
+ assertEquals("Bottom left", Color.BLUE, bitmap.getPixel(32, 96));
+ assertEquals("Bottom right", Color.YELLOW, bitmap.getPixel(96, 96));
+ } while (activity.rotate());
}
@Test
public void testWideGamutWindowProducerCopyToRGBA16F() {
- withRequestedOrientationsEnabled(() -> {
- Window window = waitForWideGamutWindowProducerActivity();
- assertEquals(
- ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT,
- window.getAttributes().getColorMode()
- );
-
- // Early out if the device does not support wide color gamut rendering
- if (!window.isWideColorGamut()) {
- return;
- }
-
- PixelCopyWideGamutViewProducerActivity activity =
- mWideGamutWindowSourceActivityRule.getActivity();
- final WindowManager windowManager = (WindowManager) activity.getSystemService(
- Context.WINDOW_SERVICE);
- final ColorSpace colorSpace = windowManager.getDefaultDisplay()
- .getPreferredWideGamutColorSpace();
- final ColorSpace.Connector proPhotoToDisplayWideColorSpace = ColorSpace.connect(
- ColorSpace.get(ColorSpace.Named.PRO_PHOTO_RGB), colorSpace);
- final ColorSpace.Connector displayWideColorSpaceToExtendedSrgb = ColorSpace.connect(
- colorSpace, ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB));
-
- final float[] intermediateRed =
- proPhotoToDisplayWideColorSpace.transform(1.0f, 0.0f, 0.0f);
- final float[] intermediateGreen = proPhotoToDisplayWideColorSpace
- .transform(0.0f, 1.0f, 0.0f);
- final float[] intermediateBlue = proPhotoToDisplayWideColorSpace
- .transform(0.0f, 0.0f, 1.0f);
- final float[] intermediateYellow = proPhotoToDisplayWideColorSpace
- .transform(1.0f, 1.0f, 0.0f);
-
- final float[] expectedRed =
- displayWideColorSpaceToExtendedSrgb.transform(intermediateRed);
- final float[] expectedGreen = displayWideColorSpaceToExtendedSrgb
- .transform(intermediateGreen);
- final float[] expectedBlue = displayWideColorSpaceToExtendedSrgb
- .transform(intermediateBlue);
- final float[] expectedYellow = displayWideColorSpaceToExtendedSrgb
- .transform(intermediateYellow);
-
- Bitmap bitmap;
- int i = 0;
- do {
- Rect src = makeWideGamutWindowRect(0, 0, 128, 128);
- bitmap = Bitmap.createBitmap(src.width(), src.height(), Config.RGBA_F16,
- true, ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB));
- int result = mCopyHelper.request(window, src, bitmap);
-
- assertEquals("Fullsize copy request failed", PixelCopy.SUCCESS, result);
- assertEquals(Config.RGBA_F16, bitmap.getConfig());
+ PixelCopyWideGamutViewProducerActivity activity = waitForWideGamutWindowProducerActivity();
+ assertEquals(
+ ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT,
+ activity.getWindow().getAttributes().getColorMode()
+ );
+
+ // Early out if the device does not support wide color gamut rendering
+ if (!activity.getWindow().isWideColorGamut()) {
+ return;
+ }
- ByteBuffer dst = ByteBuffer.allocateDirect(bitmap.getAllocationByteCount());
- bitmap.copyPixelsToBuffer(dst);
- dst.rewind();
- dst.order(ByteOrder.LITTLE_ENDIAN);
-
- // ProPhoto RGB red in scRGB-nl
- assertEqualsRgba16f("Top left", bitmap, 32, 32, dst, expectedRed[0],
- expectedRed[1], expectedRed[2], 1.0f);
- // ProPhoto RGB green in scRGB-nl
- assertEqualsRgba16f("Top right", bitmap, 96, 32, dst,
- expectedGreen[0], expectedGreen[1], expectedGreen[2], 1.0f);
- // ProPhoto RGB blue in scRGB-nl
- assertEqualsRgba16f("Bottom left", bitmap, 32, 96, dst,
- expectedBlue[0], expectedBlue[1], expectedBlue[2], 1.0f);
- // ProPhoto RGB yellow in scRGB-nl
- assertEqualsRgba16f("Bottom right", bitmap, 96, 96, dst,
- expectedYellow[0], expectedYellow[1], expectedYellow[2], 1.0f);
- } while (activity.rotate());
- });
+ final WindowManager windowManager = (WindowManager) activity.getSystemService(
+ Context.WINDOW_SERVICE);
+ final ColorSpace colorSpace = windowManager.getDefaultDisplay()
+ .getPreferredWideGamutColorSpace();
+ final ColorSpace.Connector proPhotoToDisplayWideColorSpace = ColorSpace.connect(
+ ColorSpace.get(ColorSpace.Named.PRO_PHOTO_RGB), colorSpace);
+ final ColorSpace.Connector displayWideColorSpaceToExtendedSrgb = ColorSpace.connect(
+ colorSpace, ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB));
+
+ final float[] intermediateRed =
+ proPhotoToDisplayWideColorSpace.transform(1.0f, 0.0f, 0.0f);
+ final float[] intermediateGreen = proPhotoToDisplayWideColorSpace
+ .transform(0.0f, 1.0f, 0.0f);
+ final float[] intermediateBlue = proPhotoToDisplayWideColorSpace
+ .transform(0.0f, 0.0f, 1.0f);
+ final float[] intermediateYellow = proPhotoToDisplayWideColorSpace
+ .transform(1.0f, 1.0f, 0.0f);
+
+ final float[] expectedRed =
+ displayWideColorSpaceToExtendedSrgb.transform(intermediateRed);
+ final float[] expectedGreen = displayWideColorSpaceToExtendedSrgb
+ .transform(intermediateGreen);
+ final float[] expectedBlue = displayWideColorSpaceToExtendedSrgb
+ .transform(intermediateBlue);
+ final float[] expectedYellow = displayWideColorSpaceToExtendedSrgb
+ .transform(intermediateYellow);
+
+ do {
+ Rect src = makeWideGamutWindowRect(activity, 0, 0, 128, 128);
+ Bitmap bitmap = Bitmap.createBitmap(src.width(), src.height(), Config.RGBA_F16,
+ true, ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB));
+ int result = mCopyHelper.request(activity.getWindow(), src, bitmap);
+
+ assertEquals("Fullsize copy request failed", PixelCopy.SUCCESS, result);
+ assertEquals(Config.RGBA_F16, bitmap.getConfig());
+
+ ByteBuffer dst = ByteBuffer.allocateDirect(bitmap.getAllocationByteCount());
+ bitmap.copyPixelsToBuffer(dst);
+ dst.rewind();
+ dst.order(ByteOrder.LITTLE_ENDIAN);
+
+ // ProPhoto RGB red in scRGB-nl
+ assertEqualsRgba16f("Top left", bitmap, 32, 32, dst, expectedRed[0],
+ expectedRed[1], expectedRed[2], 1.0f);
+ // ProPhoto RGB green in scRGB-nl
+ assertEqualsRgba16f("Top right", bitmap, 96, 32, dst,
+ expectedGreen[0], expectedGreen[1], expectedGreen[2], 1.0f);
+ // ProPhoto RGB blue in scRGB-nl
+ assertEqualsRgba16f("Bottom left", bitmap, 32, 96, dst,
+ expectedBlue[0], expectedBlue[1], expectedBlue[2], 1.0f);
+ // ProPhoto RGB yellow in scRGB-nl
+ assertEqualsRgba16f("Bottom right", bitmap, 96, 96, dst,
+ expectedYellow[0], expectedYellow[1], expectedYellow[2], 1.0f);
+ } while (activity.rotate());
}
- private Window waitForDialogProducerActivity() {
- PixelCopyViewProducerActivity activity =
- mDialogSourceActivityRule.launchActivity(null);
+ private PixelCopyViewProducerDialogActivity waitForDialogProducerActivity() {
+ PixelCopyViewProducerDialogActivity activity = mFullscreenActivityRule.launch(
+ PixelCopyViewProducerDialogActivity.class);
activity.waitForFirstDrawCompleted(10, TimeUnit.SECONDS);
- return activity.getWindow();
+ return activity;
}
- private Rect makeDialogRect(int left, int top, int right, int bottom) {
+ private Rect makeDialogRect(
+ PixelCopyViewProducerDialogActivity activity,
+ int left, int top, int right, int bottom) {
Rect r = new Rect(left, top, right, bottom);
- mDialogSourceActivityRule.getActivity().normalizedToSurface(r);
+ activity.normalizedToSurface(r);
return r;
}
@Test
public void testDialogProducer() {
- withRequestedOrientationsEnabled(() -> {
- Bitmap bitmap;
- Window window = waitForDialogProducerActivity();
- PixelCopyViewProducerActivity activity = mDialogSourceActivityRule.getActivity();
- do {
- Rect src = makeDialogRect(0, 0, 100, 100);
- bitmap = Bitmap.createBitmap(src.width(), src.height(), Config.ARGB_8888);
- int result = mCopyHelper.request(window, src, bitmap);
- assertEquals("Fullsize copy request failed", PixelCopy.SUCCESS, result);
- assertEquals(Config.ARGB_8888, bitmap.getConfig());
- assertBitmapQuadColor(bitmap,
- Color.RED, Color.GREEN, Color.BLUE, Color.BLACK);
- assertBitmapEdgeColor(bitmap, Color.YELLOW);
- } while (activity.rotate());
- });
+ PixelCopyViewProducerDialogActivity activity = waitForDialogProducerActivity();
+ do {
+ Rect src = makeDialogRect(activity, 0, 0, 100, 100);
+ Bitmap bitmap = Bitmap.createBitmap(src.width(), src.height(), Config.ARGB_8888);
+ int result = mCopyHelper.request(activity.getWindow(), src, bitmap);
+ assertEquals("Fullsize copy request failed", PixelCopy.SUCCESS, result);
+ assertEquals(Config.ARGB_8888, bitmap.getConfig());
+ assertBitmapQuadColor(bitmap,
+ Color.RED, Color.GREEN, Color.BLUE, Color.BLACK);
+ assertBitmapEdgeColor(bitmap, Color.YELLOW);
+ } while (activity.rotate());
}
@Test
public void testDialogProducerCropTopLeft() {
- withRequestedOrientationsEnabled(() -> {
- Window window = waitForDialogProducerActivity();
- Bitmap bitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
- PixelCopyViewProducerActivity activity = mDialogSourceActivityRule.getActivity();
- do {
- int result = mCopyHelper.request(window, makeDialogRect(0, 0, 50, 50), bitmap);
- assertEquals("Scaled copy request failed", PixelCopy.SUCCESS, result);
- assertBitmapQuadColor(bitmap,
- Color.RED, Color.RED, Color.RED, Color.RED);
- } while (activity.rotate());
- });
+ PixelCopyViewProducerDialogActivity activity = waitForDialogProducerActivity();
+ Bitmap bitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
+ do {
+ int result = mCopyHelper.request(
+ activity.getWindow(), makeDialogRect(activity, 0, 0, 50, 50), bitmap);
+ assertEquals("Scaled copy request failed", PixelCopy.SUCCESS, result);
+ assertBitmapQuadColor(bitmap,
+ Color.RED, Color.RED, Color.RED, Color.RED);
+ } while (activity.rotate());
}
@Test
public void testDialogProducerCropCenter() {
- withRequestedOrientationsEnabled(() -> {
- Window window = waitForDialogProducerActivity();
- Bitmap bitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
- PixelCopyViewProducerActivity activity = mDialogSourceActivityRule.getActivity();
- do {
- int result = mCopyHelper.request(window, makeDialogRect(25, 25, 75, 75), bitmap);
- assertEquals("Scaled copy request failed", PixelCopy.SUCCESS, result);
- assertBitmapQuadColor(bitmap,
- Color.RED, Color.GREEN, Color.BLUE, Color.BLACK);
- } while (activity.rotate());
- });
+ PixelCopyViewProducerDialogActivity activity = waitForDialogProducerActivity();
+ Bitmap bitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
+ do {
+ int result = mCopyHelper.request(
+ activity.getWindow(), makeDialogRect(activity, 25, 25, 75, 75), bitmap);
+ assertEquals("Scaled copy request failed", PixelCopy.SUCCESS, result);
+ assertBitmapQuadColor(bitmap,
+ Color.RED, Color.GREEN, Color.BLUE, Color.BLACK);
+ } while (activity.rotate());
}
@Test
public void testDialogProducerCropBottomHalf() {
- withRequestedOrientationsEnabled(() -> {
- Window window = waitForDialogProducerActivity();
- Bitmap bitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
- PixelCopyViewProducerActivity activity = mDialogSourceActivityRule.getActivity();
- do {
- int result = mCopyHelper.request(window, makeDialogRect(0, 50, 100, 100), bitmap);
- assertEquals("Scaled copy request failed", PixelCopy.SUCCESS, result);
- assertBitmapQuadColor(bitmap,
- Color.BLUE, Color.BLACK, Color.BLUE, Color.BLACK);
- } while (activity.rotate());
- });
+ PixelCopyViewProducerDialogActivity activity = waitForDialogProducerActivity();
+ Bitmap bitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
+ do {
+ int result = mCopyHelper.request(
+ activity.getWindow(), makeDialogRect(activity, 0, 50, 100, 100), bitmap);
+ assertEquals("Scaled copy request failed", PixelCopy.SUCCESS, result);
+ assertBitmapQuadColor(bitmap,
+ Color.BLUE, Color.BLACK, Color.BLUE, Color.BLACK);
+ } while (activity.rotate());
}
@Test
public void testDialogProducerScaling() {
- withRequestedOrientationsEnabled(() -> {
- // Since we only sample mid-pixel of each qudrant, filtering
- // quality isn't tested
- Window window = waitForDialogProducerActivity();
- Bitmap bitmap = Bitmap.createBitmap(20, 20, Config.ARGB_8888);
- PixelCopyViewProducerActivity activity = mDialogSourceActivityRule.getActivity();
- do {
- int result = mCopyHelper.request(window, bitmap);
- assertEquals("Scaled copy request failed", PixelCopy.SUCCESS, result);
- // Make sure nothing messed with the bitmap
- assertEquals(20, bitmap.getWidth());
- assertEquals(20, bitmap.getHeight());
- assertEquals(Config.ARGB_8888, bitmap.getConfig());
- assertBitmapQuadColor(bitmap,
- Color.RED, Color.GREEN, Color.BLUE, Color.BLACK);
- } while (activity.rotate());
- });
+ // Since we only sample mid-pixel of each qudrant, filtering
+ // quality isn't tested
+ PixelCopyViewProducerDialogActivity activity = waitForDialogProducerActivity();
+ Bitmap bitmap = Bitmap.createBitmap(20, 20, Config.ARGB_8888);
+ do {
+ int result = mCopyHelper.request(activity.getWindow(), bitmap);
+ assertEquals("Scaled copy request failed", PixelCopy.SUCCESS, result);
+ // Make sure nothing messed with the bitmap
+ assertEquals(20, bitmap.getWidth());
+ assertEquals(20, bitmap.getHeight());
+ assertEquals(Config.ARGB_8888, bitmap.getConfig());
+ assertBitmapQuadColor(bitmap,
+ Color.RED, Color.GREEN, Color.BLUE, Color.BLACK);
+ } while (activity.rotate());
}
@Test
public void testDialogProducerCopyToRGBA16F() {
- withRequestedOrientationsEnabled(() -> {
- Window window = waitForDialogProducerActivity();
- PixelCopyViewProducerActivity activity = mDialogSourceActivityRule.getActivity();
-
- Bitmap bitmap;
- do {
- Rect src = makeDialogRect(0, 0, 100, 100);
- bitmap = Bitmap.createBitmap(src.width(), src.height(), Config.RGBA_F16);
- int result = mCopyHelper.request(window, src, bitmap);
- // On OpenGL ES 2.0 devices a copy to RGBA_F16 can fail because there's
- // not support for float textures
- if (result != PixelCopy.ERROR_DESTINATION_INVALID) {
- assertEquals("Fullsize copy request failed", PixelCopy.SUCCESS, result);
- assertEquals(Config.RGBA_F16, bitmap.getConfig());
- assertBitmapQuadColor(bitmap,
- Color.RED, Color.GREEN, Color.BLUE, Color.BLACK);
- assertBitmapEdgeColor(bitmap, Color.YELLOW);
- }
- } while (activity.rotate());
- });
+ PixelCopyViewProducerDialogActivity activity = waitForDialogProducerActivity();
+ do {
+ Rect src = makeDialogRect(activity, 0, 0, 100, 100);
+ Bitmap bitmap = Bitmap.createBitmap(src.width(), src.height(), Config.RGBA_F16);
+ int result = mCopyHelper.request(activity.getWindow(), src, bitmap);
+ // On OpenGL ES 2.0 devices a copy to RGBA_F16 can fail because there's
+ // not support for float textures
+ if (result != PixelCopy.ERROR_DESTINATION_INVALID) {
+ assertEquals("Fullsize copy request failed", PixelCopy.SUCCESS, result);
+ assertEquals(Config.RGBA_F16, bitmap.getConfig());
+ assertBitmapQuadColor(bitmap,
+ Color.RED, Color.GREEN, Color.BLUE, Color.BLACK);
+ assertBitmapEdgeColor(bitmap, Color.YELLOW);
+ }
+ } while (activity.rotate());
}
private static void assertEqualsRgba16f(String message, Bitmap bitmap, int x, int y,
diff --git a/tests/tests/view/src/android/view/cts/TextureViewTest.java b/tests/tests/view/src/android/view/cts/TextureViewTest.java
index 83d794435a1..a72703fd269 100644
--- a/tests/tests/view/src/android/view/cts/TextureViewTest.java
+++ b/tests/tests/view/src/android/view/cts/TextureViewTest.java
@@ -295,6 +295,7 @@ public class TextureViewTest {
// paint surfaceView layer
SurfaceView surfaceView = activity.getSurfaceView();
+ final CountDownLatch latch = new CountDownLatch(1);
surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
@@ -303,18 +304,32 @@ public class TextureViewTest {
.setHardwareBufferFormat(PixelFormat.RGBA_8888)
.setDataSpace(dataSpace)
.build();
- Image image = writer.dequeueInputImage();
- assertEquals(dataSpace, image.getDataSpace());
- Image.Plane plane = image.getPlanes()[0];
- Bitmap bitmap = Bitmap.createBitmap(plane.getRowStride() / 4, image.getHeight(),
- Bitmap.Config.ARGB_8888, true, ColorSpace.getFromDataSpace(dataSpace));
- Canvas canvas = new Canvas(bitmap);
- Paint paint = new Paint();
- paint.setAntiAlias(false);
- paint.setColor(converted);
- canvas.drawRect(0f, 0f, width, height, paint);
- bitmap.copyPixelsToBuffer(plane.getBuffer());
- writer.queueInputImage(image);
+ // spawn a thread here to iterate 10 times from image dequeue to queue
+ // so that we can be stalled until the first frame has been displayed.
+ new Thread(() -> {
+ Bitmap bitmap = null;
+ for (int i = 0; i < 10; i++) {
+ Image image = writer.dequeueInputImage();
+ assertEquals(dataSpace, image.getDataSpace());
+ Image.Plane plane = image.getPlanes()[0];
+ // only make bitmap the first time to improve the performation
+ // if the bitmap is large.
+ if (bitmap == null) {
+ bitmap = Bitmap.createBitmap(plane.getRowStride() / 4,
+ image.getHeight(),
+ Bitmap.Config.ARGB_8888, true,
+ ColorSpace.getFromDataSpace(dataSpace));
+ Canvas canvas = new Canvas(bitmap);
+ Paint paint = new Paint();
+ paint.setAntiAlias(false);
+ paint.setColor(converted);
+ canvas.drawRect(0f, 0f, width, height, paint);
+ }
+ bitmap.copyPixelsToBuffer(plane.getBuffer());
+ writer.queueInputImage(image);
+ }
+ latch.countDown();
+ }).start();
}
@Override
@@ -329,9 +344,8 @@ public class TextureViewTest {
activity.setContentView(surfaceView);
});
- // wait here to ensure SF has latched the buffer that has been queued in
- // this is the easiest way to solve copy failure but sacrifice the performance.
- Thread.sleep(100);
+ assertTrue(latch.await(5, TimeUnit.SECONDS));
+
Bitmap surfaceViewScreenshot = mInstrumentation
.getUiAutomation()
.takeScreenshot(activity.getWindow());
@@ -374,7 +388,19 @@ public class TextureViewTest {
WidgetTestUtils.runOnMainAndDrawSync(
mSDRActivityRule, textureView, () -> textureView.getBitmap(textureViewScreenshot));
- assertTrue(textureViewScreenshot.sameAs(surfaceViewScreenshot));
+ // sample 5 pixels on the edge for bitmap comparison.
+ // TextureView and SurfaceView use different shaders, so compare these two with tolerance.
+ final int threshold = 2;
+ assertTrue(pixelsAreSame(surfaceViewScreenshot.getPixel(width / 2, 0),
+ textureViewScreenshot.getPixel(width / 2, 0), threshold));
+ assertTrue(pixelsAreSame(surfaceViewScreenshot.getPixel(0, height / 2),
+ textureViewScreenshot.getPixel(0, height / 2), threshold));
+ assertTrue(pixelsAreSame(surfaceViewScreenshot.getPixel(width / 2, height / 2),
+ textureViewScreenshot.getPixel(width / 2, height / 2), threshold));
+ assertTrue(pixelsAreSame(surfaceViewScreenshot.getPixel(width / 2, height - 1),
+ textureViewScreenshot.getPixel(width / 2, height - 1), threshold));
+ assertTrue(pixelsAreSame(surfaceViewScreenshot.getPixel(width - 1, height / 2),
+ textureViewScreenshot.getPixel(width - 1, height / 2), threshold));
}
@Test
diff --git a/tests/tests/view/src/android/view/cts/View_UsingViewsTest.java b/tests/tests/view/src/android/view/cts/View_UsingViewsTest.java
index fa4833c1f06..8326962ab27 100644
--- a/tests/tests/view/src/android/view/cts/View_UsingViewsTest.java
+++ b/tests/tests/view/src/android/view/cts/View_UsingViewsTest.java
@@ -392,15 +392,17 @@ public class View_UsingViewsTest {
CtsTouchUtils.emulateLongPressOnViewCenter(mInstrumentation, mActivityRule, mEditText);
verify(onLongClickListener, within(1000)).onLongClick(mEditText);
+ // Wait for the UI Thread to become idle.
+ final UiDevice device = UiDevice.getInstance(mInstrumentation);
+
// click the Cancel button
mActivityRule.runOnUiThread(() -> mEditText.setText("Germany"));
mInstrumentation.waitForIdleSync();
+ device.waitForIdle();
CtsTouchUtils.emulateTapOnViewCenter(mInstrumentation, mActivityRule, mButtonCancel);
assertEquals("", mEditText.getText().toString());
- // Wait for the UI Thread to become idle.
- final UiDevice device = UiDevice.getInstance(mInstrumentation);
mInstrumentation.waitForIdleSync();
device.waitForIdle();
diff --git a/tests/tests/voiceRecognition/src/android/voicerecognition/cts/RecognitionServiceMicIndicatorTest.java b/tests/tests/voiceRecognition/src/android/voicerecognition/cts/RecognitionServiceMicIndicatorTest.java
index c9ca1bd8ece..df2446c27d2 100644
--- a/tests/tests/voiceRecognition/src/android/voicerecognition/cts/RecognitionServiceMicIndicatorTest.java
+++ b/tests/tests/voiceRecognition/src/android/voicerecognition/cts/RecognitionServiceMicIndicatorTest.java
@@ -48,6 +48,7 @@ import com.android.compatibility.common.util.SettingsStateChangerRule;
import org.junit.After;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -191,6 +192,7 @@ public final class RecognitionServiceMicIndicatorTest {
testVoiceRecognitionServiceBlameCallingApp(/* trustVoiceService */ false);
}
+ @Ignore("b/266789512")
@Test
public void testTrustedRecognitionServiceCanBlameCallingApp() throws Throwable {
// We treat trusted if the current voice recognizer is also a preinstalled app. This is a
diff --git a/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/HotwordDetectionServiceBasicTest.java b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/HotwordDetectionServiceBasicTest.java
index 767143ce802..5c1e926392f 100644
--- a/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/HotwordDetectionServiceBasicTest.java
+++ b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/HotwordDetectionServiceBasicTest.java
@@ -434,6 +434,8 @@ public final class HotwordDetectionServiceBasicTest
// TODO ntmyren: test TV indicator
} else if (sPkgMgr.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
// TODO ntmyren: test Auto indicator
+ } else if (sPkgMgr.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+ // The privacy chips/indicators are not implemented on Wear
} else {
verifyMicrophoneChipHandheld(shouldBePresent);
}
diff --git a/tests/tests/webkit/src/android/webkit/cts/CookieManagerTest.java b/tests/tests/webkit/src/android/webkit/cts/CookieManagerTest.java
index bc4018adfeb..0c63294eef9 100644
--- a/tests/tests/webkit/src/android/webkit/cts/CookieManagerTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/CookieManagerTest.java
@@ -23,7 +23,6 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
-import android.content.Context;
import android.platform.test.annotations.AppModeFull;
import android.webkit.CookieManager;
import android.webkit.ValueCallback;
@@ -32,7 +31,6 @@ import android.webkit.WebView;
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.NullWebViewUtils;
import com.android.compatibility.common.util.PollingCheck;
@@ -54,12 +52,12 @@ import java.util.regex.Pattern;
@AppModeFull
@MediumTest
@RunWith(AndroidJUnit4.class)
-public class CookieManagerTest {
+public class CookieManagerTest extends SharedWebViewTest {
private static final int TEST_TIMEOUT = 5000;
private CookieManager mCookieManager;
private WebViewOnUiThread mOnUiThread;
- private CtsTestServer mServer;
+ private SharedSdkWebServer mWebServer;
@Rule
public ActivityScenarioRule mActivityScenarioRule =
@@ -67,15 +65,13 @@ public class CookieManagerTest {
@Before
public void setUp() throws Exception {
- Assume.assumeTrue("WebView is not available", NullWebViewUtils.isWebViewAvailable());
- mActivityScenarioRule.getScenario().onActivity(activity -> {
- CookieSyncManagerCtsActivity cookieSyncManagerCtsActivity =
- (CookieSyncManagerCtsActivity) activity;
- WebView webView = cookieSyncManagerCtsActivity.getWebView();
- if (webView != null) {
- mOnUiThread = new WebViewOnUiThread(webView);
- }
- });
+ WebView webView = getTestEnvironment().getWebView();
+ if (webView == null) {
+ return;
+ }
+
+ mOnUiThread = new WebViewOnUiThread(webView);
+
mCookieManager = CookieManager.getInstance();
assertNotNull(mCookieManager);
@@ -88,32 +84,37 @@ public class CookieManagerTest {
assertFalse(mCookieManager.acceptCookie());
}
+ @Override
+ protected SharedWebViewTestEnvironment createTestEnvironment() {
+ Assume.assumeTrue("WebView is not available", NullWebViewUtils.isWebViewAvailable());
+
+ SharedWebViewTestEnvironment.Builder builder = new SharedWebViewTestEnvironment.Builder();
+
+ mActivityScenarioRule
+ .getScenario()
+ .onActivity(
+ activity -> {
+ WebView webView = ((CookieSyncManagerCtsActivity) activity)
+ .getWebView();
+ builder.setHostAppInvoker(
+ SharedWebViewTestEnvironment.createHostAppInvoker(
+ activity))
+ .setWebView(webView);
+ });
+
+ return builder.build();
+ }
+
@After
public void tearDown() throws Exception {
- if (mServer != null) {
- mServer.shutdown();
+ if (mWebServer != null) {
+ mWebServer.shutdown();
}
if (mOnUiThread != null) {
mOnUiThread.cleanUp();
}
}
- private CtsTestServer createWebServer() throws Exception {
- Context context = InstrumentationRegistry.getInstrumentation().getContext();
- return new CtsTestServer(context);
- }
-
- private CtsTestServer createWebServer(@SslMode int sslMode) throws Exception {
- Context context = InstrumentationRegistry.getInstrumentation().getContext();
- return new CtsTestServer(context, sslMode);
- }
-
- private CtsTestServer createWebServer(@SslMode int sslMode, int keyResId, int certResId)
- throws Exception {
- Context context = InstrumentationRegistry.getInstrumentation().getContext();
- return new CtsTestServer(context, sslMode, keyResId, certResId);
- }
-
@Test
public void testGetInstance() {
mOnUiThread.cleanUp();
@@ -133,8 +134,8 @@ public class CookieManagerTest {
mCookieManager.setAcceptCookie(false);
assertFalse(mCookieManager.acceptCookie());
- mServer = createWebServer(SslMode.INSECURE);
- String url = mServer.getCookieUrl("conquest.html");
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
+ String url = mWebServer.getCookieUrl("conquest.html");
mOnUiThread.loadUrlAndWaitForCompletion(url);
assertEquals("0", mOnUiThread.getTitle()); // no cookies passed
Thread.sleep(500);
@@ -143,7 +144,7 @@ public class CookieManagerTest {
mCookieManager.setAcceptCookie(true);
assertTrue(mCookieManager.acceptCookie());
- url = mServer.getCookieUrl("war.html");
+ url = mWebServer.getCookieUrl("war.html");
mOnUiThread.loadUrlAndWaitForCompletion(url);
assertEquals("0", mOnUiThread.getTitle()); // no cookies passed
waitForCookie(url);
@@ -155,7 +156,7 @@ public class CookieManagerTest {
assertTrue(m.matches());
assertEquals("0", m.group(1));
- url = mServer.getCookieUrl("famine.html");
+ url = mWebServer.getCookieUrl("famine.html");
mOnUiThread.loadUrlAndWaitForCompletion(url);
assertEquals("1|count=0", mOnUiThread.getTitle()); // outgoing cookie
waitForCookie(url);
@@ -165,7 +166,7 @@ public class CookieManagerTest {
assertTrue(m.matches());
assertEquals("1", m.group(1)); // value got incremented
- url = mServer.getCookieUrl("death.html");
+ url = mWebServer.getCookieUrl("death.html");
mCookieManager.setCookie(url, "count=41");
mOnUiThread.loadUrlAndWaitForCompletion(url);
assertEquals("1|count=41", mOnUiThread.getTitle()); // outgoing cookie
@@ -348,7 +349,7 @@ public class CookieManagerTest {
// port. Instead we cheat making some of the urls come from localhost and some
// from 127.0.0.1 which count (both in theory and pratice) as having different
// origins.
- mServer = createWebServer();
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
// Turn on Javascript (otherwise <script> aren't fetched spoiling the test).
mOnUiThread.getSettings().setJavaScriptEnabled(true);
@@ -364,9 +365,10 @@ public class CookieManagerTest {
// ...we can't set third party cookies.
// First on the third party server we get a url which tries to set a cookie.
String cookieUrl = toThirdPartyUrl(
- mServer.getSetCookieUrl("/cookie_1.js", "test1", "value1", "SameSite=None; Secure"));
+ mWebServer.getSetCookieUrl("/cookie_1.js", "test1", "value1",
+ "SameSite=None; Secure"));
// Then we create a url on the first party server which links to the first url.
- String url = mServer.getLinkedScriptUrl("/content_1.html", cookieUrl);
+ String url = mWebServer.getLinkedScriptUrl("/content_1.html", cookieUrl);
mOnUiThread.loadUrlAndWaitForCompletion(url);
assertNull(mCookieManager.getCookie(cookieUrl));
@@ -376,8 +378,8 @@ public class CookieManagerTest {
// ...we can set third party cookies.
cookieUrl = toThirdPartyUrl(
- mServer.getSetCookieUrl("/cookie_2.js", "test2", "value2", "SameSite=None; Secure"));
- url = mServer.getLinkedScriptUrl("/content_2.html", cookieUrl);
+ mWebServer.getSetCookieUrl("/cookie_2.js", "test2", "value2", "SameSite=None; Secure"));
+ url = mWebServer.getLinkedScriptUrl("/content_2.html", cookieUrl);
mOnUiThread.loadUrlAndWaitForCompletion(url);
waitForCookie(cookieUrl);
String cookie = mCookieManager.getCookie(cookieUrl);
@@ -387,7 +389,7 @@ public class CookieManagerTest {
@Test
public void testSameSiteLaxByDefault() throws Throwable {
- mServer = createWebServer();
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
mOnUiThread.getSettings().setJavaScriptEnabled(true);
mCookieManager.setAcceptCookie(true);
mOnUiThread.setAcceptThirdPartyCookies(true);
@@ -395,40 +397,42 @@ public class CookieManagerTest {
// Verify that even with third party cookies enabled, cookies that don't explicitly
// specify SameSite=none are treated as SameSite=lax and not set in a 3P context.
String cookieUrl = toThirdPartyUrl(
- mServer.getSetCookieUrl("/cookie_1.js", "test1", "value1"));
- String url = mServer.getLinkedScriptUrl("/content_1.html", cookieUrl);
+ mWebServer.getSetCookieUrl("/cookie_1.js", "test1", "value1", null));
+ String url = mWebServer.getLinkedScriptUrl("/content_1.html", cookieUrl);
mOnUiThread.loadUrlAndWaitForCompletion(url);
assertNull(mCookieManager.getCookie(cookieUrl));
}
@Test
public void testSameSiteNoneRequiresSecure() throws Throwable {
- mServer = createWebServer();
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
mOnUiThread.getSettings().setJavaScriptEnabled(true);
mCookieManager.setAcceptCookie(true);
// Verify that cookies with SameSite=none are ignored when the cookie is not also Secure.
String cookieUrl =
- mServer.getSetCookieUrl("/cookie_1.js", "test1", "value1", "SameSite=None");
- String url = mServer.getLinkedScriptUrl("/content_1.html", cookieUrl);
+ mWebServer.getSetCookieUrl("/cookie_1.js", "test1", "value1", "SameSite=None");
+ String url = mWebServer.getLinkedScriptUrl("/content_1.html", cookieUrl);
mOnUiThread.loadUrlAndWaitForCompletion(url);
assertNull(mCookieManager.getCookie(cookieUrl));
}
@Test
public void testSchemefulSameSite() throws Throwable {
- mServer = createWebServer();
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
mOnUiThread.getSettings().setJavaScriptEnabled(true);
mCookieManager.setAcceptCookie(true);
mOnUiThread.setAcceptThirdPartyCookies(true);
// Verify that two servers with different schemes on the same host are not considered
// same-site to each other.
- CtsTestServer secureServer = createWebServer(SslMode.NO_CLIENT_AUTH, R.raw.trustedkey,
- R.raw.trustedcert);
+ SharedSdkWebServer secureServer = getTestEnvironment()
+ .getSetupWebServer(SslMode.NO_CLIENT_AUTH, null,
+ R.raw.trustedkey, R.raw.trustedcert);
try {
- String cookieUrl = secureServer.getSetCookieUrl("/cookie_1.js", "test1", "value1");
- String url = mServer.getLinkedScriptUrl("/content_1.html", cookieUrl);
+ String cookieUrl = secureServer.getSetCookieUrl("/cookie_1.js", "test1",
+ "value1", null);
+ String url = mWebServer.getLinkedScriptUrl("/content_1.html", cookieUrl);
mOnUiThread.loadUrlAndWaitForCompletion(url);
assertNull(mCookieManager.getCookie(cookieUrl));
} finally {
diff --git a/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java b/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java
index ec7b24e8efe..6dcf019237f 100644
--- a/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java
@@ -64,8 +64,7 @@ public class HttpAuthHandlerTest extends SharedWebViewTest {
mOnUiThread = new WebViewOnUiThread(webview);
}
- mWebServer = getTestEnvironment().getWebServer();
- mWebServer.start(SslMode.INSECURE);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
}
@After
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebBackForwardListTest.java b/tests/tests/webkit/src/android/webkit/cts/WebBackForwardListTest.java
index cc3b35631ac..e20a6b18353 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebBackForwardListTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebBackForwardListTest.java
@@ -95,8 +95,7 @@ public class WebBackForwardListTest extends SharedWebViewTest {
assertNull(list.getItemAtIndex(-1));
assertNull(list.getItemAtIndex(2));
- SharedSdkWebServer server = getTestEnvironment().getWebServer();
- server.start(SslMode.INSECURE);
+ SharedSdkWebServer server = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
try {
String url1 = server.getAssetUrl(TestHtmlConstants.HTML_URL1);
String url2 = server.getAssetUrl(TestHtmlConstants.HTML_URL2);
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java b/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
index 346a1815fae..c753bbd05c4 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
@@ -41,7 +41,6 @@ import android.webkit.cts.WebViewSyncLoader.WaitForProgressClient;
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.NullWebViewUtils;
import com.android.compatibility.common.util.PollingCheck;
@@ -61,7 +60,7 @@ import java.util.concurrent.BlockingQueue;
@AppModeFull
@MediumTest
@RunWith(AndroidJUnit4.class)
-public class WebChromeClientTest {
+public class WebChromeClientTest extends SharedWebViewTest{
private static final String JAVASCRIPT_UNLOAD = "javascript unload";
private static final String LISTENER_ADDED = "listener added";
private static final String TOUCH_RECEIVED = "touch received";
@@ -70,31 +69,21 @@ public class WebChromeClientTest {
public ActivityScenarioRule mActivityScenarioRule =
new ActivityScenarioRule(WebViewCtsActivity.class);
- private CtsTestServer mWebServer;
+ private SharedSdkWebServer mWebServer;
private WebIconDatabase mIconDb;
private WebViewOnUiThread mOnUiThread;
private boolean mBlockWindowCreationSync;
private boolean mBlockWindowCreationAsync;
- private WebViewCtsActivity mActivity;
@Before
public void setUp() throws Exception {
- Assume.assumeTrue("WebView is not available", NullWebViewUtils.isWebViewAvailable());
- mActivityScenarioRule.getScenario().onActivity(activity -> {
- mActivity = (WebViewCtsActivity) activity;
- WebView webview = mActivity.getWebView();
- if (webview != null) {
- mOnUiThread = new WebViewOnUiThread(webview);
- }
- try {
- mWebServer = new CtsTestServer(mActivity);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- });
+ WebView webview = getTestEnvironment().getWebView();
+ if (webview != null) {
+ mOnUiThread = new WebViewOnUiThread(webview);
+ }
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
}
-
@After
public void tearDown() throws Exception {
if (mOnUiThread != null) {
@@ -109,6 +98,30 @@ public class WebChromeClientTest {
}
}
+ @Override
+ protected SharedWebViewTestEnvironment createTestEnvironment() {
+ Assume.assumeTrue("WebView is not available", NullWebViewUtils.isWebViewAvailable());
+
+ SharedWebViewTestEnvironment.Builder builder = new SharedWebViewTestEnvironment.Builder();
+
+ mActivityScenarioRule
+ .getScenario()
+ .onActivity(
+ activity -> {
+ WebView webView = ((WebViewCtsActivity) activity).getWebView();
+ builder.setHostAppInvoker(
+ SharedWebViewTestEnvironment.createHostAppInvoker(
+ activity))
+ .setContext(activity)
+ .setWebView(webView)
+ .setRootLayout(((WebViewCtsActivity) activity).getRootLayout());
+ });
+
+ SharedWebViewTestEnvironment environment = builder.build();
+ return environment;
+ }
+
+
@Test
public void testOnProgressChanged() {
final MockWebChromeClient webChromeClient = new MockWebChromeClient();
@@ -153,10 +166,10 @@ public class WebChromeClientTest {
WebkitUtils.onMainThreadSync(() -> {
// getInstance must run on the UI thread
mIconDb = WebIconDatabase.getInstance();
- String dbPath = mActivity.getFilesDir().toString() + "/icons";
+ String dbPath = getTestEnvironment().getContext().getFilesDir().toString() + "/icons";
mIconDb.open(dbPath);
});
- InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ getTestEnvironment().waitForIdleSync();
Thread.sleep(100); // Wait for open to be received on the icon db thread.
assertFalse(webChromeClient.hadOnReceivedIcon());
@@ -412,17 +425,17 @@ public class WebChromeClientTest {
int middleY = location[1] + mOnUiThread.getWebView().getHeight() / 2;
long timeDown = SystemClock.uptimeMillis();
- InstrumentationRegistry.getInstrumentation().sendPointerSync(
+ getTestEnvironment().sendPointerSync(
MotionEvent.obtain(timeDown, timeDown, MotionEvent.ACTION_DOWN,
middleX, middleY, 0));
long timeUp = SystemClock.uptimeMillis();
- InstrumentationRegistry.getInstrumentation().sendPointerSync(
+ getTestEnvironment().sendPointerSync(
MotionEvent.obtain(timeUp, timeUp, MotionEvent.ACTION_UP,
middleX, middleY, 0));
// Wait for the system to process all events in the queue
- InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ getTestEnvironment().waitForIdleSync();
}
private class MockWebChromeClient extends WaitForProgressClient {
@@ -573,12 +586,12 @@ public class WebChromeClientTest {
if (mBlockWindowCreationAsync) {
transport.setWebView(null);
} else {
- mChildWebView = new WebView(mActivity);
+ mChildWebView = new WebView(getTestEnvironment().getContext());
final WebSettings settings = mChildWebView.getSettings();
settings.setJavaScriptEnabled(true);
mChildWebView.setWebChromeClient(this);
transport.setWebView(mChildWebView);
- mActivity.addContentView(mChildWebView, new ViewGroup.LayoutParams(
+ getTestEnvironment().addContentView(mChildWebView, new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
}
resultMsg.sendToTarget();
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebHistoryItemTest.java b/tests/tests/webkit/src/android/webkit/cts/WebHistoryItemTest.java
index df48ce1f41b..d0881d9bbac 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebHistoryItemTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebHistoryItemTest.java
@@ -78,8 +78,7 @@ public class WebHistoryItemTest extends SharedWebViewTest {
mOnUiThread = new WebViewOnUiThread(webview);
}
mContext = getTestEnvironment().getContext();
- mWebServer = getTestEnvironment().getWebServer();
- mWebServer.start(SslMode.INSECURE);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
}
@After
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
index 81c1eeee272..d44cbb03b24 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
@@ -22,7 +22,6 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import android.content.Context;
@@ -48,7 +47,6 @@ import android.webkit.cts.WebViewSyncLoader.WaitForProgressClient;
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.NullWebViewUtils;
import com.android.compatibility.common.util.PollingCheck;
@@ -76,7 +74,7 @@ import java.util.regex.Pattern;
@AppModeFull
@MediumTest
@RunWith(AndroidJUnit4.class)
-public class WebSettingsTest {
+public class WebSettingsTest extends SharedWebViewTest {
private static final String LOG_TAG = "WebSettingsTest";
private final String EMPTY_IMAGE_HEIGHT = "0";
@@ -96,23 +94,18 @@ public class WebSettingsTest {
new ActivityScenarioRule(WebViewCtsActivity.class);
private WebSettings mSettings;
- private CtsTestServer mWebServer;
+ private SharedSdkWebServer mWebServer;
private WebViewOnUiThread mOnUiThread;
private Context mContext;
@Before
public void setUp() throws Exception {
- Assume.assumeTrue("WebView is not available", NullWebViewUtils.isWebViewAvailable());
-
- mActivityScenarioRule.getScenario().onActivity(activity -> {
- WebViewCtsActivity webviewCtsActivity = (WebViewCtsActivity) activity;
- WebView webview = webviewCtsActivity.getWebView();
- if (webview != null) {
- mOnUiThread = new WebViewOnUiThread(webview);
- }
- });
+ WebView webview = getTestEnvironment().getWebView();
+ if (webview != null) {
+ mOnUiThread = new WebViewOnUiThread(webview);
+ }
mSettings = mOnUiThread.getSettings();
- mContext = InstrumentationRegistry.getInstrumentation().getContext();
+ mContext = getTestEnvironment().getContext();
}
@@ -126,6 +119,28 @@ public class WebSettingsTest {
}
}
+ @Override
+ protected SharedWebViewTestEnvironment createTestEnvironment() {
+ Assume.assumeTrue("WebView is not available", NullWebViewUtils.isWebViewAvailable());
+
+ SharedWebViewTestEnvironment.Builder builder = new SharedWebViewTestEnvironment.Builder();
+
+ mActivityScenarioRule
+ .getScenario()
+ .onActivity(
+ activity -> {
+ WebView webView = ((WebViewCtsActivity) activity).getWebView();
+ builder.setHostAppInvoker(
+ SharedWebViewTestEnvironment.createHostAppInvoker(
+ activity))
+ .setContext(activity)
+ .setWebView(webView)
+ .setRootLayout(((WebViewCtsActivity) activity).getRootLayout());
+ });
+
+ return builder.build();
+ }
+
/**
* Verifies that the default user agent string follows the format defined in Android
* compatibility definition (tokens in angle brackets are variables, tokens in square
@@ -219,7 +234,7 @@ public class WebSettingsTest {
@Test
public void testAccessUserAgentString() throws Exception {
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
String url = mWebServer.getUserAgentUrl();
String defaultUserAgent = mSettings.getUserAgentString();
@@ -292,7 +307,7 @@ public class WebSettingsTest {
String dbPath = mContext.getFilesDir().toString() + "/icons";
iconDb.open(dbPath);
});
- InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ getTestEnvironment().waitForIdleSync();
Thread.sleep(100); // Wait for open to be received on the icon db thread.
}
@@ -301,7 +316,7 @@ public class WebSettingsTest {
openIconDatabase();
final IconListenerClient iconListener = new IconListenerClient();
mOnUiThread.setWebChromeClient(iconListener);
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
mSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
assertEquals(WebSettings.LOAD_CACHE_ELSE_NETWORK, mSettings.getCacheMode());
@@ -324,7 +339,7 @@ public class WebSettingsTest {
openIconDatabase();
final IconListenerClient iconListener = new IconListenerClient();
mOnUiThread.setWebChromeClient(iconListener);
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
mSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
assertEquals(WebSettings.LOAD_NO_CACHE, mSettings.getCacheMode());
@@ -347,7 +362,7 @@ public class WebSettingsTest {
openIconDatabase();
final IconListenerClient iconListener = new IconListenerClient();
mOnUiThread.setWebChromeClient(iconListener);
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
// As a precondition, get the icon in the cache.
mSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
@@ -474,7 +489,7 @@ public class WebSettingsTest {
public void testAccessJavaScriptCanOpenWindowsAutomatically() throws Exception {
mSettings.setJavaScriptEnabled(true);
mSettings.setSupportMultipleWindows(true);
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
final WebView childWebView = mOnUiThread.createWebView();
final SettableFuture<Void> createWindowFuture = SettableFuture.create();
@@ -678,7 +693,7 @@ public class WebSettingsTest {
public void testAppCacheDisabled() throws Throwable {
// Test that when AppCache is disabled, we don't get any AppCache
// callbacks.
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
final String url = mWebServer.getAppCacheUrl();
mSettings.setJavaScriptEnabled(true);
@@ -702,7 +717,7 @@ public class WebSettingsTest {
// Test that when AppCache is enabled but no valid path is provided,
// we don't get any AppCache callbacks.
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
final String url = mWebServer.getAppCacheUrl();
mSettings.setAppCacheEnabled(true);
mSettings.setJavaScriptEnabled(true);
@@ -736,7 +751,7 @@ public class WebSettingsTest {
@Test
public void testDatabaseDisabled() throws Throwable {
// Verify that websql database does not work when disabled.
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
mOnUiThread.setWebChromeClient(new WebViewSyncLoader.WaitForProgressClient(mOnUiThread) {
@Override
@@ -776,7 +791,7 @@ public class WebSettingsTest {
@Test
public void testLoadsImagesAutomatically_httpImagesLoaded() throws Throwable {
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
mSettings.setJavaScriptEnabled(true);
mSettings.setLoadsImagesAutomatically(true);
@@ -786,7 +801,7 @@ public class WebSettingsTest {
@Test
public void testLoadsImagesAutomatically_dataUriImagesLoaded() throws Throwable {
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
mSettings.setJavaScriptEnabled(true);
mSettings.setLoadsImagesAutomatically(true);
@@ -796,7 +811,7 @@ public class WebSettingsTest {
@Test
public void testLoadsImagesAutomatically_blockLoadingImages() throws Throwable {
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
mSettings.setJavaScriptEnabled(true);
mSettings.setLoadsImagesAutomatically(false);
@@ -810,7 +825,7 @@ public class WebSettingsTest {
@Test
public void testLoadsImagesAutomatically_loadImagesWithoutReload() throws Throwable {
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
mSettings.setJavaScriptEnabled(true);
mSettings.setLoadsImagesAutomatically(false);
@@ -834,7 +849,7 @@ public class WebSettingsTest {
public void testBlockNetworkImage() throws Throwable {
assertFalse(mSettings.getBlockNetworkImage());
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
mSettings.setJavaScriptEnabled(true);
// Check that by default network and data url images are loaded.
@@ -864,7 +879,7 @@ public class WebSettingsTest {
public void testBlockNetworkLoads() throws Throwable {
assertFalse(mSettings.getBlockNetworkLoads());
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
mSettings.setJavaScriptEnabled(true);
// Check that by default network resources and data url images are loaded.
@@ -1047,7 +1062,7 @@ public class WebSettingsTest {
mOnUiThread.setWebViewClient(interceptClient);
mSettings.setJavaScriptEnabled(true);
- startWebServer(true);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.NO_CLIENT_AUTH);
String secureUrl = mWebServer.setResponse(SECURE_URL, SECURE_HTML, null);
mOnUiThread.clearSslPreferences();
@@ -1098,17 +1113,6 @@ public class WebSettingsTest {
}
/**
- * Starts the internal web server. The server will be shut down automatically
- * during tearDown().
- *
- * @throws Exception
- */
- private void startWebServer(boolean secure) throws Exception {
- assertNull(mWebServer);
- mWebServer = new CtsTestServer(mContext, secure ? SslMode.NO_CLIENT_AUTH : SslMode.INSECURE);
- }
-
- /**
* Load the given asset from the internal web server. Starts the server if
* it is not already running.
*
@@ -1117,7 +1121,7 @@ public class WebSettingsTest {
*/
private void loadAssetUrl(String asset) throws Exception {
if (mWebServer == null) {
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
}
String url = mWebServer.getAssetUrl(asset);
mOnUiThread.loadUrlAndWaitForCompletion(url);
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
index 03375fe2796..cbe038c955a 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
@@ -25,9 +25,9 @@ import static org.junit.Assert.assertTrue;
import android.graphics.Bitmap;
import android.os.Message;
import android.platform.test.annotations.AppModeFull;
-import android.util.Pair;
import android.view.KeyEvent;
import android.view.ViewGroup;
+import android.view.ViewParent;
import android.webkit.HttpAuthHandler;
import android.webkit.RenderProcessGoneDetail;
import android.webkit.SafeBrowsingResponse;
@@ -43,7 +43,6 @@ import android.webkit.cts.WebViewSyncLoader.WaitForLoadedClient;
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.NullWebViewUtils;
import com.android.compatibility.common.util.PollingCheck;
@@ -67,7 +66,7 @@ import java.util.Map;
@AppModeFull
@MediumTest
@RunWith(AndroidJUnit4.class)
-public class WebViewClientTest {
+public class WebViewClientTest extends SharedWebViewTest {
private static final String TEST_URL = "http://www.example.com/";
@Rule
@@ -75,8 +74,7 @@ public class WebViewClientTest {
new ActivityScenarioRule(WebViewCtsActivity.class);
private WebViewOnUiThread mOnUiThread;
- private CtsTestServer mWebServer;
- private WebViewCtsActivity mActivity;
+ private SharedSdkWebServer mWebServer;
private static final String TEST_SAFE_BROWSING_URL_PREFIX =
"chrome://safe-browsing/match?type=";
@@ -91,20 +89,10 @@ public class WebViewClientTest {
@Before
public void setUp() throws Exception {
- Assume.assumeTrue("WebView is not available", NullWebViewUtils.isWebViewAvailable());
- mActivityScenarioRule.getScenario().onActivity(activity -> {
- mActivity = (WebViewCtsActivity) activity;
- WebView webview = mActivity.getWebView();
- if (webview != null) {
- new PollingCheck(WebkitUtils.TEST_TIMEOUT_MS) {
- @Override
- protected boolean check() {
- return activity.hasWindowFocus();
- }
- }.run();
- mOnUiThread = new WebViewOnUiThread(webview);
- }
- });
+ WebView webview = getTestEnvironment().getWebView();
+ if (webview != null) {
+ mOnUiThread = new WebViewOnUiThread(webview);
+ }
}
@After
@@ -117,6 +105,40 @@ public class WebViewClientTest {
}
}
+ @Override
+ protected SharedWebViewTestEnvironment createTestEnvironment() {
+ Assume.assumeTrue("WebView is not available", NullWebViewUtils.isWebViewAvailable());
+
+ SharedWebViewTestEnvironment.Builder builder = new SharedWebViewTestEnvironment.Builder();
+
+ mActivityScenarioRule
+ .getScenario()
+ .onActivity(
+ activity -> {
+ WebView webView = ((WebViewCtsActivity) activity).getWebView();
+
+ builder.setHostAppInvoker(
+ SharedWebViewTestEnvironment.createHostAppInvoker(
+ activity))
+ .setContext(activity)
+ .setWebView(webView)
+ .setRootLayout(((WebViewCtsActivity) activity).getRootLayout());
+ });
+
+ SharedWebViewTestEnvironment environment = builder.build();
+
+ if (environment.getWebView() != null) {
+ new PollingCheck(WebkitUtils.TEST_TIMEOUT_MS) {
+ @Override
+ protected boolean check() {
+ return ((WebViewCtsActivity) environment.getContext()).hasWindowFocus();
+ }
+ }.run();
+ }
+
+ return environment;
+ }
+
/**
* This should remain functionally equivalent to
* androidx.webkit.WebViewClientCompatTest#testShouldOverrideUrlLoadingDefault. Modifications
@@ -157,7 +179,7 @@ public class WebViewClientTest {
// TODO(sgurun) upstream this test to Aw.
@Test
public void testShouldOverrideUrlLoadingOnCreateWindow() throws Exception {
- mWebServer = new CtsTestServer(mActivity);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
// WebViewClient for main window
final MockWebViewClient mainWebViewClient = new MockWebViewClient();
// WebViewClient for child window
@@ -169,56 +191,70 @@ public class WebViewClientTest {
final WebView childWebView = mOnUiThread.createWebView();
- WebViewOnUiThread childWebViewOnUiThread = new WebViewOnUiThread(childWebView);
- mOnUiThread.setWebChromeClient(new WebChromeClient() {
- @Override
- public boolean onCreateWindow(
- WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
- WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
- childWebView.setWebViewClient(childWebViewClient);
- childWebView.getSettings().setJavaScriptEnabled(true);
- transport.setWebView(childWebView);
- mActivity.addContentView(childWebView, new ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT));
- resultMsg.sendToTarget();
- return true;
- }
- });
- {
- final int childCallCount = childWebViewClient.getShouldOverrideUrlLoadingCallCount();
- mOnUiThread.loadUrl(mWebServer.getAssetUrl(TestHtmlConstants.BLANK_TAG_URL));
-
- new PollingCheck(WebkitUtils.TEST_TIMEOUT_MS) {
- @Override
- protected boolean check() {
- return childWebViewClient.hasOnPageFinishedCalled();
- }
- }.run();
- new PollingCheck(WebkitUtils.TEST_TIMEOUT_MS) {
- @Override
- protected boolean check() {
- return childWebViewClient.getShouldOverrideUrlLoadingCallCount() > childCallCount;
- }
- }.run();
- assertEquals(mWebServer.getAssetUrl(TestHtmlConstants.PAGE_WITH_LINK_URL),
- childWebViewClient.getLastShouldOverrideUrl());
- }
-
- final int childCallCount = childWebViewClient.getShouldOverrideUrlLoadingCallCount();
- final int mainCallCount = mainWebViewClient.getShouldOverrideUrlLoadingCallCount();
- clickOnLinkUsingJs("link", childWebViewOnUiThread);
- new PollingCheck(WebkitUtils.TEST_TIMEOUT_MS) {
- @Override
- protected boolean check() {
- return childWebViewClient.getShouldOverrideUrlLoadingCallCount() > childCallCount;
+ try {
+ WebViewOnUiThread childWebViewOnUiThread = new WebViewOnUiThread(childWebView);
+ mOnUiThread.setWebChromeClient(new WebChromeClient() {
+ @Override
+ public boolean onCreateWindow(
+ WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
+ WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
+ childWebView.setWebViewClient(childWebViewClient);
+ childWebView.getSettings().setJavaScriptEnabled(true);
+ transport.setWebView(childWebView);
+ getTestEnvironment().addContentView(childWebView, new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT));
+ resultMsg.sendToTarget();
+ return true;
+ }
+ });
+ {
+ final int childCallCount = childWebViewClient
+ .getShouldOverrideUrlLoadingCallCount();
+ mOnUiThread.loadUrl(mWebServer.getAssetUrl(TestHtmlConstants.BLANK_TAG_URL));
+
+ new PollingCheck(WebkitUtils.TEST_TIMEOUT_MS) {
+ @Override
+ protected boolean check() {
+ return childWebViewClient.hasOnPageFinishedCalled();
+ }
+ }.run();
+ new PollingCheck(WebkitUtils.TEST_TIMEOUT_MS) {
+ @Override
+ protected boolean check() {
+ return childWebViewClient
+ .getShouldOverrideUrlLoadingCallCount() > childCallCount;
+ }
+ }.run();
+ assertEquals(mWebServer.getAssetUrl(TestHtmlConstants.PAGE_WITH_LINK_URL),
+ childWebViewClient.getLastShouldOverrideUrl());
}
- }.run();
- assertEquals(mainCallCount, mainWebViewClient.getShouldOverrideUrlLoadingCallCount());
- // PAGE_WITH_LINK_URL has a link to BLANK_PAGE_URL (an arbitrary page also controlled by the
- // test server)
- assertEquals(mWebServer.getAssetUrl(TestHtmlConstants.BLANK_PAGE_URL),
- childWebViewClient.getLastShouldOverrideUrl());
+
+ final int childCallCount = childWebViewClient.getShouldOverrideUrlLoadingCallCount();
+ final int mainCallCount = mainWebViewClient.getShouldOverrideUrlLoadingCallCount();
+ clickOnLinkUsingJs("link", childWebViewOnUiThread);
+ new PollingCheck(WebkitUtils.TEST_TIMEOUT_MS) {
+ @Override
+ protected boolean check() {
+ return childWebViewClient
+ .getShouldOverrideUrlLoadingCallCount() > childCallCount;
+ }
+ }.run();
+ assertEquals(mainCallCount, mainWebViewClient.getShouldOverrideUrlLoadingCallCount());
+ // PAGE_WITH_LINK_URL has a link to BLANK_PAGE_URL (an arbitrary page
+ // also controlled by the test server)
+ assertEquals(mWebServer.getAssetUrl(TestHtmlConstants.BLANK_PAGE_URL),
+ childWebViewClient.getLastShouldOverrideUrl());
+
+ } finally {
+ WebkitUtils.onMainThreadSync(() -> {
+ ViewParent parent = childWebView.getParent();
+ if (parent instanceof ViewGroup) {
+ ((ViewGroup) parent).removeView(childWebView);
+ }
+ childWebView.destroy();
+ });
+ }
}
private void clickOnLinkUsingJs(final String linkId, WebViewOnUiThread webViewOnUiThread) {
@@ -231,7 +267,7 @@ public class WebViewClientTest {
public void testLoadPage() throws Exception {
final MockWebViewClient webViewClient = new MockWebViewClient();
mOnUiThread.setWebViewClient(webViewClient);
- mWebServer = new CtsTestServer(mActivity);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
assertFalse(webViewClient.hasOnPageStartedCalled());
@@ -271,10 +307,10 @@ public class WebViewClientTest {
final String page = "<head></head><body>test onReceivedLoginRequest</body>";
final String headerName = "x-auto-login";
final String headerValue = "realm=com.google&account=foo%40bar.com&args=random_string";
- List<Pair<String, String>> headers = new ArrayList<Pair<String, String>>();
- headers.add(Pair.create(headerName, headerValue));
+ List<HttpHeader> headers = new ArrayList<HttpHeader>();
+ headers.add(HttpHeader.create(headerName, headerValue));
- mWebServer = new CtsTestServer(mActivity);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
String url = mWebServer.setResponse(path, page, headers);
assertFalse(webViewClient.hasOnReceivedLoginRequest());
mOnUiThread.loadUrlAndWaitForCompletion(url);
@@ -313,9 +349,10 @@ public class WebViewClientTest {
*/
@Test
public void testOnReceivedErrorForSubresource() throws Exception {
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
+
final MockWebViewClient webViewClient = new MockWebViewClient();
mOnUiThread.setWebViewClient(webViewClient);
- mWebServer = new CtsTestServer(mActivity);
assertNull(webViewClient.hasOnReceivedResourceError());
String url = mWebServer.getAssetUrl(TestHtmlConstants.BAD_IMAGE_PAGE_URL);
@@ -327,9 +364,9 @@ public class WebViewClientTest {
@Test
public void testOnReceivedHttpError() throws Exception {
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
final MockWebViewClient webViewClient = new MockWebViewClient();
mOnUiThread.setWebViewClient(webViewClient);
- mWebServer = new CtsTestServer(mActivity);
assertNull(webViewClient.hasOnReceivedHttpError());
String url = mWebServer.getAssetUrl(TestHtmlConstants.NON_EXISTENT_PAGE_URL);
@@ -340,11 +377,11 @@ public class WebViewClientTest {
@Test
public void testOnFormResubmission() throws Exception {
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
final MockWebViewClient webViewClient = new MockWebViewClient();
mOnUiThread.setWebViewClient(webViewClient);
final WebSettings settings = mOnUiThread.getSettings();
settings.setJavaScriptEnabled(true);
- mWebServer = new CtsTestServer(mActivity);
assertFalse(webViewClient.hasOnFormResubmissionCalled());
String url = mWebServer.getAssetUrl(TestHtmlConstants.JS_FORM_URL);
@@ -366,9 +403,9 @@ public class WebViewClientTest {
@Test
public void testDoUpdateVisitedHistory() throws Exception {
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
final MockWebViewClient webViewClient = new MockWebViewClient();
mOnUiThread.setWebViewClient(webViewClient);
- mWebServer = new CtsTestServer(mActivity);
assertFalse(webViewClient.hasDoUpdateVisitedHistoryCalled());
String url1 = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
@@ -385,9 +422,9 @@ public class WebViewClientTest {
@Test
public void testOnReceivedHttpAuthRequest() throws Exception {
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
final MockWebViewClient webViewClient = new MockWebViewClient();
mOnUiThread.setWebViewClient(webViewClient);
- mWebServer = new CtsTestServer(mActivity);
assertFalse(webViewClient.hasOnReceivedHttpAuthRequestCalled());
String url = mWebServer.getAuthAssetUrl(TestHtmlConstants.EMBEDDED_IMG_URL);
@@ -410,10 +447,10 @@ public class WebViewClientTest {
mOnUiThread.setWebViewClient(webViewClient);
mOnUiThread.requestFocus();
- InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ getTestEnvironment().waitForIdleSync();
assertFalse(webViewClient.hasOnUnhandledKeyEventCalled());
- InstrumentationRegistry.getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_1);
+ getTestEnvironment().sendKeyDownUpSync(KeyEvent.KEYCODE_1);
new PollingCheck(WebkitUtils.TEST_TIMEOUT_MS) {
@Override
@@ -425,9 +462,9 @@ public class WebViewClientTest {
@Test
public void testOnScaleChanged() throws Throwable {
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
final MockWebViewClient webViewClient = new MockWebViewClient();
mOnUiThread.setWebViewClient(webViewClient);
- mWebServer = new CtsTestServer(mActivity);
assertFalse(webViewClient.hasOnScaleChangedCalled());
String url1 = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
@@ -488,14 +525,14 @@ public class WebViewClientTest {
TestClient client = new TestClient();
mOnUiThread.setWebViewClient(client);
- mWebServer = new CtsTestServer(mActivity);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
String mainUrl = mWebServer.setResponse(mainPath, mainPage, null);
mOnUiThread.loadUrlAndWaitForCompletion(mainUrl, headers);
// Inspect the fields of the saved WebResourceRequest
assertNotNull(client.interceptRequest);
assertEquals(mainUrl, client.interceptRequest.getUrl().toString());
assertTrue(client.interceptRequest.isForMainFrame());
- assertEquals(mWebServer.getLastRequest(mainPath).getRequestLine().getMethod(),
+ assertEquals(mWebServer.getLastRequest(mainPath).getMethod(),
client.interceptRequest.getMethod());
// Web request headers are case-insensitive. We provided lower-case headerName and
// headerValue. This will pass implementations which either do not mangle case,
@@ -537,7 +574,7 @@ public class WebViewClientTest {
TestClient client = new TestClient();
mOnUiThread.setWebViewClient(client);
- mWebServer = new CtsTestServer(mActivity);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
String interceptUrl = mWebServer.getAbsoluteUrl(interceptPath);
// JavaScript which makes a synchronous AJAX request and logs and returns the status
String js =
@@ -594,7 +631,7 @@ public class WebViewClientTest {
*/
@Test
public void testOnSafeBrowsingHitBackToSafety() throws Throwable {
- mWebServer = new CtsTestServer(mActivity);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
mOnUiThread.loadUrlAndWaitForCompletion(url);
final String ORIGINAL_URL = mOnUiThread.getUrl();
@@ -629,7 +666,7 @@ public class WebViewClientTest {
*/
@Test
public void testOnSafeBrowsingHitProceed() throws Throwable {
- mWebServer = new CtsTestServer(mActivity);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
mOnUiThread.loadUrlAndWaitForCompletion(url);
final String ORIGINAL_URL = mOnUiThread.getUrl();
@@ -653,7 +690,7 @@ public class WebViewClientTest {
private void testOnSafeBrowsingCode(String expectedUrl, int expectedThreatType)
throws Throwable {
- mWebServer = new CtsTestServer(mActivity);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
mOnUiThread.loadUrlAndWaitForCompletion(url);
final String ORIGINAL_URL = mOnUiThread.getUrl();
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java
index b9136067ecc..e47568d7100 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java
@@ -463,7 +463,7 @@ public class WebViewSslTest extends SharedWebViewTest {
mOnUiThread.cleanUp();
}
if (mWebServer != null) {
- stopWebServer();
+ stopWebServer(mWebServer);
}
mActivity = null;
}
@@ -505,25 +505,15 @@ public class WebViewSslTest extends SharedWebViewTest {
return environment;
}
- private void startWebServer(@SslMode int sslMode) throws Exception {
- startWebServer(new SharedSdkWebServer.Config().setSslMode(sslMode));
- }
-
- private void startWebServer(SharedSdkWebServer.Config config) throws Exception {
- assertNull(mWebServer);
- mWebServer = getTestEnvironment().getWebServer();
- mWebServer.start(config);
- }
-
- private void stopWebServer() throws Exception {
- assertNotNull(mWebServer);
+ private void stopWebServer(SharedSdkWebServer webServer) throws Exception {
+ assertNotNull(webServer);
ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
ThreadPolicy tmpPolicy = new ThreadPolicy.Builder(oldPolicy)
.permitNetwork()
.build();
StrictMode.setThreadPolicy(tmpPolicy);
- mWebServer.shutdown();
- mWebServer = null;
+ webServer.shutdown();
+ webServer = null;
StrictMode.setThreadPolicy(oldPolicy);
}
@@ -539,7 +529,7 @@ public class WebViewSslTest extends SharedWebViewTest {
}
}
- startWebServer(SslMode.NO_CLIENT_AUTH);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.NO_CLIENT_AUTH);
mOnUiThread.setWebViewClient(new MockWebViewClient());
mOnUiThread.loadUrlAndWaitForCompletion(
mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL));
@@ -547,9 +537,9 @@ public class WebViewSslTest extends SharedWebViewTest {
assertNotNull(cert);
assertEquals("Android", cert.getIssuedTo().getUName());
- stopWebServer();
+ stopWebServer(mWebServer);
- startWebServer(SslMode.INSECURE);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
mOnUiThread.loadUrlAndWaitForCompletion(
mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL));
assertNull(mOnUiThread.getCertificate());
@@ -557,6 +547,8 @@ public class WebViewSslTest extends SharedWebViewTest {
@Test
public void testSecureSiteSetsCertificate() throws Throwable {
+ SharedWebViewTestEnvironment testEnvironment = getTestEnvironment();
+
final class MockWebViewClient extends WaitForLoadedClient {
public MockWebViewClient() {
super(mOnUiThread);
@@ -567,14 +559,14 @@ public class WebViewSslTest extends SharedWebViewTest {
}
}
- startWebServer(SslMode.INSECURE);
+ mWebServer = testEnvironment.getSetupWebServer(SslMode.INSECURE);
mOnUiThread.loadUrlAndWaitForCompletion(
mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL));
assertNull(mOnUiThread.getCertificate());
- stopWebServer();
+ stopWebServer(mWebServer);
- startWebServer(SslMode.NO_CLIENT_AUTH);
+ mWebServer = testEnvironment.getSetupWebServer(SslMode.NO_CLIENT_AUTH);
mOnUiThread.setWebViewClient(new MockWebViewClient());
mOnUiThread.loadUrlAndWaitForCompletion(
mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL));
@@ -588,7 +580,7 @@ public class WebViewSslTest extends SharedWebViewTest {
// Load the first page. We expect a call to
// WebViewClient.onReceivedSslError().
final SslErrorWebViewClient webViewClient = new SslErrorWebViewClient(mOnUiThread);
- startWebServer(SslMode.NO_CLIENT_AUTH);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.NO_CLIENT_AUTH);
final String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
mOnUiThread.setWebViewClient(webViewClient);
mOnUiThread.clearSslPreferences();
@@ -637,7 +629,7 @@ public class WebViewSslTest extends SharedWebViewTest {
}
}
- startWebServer(SslMode.NO_CLIENT_AUTH);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.NO_CLIENT_AUTH);
final String errorUrl = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
final MockWebViewClient webViewClient = new MockWebViewClient();
mOnUiThread.setWebViewClient(webViewClient);
@@ -660,7 +652,7 @@ public class WebViewSslTest extends SharedWebViewTest {
}
}
- startWebServer(SslMode.NO_CLIENT_AUTH);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.NO_CLIENT_AUTH);
final String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
mOnUiThread.setWebViewClient(new MockWebViewClient());
mOnUiThread.loadUrlAndWaitForCompletion(url);
@@ -679,7 +671,7 @@ public class WebViewSslTest extends SharedWebViewTest {
}
}
- startWebServer(SslMode.NO_CLIENT_AUTH);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.NO_CLIENT_AUTH);
final String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
mOnUiThread.setWebViewClient(new MockWebViewClient());
mOnUiThread.clearSslPreferences();
@@ -692,7 +684,7 @@ public class WebViewSslTest extends SharedWebViewTest {
// Load the first page. We expect a call to
// WebViewClient.onReceivedSslError().
final SslErrorWebViewClient webViewClient = new SslErrorWebViewClient(mOnUiThread);
- startWebServer(SslMode.NO_CLIENT_AUTH);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.NO_CLIENT_AUTH);
final String firstUrl = mWebServer.getAssetUrl(TestHtmlConstants.HTML_URL1);
mOnUiThread.setWebViewClient(webViewClient);
mOnUiThread.clearSslPreferences();
@@ -715,7 +707,7 @@ public class WebViewSslTest extends SharedWebViewTest {
// Load the first page. We expect a call to
// WebViewClient.onReceivedSslError().
final SslErrorWebViewClient webViewClient = new SslErrorWebViewClient(mOnUiThread);
- startWebServer(SslMode.NO_CLIENT_AUTH);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.NO_CLIENT_AUTH);
final String firstUrl = mWebServer.getAssetUrl(TestHtmlConstants.HTML_URL1);
mOnUiThread.setWebViewClient(webViewClient);
mOnUiThread.clearSslPreferences();
@@ -738,7 +730,7 @@ public class WebViewSslTest extends SharedWebViewTest {
@Test
public void testSecureServerRequestingClientCertDoesNotCancelRequest() throws Throwable {
- startWebServer(SslMode.WANTS_CLIENT_AUTH);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.WANTS_CLIENT_AUTH);
final String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
final SslErrorWebViewClient webViewClient = new SslErrorWebViewClient(mOnUiThread);
mOnUiThread.setWebViewClient(webViewClient);
@@ -753,7 +745,7 @@ public class WebViewSslTest extends SharedWebViewTest {
@Test
public void testSecureServerRequiringClientCertDoesCancelRequest() throws Throwable {
- startWebServer(SslMode.NEEDS_CLIENT_AUTH);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.NEEDS_CLIENT_AUTH);
final String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
final SslErrorWebViewClient webViewClient = new SslErrorWebViewClient(mOnUiThread);
mOnUiThread.setWebViewClient(webViewClient);
@@ -779,7 +771,7 @@ public class WebViewSslTest extends SharedWebViewTest {
@Test
public void testProceedClientCertRequest() throws Throwable {
- startWebServer(SslMode.NEEDS_CLIENT_AUTH);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.NEEDS_CLIENT_AUTH);
String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
final ClientCertWebViewClient webViewClient = new ClientCertWebViewClient(mOnUiThread);
mOnUiThread.setWebViewClient(webViewClient);
@@ -807,7 +799,7 @@ public class WebViewSslTest extends SharedWebViewTest {
@Test
public void testProceedClientCertRequestKeyWithAndroidKeystoreKey() throws Throwable {
- startWebServer(SslMode.NEEDS_CLIENT_AUTH);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.NEEDS_CLIENT_AUTH);
String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
final ClientCertWebViewClient webViewClient = new ClientCertWebViewClient(
mOnUiThread,
@@ -858,7 +850,7 @@ public class WebViewSslTest extends SharedWebViewTest {
@Test
public void testIgnoreClientCertRequest() throws Throwable {
- startWebServer(SslMode.NEEDS_CLIENT_AUTH);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.NEEDS_CLIENT_AUTH);
String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
final ClientCertWebViewClient webViewClient = new ClientCertWebViewClient(mOnUiThread);
mOnUiThread.setWebViewClient(webViewClient);
@@ -892,7 +884,7 @@ public class WebViewSslTest extends SharedWebViewTest {
@Test
public void testCancelClientCertRequest() throws Throwable {
- startWebServer(SslMode.NEEDS_CLIENT_AUTH);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.NEEDS_CLIENT_AUTH);
final String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
final ClientCertWebViewClient webViewClient = new ClientCertWebViewClient(mOnUiThread);
mOnUiThread.setWebViewClient(webViewClient);
@@ -917,10 +909,8 @@ public class WebViewSslTest extends SharedWebViewTest {
@Test
public void testClientCertIssuersReceivedCorrectly() throws Throwable {
-
- startWebServer(new SharedSdkWebServer.Config()
- .setSslMode(SslMode.NEEDS_CLIENT_AUTH)
- .setAcceptedIssuer(FAKE_RSA_CA_1));
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.NEEDS_CLIENT_AUTH,
+ FAKE_RSA_CA_1, 0, 0);
final String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
final ClientCertWebViewClient webViewClient = new ClientCertWebViewClient(mOnUiThread);
mOnUiThread.setWebViewClient(webViewClient);
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
index e6499d063d0..f6c60018b31 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
@@ -216,12 +216,6 @@ public class WebViewTest extends SharedWebViewTest {
return environment;
}
- private void startWebServer(boolean secure) throws Exception {
- assertNull(mWebServer);
- mWebServer = getTestEnvironment().getWebServer();
- mWebServer.start(secure ? SslMode.NO_CLIENT_AUTH : SslMode.INSECURE);
- }
-
@Test
public void testConstructor() {
WebkitUtils.onMainThreadSync(
@@ -325,7 +319,7 @@ public class WebViewTest extends SharedWebViewTest {
@Test
@Presubmit
public void testLoadUrl() throws Exception {
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
WebkitUtils.onMainThreadSync(
() -> {
@@ -368,7 +362,7 @@ public class WebViewTest extends SharedWebViewTest {
@Test
public void testPostUrlWithNetworkUrl() throws Exception {
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
final String networkUrl = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
final String postDataString = "username=my_username&password=my_password";
@@ -400,7 +394,7 @@ public class WebViewTest extends SharedWebViewTest {
@Test
public void testAppInjectedXRequestedWithHeaderIsNotOverwritten() throws Exception {
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
WebkitUtils.onMainThreadSync(
() -> {
@@ -424,7 +418,7 @@ public class WebViewTest extends SharedWebViewTest {
@Test
public void testAppCanInjectHeadersViaImmutableMap() throws Exception {
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
WebkitUtils.onMainThreadSync(
() -> {
@@ -453,7 +447,7 @@ public class WebViewTest extends SharedWebViewTest {
final String X_REFERER = "Referer";
final String X_REFERER_VALUE = "http://www.example.com/";
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
HashMap<String, String> map = new HashMap<String, String>();
map.put(X_FOO, X_FOO_VALUE);
@@ -472,7 +466,7 @@ public class WebViewTest extends SharedWebViewTest {
@Test
@SuppressWarnings("deprecation")
public void testGetVisibleTitleHeight() throws Exception {
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
WebkitUtils.onMainThreadSync(
() -> {
@@ -484,7 +478,7 @@ public class WebViewTest extends SharedWebViewTest {
@Test
public void testGetOriginalUrl() throws Throwable {
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
WebkitUtils.onMainThreadSync(
() -> {
@@ -512,7 +506,7 @@ public class WebViewTest extends SharedWebViewTest {
public void testStopLoading() throws Exception {
assertEquals(INITIAL_PROGRESS, mOnUiThread.getProgress());
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
String url = mWebServer.getDelayedAssetUrl(TestHtmlConstants.STOP_LOADING_URL);
class JsInterface {
@@ -546,7 +540,7 @@ public class WebViewTest extends SharedWebViewTest {
@Test
public void testGoBackAndForward() throws Exception {
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
WebkitUtils.onMainThreadSync(
() -> {
@@ -633,7 +627,7 @@ public class WebViewTest extends SharedWebViewTest {
mOnUiThread.addJavascriptInterface(obj, "interface");
assertFalse(obj.wasProvideResultCalled());
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
String url = mWebServer.getAssetUrl(TestHtmlConstants.ADD_JAVA_SCRIPT_INTERFACE_URL);
mOnUiThread.loadUrlAndWaitForCompletion(url);
assertEquals("Original title", obj.waitForResult());
@@ -839,7 +833,7 @@ public class WebViewTest extends SharedWebViewTest {
}
});
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
mOnUiThread.loadUrlAndWaitForCompletion(
mWebServer.getAssetUrl(TestHtmlConstants.POPUP_URL));
WebkitUtils.waitForFuture(onCreateWindowFuture);
@@ -891,7 +885,7 @@ public class WebViewTest extends SharedWebViewTest {
public void testCapturePicture() throws Exception, Throwable {
final TestPictureListener listener = new TestPictureListener();
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
final String url = mWebServer.getAssetUrl(TestHtmlConstants.BLANK_PAGE_URL);
mOnUiThread.setPictureListener(listener);
// Showing the blank page will fill the picture with the background color.
@@ -930,7 +924,7 @@ public class WebViewTest extends SharedWebViewTest {
}
final MyPictureListener listener = new MyPictureListener();
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
final String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
mOnUiThread.setPictureListener(listener);
mOnUiThread.loadUrlAndWaitForCompletion(url);
@@ -1095,7 +1089,7 @@ public class WebViewTest extends SharedWebViewTest {
mOnUiThread.loadDataAndWaitForCompletion(HTML_CONTENT, "text/html", null);
assertEquals(firstTitle, mOnUiThread.getTitle());
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
final String crossOriginUrl = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
mOnUiThread.getSettings().setJavaScriptEnabled(true);
final String secondTitle = "Foo bar";
@@ -1126,7 +1120,7 @@ public class WebViewTest extends SharedWebViewTest {
// will fail and we won't make a request to the test web server.
// By using the test web server as the base URL we expect to see a request
// for the relative URL in the test server.
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
final String baseUrl = mWebServer.getAssetUrl("foo.html");
mWebServer.resetRequestState();
mOnUiThread.loadDataWithBaseURLAndWaitForCompletion(
@@ -1163,7 +1157,7 @@ public class WebViewTest extends SharedWebViewTest {
public void testLoadDataWithBaseUrl_javascriptCanAccessOrigin() throws Throwable {
// Test that JavaScript can access content from the same origin as the base URL.
mOnUiThread.getSettings().setJavaScriptEnabled(true);
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
final String baseUrl = mWebServer.getAssetUrl("foo.html");
final String crossOriginUrl = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
mOnUiThread.loadDataWithBaseURLAndWaitForCompletion(
@@ -1467,7 +1461,7 @@ public class WebViewTest extends SharedWebViewTest {
}
}
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
final String imgUrl = mWebServer.getAssetUrl(TestHtmlConstants.SMALL_IMG_URL);
// Create a handler on the UI thread.
@@ -1715,7 +1709,7 @@ public class WebViewTest extends SharedWebViewTest {
@Test
public void testRequestFocusNodeHref() throws Throwable {
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
final String url1 = mWebServer.getAssetUrl(TestHtmlConstants.HTML_URL1);
final String url2 = mWebServer.getAssetUrl(TestHtmlConstants.HTML_URL2);
@@ -1802,7 +1796,7 @@ public class WebViewTest extends SharedWebViewTest {
mOnUiThread.getSettings().setJavaScriptEnabled(true);
mOnUiThread.addJavascriptInterface(imageLoaded, "imageLoaded");
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
final String imgUrl = mWebServer.getAssetUrl(TestHtmlConstants.LARGE_IMG_URL);
mOnUiThread.loadDataAndWaitForCompletion(
"<html><head><title>Title</title><style type='text/css'>"
@@ -1993,7 +1987,7 @@ public class WebViewTest extends SharedWebViewTest {
@Test
public void testClearHistory() throws Exception {
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
WebkitUtils.onMainThreadSync(
() -> {
@@ -2019,7 +2013,7 @@ public class WebViewTest extends SharedWebViewTest {
@Test
public void testSaveAndRestoreState() throws Throwable {
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
WebkitUtils.onMainThreadSync(
() -> {
@@ -2142,7 +2136,7 @@ public class WebViewTest extends SharedWebViewTest {
final int length = 100;
final MyDownloadListener listener = new MyDownloadListener();
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
final String url = mWebServer.getBinaryUrl(mimeType, length);
// By default, WebView sends an intent to ask the system to
@@ -2187,7 +2181,7 @@ public class WebViewTest extends SharedWebViewTest {
public void testSetNetworkAvailable() throws Exception {
WebSettings settings = mOnUiThread.getSettings();
settings.setJavaScriptEnabled(true);
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
String url = mWebServer.getAssetUrl(TestHtmlConstants.NETWORK_STATE_URL);
mOnUiThread.loadUrlAndWaitForCompletion(url);
@@ -2228,7 +2222,7 @@ public class WebViewTest extends SharedWebViewTest {
getTestEnvironment().waitForIdleSync();
assertFalse(future.isDone());
- startWebServer(false);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
final String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
mOnUiThread.loadUrlAndWaitForCompletion(url);
getTestEnvironment().waitForIdleSync();
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewTransportTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewTransportTest.java
index 612c603db26..1f159dcb321 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewTransportTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewTransportTest.java
@@ -29,33 +29,41 @@ import androidx.test.filters.MediumTest;
import com.android.compatibility.common.util.NullWebViewUtils;
import org.junit.Assume;
-import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@MediumTest
@RunWith(AndroidJUnit4.class)
-public class WebViewTransportTest {
+public class WebViewTransportTest extends SharedWebViewTest {
@Rule
public ActivityScenarioRule mActivityScenarioRule =
new ActivityScenarioRule(WebViewCtsActivity.class);
- private WebViewCtsActivity mActivity;
-
- @Before
- public void setUp() throws Throwable {
+ @Override
+ protected SharedWebViewTestEnvironment createTestEnvironment() {
Assume.assumeTrue("WebView is not available", NullWebViewUtils.isWebViewAvailable());
- mActivityScenarioRule.getScenario().onActivity(activity -> {
- mActivity = (WebViewCtsActivity) activity;
- });
+ SharedWebViewTestEnvironment.Builder builder = new SharedWebViewTestEnvironment.Builder();
+
+ mActivityScenarioRule
+ .getScenario()
+ .onActivity(
+ activity -> {
+ WebView webView = ((WebViewCtsActivity) activity).getWebView();
+ builder.setHostAppInvoker(
+ SharedWebViewTestEnvironment.createHostAppInvoker(
+ activity))
+ .setWebView(webView);
+ });
+
+ return builder.build();
}
@Test
public void testAccessWebView() {
WebkitUtils.onMainThreadSync(() -> {
- WebView webView = mActivity.getWebView();
+ WebView webView = getTestEnvironment().getWebView();
WebViewTransport transport = webView.new WebViewTransport();
assertNull(transport.getWebView());
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewZoomTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewZoomTest.java
index 84384d39609..6b8ea8de9f8 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewZoomTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewZoomTest.java
@@ -131,10 +131,9 @@ public class WebViewZoomTest extends SharedWebViewTest{
assertFalse("onScaleChanged has already been called before page has been setup",
mWebViewClient.onScaleChangedCalled());
assertNull(mWebServer);
- mWebServer = getTestEnvironment().getWebServer();
// Pass SslMode.TRUST_ANY_CLIENT to make the server serve https URLs yet do
// not ask client for client authentication.
- mWebServer.start(SslMode.TRUST_ANY_CLIENT);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.TRUST_ANY_CLIENT);
mOnUiThread.loadUrlAndWaitForCompletion(
mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL));
pollingCheckForCanZoomIn();
diff --git a/tests/tests/widget/res/layout/horizontal_scrollview.xml b/tests/tests/widget/res/layout/horizontal_scrollview.xml
index c82472b0c1f..11ba673427c 100644
--- a/tests/tests/widget/res/layout/horizontal_scrollview.xml
+++ b/tests/tests/widget/res/layout/horizontal_scrollview.xml
@@ -22,89 +22,89 @@
<view
class="android.widget.cts.HorizontalScrollViewTest$MyHorizontalScrollView"
android:id="@+id/horizontal_scroll_view_custom"
- android:layout_width="100px"
- android:layout_height="100px">
+ android:layout_width="200px"
+ android:layout_height="200px">
<LinearLayout
android:orientation="horizontal"
- android:layout_width="250px"
+ android:layout_width="500px"
android:layout_height="wrap_content">
<Button
android:id="@+id/first_horizontal_child"
- android:layout_width="250px"
- android:layout_height="100px"
+ android:layout_width="500px"
+ android:layout_height="200px"
android:text="@string/vertical_text_1"/>
<Button
- android:layout_width="250px"
- android:layout_height="100px"
+ android:layout_width="500px"
+ android:layout_height="200px"
android:text="@string/vertical_text_2"/>
<Button
- android:layout_width="250px"
- android:layout_height="100px"
+ android:layout_width="500px"
+ android:layout_height="200px"
android:text="@string/vertical_text_3"/>
<Button
- android:layout_width="250px"
- android:layout_height="100px"
+ android:layout_width="500px"
+ android:layout_height="200px"
android:text="@string/vertical_text_1"/>
<Button
- android:layout_width="250px"
- android:layout_height="100px"
+ android:layout_width="500px"
+ android:layout_height="200px"
android:text="@string/vertical_text_2"/>
<Button
- android:layout_width="250px"
- android:layout_height="100px"
+ android:layout_width="500px"
+ android:layout_height="200px"
android:text="@string/vertical_text_3"/>
<Button
- android:layout_width="250px"
- android:layout_height="100px"
+ android:layout_width="500px"
+ android:layout_height="200px"
android:text="@string/vertical_text_1"/>
<Button
- android:layout_width="250px"
- android:layout_height="100px"
+ android:layout_width="500px"
+ android:layout_height="200px"
android:text="@string/vertical_text_2"/>
<Button
- android:layout_width="250px"
- android:layout_height="100px"
+ android:layout_width="500px"
+ android:layout_height="200px"
android:text="@string/vertical_text_3"/>
<Button
- android:layout_width="250px"
- android:layout_height="100px"
+ android:layout_width="500px"
+ android:layout_height="200px"
android:text="@string/vertical_text_1"/>
<Button
- android:layout_width="250px"
- android:layout_height="100px"
+ android:layout_width="500px"
+ android:layout_height="200px"
android:text="@string/vertical_text_2"/>
<Button
- android:layout_width="250px"
- android:layout_height="100px"
+ android:layout_width="500px"
+ android:layout_height="200px"
android:text="@string/vertical_text_3"/>
<Button
- android:layout_width="250px"
- android:layout_height="100px"
+ android:layout_width="500px"
+ android:layout_height="200px"
android:text="@string/vertical_text_1"/>
<Button
- android:layout_width="250px"
- android:layout_height="100px"
+ android:layout_width="500px"
+ android:layout_height="200px"
android:text="@string/vertical_text_2"/>
<Button
android:id="@+id/last_horizontal_child"
- android:layout_width="250px"
- android:layout_height="100px"
+ android:layout_width="500px"
+ android:layout_height="200px"
android:text="@string/vertical_text_3"/>
</LinearLayout>
@@ -118,8 +118,8 @@
<view
class="android.widget.cts.HorizontalScrollViewTest$MyHorizontalScrollView"
android:id="@+id/horizontal_scroll_view_custom_empty"
- android:layout_width="100px"
- android:layout_height="100px" />
+ android:layout_width="200px"
+ android:layout_height="200px" />
<view
class="android.widget.cts.HorizontalScrollViewTest$InterceptView"
@@ -128,8 +128,8 @@
android:layout_height="wrap_content">
<HorizontalScrollView
android:id="@+id/horizontal_scroll_view_stretch"
- android:layout_width="90px"
- android:layout_height="90px"
+ android:layout_width="180px"
+ android:layout_height="180px"
android:background="#FFF">
<LinearLayout
android:layout_width="match_parent"
@@ -137,28 +137,28 @@
android:orientation="horizontal">
<View
android:background="#00F"
- android:layout_width="50px"
- android:layout_height="90px"/>
+ android:layout_width="100px"
+ android:layout_height="180px"/>
<View
android:background="#0FF"
- android:layout_width="50px"
- android:layout_height="90px"/>
+ android:layout_width="100px"
+ android:layout_height="180px"/>
<View
android:background="#0F0"
- android:layout_width="50px"
- android:layout_height="90px"/>
+ android:layout_width="100px"
+ android:layout_height="180px"/>
<View
android:background="#FF0"
- android:layout_width="50px"
- android:layout_height="90px"/>
+ android:layout_width="100px"
+ android:layout_height="180px"/>
<View
android:background="#F00"
- android:layout_width="50px"
- android:layout_height="90px"/>
+ android:layout_width="100px"
+ android:layout_height="180px"/>
<View
android:background="#F0F"
- android:layout_width="50px"
- android:layout_height="90px"/>
+ android:layout_width="100px"
+ android:layout_height="180px"/>
</LinearLayout>
</HorizontalScrollView>
</view>
diff --git a/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewTest.java b/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewTest.java
index 0067a8ab837..cf9bb246faf 100644
--- a/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewTest.java
@@ -71,11 +71,11 @@ import java.util.ArrayList;
@MediumTest
@RunWith(AndroidJUnit4.class)
public class HorizontalScrollViewTest {
- private static final int ITEM_WIDTH = 250;
- private static final int ITEM_HEIGHT = 100;
+ private static final int ITEM_WIDTH = 500;
+ private static final int ITEM_HEIGHT = 200;
private static final int ITEM_COUNT = 15;
- private static final int PAGE_WIDTH = 100;
- private static final int PAGE_HEIGHT = 100;
+ private static final int PAGE_WIDTH = 200;
+ private static final int PAGE_HEIGHT = 200;
private static final int SCROLL_RIGHT = ITEM_WIDTH * ITEM_COUNT - PAGE_WIDTH;
private Instrumentation mInstrumentation;
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewTest.java b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
index 000ae807d59..1f52b25ee32 100644
--- a/tests/tests/widget/src/android/widget/cts/TextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
@@ -203,8 +203,6 @@ public class TextViewTest {
}
};
private static final int CLICK_TIMEOUT = ViewConfiguration.getDoubleTapTimeout() + 50;
- private static final int BOLD_TEXT_ADJUSTMENT =
- FontStyle.FONT_WEIGHT_BOLD - FontStyle.FONT_WEIGHT_NORMAL;
private CharSequence mTransformedText;
@@ -330,26 +328,32 @@ public class TextViewTest {
@Test
public void testFontWeightAdjustment_forceBoldTextEnabled_textIsBolded() throws Throwable {
mActivityRule.runOnUiThread(() -> mTextView = findTextView(R.id.textview_text));
+ final int defaultFontWeight = mTextView.getTypeface().getWeight();
mInstrumentation.waitForIdleSync();
- assertEquals(FontStyle.FONT_WEIGHT_NORMAL, mTextView.getTypeface().getWeight());
-
Configuration cf = new Configuration();
- cf.fontWeightAdjustment = BOLD_TEXT_ADJUSTMENT;
+ final int fontWeightAdjustment = FontStyle.FONT_WEIGHT_BOLD - defaultFontWeight;
+ cf.fontWeightAdjustment =
+ fontWeightAdjustment <= 0 ? FontStyle.FONT_WEIGHT_MAX : fontWeightAdjustment;
mActivityRule.runOnUiThread(() -> mTextView.dispatchConfigurationChanged(cf));
mInstrumentation.waitForIdleSync();
Typeface forceBoldedPaintTf = mTextView.getPaint().getTypeface();
assertEquals(FontStyle.FONT_WEIGHT_BOLD, forceBoldedPaintTf.getWeight());
- assertEquals(FontStyle.FONT_WEIGHT_NORMAL, mTextView.getTypeface().getWeight());
+ assertEquals(defaultFontWeight, mTextView.getTypeface().getWeight());
}
@Test
public void testFontWeightAdjustment_forceBoldTextDisabled_textIsUnbolded() throws Throwable {
+ mActivityRule.runOnUiThread(() -> mTextView = findTextView(R.id.textview_text));
+ final int defaultFontWeight = mTextView.getTypeface().getWeight();
+
Configuration cf = new Configuration();
- cf.fontWeightAdjustment = BOLD_TEXT_ADJUSTMENT;
+ final int fontWeightAdjustment = FontStyle.FONT_WEIGHT_BOLD - defaultFontWeight;
+ cf.fontWeightAdjustment =
+ fontWeightAdjustment <= 0 ? FontStyle.FONT_WEIGHT_MAX : fontWeightAdjustment;
+
mActivityRule.runOnUiThread(() -> {
- mTextView = findTextView(R.id.textview_text);
mTextView.dispatchConfigurationChanged(cf);
cf.fontWeightAdjustment = 0;
mTextView.dispatchConfigurationChanged(cf);
@@ -357,8 +361,8 @@ public class TextViewTest {
mInstrumentation.waitForIdleSync();
Typeface forceUnboldedPaintTf = mTextView.getPaint().getTypeface();
- assertEquals(FontStyle.FONT_WEIGHT_NORMAL, forceUnboldedPaintTf.getWeight());
- assertEquals(FontStyle.FONT_WEIGHT_NORMAL, mTextView.getTypeface().getWeight());
+ assertEquals(defaultFontWeight, forceUnboldedPaintTf.getWeight());
+ assertEquals(defaultFontWeight, mTextView.getTypeface().getWeight());
}
@Test
@@ -367,7 +371,7 @@ public class TextViewTest {
mActivityRule.runOnUiThread(() -> {
mTextView = findTextView(R.id.textview_text);
Configuration cf = new Configuration();
- cf.fontWeightAdjustment = BOLD_TEXT_ADJUSTMENT;
+ cf.fontWeightAdjustment = FontStyle.FONT_WEIGHT_BOLD - FontStyle.FONT_WEIGHT_NORMAL;
mTextView.dispatchConfigurationChanged(cf);
mTextView.setTypeface(Typeface.MONOSPACE);
});
@@ -381,7 +385,6 @@ public class TextViewTest {
FontStyle.FONT_WEIGHT_BOLD, false), forceBoldedPaintTf);
}
-
@Test
public void testFontWeightAdjustment_forceBoldTextDisabled_originalTypefaceIsKept()
throws Throwable {
@@ -405,7 +408,7 @@ public class TextViewTest {
mActivityRule.runOnUiThread(() -> {
mTextView = findTextView(R.id.textview_text);
Configuration cf = new Configuration();
- cf.fontWeightAdjustment = BOLD_TEXT_ADJUSTMENT;
+ cf.fontWeightAdjustment = FontStyle.FONT_WEIGHT_BOLD - FontStyle.FONT_WEIGHT_NORMAL;
mTextView.dispatchConfigurationChanged(cf);
mTextView.setTypeface(originalTypeface);
});
diff --git a/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java b/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java
index 4eecaf0ec28..864b31c6bf2 100644
--- a/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java
@@ -18,6 +18,7 @@ package android.net.wifi.cts;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+import static android.net.wifi.SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD;
import static android.net.wifi.WifiAvailableChannel.OP_MODE_SAP;
import static android.net.wifi.WifiAvailableChannel.OP_MODE_STA;
import static android.net.wifi.WifiConfiguration.INVALID_NETWORK_ID;
@@ -2742,6 +2743,10 @@ public class WifiManagerTest extends WifiJUnit3TestBase {
() -> mWifiManager.isWifiEnabled() == true);
turnOffWifiAndTetheredHotspotIfEnabled();
verifyRegisterSoftApCallback(executor, callback);
+ if (!callback.getCurrentSoftApCapability()
+ .areFeaturesSupported(SOFTAP_FEATURE_ACS_OFFLOAD)) {
+ return;
+ }
int[] testBands = {SoftApConfiguration.BAND_2GHZ,
SoftApConfiguration.BAND_5GHZ};
int[] expectedBands = {SoftApConfiguration.BAND_2GHZ,
diff --git a/tools/cts-tradefed/etc/cts-tradefed b/tools/cts-tradefed/etc/cts-tradefed
index 21b36ca8d45..3d57a11d0f7 100755
--- a/tools/cts-tradefed/etc/cts-tradefed
+++ b/tools/cts-tradefed/etc/cts-tradefed
@@ -41,9 +41,9 @@ checkPath adb
checkPath java
# check java version
-JAVA_VERSION=$(java -version 2>&1 | grep -m 1 'version [ "]\(1\.8\|9\|11\).*[ "]')
+JAVA_VERSION=$(java -version 2>&1 | grep -m 1 'version [ "]\(1\.8\|9\|11\|17\).*[ "]')
if [ "${JAVA_VERSION}" == "" ]; then
- echo "Wrong java version. 1.8, 9, or 11 is required."
+ echo "Wrong java version. 1.8, 9, 11 or 17 is required."
exit
fi
diff --git a/tools/cts-tradefed/res/config/cts-known-failures.xml b/tools/cts-tradefed/res/config/cts-known-failures.xml
index b85626eb9da..4f6360f27ca 100644
--- a/tools/cts-tradefed/res/config/cts-known-failures.xml
+++ b/tools/cts-tradefed/res/config/cts-known-failures.xml
@@ -311,4 +311,7 @@
<option name="compatibility:exclude-filter" value="CtsTelephonyTestCases android.telephony.cts.VisualVoicemailServiceTest#testFilter_port_match" />
<option name="compatibility:exclude-filter" value="CtsTelephonyTestCases android.telephony.cts.VisualVoicemailServiceTest#testFilter_port_mismatch" />
<option name="compatibility:exclude-filter" value="CtsTelephonyTestCases android.telephony.cts.VisualVoicemailServiceTest#testFilter_port_anydata" />
-</configuration> \ No newline at end of file
+
+ <!-- b/266101051-->
+ <option name="compatibility:exclude-filter" value="CtsGameServiceTestCases" />
+</configuration>
diff --git a/tools/cts-tradefed/tests/src/com/android/compatibility/common/tradefed/loading/CommonConfigLoadingTest.java b/tools/cts-tradefed/tests/src/com/android/compatibility/common/tradefed/loading/CommonConfigLoadingTest.java
index c4d65418376..36ee7344a23 100644
--- a/tools/cts-tradefed/tests/src/com/android/compatibility/common/tradefed/loading/CommonConfigLoadingTest.java
+++ b/tools/cts-tradefed/tests/src/com/android/compatibility/common/tradefed/loading/CommonConfigLoadingTest.java
@@ -83,6 +83,7 @@ public class CommonConfigLoadingTest {
"com.android.tradefed.testtype.HostTest",
"com.android.tradefed.testtype.GTest",
"com.android.tradefed.testtype.mobly.MoblyBinaryHostTest",
+ "com.android.tradefed.testtype.pandora.PtsBotTest",
// VTS specific runners
"com.android.tradefed.testtype.binary.KernelTargetTest",
"com.android.tradefed.testtype.python.PythonBinaryHostTest",
@@ -107,8 +108,11 @@ public class CommonConfigLoadingTest {
RUNNER_EXCEPTION.add("repackaged.android.test.InstrumentationTestRunner");
// Used by a UiRendering scenario where an activity is persisted between tests
RUNNER_EXCEPTION.add("android.uirendering.cts.runner.UiRenderingRunner");
+ // Used to avoid crashing runner on -eng build due to Log.wtf() - b/216648699
+ RUNNER_EXCEPTION.add("com.android.server.uwb.CustomTestRunner");
+ RUNNER_EXCEPTION.add("com.android.server.wifi.CustomTestRunner");
}
-
+
/**
* Test that configuration shipped in Tradefed can be parsed.
* -> Exclude deprecated ApkInstaller.