summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-07-21 20:17:43 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-07-21 20:17:43 +0000
commit379051408890472cb22087500871d376783ce3c4 (patch)
tree8778ae438000e70f3f730e7714b3ce265c8c209e
parente5fcea1e50da99f58f6e1f5d1476b28b7c8b0bdb (diff)
parent594dfb3dc7876ac581cd510d4292cff64e6bfe1c (diff)
downloadcts-android13-mainline-go-ipsec-release.tar.gz
Snap for 8857176 from 594dfb3dc7876ac581cd510d4292cff64e6bfe1c to mainline-go-ipsec-releaseaml_go_ips_330911000android13-mainline-go-ipsec-release
Change-Id: Iaa4a479b040066033502d123e538924f81e78434
-rw-r--r--apps/CameraITS/tests/scene2_a/test_auto_flash.py4
-rw-r--r--apps/CameraITS/tests/scene4/test_preview_stabilization_fov.py31
-rw-r--r--apps/CameraITS/tests/scene4/test_video_aspect_ratio_and_crop.py6
-rw-r--r--apps/CameraITS/tests/sensor_fusion/test_video_stabilization.py6
-rw-r--r--apps/CameraITS/utils/its_session_utils.py12
-rw-r--r--apps/CtsVerifier/Android.bp3
-rw-r--r--apps/CtsVerifier/AndroidManifest.xml170
-rw-r--r--apps/CtsVerifier/res/layout/ble_rssi_precision.xml60
-rw-r--r--apps/CtsVerifier/res/layout/ble_rx_tx_calibration.xml66
-rw-r--r--apps/CtsVerifier/res/layout/clipboard_preview.xml80
-rw-r--r--apps/CtsVerifier/res/layout/nan_precision.xml92
-rw-r--r--apps/CtsVerifier/res/layout/uwb_precision.xml51
-rw-r--r--apps/CtsVerifier/res/layout/uwb_short_range.xml51
-rw-r--r--apps/CtsVerifier/res/values/strings.xml19
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/CtsVerifierReportLog.java4
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java21
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/audio/AnalogHeadsetAudioActivity.java11
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioAEC.java6
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackLatencyActivity.java13
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioTap2ToneActivity.java7
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java12
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralNotificationsTest.java13
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertisingSetTestActivity.java22
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java4
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java115
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java21
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/clipboard/ClipboardPreviewTestActivity.java115
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/companion/CompanionDeviceServiceTestActivity.java13
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/companion/DevicePresenceListener.java4
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/presence/BleRssiPrecisionActivity.java113
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/presence/BleRxTxCalibrationActivity.java140
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/presence/DeviceFeatureChecker.java44
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/presence/InputTextHandler.java52
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/presence/NanPrecisionTestActivity.java271
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/presence/OWNERS4
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/presence/PresenceTestActivity.java60
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/presence/UwbPrecisionActivity.java100
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/presence/UwbShortRangeActivity.java95
-rw-r--r--hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/ScopedStorageDeviceTest.java31
-rw-r--r--hostsidetests/security/src/android/security/cts/SELinuxHostTest.java2
-rw-r--r--hostsidetests/securitybulletin/Android.bp1
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0954.java46
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20353.java54
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0954/Android.bp8
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0954/AndroidManifest.xml18
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/integers.xml21
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/strings.xml38
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/DeviceTest.java164
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/PocService.java98
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2022-20353/Android.bp38
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2022-20353/AndroidManifest.xml35
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2022-20353/res/values/integers.xml22
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2022-20353/res/values/strings.xml38
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2022-20353/src/android/security/cts/CVE_2022_20353/DeviceTest.java151
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2022-20353/src/android/security/cts/CVE_2022_20353/PocActivity.java62
-rw-r--r--hostsidetests/statsdatom/src/android/cts/statsdatom/lib/ConfigUtils.java4
-rw-r--r--tests/camera/Android.bp1
-rw-r--r--tests/camera/api31test/src/android/camera/cts/api31test/SPerfClassTest.java6
-rw-r--r--tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java384
-rw-r--r--tests/camera/src/android/hardware/camera2/cts/RecordingTest.java13
-rw-r--r--tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java29
-rw-r--r--tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java17
-rw-r--r--tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagementRoleHolderTest.java3
-rw-r--r--tests/devicepolicy/src/android/devicepolicy/cts/UserControlDisabledPackagesTest.java6
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/TaskFragmentTrustedModeTest.java12
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsControllerTests.java6
-rw-r--r--tests/inputmethod/mockime/src/com/android/cts/mockime/Watermark.java2
-rw-r--r--tests/media/src/android/mediav2/cts/CodecInfoTest.java6
-rw-r--r--tests/mediapc/common/src/android/mediapc/cts/common/PerformanceClassEvaluator.java550
-rw-r--r--tests/mediapc/common/src/android/mediapc/cts/common/RequirementConstants.java45
-rw-r--r--tests/mediapc/common/src/android/mediapc/cts/common/Utils.java28
-rwxr-xr-xtests/tests/assist/common/src/android/assist/common/Utils.java1
-rw-r--r--tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java11
-rw-r--r--tests/tests/assist/src/android/assist/cts/AssistTestBase.java4
-rw-r--r--tests/tests/bluetooth/AndroidTest.xml2
-rw-r--r--tests/tests/content/CtsSyncAccountAccessOtherCertTests/src/com/android/cts/content/CtsSyncAccountAccessOtherCertTestCases.java17
-rw-r--r--tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTest.java8
-rw-r--r--tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTestAacFormat.java6
-rw-r--r--tests/tests/permission/src/android/permission/cts/SafetyCenterUtils.kt2
-rw-r--r--tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt22
-rw-r--r--tests/tests/permission5/src/android/permission5/cts/RuntimePermissionsAppOpTrackingTest.kt8
-rw-r--r--tests/tests/preference/src/android/preference/cts/PreferenceActivityLegacyFlowTest.java3
-rw-r--r--tests/tests/security/src/android/security/cts/LocationDisabledAppOpsTest.java132
-rw-r--r--tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java2
-rw-r--r--tests/tests/wifi/src/android/net/wifi/cts/ConcurrencyTest.java76
85 files changed, 1927 insertions, 2217 deletions
diff --git a/apps/CameraITS/tests/scene2_a/test_auto_flash.py b/apps/CameraITS/tests/scene2_a/test_auto_flash.py
index b20da2dbc54..c00cd5c358c 100644
--- a/apps/CameraITS/tests/scene2_a/test_auto_flash.py
+++ b/apps/CameraITS/tests/scene2_a/test_auto_flash.py
@@ -107,10 +107,10 @@ class AutoFlashTest(its_base_test.ItsBaseTest):
test_name = os.path.join(self.log_path, _TEST_NAME)
# check SKIP conditions
- first_api_level = its_session_utils.get_first_api_level(self.dut.serial)
+ vendor_api_level = its_session_utils.get_vendor_api_level(self.dut.serial)
camera_properties_utils.skip_unless(
camera_properties_utils.flash(props) and
- first_api_level >= its_session_utils.ANDROID13_API_LEVEL)
+ vendor_api_level >= its_session_utils.ANDROID13_API_LEVEL)
# establish connection with lighting controller
arduino_serial_port = lighting_control_utils.lighting_control(
diff --git a/apps/CameraITS/tests/scene4/test_preview_stabilization_fov.py b/apps/CameraITS/tests/scene4/test_preview_stabilization_fov.py
index 1f5b7c0bad9..2781f18805e 100644
--- a/apps/CameraITS/tests/scene4/test_preview_stabilization_fov.py
+++ b/apps/CameraITS/tests/scene4/test_preview_stabilization_fov.py
@@ -35,9 +35,9 @@ _MAX_STABILIZED_RADIUS_RATIO = 1.2 # radius of circle in stabilized preview
_ROUNDESS_DELTA_THRESHOLD = 0.05
_MAX_CENTER_THRESHOLD_PERCENT = 0.075
-_MAX_DIMENSION_SIZE = (1920, 1440) # max mandatory preview stream resolution
+_MAX_AREA = 1920 * 1440 # max mandatory preview stream resolution
_MIN_CENTER_THRESHOLD_PERCENT = 0.02
-_MIN_DIMENSION_SIZE = (176, 144) # assume QCIF to be min preview size
+_MIN_AREA = 176 * 144 # assume QCIF to be min preview size
def _collect_data(cam, video_size, stabilize):
@@ -93,23 +93,19 @@ def _calculate_center_offset_threshold(image_size):
threshold value ratio between which the circle centers can differ
"""
- max_diagonal = _point_distance(0, 0,
- _MAX_DIMENSION_SIZE[0], _MAX_DIMENSION_SIZE[1])
- min_diagonal = _point_distance(0, 0,
- _MIN_DIMENSION_SIZE[0], _MIN_DIMENSION_SIZE[1])
+ img_area = image_size[0] * image_size[1]
- img_diagonal = _point_distance(0, 0, image_size[0], image_size[1])
+ normalized_area = ((img_area - _MIN_AREA) /
+ (_MAX_AREA - _MIN_AREA))
- normalized_diagonal = ((img_diagonal - min_diagonal) /
- (max_diagonal - min_diagonal))
-
- if normalized_diagonal > 1 or normalized_diagonal < 0:
- raise AssertionError(f'normalized diagonal > 1 or < 0!'
- f' img_diag: {img_diagonal}, '
- f' normalized_diagonal: {normalized_diagonal}')
+ if normalized_area > 1 or normalized_area < 0:
+ raise AssertionError(f'normalized area > 1 or < 0! '
+ f'image_size[0]: {image_size[0]}, '
+ f'image_size[1]: {image_size[1]}, '
+ f'normalized_area: {normalized_area}')
# Threshold should be larger for images with smaller resolution
- normalized_threshold_percent = ((1 - normalized_diagonal) *
+ normalized_threshold_percent = ((1 - normalized_area) *
(_MAX_CENTER_THRESHOLD_PERCENT -
_MIN_CENTER_THRESHOLD_PERCENT))
@@ -144,7 +140,7 @@ class PreviewStabilizationFoVTest(its_base_test.ItsBaseTest):
# Load scene.
its_session_utils.load_scene(cam, props, self.scene,
- self.tablet, chart_distance=0)
+ self.tablet, self.chart_distance)
# Check skip condition
first_api_level = its_session_utils.get_first_api_level(self.dut.serial)
@@ -253,7 +249,8 @@ class PreviewStabilizationFoVTest(its_base_test.ItsBaseTest):
f'{_ROUNDESS_DELTA_THRESHOLD}, '
f'actual ratio difference: {roundness_diff}. ')
- # Distance between centers
+ # Distance between centers, x_offset and y_offset are relative to the
+ # radius of the circle, so they're normalized. Not pixel values.
unstab_center = (ustab_circle['x_offset'], ustab_circle['y_offset'])
logging.debug('unstabilized center: %s', unstab_center)
stab_center = (stab_circle['x_offset'], stab_circle['y_offset'])
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 6eaca195c22..bb713672e00 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
@@ -137,13 +137,13 @@ class VideoAspectRatioAndCropTest(its_base_test.ItsBaseTest):
logging.debug('physical available focal lengths: %s', str(fls_physical))
# Check SKIP conditions.
- first_api_level = its_session_utils.get_first_api_level(self.dut.serial)
+ vendor_api_level = its_session_utils.get_vendor_api_level(self.dut.serial)
camera_properties_utils.skip_unless(
- first_api_level >= its_session_utils.ANDROID13_API_LEVEL)
+ vendor_api_level >= its_session_utils.ANDROID13_API_LEVEL)
# Load scene.
its_session_utils.load_scene(cam, props, self.scene,
- self.tablet, chart_distance=0)
+ self.tablet, self.chart_distance)
# Determine camera capabilities.
supported_video_qualities = cam.get_supported_video_qualities(
diff --git a/apps/CameraITS/tests/sensor_fusion/test_video_stabilization.py b/apps/CameraITS/tests/sensor_fusion/test_video_stabilization.py
index 0be38b56d11..195d5670eba 100644
--- a/apps/CameraITS/tests/sensor_fusion/test_video_stabilization.py
+++ b/apps/CameraITS/tests/sensor_fusion/test_video_stabilization.py
@@ -129,7 +129,7 @@ class VideoStabilizationTest(its_base_test.ItsBaseTest):
in gyroscope movement. Test is a PASS if rotation is reduced in video.
"""
- def test_video_stability(self):
+ def test_video_stabilization(self):
rot_rig = {}
log_path = self.log_path
@@ -139,12 +139,12 @@ class VideoStabilizationTest(its_base_test.ItsBaseTest):
hidden_physical_id=self.hidden_physical_id) as cam:
props = cam.get_camera_properties()
props = cam.override_with_hidden_physical_camera_props(props)
- first_api_level = its_session_utils.get_first_api_level(self.dut.serial)
+ vendor_api_level = its_session_utils.get_vendor_api_level(self.dut.serial)
supported_stabilization_modes = props[
'android.control.availableVideoStabilizationModes']
camera_properties_utils.skip_unless(
- first_api_level >= its_session_utils.ANDROID13_API_LEVEL and
+ vendor_api_level >= its_session_utils.ANDROID13_API_LEVEL and
_VIDEO_STABILIZATION_MODE in supported_stabilization_modes)
# Raise error if not FRONT or REAR facing camera
diff --git a/apps/CameraITS/utils/its_session_utils.py b/apps/CameraITS/utils/its_session_utils.py
index e91565e250f..c2065ba6ac4 100644
--- a/apps/CameraITS/utils/its_session_utils.py
+++ b/apps/CameraITS/utils/its_session_utils.py
@@ -1612,6 +1612,18 @@ def get_first_api_level(device_id):
return first_api_level
+def get_vendor_api_level(device_id):
+ """Return the int value for the vendor API level of the device."""
+ cmd = 'adb -s %s shell getprop ro.vendor.api_level' % device_id
+ try:
+ vendor_api_level = int(subprocess.check_output(cmd.split()).rstrip())
+ logging.debug('First vendor API level: %d', vendor_api_level)
+ except (subprocess.CalledProcessError, ValueError):
+ logging.error('No vendor_api_level. Setting to build version.')
+ vendor_api_level = get_build_sdk_version(device_id)
+ return vendor_api_level
+
+
class ItsSessionUtilsTests(unittest.TestCase):
"""Run a suite of unit tests on this module."""
diff --git a/apps/CtsVerifier/Android.bp b/apps/CtsVerifier/Android.bp
index b4485d19e99..024e0387c6f 100644
--- a/apps/CtsVerifier/Android.bp
+++ b/apps/CtsVerifier/Android.bp
@@ -91,6 +91,7 @@ android_library {
"CtsForceStopHelper-constants",
"ctsmediautil",
"DpmWrapper",
+ "MediaPerformanceClassCommon",
],
libs: ["telephony-common"] + ["android.test.runner.stubs"] + ["android.test.base.stubs"] + ["android.test.mock.stubs"] + ["android.car-test-stubs"] + ["voip-common"] + ["truth-prebuilt"],
@@ -114,7 +115,7 @@ android_test {
compile_multilib: "both",
- manifest: "AndroidManifest-verifierConfig.xml",
+ additional_manifests: ["AndroidManifest-verifierConfig.xml"],
jni_libs: [
"libctsverifier_jni",
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 5a257de64f1..db1ca21c978 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -248,6 +248,7 @@
<action android:name="android.intent.action.MAIN" />
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
+ <meta-data android:name="CddTest" android:value="3.8.17/C-1-1,C-2-1" />
<meta-data android:name="test_category" android:value="@string/test_category_features" />
<meta-data android:name="test_excluded_features"
android:value="android.hardware.type.watch:android.software.leanback:android.hardware.type.automotive" />
@@ -3901,174 +3902,6 @@
android:value="single_display_mode" />
</activity>
- <!-- CTS Verifier Presence Test Top Screen -->
- <activity
- android:name=".presence.PresenceTestActivity"
- android:configChanges="keyboardHidden|orientation|screenSize"
- android:exported="true"
- android:label="@string/presence_test" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
-
- <category android:name="android.cts.intent.category.MANUAL_TEST" />
- </intent-filter>
-
- <meta-data
- android:name="test_category"
- android:value="@string/test_category_networking" />
- <meta-data android:name="display_mode"
- android:value="single_display_mode" />
- </activity>
-
- <!--
- CTS Verifier Uwb Precision Test Screen
- test category : uwb
- test parent : PresenceTestActivity
- -->
- <activity
- android:name=".presence.UwbPrecisionActivity"
- android:configChanges="keyboardHidden|orientation|screenSize"
- android:exported="true"
- android:label="@string/uwb_precision" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
-
- <category android:name="android.cts.intent.category.MANUAL_TEST" />
- </intent-filter>
-
- <meta-data
- android:name="test_category"
- android:value="@string/uwb" />
- <meta-data
- android:name="test_parent"
- android:value="com.android.cts.verifier.presence.PresenceTestActivity" />
- <meta-data android:name="display_mode"
- android:value="single_display_mode" />
- <meta-data android:name="CddTest"
- android:value="7.4.9/C-1-1" />
- </activity>
-
- <!--
- CTS Verifier Uwb Short Range Test Screen
- test category : uwb
- test parent : PresenceTestActivity
- -->
- <activity
- android:name=".presence.UwbShortRangeActivity"
- android:configChanges="keyboardHidden|orientation|screenSize"
- android:exported="true"
- android:label="@string/uwb_short_range" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
-
- <category android:name="android.cts.intent.category.MANUAL_TEST" />
- </intent-filter>
-
- <meta-data
- android:name="test_category"
- android:value="@string/uwb" />
- <meta-data
- android:name="test_parent"
- android:value="com.android.cts.verifier.presence.PresenceTestActivity" />
- <meta-data
- android:name="display_mode"
- android:value="single_display_mode" />
- <meta-data
- android:name="CddTest"
- android:value="7.4.9/C-1-2" />
- </activity>
-
- <!--
- CTS Verifier BLE RSSI Precision Test Screen
- test category : BLE
- test parent : PresenceTestActivity
- -->
- <activity
- android:name=".presence.BleRssiPrecisionActivity"
- android:exported="true"
- android:label="@string/ble_rssi_precision_name">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
-
- <category android:name="android.cts.intent.category.MANUAL_TEST" />
- </intent-filter>
-
- <meta-data
- android:name="test_category"
- android:value="@string/ble" />
- <meta-data
- android:name="test_parent"
- android:value="com.android.cts.verifier.presence.PresenceTestActivity" />
- <meta-data
- android:name="test_required_features"
- android:value="android.hardware.bluetooth_le" />
- <meta-data
- android:name="display_mode"
- android:value="single_display_mode" />
- <meta-data
- android:name="CddText"
- android:value="7.4.3/C-7-1" />
- </activity>
-
- <!--
- CTS Verifier BLE Rx/Tx Calibration Test Screen
- test category : BLE
- test parent : PresenceTestActivity
- -->
- <activity
- android:name=".presence.BleRxTxCalibrationActivity"
- android:exported="true"
- android:label="@string/ble_rx_tx_calibration_name">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
-
- <category android:name="android.cts.intent.category.MANUAL_TEST" />
- </intent-filter>
-
- <meta-data
- android:name="test_category"
- android:value="@string/ble" />
- <meta-data
- android:name="test_parent"
- android:value="com.android.cts.verifier.presence.PresenceTestActivity" />
- <meta-data
- android:name="test_required_features"
- android:value="android.hardware.bluetooth_le" />
- <meta-data
- android:name="display_mode"
- android:value="single_display_mode" />
- <meta-data
- android:name="CddText"
- android:value="7.4.3/C-7-2" />
- </activity>
-
- <!-- CTS Verifier Nan Precision and Bias Test Screen
- test category : wifi_nan
- test parent : PresenceTestActivity
- -->
- <activity
- android:name=".presence.NanPrecisionTestActivity"
- android:configChanges="keyboardHidden|orientation|screenSize"
- android:exported="true"
- android:label="@string/nan_precision" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
-
- <category android:name="android.cts.intent.category.MANUAL_TEST" />
- </intent-filter>
-
- <meta-data
- android:name="test_category"
- android:value="@string/wifi_nan" />
- <meta-data
- android:name="test_parent"
- android:value="com.android.cts.verifier.presence.PresenceTestActivity" />
- <meta-data android:name="display_mode"
- android:value="single_display_mode" />
- <meta-data android:name="CddTest"
- android:value="7.4.2.5/H-1-1|7.4.2.5/H-1-2" />
- </activity>
-
<activity-alias
android:name=".CtsVerifierActivity"
android:label="@string/app_name"
@@ -6159,6 +5992,7 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_logcat" />
+ <meta-data android:name="test_excluded_features" android:value="android.hardware.type.automotive" />
</activity>
<activity android:name=".displaycutout.DisplayCutoutTestActivity"
diff --git a/apps/CtsVerifier/res/layout/ble_rssi_precision.xml b/apps/CtsVerifier/res/layout/ble_rssi_precision.xml
deleted file mode 100644
index 5f01e1fc442..00000000000
--- a/apps/CtsVerifier/res/layout/ble_rssi_precision.xml
+++ /dev/null
@@ -1,60 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2022 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- style="@style/RootLayoutPadding"
- tools:ignore="Autofill">
-
- <ScrollView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content">
-
- <LinearLayout
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <TextView
- android:text="@string/ble_rssi_precision_test_instructions"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:scrollbars="vertical" />
-
- <EditText
- android:id="@+id/report_rssi_range"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:hint="@string/report_ble_rssi_range"
- android:inputType="number" />
-
- <EditText
- android:id="@+id/report_reference_device"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:hint="@string/report_reference_device"
- android:inputType="text" />
-
- <include
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- layout="@layout/pass_fail_buttons" />
- </LinearLayout>
- </ScrollView>
-</RelativeLayout>
diff --git a/apps/CtsVerifier/res/layout/ble_rx_tx_calibration.xml b/apps/CtsVerifier/res/layout/ble_rx_tx_calibration.xml
deleted file mode 100644
index 3ca955b7e30..00000000000
--- a/apps/CtsVerifier/res/layout/ble_rx_tx_calibration.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright (C) 2022 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- style="@style/RootLayoutPadding"
- tools:ignore="Autofill">
-
- <ScrollView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content">
-
- <LinearLayout
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <TextView
- android:text="@string/ble_rx_tx_calibration_test_instructions"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:scrollbars="vertical" />
-
- <EditText
- android:id="@+id/report_channels_rssi_range"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:hint="@string/report_channels_ble_rssi_range"
- android:inputType="number" />
-
- <EditText
- android:id="@+id/report_cores_rssi_range"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:hint="@string/report_cores_ble_rssi_range"
- android:inputType="number" />
-
- <EditText
- android:id="@+id/report_reference_device"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:hint="@string/report_reference_device"
- android:inputType="text" />
-
- <include
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- layout="@layout/pass_fail_buttons" />
- </LinearLayout>
- </ScrollView>
-</RelativeLayout>
diff --git a/apps/CtsVerifier/res/layout/clipboard_preview.xml b/apps/CtsVerifier/res/layout/clipboard_preview.xml
index 85f38c8eef7..efec118cb4d 100644
--- a/apps/CtsVerifier/res/layout/clipboard_preview.xml
+++ b/apps/CtsVerifier/res/layout/clipboard_preview.xml
@@ -31,86 +31,6 @@
android:layout_marginBottom="100dp"
android:layout_marginTop="30dp"
android:text="@string/clipboard_preview_test_copy_button"/>
-
- <TableLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
- <TableRow
- android:layout_width="match_parent"
- android:layout_height="50dp">
- <View android:layout_weight="3"
- android:layout_height="50dp"/>
- <Button android:layout_weight="1"
- android:id="@+id/clipboard_preview_test_b1"
- android:layout_width="50dp"
- android:layout_height="50dp"
- android:text="1"/>
- <Button android:layout_weight="1"
- android:id="@+id/clipboard_preview_test_b2"
- android:layout_width="50dp"
- android:layout_height="50dp"
- android:text="2"/>
- <Button android:layout_weight="1"
- android:id="@+id/clipboard_preview_test_b3"
- android:layout_width="50dp"
- android:layout_height="50dp"
- android:text="3"/>
- <View android:layout_weight="3"
- android:layout_height="50dp"/>
- </TableRow>
- <TableRow
- android:layout_width="match_parent"
- android:layout_height="50dp">
- <View android:layout_weight="3"
- android:layout_height="50dp"/>
- <Button android:layout_weight="1"
- android:id="@+id/clipboard_preview_test_b4"
- android:layout_width="50dp"
- android:layout_height="50dp"
- android:text="4"/>
- <Button android:layout_weight="1"
- android:id="@+id/clipboard_preview_test_b5"
- android:layout_width="50dp"
- android:layout_height="50dp"
- android:text="5"/>
- <Button android:layout_weight="1"
- android:id="@+id/clipboard_preview_test_b6"
- android:layout_width="50dp"
- android:layout_height="50dp"
- android:text="6"/>
- <View android:layout_weight="3"
- android:layout_height="50dp"/>
- </TableRow>
- <TableRow
- android:layout_width="match_parent"
- android:layout_height="50dp">
- <View android:layout_weight="3"
- android:layout_height="match_parent"/>
- <Button android:layout_weight="1"
- android:id="@+id/clipboard_preview_test_b7"
- android:layout_width="50dp"
- android:layout_height="match_parent"
- android:text="7"/>
- <Button android:layout_weight="1"
- android:id="@+id/clipboard_preview_test_b8"
- android:layout_width="50dp"
- android:layout_height="match_parent"
- android:text="8"/>
- <Button android:layout_weight="1"
- android:id="@+id/clipboard_preview_test_b9"
- android:layout_width="50dp"
- android:layout_height="match_parent"
- android:text="9"/>
- <View android:layout_weight="3"
- android:layout_height="50dp"/>
- </TableRow>
- </TableLayout>
- <Button
- android:id="@+id/clipboard_preview_test_b0"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:text="0"/>
<include
android:id="@+id/clipboard_preview_test_pass_fail"
android:layout_width="match_parent"
diff --git a/apps/CtsVerifier/res/layout/nan_precision.xml b/apps/CtsVerifier/res/layout/nan_precision.xml
deleted file mode 100644
index c81a9c4f120..00000000000
--- a/apps/CtsVerifier/res/layout/nan_precision.xml
+++ /dev/null
@@ -1,92 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2022 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- style="@style/RootLayoutPadding">
- <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content">
- <LinearLayout android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
- <TextView android:text="@string/nan_precision_instruction"
- android:id="@+id/nan_precision_instruction"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:scrollbars="vertical"/>
- <LinearLayout android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
- <EditText android:id="@+id/nan_bandwidth"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:inputType="number"
- android:hint="@string/report_nan_bandwidth_mhz"/>
- <EditText android:id="@+id/distance_range_10cm_gt_68p"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:inputType="numberDecimal"
- android:hint="@string/report_distance_range_10cm_gt_68p"/>
- <EditText android:id="@+id/distance_range_1m_gt_68p"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:inputType="numberDecimal"
- android:hint="@string/report_distance_range_1m_gt_68p"/>
- <EditText android:id="@+id/distance_range_3m_gt_68p"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:inputType="numberDecimal"
- android:hint="@string/report_distance_range_3m_gt_68p"/>
- <EditText android:id="@+id/distance_range_5m_gt_68p"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:inputType="numberDecimal"
- android:hint="@string/report_distance_range_5m_gt_68p"/>
- <EditText android:id="@+id/distance_range_10cm_gt_90p"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:inputType="numberDecimal"
- android:hint="@string/report_distance_range_10cm_gt_90p"/>
- <EditText android:id="@+id/distance_range_1m_gt_90p"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:inputType="numberDecimal"
- android:hint="@string/report_distance_range_1m_gt_90p"/>
- <EditText android:id="@+id/distance_range_3m_gt_90p"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:inputType="numberDecimal"
- android:hint="@string/report_distance_range_3m_gt_90p"/>
- <EditText android:id="@+id/distance_range_5m_gt_90p"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:inputType="numberDecimal"
- android:hint="@string/report_distance_range_5m_gt_90p"/>
- <EditText android:id="@+id/reference_device"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:hint="@string/report_reference_device"/>
- </LinearLayout>
-
- <include android:layout_width="match_parent"
- android:layout_height="wrap_content"
- layout="@layout/pass_fail_buttons"/>
- </LinearLayout>
- </ScrollView>
-</RelativeLayout>
diff --git a/apps/CtsVerifier/res/layout/uwb_precision.xml b/apps/CtsVerifier/res/layout/uwb_precision.xml
deleted file mode 100644
index 14e996d6f5f..00000000000
--- a/apps/CtsVerifier/res/layout/uwb_precision.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- style="@style/RootLayoutPadding">
- <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content">
- <LinearLayout android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
- <TextView android:text="@string/uwb_precision_instruction"
- android:id="@+id/uwb_precision_instruction"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:scrollbars="vertical"/>
- <LinearLayout android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
- <EditText android:id="@+id/distance_range_cm"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:inputType="numberDecimal"
- android:hint="@string/report_distance_range_cm"/>
- <EditText android:id="@+id/reference_device"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:hint="@string/report_reference_device"/>
- </LinearLayout>
-
- <include android:layout_width="match_parent"
- android:layout_height="wrap_content"
- layout="@layout/pass_fail_buttons"/>
- </LinearLayout>
- </ScrollView>
-</RelativeLayout>
diff --git a/apps/CtsVerifier/res/layout/uwb_short_range.xml b/apps/CtsVerifier/res/layout/uwb_short_range.xml
deleted file mode 100644
index 9afc6e5a6b4..00000000000
--- a/apps/CtsVerifier/res/layout/uwb_short_range.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- style="@style/RootLayoutPadding">
- <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content">
- <LinearLayout android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
- <TextView android:text="@string/uwb_short_range_instruction"
- android:id="@+id/uwb_short_range_instruction"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:scrollbars="vertical"/>
- <LinearLayout android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
- <EditText android:id="@+id/distance_median_meters"
- android:layout_width="wrap_content"
- android:inputType="numberDecimal"
- android:layout_height="wrap_content"
- android:hint="@string/report_distance_median_meters"/>
- <EditText android:id="@+id/reference_device"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:hint="@string/report_reference_device"/>
- </LinearLayout>
-
- <include android:layout_width="match_parent"
- android:layout_height="wrap_content"
- layout="@layout/pass_fail_buttons"/>
- </LinearLayout>
- </ScrollView>
-</RelativeLayout>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 4862965ba9d..0f32b34e78e 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -32,6 +32,16 @@
<string name="finish_button_text">Finish</string>
<string name="fail_and_next_button_text">Fail and Next</string>
+ <!-- Strings for CtsReportLog warning -->
+ <string name="reportlog_warning_title">CTS-Verifier Report Log</string>
+ <string name="reportlog_warning_body">Can\'t create folder for CTS-Verifier Report Logs.
+ \n\nPlease enable Report Log creation by exiting CTS Verifier and running the following commands:
+ \n\n<code>adb shell appops set com.android.cts.verifier android:read_device_identifiers allow</code>
+ \n\n<code>adb shell appops set com.android.cts.verifier MANAGE_EXTERNAL_STORAGE 0</code>
+ \n\nTest instructions are found in the \"Using CTS Verifier\" document found at
+ <a href="https://source.android.com/compatibility/cts/verifier">https://source.android.com/compatibility/cts/verifier</a>
+ </string>
+
<!-- Strings for TestListActivity -->
<string name="test_category_audio">Audio</string>
<string name="test_category_camera">Camera</string>
@@ -301,9 +311,11 @@
</string>
<string name="clipboard_preview_test_instructions">
Press the \'Copy\' button to copy the secret code to the clipboard.
- \n\nUse the clipboard preview UI, or the clipboard editor component to view the secret code.
- \n\nEnter the secret code using the buttons below.
+ \n\n If nothing happens, press Fail.
+ \n\n If you see the word "FAIL" appear on screen, press Fail.
+ \n\n If you see a confirmation that content has been copied to the clipboard, press Pass.
</string>
+ <string name="clipboard_preview_test_secret">FAIL</string>
<string name="clipboard_preview_test_copy_button">Copy</string>
@@ -778,7 +790,7 @@
<!-- BLE Advertising Set test strings -->
<string name="ble_advertising_set_test_name">Bluetooth LE Advertising Set Test</string>
<string name="ble_advertising_set_test_info">Bluetooth LE Advertising Set tests AdvertisingSet and AdvertisingSetCallback APIs.</string>
- <string name="ble_advertising_set_test_instruction">Press the \"Set Up\" button first, then start the test by pressing the \"Start Test\" button. UI thread may freeze for a few seconds while enabling/disabling bluetooth adapter.</string>
+ <string name="ble_advertising_set_test_instruction">Press the \"Start Test\" button. UI thread may freeze for a few seconds while enabling/disabling bluetooth adapter.</string>
<string name="ble_advertising_set_start_test">Start Test</string>
<string name="ble_advertising_set_running_test">Running Test...</string>
<string name="ble_advertising_set_finished_test">Finished Test</string>
@@ -5480,6 +5492,7 @@ You should be prompted to select credentials; choose the ones you just installed
<string name="audio_general_test_not_run">Test Not Run</string>
<string name="audio_general_testnotcompleted">Test not completed.</string>
+ <string name="audio_general_reportlogtest">[Can\'t Write ReportLog]</string>
<!-- Audio Loopback Latency Test -->
<string name="audio_loopback_latency_test">Audio Loopback Latency Test</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/CtsVerifierReportLog.java b/apps/CtsVerifier/src/com/android/cts/verifier/CtsVerifierReportLog.java
index b013bb7180e..a93e3b58c33 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/CtsVerifierReportLog.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/CtsVerifierReportLog.java
@@ -74,6 +74,10 @@ public class CtsVerifierReportLog extends ReportLog {
}
}
+ public boolean isOpen() {
+ return mStore != null;
+ }
+
/**
* Closes report file. Static functions that do not have access to instrumentation can
* use this to close report logs. Summary, if present, is not reported to instrumentation, hence
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java b/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java
index 0294ff78e7c..7b993eefc58 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java
@@ -32,7 +32,6 @@ import android.database.Cursor;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
@@ -146,6 +145,8 @@ public class PassFailButtons {
private final CtsVerifierReportLog mReportLog;
private final TestResultHistoryCollection mHistoryCollection;
+ protected boolean mRequireReportLogToPass;
+
public Activity() {
this.mReportLog = new CtsVerifierReportLog(getReportFileName(), getReportSectionName());
this.mHistoryCollection = new TestResultHistoryCollection();
@@ -159,6 +160,10 @@ public class PassFailButtons {
.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "PassFailButtons");
mWakeLock.acquire();
}
+
+ if (!this.mReportLog.isOpen()) {
+ showReportLogWarningDialog(this);
+ }
}
@Override
@@ -212,6 +217,14 @@ public class PassFailButtons {
}
/**
+ * A mechanism to block tests from passing if no ReportLog data has been collected.
+ * @return true if the ReportLog is open OR if the test does not require that.
+ */
+ public boolean isReportLogOkToPass() {
+ return !mRequireReportLogToPass || mReportLog.isOpen();
+ }
+
+ /**
* @return The name of the file to store the (suite of) ReportLog information.
*/
@Override
@@ -527,6 +540,12 @@ public class PassFailButtons {
activity.showDialog(INFO_DIALOG_ID, args);
}
+ protected static void showReportLogWarningDialog(final android.app.Activity activity) {
+ showInfoDialog(activity,
+ R.string.reportlog_warning_title, R.string.reportlog_warning_body, -1);
+ }
+
+
protected static Dialog createDialog(final android.app.Activity activity, int id, Bundle args) {
switch (id) {
case INFO_DIALOG_ID:
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AnalogHeadsetAudioActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AnalogHeadsetAudioActivity.java
index 528d9149588..83b32def714 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AnalogHeadsetAudioActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AnalogHeadsetAudioActivity.java
@@ -182,12 +182,15 @@ public class AnalogHeadsetAudioActivity
mResultsTxt.setText(getResources().getString(R.string.analog_headset_pass_noheadset));
return true;
} else {
- boolean pass = mPlugIntentReceived &&
- mHeadsetDeviceInfo != null &&
- mPlaybackSuccess &&
- (mHasHeadsetHook || mHasPlayPause) && mHasVolUp && mHasVolDown;
+ boolean pass = isReportLogOkToPass()
+ && mPlugIntentReceived
+ && mHeadsetDeviceInfo != null
+ && mPlaybackSuccess
+ && (mHasHeadsetHook || mHasPlayPause) && mHasVolUp && mHasVolDown;
if (pass) {
mResultsTxt.setText(getResources().getString(R.string.analog_headset_pass));
+ } else if (!isReportLogOkToPass()) {
+ mResultsTxt.setText(getResources().getString(R.string.audio_general_reportlogtest));
}
return pass;
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioAEC.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioAEC.java
index 48795efc142..3c1b8a1151e 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioAEC.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioAEC.java
@@ -542,8 +542,10 @@ public class AudioAEC extends AudioFrequencyActivity implements View.OnClickList
Log.v(TAG, "Test EndedOk. " + testId + " str:"+str);
showView(mProgress, false);
mResultTest.setText("test completed. " + str);
- if (mTestAECPassed) {
- getPassButton().setEnabled(true);;
+ if (!isReportLogOkToPass()) {
+ mResultTest.setText(getResources().getString(R.string.audio_general_reportlogtest));
+ } else if (mTestAECPassed) {
+ getPassButton().setEnabled(true);
}
}
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 a6bd4add994..79d3e3b2b0b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackLatencyActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackLatencyActivity.java
@@ -294,6 +294,8 @@ public class AudioLoopbackLatencyActivity extends PassFailButtons.Activity {
getPassButton().setEnabled(false);
setInfoResources(R.string.audio_loopback_latency_test, R.string.audio_loopback_info, -1);
+ mRequireReportLogToPass = true;
+
mClaimsOutput = AudioSystemFlags.claimsOutput(this);
mClaimsInput = AudioSystemFlags.claimsInput(this);
mClaimsProAudio = AudioSystemFlags.claimsProAudio(this);
@@ -683,7 +685,8 @@ public class AudioLoopbackLatencyActivity extends PassFailButtons.Activity {
mResultsText[mTestRoute].setText(testSpec.getResultString());
LoopbackLatencyRequirements requirements = new LoopbackLatencyRequirements();
- boolean pass = requirements.evaluate(mClaimsProAudio,
+ boolean pass = isReportLogOkToPass()
+ && requirements.evaluate(mClaimsProAudio,
Build.VERSION.MEDIA_PERFORMANCE_CLASS,
mTestSpecs[TESTROUTE_DEVICE].isMeasurementValid()
? mTestSpecs[TESTROUTE_DEVICE].mMeanLatencyMS : 0.0,
@@ -694,8 +697,12 @@ public class AudioLoopbackLatencyActivity extends PassFailButtons.Activity {
getPassButton().setEnabled(pass);
- String resultText = requirements.getResultsString();
- mTestStatusText.setText(resultText);
+ StringBuilder sb = new StringBuilder();
+ if (!isReportLogOkToPass()) {
+ sb.append(getResources().getString(R.string.audio_general_reportlogtest) + "\n");
+ }
+ sb.append(requirements.getResultsString());
+ mTestStatusText.setText(sb.toString());
showWait(false);
enableStartButtons(true);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioTap2ToneActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioTap2ToneActivity.java
index 215d26fd65b..8ff23588889 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioTap2ToneActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioTap2ToneActivity.java
@@ -154,6 +154,8 @@ public class AudioTap2ToneActivity
String yesString = getResources().getString(R.string.audio_general_yes);
String noString = getResources().getString(R.string.audio_general_no);
+ mRequireReportLogToPass = true;
+
boolean claimsProAudio = AudioSystemFlags.claimsProAudio(this);
boolean claimsLowLatencyAudio = AudioSystemFlags.claimsLowLatencyAudio(this);
@@ -311,11 +313,14 @@ public class AudioTap2ToneActivity
}
double averageLatency = mLatencyAve[mActiveTestAPI];
- boolean pass = averageLatency != 0 && averageLatency <= mMaxRequiredLatency;
+ boolean pass = isReportLogOkToPass()
+ && averageLatency != 0 && averageLatency <= mMaxRequiredLatency;
if (pass) {
mSpecView.setText("Average: " + averageLatency + " ms <= "
+ mMaxRequiredLatency + " ms -- PASS");
+ } else if (!isReportLogOkToPass()) {
+ mSpecView.setText(getResources().getString(R.string.audio_general_reportlogtest));
} else {
mSpecView.setText("Average: " + averageLatency + " ms > "
+ mMaxRequiredLatency + " ms -- FAIL");
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java
index 126d15fdacb..e93d2b319ff 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java
@@ -158,11 +158,9 @@ public class ProAudioActivity
boolean usbOK = mClaimsUSBHostMode && mClaimsUSBPeripheralMode;
boolean hdmiOK = !mClaimsHDMI || isHDMIValid();
- boolean hasPassed = !mClaimsProAudio ||
- (mClaimsLowLatencyAudio &&
- mClaimsMIDI &&
- usbOK &&
- hdmiOK);
+ boolean hasPassed = isReportLogOkToPass()
+ && !mClaimsProAudio
+ || (mClaimsLowLatencyAudio && mClaimsMIDI && usbOK && hdmiOK);
getPassButton().setEnabled(hasPassed);
return hasPassed;
@@ -172,7 +170,9 @@ public class ProAudioActivity
boolean hasPassed = calculatePass();
Resources strings = getResources();
- if (hasPassed) {
+ if (!isReportLogOkToPass()) {
+ mTestStatusLbl.setText(getResources().getString(R.string.audio_general_reportlogtest));
+ } else if (hasPassed) {
mTestStatusLbl.setText(strings.getString(R.string.audio_proaudio_pass));
} else if (!mClaimsMIDI) {
mTestStatusLbl.setText(strings.getString(R.string.audio_proaudio_midinotreported));
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralNotificationsTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralNotificationsTest.java
index bc23048c28e..6270a5a8311 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralNotificationsTest.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralNotificationsTest.java
@@ -20,23 +20,17 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-
import android.media.AudioDeviceCallback;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
-
import android.os.Bundle;
import android.os.Handler;
-
import android.util.Log;
-
import android.widget.TextView;
import com.android.compatibility.common.util.CddTest;
-import com.android.compatibility.common.util.ReportLog;
import com.android.compatibility.common.util.ResultType;
import com.android.compatibility.common.util.ResultUnit;
-
import com.android.cts.verifier.PassFailButtons;
import com.android.cts.verifier.R; // needed to access resource in CTSVerifier project namespace.
@@ -173,9 +167,10 @@ public class USBAudioPeripheralNotificationsTest extends PassFailButtons.Activit
// Test Status
//
private boolean calculatePass() {
- return mUsbHeadsetInReceived && mUsbHeadsetOutReceived &&
- mUsbDeviceInReceived && mUsbDeviceOutReceived &&
- mPlugIntentReceived;
+ return isReportLogOkToPass()
+ && mUsbHeadsetInReceived && mUsbHeadsetOutReceived
+ && mUsbDeviceInReceived && mUsbDeviceOutReceived
+ && mPlugIntentReceived;
}
//
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertisingSetTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertisingSetTestActivity.java
index 07a70c69cb4..164992b94a9 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertisingSetTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertisingSetTestActivity.java
@@ -99,11 +99,6 @@ public class BleAdvertisingSetTestActivity extends PassFailButtons.Activity {
R.string.ble_advertising_set_test_info, -1);
getPassButton().setEnabled(false);
- mBluetoothManager = getSystemService(BluetoothManager.class);
- mBluetoothAdapter = mBluetoothManager.getAdapter();
- mAdvertiser = mBluetoothAdapter.getBluetoothLeAdvertiser();
- mCallback = new TestAdvertisingSetCallback();
-
mTestAdapter = new TestAdapter(this, setupTestList());
ListView listView = findViewById(R.id.ble_advertising_set_tests);
listView.setAdapter(mTestAdapter);
@@ -133,9 +128,7 @@ public class BleAdvertisingSetTestActivity extends PassFailButtons.Activity {
testEnableAndDisableAdvertising();
testSetAdvertisingData();
testSetAdvertisingParameters();
- if (mBluetoothAdapter.isLePeriodicAdvertisingSupported()) {
- testPeriodicAdvertising();
- }
+ testPeriodicAdvertising();
testSetScanResponseData();
stopAdvertisingSet();
} catch (InterruptedException e) {
@@ -167,6 +160,11 @@ public class BleAdvertisingSetTestActivity extends PassFailButtons.Activity {
});
mAllTestsPassed = 0;
+
+ mBluetoothManager = getSystemService(BluetoothManager.class);
+ mBluetoothAdapter = mBluetoothManager.getAdapter();
+ mAdvertiser = mBluetoothAdapter.getBluetoothLeAdvertiser();
+ mCallback = new TestAdvertisingSetCallback();
}
private void startAdvertisingSet() throws InterruptedException {
@@ -323,11 +321,9 @@ public class BleAdvertisingSetTestActivity extends PassFailButtons.Activity {
testList.add(R.string.ble_advertising_set_enable_disable);
testList.add(R.string.ble_advertising_set_advertising_data);
testList.add(R.string.ble_advertising_set_advertising_params);
- if (mBluetoothAdapter.isLePeriodicAdvertisingSupported()) {
- testList.add(R.string.ble_advertising_set_periodic_advertising_data);
- testList.add(R.string.ble_advertising_set_periodic_advertising_enabled_disabled);
- testList.add(R.string.ble_advertising_set_periodic_advertising_params);
- }
+ testList.add(R.string.ble_advertising_set_periodic_advertising_data);
+ testList.add(R.string.ble_advertising_set_periodic_advertising_enabled_disabled);
+ testList.add(R.string.ble_advertising_set_periodic_advertising_params);
testList.add(R.string.ble_advertising_set_scan_response_data);
testList.add(R.string.ble_advertising_set_stop);
return testList;
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 861c6f68810..212f988d205 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
@@ -1847,6 +1847,8 @@ public class ItsService extends Service implements SensorEventListener {
// s1440p which is the max supported stream size in a combination, when preview
// stabilization is on.
Size maxPreviewSize = new Size(1920, 1440);
+ // QCIF, we test only sizes >= this.
+ Size minPreviewSize = new Size(176, 144);
Size[] outputSizes = configMap.getOutputSizes(ImageFormat.YUV_420_888);
if (outputSizes == null) {
mSocketRunnableObj.sendResponse("supportedPreviewSizes", "");
@@ -1857,6 +1859,8 @@ public class ItsService extends Service implements SensorEventListener {
.distinct()
.filter(s -> s.getWidth() * s.getHeight()
<= maxPreviewSize.getWidth() * maxPreviewSize.getHeight())
+ .filter(s -> s.getWidth() * s.getHeight()
+ >= minPreviewSize.getWidth() * minPreviewSize.getHeight())
.sorted(Comparator.comparingInt(s -> s.getWidth() * s.getHeight()))
.map(Size::toString)
.collect(Collectors.joining(";"));
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java
index d83464bd549..692538a81c3 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java
@@ -21,9 +21,8 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
-import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraManager;
-import android.os.Build;
+import android.mediapc.cts.common.PerformanceClassEvaluator;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
@@ -31,6 +30,11 @@ import android.view.WindowManager;
import android.widget.TextView;
import android.widget.Toast;
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
@@ -39,17 +43,11 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
-import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import java.io.BufferedReader;
-import java.io.FileReader;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-
import com.android.compatibility.common.util.ResultType;
import com.android.compatibility.common.util.ResultUnit;
import com.android.cts.verifier.ArrayTestListAdapter;
@@ -59,6 +57,7 @@ import com.android.cts.verifier.TestResult;
import org.json.JSONArray;
import org.json.JSONObject;
+import org.junit.rules.TestName;
/**
* Test for Camera features that require that the camera be aimed at a specific test scene.
@@ -81,12 +80,6 @@ public class ItsTestActivity extends DialogTestListActivity {
Arrays.asList(new String[] {RESULT_PASS, RESULT_FAIL, RESULT_NOT_EXECUTED}));
private static final int MAX_SUMMARY_LEN = 200;
- private static final int MPC12_CAMERA_LAUNCH_THRESHOLD = 600; // ms
- private static final int MPC12_JPEG_CAPTURE_THRESHOLD = 1000; // ms
-
- private static final String MPC_TESTS_REPORT_LOG_NAME = "MediaPerformanceClassLogs";
- private static final String MPC_TESTS_REPORT_LOG_SECTION = "CameraIts";
-
private static final Pattern MPC12_CAMERA_LAUNCH_PATTERN =
Pattern.compile("camera_launch_time_ms:(\\d+(\\.\\d+)?)");
private static final Pattern MPC12_JPEG_CAPTURE_PATTERN =
@@ -95,8 +88,12 @@ public class ItsTestActivity extends DialogTestListActivity {
private final ResultReceiver mResultsReceiver = new ResultReceiver();
private boolean mReceiverRegistered = false;
+ public final TestName mTestName = new TestName();
+
// Initialized in onCreate
List<String> mToBeTestedCameraIds = null;
+ String mPrimaryRearCameraId = null;
+ String mPrimaryFrontCameraId = null;
// Scenes
private static final ArrayList<String> mSceneIds = new ArrayList<String> () {{
@@ -132,8 +129,15 @@ public class ItsTestActivity extends DialogTestListActivity {
private final HashMap<ResultKey, String> mSummaryMap = new HashMap<>();
// All primary cameras for which MPC level test has run
private Set<ResultKey> mExecutedMpcTests = null;
- // Map primary camera id to MPC level
- private final HashMap<String, Integer> mMpcLevelMap = new HashMap<>();
+ private static final String MPC_LAUNCH_REQ_NUM = "2.2.7.2/7.5/H-1-6";
+ private static final String MPC_JPEG_CAPTURE_REQ_NUM = "2.2.7.2/7.5/H-1-5";
+ // Performance class evaluator used for writing test result
+ PerformanceClassEvaluator mPce = new PerformanceClassEvaluator(mTestName);
+ PerformanceClassEvaluator.CameraLatencyRequirement mJpegLatencyReq =
+ mPce.addR7_5__H_1_5();
+ PerformanceClassEvaluator.CameraLatencyRequirement mLaunchLatencyReq =
+ mPce.addR7_5__H_1_6();
+
final class ResultKey {
public final String cameraId;
@@ -266,10 +270,7 @@ public class ItsTestActivity extends DialogTestListActivity {
JSONArray metrics = sceneResult.getJSONArray("mpc_metrics");
for (int i = 0; i < metrics.length(); i++) {
String mpcResult = metrics.getString(i);
- if (!matchMpcResult(cameraId, mpcResult, MPC12_CAMERA_LAUNCH_PATTERN,
- "2.2.7.2/7.5/H-1-6", MPC12_CAMERA_LAUNCH_THRESHOLD) &&
- !matchMpcResult(cameraId, mpcResult, MPC12_JPEG_CAPTURE_PATTERN,
- "2.2.7.2/7.5/H-1-5", MPC12_JPEG_CAPTURE_THRESHOLD)) {
+ if (!matchMpcResult(cameraId, mpcResult)) {
Log.e(TAG, "Error parsing MPC result string:" + mpcResult);
return;
}
@@ -294,17 +295,6 @@ public class ItsTestActivity extends DialogTestListActivity {
summary.toString(), 1.0, ResultType.NEUTRAL, ResultUnit.NONE);
}
- // Save MPC info once both front primary and rear primary data are collected.
- if (mExecutedMpcTests.size() == 4) {
- ItsTestActivity.this.getReportLog().addValue(
- "Version", "0.0.1", ResultType.NEUTRAL, ResultUnit.NONE);
- for (Map.Entry<String, Integer> entry : mMpcLevelMap.entrySet()) {
- ItsTestActivity.this.getReportLog().addValue(entry.getKey(),
- entry.getValue(), ResultType.NEUTRAL, ResultUnit.NONE);
- }
- ItsTestActivity.this.getReportLog().submit();
- }
-
// Display current progress
StringBuilder progress = new StringBuilder();
for (ResultKey k : mAllScenes) {
@@ -367,28 +357,44 @@ public class ItsTestActivity extends DialogTestListActivity {
}
}
- private boolean matchMpcResult(String cameraId, String mpcResult, Pattern pattern,
- String reqNum, float threshold) {
- Matcher matcher = pattern.matcher(mpcResult);
- boolean match = matcher.matches();
- final int LATEST_MPC_LEVEL = Build.VERSION_CODES.TIRAMISU;
+ private boolean matchMpcResult(String cameraId, String mpcResult) {
+ Matcher launchMatcher = MPC12_CAMERA_LAUNCH_PATTERN.matcher(mpcResult);
+ boolean launchMatches = launchMatcher.matches();
- if (match) {
- // Store test result
- ItsTestActivity.this.getReportLog().addValue("Cam" + cameraId,
- mpcResult, ResultType.NEUTRAL, ResultUnit.NONE);
+ Matcher jpegMatcher = MPC12_JPEG_CAPTURE_PATTERN.matcher(mpcResult);
+ boolean jpegMatches = jpegMatcher.matches();
- float latency = Float.parseFloat(matcher.group(1));
- int mpcLevel = latency < threshold ? LATEST_MPC_LEVEL : 0;
- mExecutedMpcTests.add(new ResultKey(cameraId, reqNum));
+ if (!launchMatches && !jpegMatches) {
+ return false;
+ }
+ if (!cameraId.equals(mPrimaryRearCameraId) &&
+ !cameraId.equals(mPrimaryFrontCameraId)) {
+ return false;
+ }
- if (mMpcLevelMap.containsKey(reqNum)) {
- mpcLevel = Math.min(mpcLevel, mMpcLevelMap.get(reqNum));
+ if (launchMatches) {
+ float latency = Float.parseFloat(launchMatcher.group(1));
+ if (cameraId.equals(mPrimaryRearCameraId)) {
+ mLaunchLatencyReq.setRearCameraLatency(latency);
+ } else {
+ mLaunchLatencyReq.setFrontCameraLatency(latency);
+ }
+ mExecutedMpcTests.add(new ResultKey(cameraId, MPC_LAUNCH_REQ_NUM));
+ } else {
+ float latency = Float.parseFloat(jpegMatcher.group(1));
+ if (cameraId.equals(mPrimaryRearCameraId)) {
+ mJpegLatencyReq.setRearCameraLatency(latency);
+ } else {
+ mJpegLatencyReq.setFrontCameraLatency(latency);
}
- mMpcLevelMap.put(reqNum, mpcLevel);
+ mExecutedMpcTests.add(new ResultKey(cameraId, MPC_JPEG_CAPTURE_REQ_NUM));
}
- return match;
+ // Save MPC info once both front primary and rear primary data are collected.
+ if (mExecutedMpcTests.size() == 4) {
+ mPce.submit();
+ }
+ return true;
}
}
@@ -397,8 +403,11 @@ public class ItsTestActivity extends DialogTestListActivity {
// Hide the test if all camera devices are legacy
CameraManager manager = (CameraManager) this.getSystemService(Context.CAMERA_SERVICE);
try {
- ItsUtils.ItsCameraIdList cameraIdList = ItsUtils.getItsCompatibleCameraIds(manager);
+ ItsUtils.ItsCameraIdList cameraIdList =
+ ItsUtils.getItsCompatibleCameraIds(manager);
mToBeTestedCameraIds = cameraIdList.mCameraIdCombos;
+ mPrimaryRearCameraId = cameraIdList.mPrimaryRearCameraId;
+ mPrimaryFrontCameraId = cameraIdList.mPrimaryFrontCameraId;
} catch (ItsException e) {
Toast.makeText(ItsTestActivity.this,
"Received error from camera service while checking device capabilities: "
@@ -499,14 +508,4 @@ public class ItsTestActivity extends DialogTestListActivity {
setInfoResources(R.string.camera_its_test, R.string.camera_its_test_info, -1);
setPassFailButtonClickListeners();
}
-
- @Override
- public String getReportFileName() {
- return MPC_TESTS_REPORT_LOG_NAME;
- }
-
- @Override
- public String getReportSectionName() {
- return MPC_TESTS_REPORT_LOG_SECTION;
- }
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java
index c648e8e18d9..734b4a2a780 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java
@@ -16,28 +16,24 @@
package com.android.cts.verifier.camera.its;
-import android.content.Context;
import android.graphics.ImageFormat;
import android.graphics.Rect;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.params.MeteringRectangle;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.Image;
import android.media.Image.Plane;
-import android.net.Uri;
-import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
import android.util.Size;
import com.android.ex.camera2.blocking.BlockingCameraManager;
-import com.android.ex.camera2.blocking.BlockingCameraManager.BlockingOpenException;
import com.android.ex.camera2.blocking.BlockingStateCallback;
import org.json.JSONArray;
@@ -322,6 +318,9 @@ public class ItsUtils {
// Camera Id combos (ids from CameraIdList, and hidden physical camera Ids
// in the form of [logical camera id]:[hidden physical camera id]
public List<String> mCameraIdCombos;
+ // Primary rear and front camera Ids (as defined in MPC)
+ public String mPrimaryRearCameraId;
+ public String mPrimaryFrontCameraId;
}
public static ItsCameraIdList getItsCompatibleCameraIds(CameraManager manager)
@@ -345,6 +344,18 @@ public class ItsUtils {
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE;
final int LOGICAL_MULTI_CAMERA =
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA;
+
+ final Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
+ if (facing != null) {
+ if (facing == CameraMetadata.LENS_FACING_BACK
+ && outList.mPrimaryRearCameraId == null) {
+ outList.mPrimaryRearCameraId = id;
+ } else if (facing == CameraMetadata.LENS_FACING_FRONT
+ && outList.mPrimaryFrontCameraId == null) {
+ outList.mPrimaryFrontCameraId = id;
+ }
+ }
+
for (int capability : actualCapabilities) {
if (capability == BACKWARD_COMPAT) {
haveBC = true;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/clipboard/ClipboardPreviewTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/clipboard/ClipboardPreviewTestActivity.java
index 3587e6f9b8c..63b8904fa03 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/clipboard/ClipboardPreviewTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/clipboard/ClipboardPreviewTestActivity.java
@@ -18,49 +18,22 @@ package com.android.cts.verifier.clipboard;
import android.content.ClipData;
+import android.content.ClipDescription;
import android.content.ClipboardManager;
-import android.graphics.Color;
import android.os.Bundle;
+import android.os.PersistableBundle;
import android.view.View;
import android.widget.Button;
import com.android.cts.verifier.PassFailButtons;
import com.android.cts.verifier.R;
-import java.util.concurrent.ThreadLocalRandom;
-
/**
- * A CTS Verifier test case for validating the user-visible clipboard preview.
- *
- * This test assumes bluetooth is turned on and the device is already paired with a second device.
- * Note: the second device need not be an Android device; it could be a laptop or desktop.
+ * A CTS Verifier test case for validating the user-visible clipboard confirmation.
*/
public class ClipboardPreviewTestActivity extends PassFailButtons.Activity {
- /**
- * The content of the test file being transferred.
- */
- private static final String TEST_STRING = "Sample Test String";
- /**
- * The name of the test file being transferred.
- */
- private final int[] mSecretCode = new int[4];
- private final int[] mSecretGuess = new int[4];
- private final int[] mButtons = {
- R.id.clipboard_preview_test_b0,
- R.id.clipboard_preview_test_b1,
- R.id.clipboard_preview_test_b2,
- R.id.clipboard_preview_test_b3,
- R.id.clipboard_preview_test_b4,
- R.id.clipboard_preview_test_b5,
- R.id.clipboard_preview_test_b6,
- R.id.clipboard_preview_test_b7,
- R.id.clipboard_preview_test_b8,
- R.id.clipboard_preview_test_b9
- };
- private int mGuessIndex = 0;
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -74,87 +47,29 @@ public class ClipboardPreviewTestActivity extends PassFailButtons.Activity {
copyButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- generateAndCopySecret();
+ setClipboardData();
}
});
- disableKeypad();
+ disablePassFail();
}
- private void generateAndCopySecret() {
- String s = "";
- resetState();
- for (int i = 0; i < mSecretCode.length; ++i) {
- mSecretCode[i] = ThreadLocalRandom.current().nextInt(0, 10);
- s += mSecretCode[i];
- }
+ private void setClipboardData() {
ClipboardManager cm = this.getSystemService(ClipboardManager.class);
- cm.setPrimaryClip(ClipData.newPlainText("Secret", s));
- enableKeypad();
- }
- private void enableKeypad() {
- for (int i = 0; i < mButtons.length; ++i) {
- Button numButton = findViewById(mButtons[i]);
- numButton.setBackgroundColor(Color.GREEN);
- int finalI = i;
- numButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- buttonClicked(finalI);
- }
- });
- }
+ ClipData cd = ClipData.newPlainText("",
+ getString(R.string.clipboard_preview_test_secret));
+ PersistableBundle pb = new PersistableBundle(1);
+ pb.putBoolean(ClipDescription.EXTRA_IS_SENSITIVE, true);
+ cd.getDescription().setExtras(pb);
+ cm.setPrimaryClip(cd);
+ enablePassFail();
}
- private void disableKeypad() {
- for (int i = 0; i < mButtons.length; ++i) {
- Button numButton = findViewById(mButtons[i]);
- numButton.setOnClickListener(null);
- numButton.setBackgroundColor(Color.LTGRAY);
- }
- }
-
- private void resetState() {
- for (int i = 0; i < mSecretGuess.length; ++i) {
- mSecretGuess[i] = -1;
- }
- mGuessIndex = 0;
- View v = findViewById(R.id.clipboard_preview_test_pass_fail);
+ private void disablePassFail() {
findViewById(R.id.clipboard_preview_test_pass_fail).setVisibility(View.INVISIBLE);
- findViewById(R.id.fail_button).setVisibility(View.VISIBLE);
- findViewById(R.id.pass_button).setVisibility(View.VISIBLE);
- }
-
- private void buttonClicked(int i) {
- if (mGuessIndex < mSecretGuess.length) {
- mSecretGuess[mGuessIndex] = i;
- ++mGuessIndex;
- }
- checkSolution();
- }
-
- private void checkSolution() {
- boolean testPassed = true;
- if (mGuessIndex == mSecretGuess.length) {
- for (int i = 0; i < mSecretGuess.length && i < mSecretCode.length; ++i) {
- if (mSecretGuess[i] != mSecretCode[i]) {
- testPassed = false;
- }
- }
- markPassed(testPassed);
- disableKeypad();
- }
}
- private void markPassed(boolean passed) {
+ private void enablePassFail() {
findViewById(R.id.clipboard_preview_test_pass_fail).setVisibility(View.VISIBLE);
- if (passed) {
- findViewById(R.id.fail_button).setVisibility(View.INVISIBLE);
- } else {
- findViewById(R.id.pass_button).setVisibility(View.INVISIBLE);
- }
-
}
-
-
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/companion/CompanionDeviceServiceTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/companion/CompanionDeviceServiceTestActivity.java
index b8b96023cb7..97ec07acf78 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/companion/CompanionDeviceServiceTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/companion/CompanionDeviceServiceTestActivity.java
@@ -118,7 +118,7 @@ public class CompanionDeviceServiceTestActivity extends PassFailButtons.Activity
/** Stop observing to associated device and then disassociate. */
private void disassociate(AssociationInfo association) {
- String deviceAddress = association.getDeviceMacAddressAsString();
+ String deviceAddress = association.getDeviceMacAddress().toString();
mCompanionDeviceManager.stopObservingDevicePresence(deviceAddress);
mCompanionDeviceManager.disassociate(association.getId());
Log.d(LOG_TAG, "Disassociated with device: " + deviceAddress);
@@ -142,11 +142,14 @@ public class CompanionDeviceServiceTestActivity extends PassFailButtons.Activity
AssociationInfo association =
data.getParcelableExtra(CompanionDeviceManager.EXTRA_ASSOCIATION,
AssociationInfo.class);
- String deviceAddress = association.getDeviceMacAddressAsString();
// This test is for bluetooth devices, which should all have a MAC address.
- if (deviceAddress == null) fail("The device was present but its address was null.");
+ if (association == null || association.getDeviceMacAddress() == null) {
+ fail("The device was present but its address was null.");
+ return;
+ }
+ String deviceAddress = association.getDeviceMacAddress().toString();
mCompanionDeviceManager.startObservingDevicePresence(deviceAddress);
mCurrentAssociation = getAssociation(association.getId());
Log.d(LOG_TAG, "Associated with device: " + deviceAddress);
@@ -285,7 +288,9 @@ public class CompanionDeviceServiceTestActivity extends PassFailButtons.Activity
@Override
boolean verify() {
// Check that it is associated and being observed.
- return mCurrentAssociation != null && mCurrentAssociation.isNotifyOnDeviceNearby();
+ // Bypass inaccessible AssociationInfo#isNotifyOnDeviceNearby() with toString()
+ return mCurrentAssociation != null
+ && mCurrentAssociation.toString().contains("mNotifyOnDeviceNearby=true");
}
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/companion/DevicePresenceListener.java b/apps/CtsVerifier/src/com/android/cts/verifier/companion/DevicePresenceListener.java
index 37760d54440..11829c3d4b7 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/companion/DevicePresenceListener.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/companion/DevicePresenceListener.java
@@ -45,7 +45,7 @@ public class DevicePresenceListener extends CompanionDeviceService {
@Override
public void onDeviceAppeared(AssociationInfo association) {
NEARBY_DEVICES.add(association.getId());
- String message = "Device appeared: " + association.getDeviceMacAddressAsString();
+ String message = "Device appeared: " + association.getDeviceMacAddress();
Log.d(LOG_TAG, message);
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
@@ -53,7 +53,7 @@ public class DevicePresenceListener extends CompanionDeviceService {
@Override
public void onDeviceDisappeared(AssociationInfo association) {
NEARBY_DEVICES.remove(association.getId());
- String message = "Device disappeared: " + association.getDeviceMacAddressAsString();
+ String message = "Device disappeared: " + association.getDeviceMacAddress();
Log.d(LOG_TAG, message);
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/BleRssiPrecisionActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/presence/BleRssiPrecisionActivity.java
deleted file mode 100644
index 1548910093a..00000000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/presence/BleRssiPrecisionActivity.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.verifier.presence;
-
-import android.app.AlertDialog;
-import android.bluetooth.BluetoothAdapter;
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-import android.text.Editable;
-import android.util.Log;
-import android.widget.EditText;
-
-import com.android.compatibility.common.util.ResultType;
-import com.android.compatibility.common.util.ResultUnit;
-import com.android.cts.verifier.PassFailButtons;
-import com.android.cts.verifier.R;
-
-/** Tests the precision of the device's RSSI measurement wtfdelet */
-public class BleRssiPrecisionActivity extends PassFailButtons.Activity {
- private static final String TAG = BleRssiPrecisionActivity.class.getName();
-
- // Report log schema
- private static final String KEY_RSSI_RANGE_DBM = "rssi_range_dbm";
- private static final String KEY_REFERENCE_DEVICE = "reference_device";
-
- // Thresholds
- private static final int MAX_RSSI_RANGE_DBM = 18;
-
- private EditText reportRssiRangeEditText;
- private EditText reportReferenceDeviceEditText;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.ble_rssi_precision);
- setPassFailButtonClickListeners();
- getPassButton().setEnabled(false);
-
- reportRssiRangeEditText = findViewById(R.id.report_rssi_range);
- reportReferenceDeviceEditText = findViewById(R.id.report_reference_device);
-
- DeviceFeatureChecker.checkFeatureSupported(this, getPassButton(),
- PackageManager.FEATURE_BLUETOOTH_LE);
-
- BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-
- if (!adapter.isEnabled()) {
- new AlertDialog.Builder(this)
- .setTitle(R.string.ble_bluetooth_disable_title)
- .setMessage(R.string.ble_bluetooth_disable_message)
- .setOnCancelListener(dialog -> finish())
- .create().show();
- }
-
- reportRssiRangeEditText.addTextChangedListener(
- InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
- reportReferenceDeviceEditText.addTextChangedListener(
- InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
- }
-
- private void checkTestInputs() {
- getPassButton().setEnabled(checkDistanceRangeInput() && checkReferenceDeviceInput());
- }
-
- private boolean checkDistanceRangeInput() {
- String rssiRangeInput = reportRssiRangeEditText.getText().toString();
-
- if (!rssiRangeInput.isEmpty()) {
- int rssiRange = Integer.parseInt(rssiRangeInput);
- // RSSI range must be inputted and within acceptable range before test can be passed
- return rssiRange <= MAX_RSSI_RANGE_DBM;
- }
- return false;
- }
-
- private boolean checkReferenceDeviceInput() {
- // Reference device must be inputted before test can be passed
- return !reportReferenceDeviceEditText.getText().toString().isEmpty();
- }
-
- @Override
- public void recordTestResults() {
- String rssiRange = reportRssiRangeEditText.getText().toString();
- String referenceDevice = reportReferenceDeviceEditText.getText().toString();
-
- if (!rssiRange.isEmpty()) {
- Log.i(TAG, "BLE RSSI Range (dBm): " + rssiRange);
- getReportLog().addValue(KEY_RSSI_RANGE_DBM, Integer.parseInt(rssiRange),
- ResultType.NEUTRAL, ResultUnit.NONE);
- }
-
- if (!referenceDevice.isEmpty()) {
- Log.i(TAG, "BLE Reference Device: " + referenceDevice);
- getReportLog().addValue(KEY_REFERENCE_DEVICE, referenceDevice,
- ResultType.NEUTRAL, ResultUnit.NONE);
- }
- getReportLog().submit();
- }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/BleRxTxCalibrationActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/presence/BleRxTxCalibrationActivity.java
deleted file mode 100644
index 2de7edffe7c..00000000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/presence/BleRxTxCalibrationActivity.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.verifier.presence;
-
-import android.app.AlertDialog;
-import android.bluetooth.BluetoothAdapter;
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-import android.text.Editable;
-import android.util.Log;
-import android.widget.EditText;
-
-import com.android.compatibility.common.util.ResultType;
-import com.android.compatibility.common.util.ResultUnit;
-import com.android.cts.verifier.PassFailButtons;
-import com.android.cts.verifier.R;
-
-/**
- * Tests that the device's Rx/Tx calibration results in a median range (cm) within the specified
- * bounds
- */
-public class BleRxTxCalibrationActivity extends PassFailButtons.Activity {
- private static final String TAG = BleRxTxCalibrationActivity.class.getName();
-
- // Report log schema
- private static final String KEY_CHANNEL_RSSI_RANGE = "channel_rssi_range";
- private static final String KEY_CORE_RSSI_RANGE = "core_rssi_range";
- private static final String KEY_REFERENCE_DEVICE = "reference_device";
-
- // Thresholds
- private static final int MAX_RSSI_RANGE = 6;
-
- private EditText reportChannelsRssiRangeEditText;
- private EditText reportCoresRssiRangeEditText;
- private EditText reportReferenceDeviceEditText;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.ble_rx_tx_calibration);
- setPassFailButtonClickListeners();
- getPassButton().setEnabled(false);
-
- reportChannelsRssiRangeEditText = findViewById(R.id.report_channels_rssi_range);
- reportCoresRssiRangeEditText = findViewById(R.id.report_cores_rssi_range);
- reportReferenceDeviceEditText = findViewById(R.id.report_reference_device);
-
- DeviceFeatureChecker.checkFeatureSupported(this, getPassButton(),
- PackageManager.FEATURE_BLUETOOTH_LE);
-
- BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-
- if (!adapter.isEnabled()) {
- new AlertDialog.Builder(this)
- .setTitle(R.string.ble_bluetooth_disable_title)
- .setMessage(R.string.ble_bluetooth_disable_message)
- .setOnCancelListener(dialog -> finish())
- .create().show();
- }
-
- reportChannelsRssiRangeEditText.addTextChangedListener(
- InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
- reportCoresRssiRangeEditText.addTextChangedListener(
- InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
- reportReferenceDeviceEditText.addTextChangedListener(
- InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
- }
-
- private void checkTestInputs() {
- getPassButton().setEnabled(
- checkChannelRssiInput() && checkCoreRssiInput() && checkReferenceDeviceInput());
- }
-
- private boolean checkChannelRssiInput() {
- String channelsRssiRangeInput = reportChannelsRssiRangeEditText.getText().toString();
- if (!channelsRssiRangeInput.isEmpty()) {
- int channelsRssiRange = Integer.parseInt(channelsRssiRangeInput);
- // RSSI range must be inputted and within acceptable range before test can be passed
- return channelsRssiRange <= MAX_RSSI_RANGE;
- }
- return false;
- }
-
- private boolean checkCoreRssiInput() {
- String coresRssiRangeInput = reportCoresRssiRangeEditText.getText().toString();
- if (!coresRssiRangeInput.isEmpty()) {
- int coresRssiRange = Integer.parseInt(coresRssiRangeInput);
- // RSSI range must be inputted and within acceptable range before test can be passed
- return coresRssiRange <= MAX_RSSI_RANGE;
- }
- // This field is optional, so return true even if the user has not inputted anything
- return true;
- }
-
- private boolean checkReferenceDeviceInput() {
- // Reference device must be inputted before test can be passed
- return !reportReferenceDeviceEditText.getText().toString().isEmpty();
- }
-
- @Override
- public void recordTestResults() {
- String channelRssiRange = reportChannelsRssiRangeEditText.getText().toString();
- String coreRssiRange = reportCoresRssiRangeEditText.getText().toString();
- String referenceDevice = reportReferenceDeviceEditText.getText().toString();
-
- if (!channelRssiRange.isEmpty()) {
- Log.i(TAG, "BLE RSSI Range Across Channels (dBm): " + channelRssiRange);
- getReportLog().addValue(KEY_CHANNEL_RSSI_RANGE, Integer.parseInt(channelRssiRange),
- ResultType.NEUTRAL, ResultUnit.NONE);
- }
-
- if (!coreRssiRange.isEmpty()) {
- Log.i(TAG, "BLE RSSI Range Across Cores (dBm): " + coreRssiRange);
- getReportLog().addValue(KEY_CORE_RSSI_RANGE, Integer.parseInt(coreRssiRange),
- ResultType.NEUTRAL, ResultUnit.NONE);
- }
-
- if (!referenceDevice.isEmpty()) {
- Log.i(TAG, "BLE Reference Device: " + referenceDevice);
- getReportLog().addValue(KEY_REFERENCE_DEVICE, referenceDevice,
- ResultType.NEUTRAL, ResultUnit.NONE);
- }
-
- getReportLog().submit();
- }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/DeviceFeatureChecker.java b/apps/CtsVerifier/src/com/android/cts/verifier/presence/DeviceFeatureChecker.java
deleted file mode 100644
index 256fe3a078d..00000000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/presence/DeviceFeatureChecker.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.verifier.presence;
-import android.app.Activity;
-import android.content.Context;
-import android.util.Log;
-import android.view.View;
-import android.widget.Toast;
-
-/**
- * Checks if a device supports a hardware feature needed for a test, and passes the test
- * automatically otherwise.
- */
-public class DeviceFeatureChecker {
-
- /** Checks if a feature is supported.
- *
- * @param feature must be a string defined in PackageManager
- */
- public static void checkFeatureSupported(Context context, View passButton, String feature) {
- if (!context.getPackageManager().hasSystemFeature(feature)) {
- String message = String.format("Device does not support %s, automatically passing test",
- feature);
- Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
- Log.e(context.getClass().getName(), message);
- passButton.performClick();
- Activity activity = (Activity) (context);
- activity.finish();
- }
- }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/InputTextHandler.java b/apps/CtsVerifier/src/com/android/cts/verifier/presence/InputTextHandler.java
deleted file mode 100644
index 2de68a5a78e..00000000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/presence/InputTextHandler.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package com.android.cts.verifier.presence;
-
-import android.text.Editable;
-import android.text.TextWatcher;
-
-/**
- * Handles editable text inputted into test activities.
- */
-public class InputTextHandler {
-
- /** Callback that is executed when text is changed. Takes modified text as input. */
- public interface OnTextChanged {
- void run(Editable s);
- }
-
- /**
- * Generic text changed handler that will execute the provided callback when text is modified.
- *
- * @param callback called when text is changed, and passed the modified text
- */
- public static TextWatcher getOnTextChangedHandler(OnTextChanged callback) {
- return new TextWatcher() {
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {}
-
- @Override
- public void afterTextChanged(Editable s) {
- callback.run(s);
- }
- };
- }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/NanPrecisionTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/presence/NanPrecisionTestActivity.java
deleted file mode 100644
index 458d1920eca..00000000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/presence/NanPrecisionTestActivity.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.verifier.presence;
-
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-import android.text.Editable;
-import android.util.Log;
-import android.widget.EditText;
-
-import com.android.compatibility.common.util.ResultType;
-import com.android.compatibility.common.util.ResultUnit;
-import com.android.cts.verifier.PassFailButtons;
-import com.android.cts.verifier.R;
-
-import com.google.common.collect.ImmutableMap;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Activity for testing that NAN measurements are within the acceptable ranges
- */
-public class NanPrecisionTestActivity extends PassFailButtons.Activity {
- private static final String TAG = NanPrecisionTestActivity.class.getName();
-
- // Report log schema
- private static final String KEY_BANDWIDTH = "nan_bandwidth";
- private static final String KEY_MEASUREMENT_RANGE_10CM_AT_68P = "measurement_range_10cm_68p";
- private static final String KEY_MEASUREMENT_RANGE_1M_AT_68P = "measurement_range_1m_68p";
- private static final String KEY_MEASUREMENT_RANGE_3M_AT_68p = "measurement_range_3m_68p";
- private static final String KEY_MEASUREMENT_RANGE_5M_AT_68p = "measurement_range_5m_68p";
- private static final String KEY_MEASUREMENT_RANGE_10CM_AT_90P = "measurement_range_10cm_90p";
- private static final String KEY_MEASUREMENT_RANGE_1M_AT_90P = "measurement_range_1m_90p";
- private static final String KEY_MEASUREMENT_RANGE_3M_AT_90p = "measurement_range_3m_90p";
- private static final String KEY_MEASUREMENT_RANGE_5M_AT_90p = "measurement_range_5m_90p";
- private static final String KEY_REFERENCE_DEVICE = "reference_device";
-
- // Thresholds
- private static final int MAX_DISTANCE_RANGE_METERS_160MHZ = 2;
- private static final int MAX_DISTANCE_RANGE_METERS_80MHZ = 4;
- private static final int MAX_DISTANCE_RANGE_METERS_40MHZ = 8;
- private static final int MAX_DISTANCE_RANGE_METERS_20MHZ = 16;
-
- // Maps NAN bandwidths to acceptable range thresholds
- private static final ImmutableMap<Integer, Integer> BANDWIDTH_TO_THRESHOLD_MAP =
- ImmutableMap.of(160, MAX_DISTANCE_RANGE_METERS_160MHZ, 80,
- MAX_DISTANCE_RANGE_METERS_80MHZ, 40, MAX_DISTANCE_RANGE_METERS_40MHZ, 20,
- MAX_DISTANCE_RANGE_METERS_20MHZ);
-
- private EditText mBandwidthMhz;
- private EditText mMeasurementRange10cmGt68p;
- private EditText mMeasurementRange1mGt68p;
- private EditText mMeasurementRange3mGt68p;
- private EditText mMeasurementRange5mGt68p;
- private EditText mMeasurementRange10cmGt90p;
- private EditText mMeasurementRange1mGt90p;
- private EditText mMeasurementRange3mGt90p;
- private EditText mMeasurementRange5mGt90p;
- private EditText mReferenceDeviceInput;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.nan_precision);
- setPassFailButtonClickListeners();
- getPassButton().setEnabled(false);
-
- mBandwidthMhz = (EditText) findViewById(R.id.nan_bandwidth);
- mMeasurementRange10cmGt68p = (EditText) findViewById(R.id.distance_range_10cm_gt_68p);
- mMeasurementRange1mGt68p = (EditText) findViewById(R.id.distance_range_1m_gt_68p);
- mMeasurementRange3mGt68p = (EditText) findViewById(R.id.distance_range_3m_gt_68p);
- mMeasurementRange5mGt68p = (EditText) findViewById(R.id.distance_range_5m_gt_68p);
- mMeasurementRange10cmGt90p = (EditText) findViewById(R.id.distance_range_10cm_gt_90p);
- mMeasurementRange1mGt90p = (EditText) findViewById(R.id.distance_range_1m_gt_90p);
- mMeasurementRange3mGt90p = (EditText) findViewById(R.id.distance_range_3m_gt_90p);
- mMeasurementRange5mGt90p = (EditText) findViewById(R.id.distance_range_5m_gt_90p);
- mReferenceDeviceInput = (EditText) findViewById(R.id.reference_device);
-
- DeviceFeatureChecker.checkFeatureSupported(this, getPassButton(),
- PackageManager.FEATURE_WIFI_AWARE);
-
- mBandwidthMhz.addTextChangedListener(
- InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
- mMeasurementRange10cmGt68p.addTextChangedListener(
- InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
- mMeasurementRange1mGt68p.addTextChangedListener(
- InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
- mMeasurementRange3mGt68p.addTextChangedListener(
- InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
- mMeasurementRange5mGt68p.addTextChangedListener(
- InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
- mMeasurementRange10cmGt90p.addTextChangedListener(
- InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
- mMeasurementRange1mGt90p.addTextChangedListener(
- InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
- mMeasurementRange3mGt90p.addTextChangedListener(
- InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
- mMeasurementRange5mGt90p.addTextChangedListener(
- InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
- mReferenceDeviceInput.addTextChangedListener(
- InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
- }
-
- private void checkTestInputs() {
- getPassButton().setEnabled(checkMeasurementRange68thPercentileInput()
- && checkMeasurementRange90thPercentileInput()
- && checkReferenceDeviceInput());
- }
-
- private boolean checkMeasurementRange68thPercentileInput() {
- return checkRequiredMeasurementRangeInput(mMeasurementRange10cmGt68p,
- mMeasurementRange1mGt68p, mMeasurementRange3mGt68p, mMeasurementRange5mGt68p);
- }
-
- private boolean checkMeasurementRange90thPercentileInput() {
- String measurementRangeInput10cmGt90p = mMeasurementRange10cmGt90p.getText().toString();
- String measurementRangeInput1mGt90p = mMeasurementRange1mGt90p.getText().toString();
- String measurementRangeInput3mGt90p = mMeasurementRange3mGt90p.getText().toString();
- String measurementRangeInput5mGt90p = mMeasurementRange5mGt90p.getText().toString();
- List<String> optionalMeasurementRangeList = Arrays.asList(measurementRangeInput10cmGt90p,
- measurementRangeInput1mGt90p,
- measurementRangeInput3mGt90p, measurementRangeInput5mGt90p);
-
- boolean inputted = false;
- for (String input : optionalMeasurementRangeList) {
- if (!input.isEmpty()) {
- inputted = true;
- break;
- }
- }
- // If one of the ranges is inputted for one of the distances, then it becomes required
- // that the ranges are inputted for all the distances and for tests to pass, must be
- // acceptable values
- return !inputted || checkRequiredMeasurementRangeInput(mMeasurementRange10cmGt90p,
- mMeasurementRange1mGt90p, mMeasurementRange3mGt90p, mMeasurementRange5mGt90p);
- }
-
- private boolean checkRequiredMeasurementRangeInput(EditText rangeInput10cm,
- EditText rangeInput1m, EditText rangeInput3m, EditText rangeInput5m) {
- String bandwidthInputMhz = mBandwidthMhz.getText().toString();
- String measurementRangeInput10cmGt = rangeInput10cm.getText().toString();
- String measurementRangeInput1mGt = rangeInput1m.getText().toString();
- String measurementRangeInput3mGt = rangeInput3m.getText().toString();
- String measurementRangeInput5mGt = rangeInput5m.getText().toString();
- List<String> requiredMeasurementRangeList = Arrays.asList(measurementRangeInput10cmGt,
- measurementRangeInput1mGt,
- measurementRangeInput3mGt, measurementRangeInput5mGt);
-
- for (String input : requiredMeasurementRangeList) {
- if (bandwidthInputMhz.isEmpty() || input.isEmpty()) {
- // Distance range must be inputted for all fields so fail early otherwise
- return false;
- }
- if (!BANDWIDTH_TO_THRESHOLD_MAP.containsKey(Integer.parseInt(bandwidthInputMhz))) {
- // bandwidth must be one of the expected thresholds
- return false;
- }
- double distanceRange = Double.parseDouble(input);
- int bandwidth = Integer.parseInt(bandwidthInputMhz);
- if (distanceRange > BANDWIDTH_TO_THRESHOLD_MAP.get(bandwidth)) {
- // All inputs must be in acceptable range so fail early otherwise
- return false;
- }
- }
- return true;
- }
-
- private boolean checkReferenceDeviceInput() {
- // Reference device used must be inputted before test can be passed.
- return !mReferenceDeviceInput.getText().toString().isEmpty();
- }
-
- @Override
- public void recordTestResults() {
- String nanBandwidthMhz = mBandwidthMhz.getText().toString();
- String measurementRange10cmGt68p = mMeasurementRange10cmGt68p.getText().toString();
- String measurementRange1mGt68p = mMeasurementRange1mGt68p.getText().toString();
- String measurementRange3mGt68p = mMeasurementRange3mGt68p.getText().toString();
- String measurementRange5mGt68p = mMeasurementRange5mGt68p.getText().toString();
- String measurementRange10cmGt90p = mMeasurementRange10cmGt90p.getText().toString();
- String measurementRange1mGt90p = mMeasurementRange1mGt90p.getText().toString();
- String measurementRange3mGt90p = mMeasurementRange3mGt90p.getText().toString();
- String measurementRange5mGt90p = mMeasurementRange5mGt90p.getText().toString();
- String referenceDevice = mReferenceDeviceInput.getText().toString();
-
- if (!nanBandwidthMhz.isEmpty()) {
- Log.i(TAG, "NAN Bandwidth at which data was collected: " + nanBandwidthMhz);
- getReportLog().addValue(KEY_BANDWIDTH,
- Integer.parseInt(nanBandwidthMhz),
- ResultType.NEUTRAL, ResultUnit.NONE);
- }
-
- if (!measurementRange10cmGt68p.isEmpty()) {
- Log.i(TAG, "NAN Measurement Range at 10cm: " + measurementRange10cmGt68p);
- getReportLog().addValue(KEY_MEASUREMENT_RANGE_10CM_AT_68P,
- Double.parseDouble(measurementRange10cmGt68p),
- ResultType.NEUTRAL, ResultUnit.NONE);
- }
-
- if (!measurementRange1mGt68p.isEmpty()) {
- Log.i(TAG, "NAN Measurement Range at 1m: " + measurementRange1mGt68p);
- getReportLog().addValue(KEY_MEASUREMENT_RANGE_1M_AT_68P,
- Double.parseDouble(measurementRange1mGt68p),
- ResultType.NEUTRAL, ResultUnit.NONE);
- }
-
- if (!measurementRange3mGt68p.isEmpty()) {
- Log.i(TAG, "NAN Measurement Range at 3m: " + measurementRange3mGt68p);
- getReportLog().addValue(KEY_MEASUREMENT_RANGE_3M_AT_68p,
- Double.parseDouble(measurementRange3mGt68p),
- ResultType.NEUTRAL, ResultUnit.NONE);
- }
-
- if (!measurementRange5mGt68p.isEmpty()) {
- Log.i(TAG, "NAN Measurement Range at 5m: " + measurementRange5mGt68p);
- getReportLog().addValue(KEY_MEASUREMENT_RANGE_5M_AT_68p,
- Double.parseDouble(measurementRange5mGt68p),
- ResultType.NEUTRAL, ResultUnit.NONE);
- }
-
- if (!measurementRange10cmGt90p.isEmpty()) {
- Log.i(TAG, "NAN Measurement Range at 10cm: " + measurementRange10cmGt68p);
- getReportLog().addValue(KEY_MEASUREMENT_RANGE_10CM_AT_90P,
- Double.parseDouble(measurementRange10cmGt90p),
- ResultType.NEUTRAL, ResultUnit.NONE);
- }
-
- if (!measurementRange1mGt90p.isEmpty()) {
- Log.i(TAG, "NAN Measurement Range at 1m: " + measurementRange1mGt90p);
- getReportLog().addValue(KEY_MEASUREMENT_RANGE_1M_AT_90P,
- Double.parseDouble(measurementRange1mGt90p),
- ResultType.NEUTRAL, ResultUnit.NONE);
- }
-
- if (!measurementRange3mGt90p.isEmpty()) {
- Log.i(TAG, "NAN Measurement Range at 3m: " + measurementRange3mGt90p);
- getReportLog().addValue(KEY_MEASUREMENT_RANGE_3M_AT_90p,
- Double.parseDouble(measurementRange3mGt90p),
- ResultType.NEUTRAL, ResultUnit.NONE);
- }
-
- if (!measurementRange5mGt90p.isEmpty()) {
- Log.i(TAG, "NAN Measurement Range at 5m: " + measurementRange5mGt90p);
- getReportLog().addValue(KEY_MEASUREMENT_RANGE_5M_AT_90p,
- Double.parseDouble(measurementRange5mGt90p),
- ResultType.NEUTRAL, ResultUnit.NONE);
- }
-
- if (!referenceDevice.isEmpty()) {
- Log.i(TAG, "NAN Reference Device: " + referenceDevice);
- getReportLog().addValue(KEY_REFERENCE_DEVICE, referenceDevice,
- ResultType.NEUTRAL, ResultUnit.NONE);
- }
- getReportLog().submit();
- }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/presence/OWNERS
deleted file mode 100644
index e8744995b6c..00000000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/presence/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Bug component: 1106357
-asalo@google.com
-jbabs@google.com
-christinatao@google.com \ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/PresenceTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/presence/PresenceTestActivity.java
deleted file mode 100644
index 67766931591..00000000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/presence/PresenceTestActivity.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.verifier.presence;
-
-import android.content.pm.PackageManager;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.SystemProperties;
-
-import com.android.cts.verifier.ManifestTestListAdapter;
-import com.android.cts.verifier.PassFailButtons;
-import com.android.cts.verifier.R;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class PresenceTestActivity extends PassFailButtons.TestListActivity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.pass_fail_list);
- setPassFailButtonClickListeners();
-
- List<String> disabledTest = new ArrayList<String>();
- boolean isTv = getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK);
- if (isTv) {
- setInfoResources(R.string.presence_test, R.string.presence_test_tv_info, -1);
- int firstSdk = SystemProperties.getInt("ro.product.first_api_level", 0);
- if (firstSdk < Build.VERSION_CODES.TIRAMISU) {
- disabledTest.add("com.android.cts.verifier.presence.UwbPrecisionActivity");
- disabledTest.add("com.android.cts.verifier.presence.UwbShortRangeActivity");
- disabledTest.add("com.android.cts.verifier.presence.BleRssiPrecisionActivity");
- disabledTest.add("com.android.cts.verifier.presence.BleRxTxCalibrationActivity");
- disabledTest.add("com.android.cts.verifier.presence.BleRxOffsetActivity");
- disabledTest.add("com.android.cts.verifier.presence.BleTxOffsetActivity");
- disabledTest.add("com.android.cts.verifier.presence.NanPrecisionTestActivity");
- }
- } else {
- setInfoResources(R.string.presence_test, R.string.presence_test_info, -1);
- }
-
- setTestListAdapter(new ManifestTestListAdapter(this, PresenceTestActivity.class.getName(),
- disabledTest.toArray(new String[disabledTest.size()])));
- }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/UwbPrecisionActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/presence/UwbPrecisionActivity.java
deleted file mode 100644
index 5d1ff8628dd..00000000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/presence/UwbPrecisionActivity.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.verifier.presence;
-
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-import android.text.Editable;
-import android.util.Log;
-import android.widget.EditText;
-
-import com.android.compatibility.common.util.ResultType;
-import com.android.compatibility.common.util.ResultUnit;
-import com.android.cts.verifier.PassFailButtons;
-import com.android.cts.verifier.R;
-
-/**
- * Activity for testing that UWB distance and angle of arrival measurements are within the right
- * range.
- */
-public class UwbPrecisionActivity extends PassFailButtons.Activity {
- private static final String TAG = UwbPrecisionActivity.class.getName();
- // Report log schema
- private static final String KEY_DISTANCE_RANGE_CM = "distance_range_cm";
- private static final String KEY_REFERENCE_DEVICE = "reference_device";
- // Thresholds
- private static final int MAX_DISTANCE_RANGE_CM = 30;
-
- private EditText mDistanceRangeInput;
- private EditText mReferenceDeviceInput;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.uwb_precision);
- setPassFailButtonClickListeners();
- getPassButton().setEnabled(false);
-
- mDistanceRangeInput = (EditText) findViewById(R.id.distance_range_cm);
- mReferenceDeviceInput = (EditText) findViewById(R.id.reference_device);
-
- DeviceFeatureChecker.checkFeatureSupported(this, getPassButton(),
- PackageManager.FEATURE_UWB);
-
- mDistanceRangeInput.addTextChangedListener(
- InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
- mReferenceDeviceInput.addTextChangedListener(
- InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
- }
-
- private void checkTestInputs() {
- getPassButton().setEnabled(
- checkDistanceRangeInput() && checkReferenceDeviceInput());
- }
-
- private boolean checkDistanceRangeInput() {
- String distanceRangeInput = mDistanceRangeInput.getText().toString();
- if (!distanceRangeInput.isEmpty()) {
- double distanceRange = Double.parseDouble(distanceRangeInput);
- // Distance range must be inputted and within acceptable range before test can be
- // passed.
- return distanceRange <= MAX_DISTANCE_RANGE_CM;
- }
- return false;
- }
-
- private boolean checkReferenceDeviceInput() {
- // Reference device must be inputted before test can be passed.
- return !mReferenceDeviceInput.getText().toString().isEmpty();
- }
-
- @Override
- public void recordTestResults() {
- String distanceRange = mDistanceRangeInput.getText().toString();
- String referenceDevice = mReferenceDeviceInput.getText().toString();
- if (!distanceRange.isEmpty()) {
- Log.i(TAG, "UWB Distance Range: " + distanceRange);
- getReportLog().addValue(KEY_DISTANCE_RANGE_CM, Double.parseDouble(distanceRange),
- ResultType.NEUTRAL, ResultUnit.NONE);
- }
- if (!referenceDevice.isEmpty()) {
- Log.i(TAG, "UWB Reference Device: " + referenceDevice);
- getReportLog().addValue(KEY_REFERENCE_DEVICE, referenceDevice,
- ResultType.NEUTRAL, ResultUnit.NONE);
- }
- getReportLog().submit();
- }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/UwbShortRangeActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/presence/UwbShortRangeActivity.java
deleted file mode 100644
index 7f14800b68c..00000000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/presence/UwbShortRangeActivity.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.verifier.presence;
-
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-import android.text.Editable;
-import android.util.Log;
-import android.widget.EditText;
-
-import com.android.compatibility.common.util.ResultType;
-import com.android.compatibility.common.util.ResultUnit;
-import com.android.cts.verifier.PassFailButtons;
-import com.android.cts.verifier.R;
-
-/**
- * Activity for testing that UWB distance measurements are within the acceptable median.
- */
-public class UwbShortRangeActivity extends PassFailButtons.Activity {
- private static final String TAG = UwbShortRangeActivity.class.getName();
- // Report log schema
- private static final String KEY_DISTANCE_MEDIAN_CM = "distance_median_cm";
- private static final String KEY_REFERENCE_DEVICE = "reference_device";
- // Median Thresholds
- private static final double MIN_MEDIAN = 0.75;
- private static final double MAX_MEDIAN = 1.25;
- private EditText mMedianInput;
- private EditText mReferenceDeviceInput;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.uwb_short_range);
- setPassFailButtonClickListeners();
- getPassButton().setEnabled(false);
-
- mMedianInput = (EditText) findViewById(R.id.distance_median_meters);
- mReferenceDeviceInput = (EditText) findViewById(R.id.reference_device);
-
- DeviceFeatureChecker.checkFeatureSupported(this, getPassButton(),
- PackageManager.FEATURE_UWB);
-
- mMedianInput.addTextChangedListener(
- InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
- mReferenceDeviceInput.addTextChangedListener(
- InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs()));
- }
-
- private void checkTestInputs() {
- getPassButton().setEnabled(checkMedianInput() && checkReferenceDeviceInput());
- }
-
- private boolean checkMedianInput() {
- String medianInput = mMedianInput.getText().toString();
- if (!medianInput.isEmpty()) {
- double median = Double.parseDouble(medianInput);
- return median >= MIN_MEDIAN && median <= MAX_MEDIAN;
- }
- return false;
- }
-
- private boolean checkReferenceDeviceInput() {
- return !mReferenceDeviceInput.getText().toString().isEmpty();
- }
-
- @Override
- public void recordTestResults() {
- String medianInput = mMedianInput.getText().toString();
- String referenceDeviceInput = mReferenceDeviceInput.getText().toString();
- if (!medianInput.isEmpty()) {
- Log.i(TAG, "UWB Distance Median: " + medianInput);
- getReportLog().addValue(KEY_DISTANCE_MEDIAN_CM, Double.parseDouble(medianInput),
- ResultType.NEUTRAL, ResultUnit.NONE);
- }
- if (!referenceDeviceInput.isEmpty()) {
- Log.i(TAG, "UWB Reference Device: " + referenceDeviceInput);
- getReportLog().addValue(KEY_REFERENCE_DEVICE, referenceDeviceInput, ResultType.NEUTRAL,
- ResultUnit.NONE);
- }
- getReportLog().submit();
- }
-}
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 099a0ab7276..35cb549c529 100644
--- a/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/ScopedStorageDeviceTest.java
+++ b/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/ScopedStorageDeviceTest.java
@@ -1772,6 +1772,37 @@ public class ScopedStorageDeviceTest extends ScopedStorageBaseDeviceTest {
}
/**
+ * Test that renaming file paths to an external directory such as Android/* and Android/* /*
+ * except Android/media/* /* is not allowed.
+ */
+ @Test
+ public void testRenameFileToAppSpecificDir() throws Exception {
+ final File testFile = new File(getExternalMediaDir(), IMAGE_FILE_NAME);
+ final File testFileNew = new File(getExternalMediaDir(), NONMEDIA_FILE_NAME);
+
+ try {
+ // Create a file in app's external media directory
+ if (!testFile.exists()) {
+ assertThat(testFile.createNewFile()).isTrue();
+ }
+
+ final String androidDirPath = getExternalStorageDir().getPath() + "/Android";
+
+ // Verify that we can't rename a file to Android/ or Android/data or
+ // Android/media directory
+ assertCantRenameFile(testFile, new File(androidDirPath, IMAGE_FILE_NAME));
+ assertCantRenameFile(testFile, new File(androidDirPath + "/data", IMAGE_FILE_NAME));
+ assertCantRenameFile(testFile, new File(androidDirPath + "/media", IMAGE_FILE_NAME));
+
+ // Verify that we can rename a file to app specific media directory.
+ assertCanRenameFile(testFile, testFileNew);
+ } finally {
+ testFile.delete();
+ testFileNew.delete();
+ }
+ }
+
+ /**
* Test that renaming directories is allowed and aligns to default directory restrictions.
*/
@Test
diff --git a/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java b/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
index 573035c2de3..13ade8b0585 100644
--- a/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
+++ b/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
@@ -1367,7 +1367,7 @@ public class SELinuxHostTest extends BaseHostJUnit4Test {
@CddTest(requirement="9.7")
@Test
public void testDrmServerDomain() throws DeviceNotAvailableException {
- assertDomainN("u:r:drmserver:s0", "/system/bin/drmserver", "/system/bin/drmserver64");
+ assertDomainHasExecutable("u:r:drmserver:s0", "/system/bin/drmserver", "/system/bin/drmserver64");
}
/* Installd is always running */
diff --git a/hostsidetests/securitybulletin/Android.bp b/hostsidetests/securitybulletin/Android.bp
index 30b61613f08..25242273f6b 100644
--- a/hostsidetests/securitybulletin/Android.bp
+++ b/hostsidetests/securitybulletin/Android.bp
@@ -43,6 +43,7 @@ java_test_host {
cc_defaults {
name: "cts_hostsidetests_securitybulletin_defaults",
+ auto_gen_config: false,
compile_multilib: "both",
multilib: {
lib32: {
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0954.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0954.java
index 12287b0151d..95c90d4ec4b 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0954.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0954.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,43 +16,39 @@
package android.security.cts;
-import android.platform.test.annotations.AppModeFull;
+import static org.junit.Assume.assumeNoException;
+
import android.platform.test.annotations.AsbSecurityTest;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
-import org.junit.Assert;
-import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
public class CVE_2021_0954 extends StsExtraBusinessLogicHostTestBase {
- private static final String TEST_PKG = "android.security.cts.cve_2021_0954";
- private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
- private static final String TEST_APP = "CVE-2021-0954.apk";
- private ITestDevice device;
-
- @Before
- public void setUp() throws Exception {
- device = getDevice();
- uninstallPackage(device, TEST_PKG);
-
- /* Wake up the screen */
- AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
- AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
- AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
- }
+ private static final String TEST_PKG = "android.security.cts.CVE_2021_0954";
- @AppModeFull
@AsbSecurityTest(cveBugId = 143559931)
@Test
public void testPocCVE_2021_0954() throws Exception {
- installPackage(TEST_APP);
- AdbUtils.runCommandLine("pm grant " + TEST_PKG + " android.permission.SYSTEM_ALERT_WINDOW",
- device);
- runDeviceTests(TEST_PKG, TEST_CLASS, "testVulnerableActivityPresence");
+ try {
+ ITestDevice device = getDevice();
+ uninstallPackage(device, TEST_PKG);
+
+ /* Wake up the screen */
+ AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+
+ installPackage("CVE-2021-0954.apk");
+ AdbUtils.runCommandLine(
+ "pm grant " + TEST_PKG + " android.permission.SYSTEM_ALERT_WINDOW", device);
+ runDeviceTests(TEST_PKG, TEST_PKG + "." + "DeviceTest", "testOverlayButtonPresence");
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
}
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20353.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20353.java
new file mode 100644
index 00000000000..e661b4ff4a1
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20353.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2022_20353 extends StsExtraBusinessLogicHostTestBase {
+
+ @AsbSecurityTest(cveBugId = 221041256)
+ @Test
+ public void testPocCVE_2022_20353() {
+ try {
+ final String testPkg = "android.security.cts.CVE_2022_20353";
+ ITestDevice device = getDevice();
+
+ AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+
+ // to generate NOTICE.html if not already present
+ AdbUtils.runCommandLine("am start -a android.settings.LICENSE", device);
+
+ installPackage("CVE-2022-20353.apk");
+
+ runDeviceTests(testPkg, testPkg + ".DeviceTest", "testDefaultRingtonePreference");
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/Android.bp
index aa9f71f574b..59350cf546f 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/Android.bp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,10 +18,10 @@
android_test_helper_app {
name: "CVE-2021-0954",
defaults: ["cts_support_defaults"],
- srcs: ["src/**/*.java"],
+ srcs: [
+ "src/**/*.java"
+ ],
test_suites: [
- "cts",
- "vts10",
"sts",
],
static_libs: [
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/AndroidManifest.xml
index a7e0218c422..75299c4ddfe 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/AndroidManifest.xml
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/AndroidManifest.xml
@@ -1,5 +1,5 @@
<!--
- Copyright 2021 The Android Open Source Project
+ Copyright 2022 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -13,25 +13,19 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
- package="android.security.cts.cve_2021_0954"
+ package="android.security.cts.CVE_2021_0954"
android:versionCode="1"
android:versionName="1.0">
-
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
-
- <application
- android:allowBackup="true"
- android:label="CVE_2021_0954"
- android:supportsRtl="true">
- <uses-library android:name="android.test.runner" />
+ <application>
<service android:name=".PocService"
android:enabled="true"
- android:exported="false" />
+ android:exported="true" />
</application>
-
<instrumentation
android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.security.cts.cve_2021_0954" />
+ android:targetPackage="android.security.cts.CVE_2021_0954" />
</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/integers.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/integers.xml
new file mode 100644
index 00000000000..363df0001d7
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/integers.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources>
+ <integer name="assumptionFailure">-1</integer>
+ <integer name="noAssumptionFailure">0</integer>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/strings.xml
new file mode 100644
index 00000000000..7c4d959b70f
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <string name="canNotDrawOverlaysMsg">The application cannot draw overlays</string>
+ <string name="defaultSemaphoreMsg">Could not get message key in shared preferences</string>
+ <string name="cmdDumpsysActivity">dumpsys activity %1$s</string>
+ <string name="empty"></string>
+ <string name="overlayErrorMessage">Device is vulnerable to b/143559931 hence any app with
+ "SYSTEM_ALERT_WINDOW can overlay the %1$s screen</string>
+ <string name="mResumedTrue">mResumed=true</string>
+ <string name="messageKey">message</string>
+ <string name="overlayButtonText">OverlayButton</string>
+ <string name="overlayUiScreenError">Overlay UI did not appear on the screen</string>
+ <string name="resultKey">result</string>
+ <string name="sharedPreferences">CVE_2021_0954_prefs</string>
+ <string name="timedOutPocActivity">Timed out waiting on a result from PocActivity</string>
+ <string name="vulClass">com.android.internal.app.ResolverActivity</string>
+ <string name="vulClassAuto">com.android.car.activityresolver.CarResolverActivity</string>
+ <string name="vulPkg">android</string>
+ <string name="vulPkgAuto">com.android.car.activityresolver</string>
+ <string name="vulActivityNotRunningError">The %1$s is not currently running on the device
+ </string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/DeviceTest.java
index f98690625e9..9a94ef953c1 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/DeviceTest.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/DeviceTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,17 +14,20 @@
* limitations under the License.
*/
-package android.security.cts.cve_2021_0954;
+package android.security.cts.CVE_2021_0954;
import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
+
+import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
-import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.content.pm.PackageManager;
import android.provider.Settings;
import androidx.test.runner.AndroidJUnit4;
@@ -32,90 +35,107 @@ import androidx.test.uiautomator.By;
import androidx.test.uiautomator.UiDevice;
import androidx.test.uiautomator.Until;
-import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.io.IOException;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
@RunWith(AndroidJUnit4.class)
public class DeviceTest {
- private static final String TEST_PKG = "android.security.cts.cve_2021_0954";
- private static final String TEST_VULNERABLE_PKG = "android";
- private static final String TEST_VULNERABLE_ACTIVITY =
- "com.android.internal.app.ResolverActivity";
- private static final int LAUNCH_TIMEOUT_MS = 20000;
- private static final String vulnerableActivityName = "ResolverActivity";
- private UiDevice mDevice;
- String activityDump = "";
-
- private void startOverlayService() {
- Context context = getApplicationContext();
- assertNotNull(context);
- Intent intent = new Intent(context, PocService.class);
- assertNotNull(intent);
-
- if (Settings.canDrawOverlays(getApplicationContext())) {
- context.startService(intent);
- } else {
- try {
- context.startService(intent);
- } catch (Exception e) {
- throw new RuntimeException("Unable to start the overlay service", e);
- }
- }
+ private Context mContext = getApplicationContext();
+ private static final int TIMEOUT_MS = 10000;
+
+ private boolean hasFeature(String feature) {
+ return mContext.getPackageManager().hasSystemFeature(feature);
}
- public void startVulnerableActivity() {
- Context context = getApplicationContext();
- Intent intent = new Intent();
- intent.setClassName(TEST_VULNERABLE_PKG, TEST_VULNERABLE_ACTIVITY);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- try {
- context.startActivity(intent);
- } catch (ActivityNotFoundException e) {
- assumeNoException("Activity not found on device", e);
- }
+ private boolean isAuto() {
+ return hasFeature(PackageManager.FEATURE_AUTOMOTIVE);
}
- @Before
- public void setUp() throws Exception {
- mDevice = UiDevice.getInstance(getInstrumentation());
+ String getStringRes(int key) {
+ return mContext.getResources().getString(key);
+ }
- /* Start the vulnerable activity */
- startVulnerableActivity();
- if (!mDevice.wait(Until.hasObject(By.res("android:id/contentPanel")
- .clazz("android.widget.ScrollView").pkg("android")), LAUNCH_TIMEOUT_MS)) {
- return;
- }
+ String getStringResWithArg(int key, String arg) {
+ return mContext.getResources().getString(key, arg);
+ }
- /* Start the overlay service */
- startOverlayService();
+ int getIntegerRes(int key) {
+ return mContext.getResources().getInteger(key);
}
@Test
- public void testVulnerableActivityPresence() {
- Pattern overlayTextPattern = Pattern.compile("OverlayButton", Pattern.CASE_INSENSITIVE);
- if (!mDevice.wait(Until.hasObject(By.text(overlayTextPattern)), LAUNCH_TIMEOUT_MS)) {
- return;
- }
-
- /*
- * Check if the currently running activity is the vulnerable activity, if not abort the test
- */
+ public void testOverlayButtonPresence() {
try {
- activityDump = mDevice.executeShellCommand("dumpsys activity");
- } catch (IOException e) {
- throw new RuntimeException("Could not execute dumpsys activity command");
- }
- Pattern activityPattern =
- Pattern.compile("mResumedActivity.*" + vulnerableActivityName + ".*\n");
- if (!activityPattern.matcher(activityDump).find()) {
- return;
+ UiDevice device = UiDevice.getInstance(getInstrumentation());
+
+ /* Start the overlay service */
+ assumeTrue(getStringRes(R.string.canNotDrawOverlaysMsg),
+ Settings.canDrawOverlays(mContext));
+ Intent intent = new Intent(mContext, PocService.class);
+ mContext.startService(intent);
+
+ /* Wait for a result from overlay service */
+ SharedPreferences sharedPrefs = mContext.getSharedPreferences(
+ getStringRes(R.string.sharedPreferences), Context.MODE_PRIVATE);
+ final Semaphore preferenceChanged = new Semaphore(0);
+ OnSharedPreferenceChangeListener listener = new OnSharedPreferenceChangeListener() {
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+ String key) {
+ if (key.equals(getStringRes(R.string.resultKey))) {
+ preferenceChanged.release();
+ }
+ }
+ };
+ sharedPrefs.registerOnSharedPreferenceChangeListener(listener);
+ assumeTrue(preferenceChanged.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ int result = sharedPrefs.getInt(getStringRes(R.string.resultKey),
+ getIntegerRes(R.integer.assumptionFailure));
+ String message = sharedPrefs.getString(getStringRes(R.string.messageKey),
+ getStringRes(R.string.defaultSemaphoreMsg));
+ assumeTrue(message, result != getIntegerRes(R.integer.assumptionFailure));
+
+ /* Wait for the UI of overlay window to appear */
+ Pattern overlayTextPattern = Pattern.compile(
+ mContext.getString(R.string.overlayButtonText), Pattern.CASE_INSENSITIVE);
+ assumeTrue(mContext.getString(R.string.overlayUiScreenError),
+ device.wait(Until.hasObject(By.text(overlayTextPattern)), TIMEOUT_MS));
+
+ /* Start the vulnerable activity */
+ intent = new Intent();
+ String vulActivity = getStringRes(R.string.vulClass);
+ String vulPkg = getStringRes(R.string.vulPkg);
+ if (isAuto()) {
+ vulActivity = getStringRes(R.string.vulClassAuto);
+ vulPkg = getStringRes(R.string.vulPkgAuto);
+ }
+ intent.setClassName(vulPkg, vulActivity);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(intent);
+
+ /* Wait until the object of overlay window is gone */
+ boolean overlayDisallowed =
+ device.wait(Until.gone(By.pkg(mContext.getPackageName())), TIMEOUT_MS);
+
+ /*
+ * Check if the currently running activity is the vulnerable activity, if not abort the
+ * test
+ */
+ String activityDump = device.executeShellCommand(
+ getStringResWithArg(R.string.cmdDumpsysActivity, vulActivity));
+ Pattern activityPattern = Pattern.compile(getStringRes(R.string.mResumedTrue));
+ assumeTrue(getStringRes(R.string.vulActivityNotRunningError),
+ activityPattern.matcher(activityDump).find());
+
+ /* Failing the test as fix is not present */
+ assertTrue(getStringResWithArg(R.string.overlayErrorMessage, vulActivity),
+ overlayDisallowed);
+ } catch (Exception e) {
+ assumeNoException(e);
}
- String message = "Device is vulnerable to b/143559931 hence any app with "
- + "SYSTEM_ALERT_WINDOW can overlay the ResolverActivity screen";
- assertNull(message, mDevice.findObject(By.text(overlayTextPattern)));
}
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/PocService.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/PocService.java
index 82b78a2beba..79270baa65e 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/PocService.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/PocService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,47 +14,65 @@
* limitations under the License.
*/
-package android.security.cts.cve_2021_0954;
+package android.security.cts.CVE_2021_0954;
import android.app.Service;
+import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.PixelFormat;
-import android.os.Handler;
import android.os.IBinder;
-import android.provider.Settings;
import android.view.Gravity;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.widget.Button;
public class PocService extends Service {
- public static Button mButton;
- private WindowManager mWindowManager;
- private WindowManager.LayoutParams mLayoutParams;
+ Button mButton;
+ WindowManager mWindowManager;
- private static int getScreenWidth() {
+ private int getScreenWidth() {
return Resources.getSystem().getDisplayMetrics().widthPixels;
}
- private static int getScreenHeight() {
+ private int getScreenHeight() {
return Resources.getSystem().getDisplayMetrics().heightPixels;
}
+ String getStringRes(int key) {
+ return getResources().getString(key);
+ }
+
+ int getIntegerRes(int key) {
+ return getResources().getInteger(key);
+ }
+
@Override
public void onCreate() {
- super.onCreate();
- mWindowManager = getSystemService(WindowManager.class);
- mLayoutParams = new WindowManager.LayoutParams();
- mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
- mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
- | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
- mLayoutParams.format = PixelFormat.OPAQUE;
- mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
- mLayoutParams.width = getScreenWidth();
- mLayoutParams.height = getScreenHeight();
- mLayoutParams.x = getScreenWidth() / 2;
- mLayoutParams.y = getScreenHeight() / 2;
+ try {
+ super.onCreate();
+ mWindowManager = getSystemService(WindowManager.class);
+ LayoutParams layoutParams = new LayoutParams();
+ layoutParams.type = LayoutParams.TYPE_APPLICATION_OVERLAY;
+ layoutParams.flags =
+ LayoutParams.FLAG_NOT_TOUCH_MODAL | LayoutParams.FLAG_NOT_FOCUSABLE;
+ layoutParams.format = PixelFormat.OPAQUE;
+ layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
+ layoutParams.width = getScreenWidth();
+ layoutParams.height = getScreenHeight();
+ layoutParams.x = getScreenWidth() / 2;
+ layoutParams.y = getScreenHeight() / 2;
+
+ /* Show the floating window */
+ mButton = new Button(this);
+ mButton.setText(getString(R.string.overlayButtonText));
+ mWindowManager.addView(mButton, layoutParams);
+ } catch (Exception e) {
+ sendTestResult(getIntegerRes(R.integer.assumptionFailure), e.getMessage());
+ return;
+ }
+ sendTestResult(getIntegerRes(R.integer.noAssumptionFailure), getStringRes(R.string.empty));
}
@Override
@@ -63,31 +81,27 @@ public class PocService extends Service {
}
@Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- showFloatingWindow();
- return super.onStartCommand(intent, flags, startId);
- }
-
- @Override
public void onDestroy() {
- if (mWindowManager != null && mButton != null) {
- mWindowManager.removeView(mButton);
+ try {
+ if (mWindowManager != null && mButton != null) {
+ mWindowManager.removeView(mButton);
+ }
+ super.onDestroy();
+ } catch (Exception e) {
+ sendTestResult(getIntegerRes(R.integer.assumptionFailure), e.getMessage());
}
- super.onDestroy();
}
- private void showFloatingWindow() {
- if (Settings.canDrawOverlays(this)) {
- mButton = new Button(getApplicationContext());
- mButton.setText("OverlayButton");
- mWindowManager.addView(mButton, mLayoutParams);
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- onDestroy();
- }
- }, 60000); // one minute
- mButton.setTag(mButton.getVisibility());
+ private void sendTestResult(int result, String message) {
+ try {
+ SharedPreferences sh = getSharedPreferences(getStringRes(R.string.sharedPreferences),
+ Context.MODE_PRIVATE);
+ SharedPreferences.Editor edit = sh.edit();
+ edit.putInt(getStringRes(R.string.resultKey), result);
+ edit.putString(getStringRes(R.string.messageKey), message);
+ edit.commit();
+ } catch (Exception e) {
+ // ignore the exception
}
}
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/Android.bp
new file mode 100644
index 00000000000..37d35eb74f2
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/Android.bp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test_helper_app {
+ name: "CVE-2022-20353",
+ defaults: [
+ "cts_support_defaults",
+ ],
+ srcs: [
+ "src/**/*.java",
+ ],
+ test_suites: [
+ "sts",
+ ],
+ static_libs: [
+ "androidx.test.core",
+ "androidx.test.rules",
+ "androidx.test.uiautomator_uiautomator",
+ ],
+ sdk_version: "current",
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/AndroidManifest.xml
new file mode 100644
index 00000000000..d4129ac8823
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2022_20353">
+ <application
+ android:label="@string/appName"
+ android:supportsRtl="true">
+ <activity
+ android:name=".PocActivity"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.RINGTONE_PICKER" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+ </application>
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2022_20353" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/res/values/integers.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/res/values/integers.xml
new file mode 100644
index 00000000000..3207c29a0bd
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/res/values/integers.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources>
+ <integer name="assumptionFailure">-1</integer>
+ <integer name="success">0</integer>
+ <integer name="timeoutMs">20000</integer>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/res/values/strings.xml
new file mode 100644
index 00000000000..27e87f65446
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/res/values/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources>
+ <string name="alwaysButtonId">android:id/button_always</string>
+ <string name="appName">CVE-2022-20353</string>
+ <string name="defaultSemaphoreMsg">Could not get message key in shared preferences</string>
+ <string name="failureMessage">
+ Device is vulnerable to b/221041256!! Privilege escalation possible in
+ com.android.settings.DefaultRingtonePreference
+ </string>
+ <string name="fileName">NOTICE.html</string>
+ <string name="getRingtoneCmd">settings get system ringtone</string>
+ <string name="messageKey">message</string>
+ <string name="noticeUri">
+ content://com.android.settings.files/my_cache/NOTICE.html
+ </string>
+ <string name="resType">string</string>
+ <string name="resultKey">result</string>
+ <string name="setRingtoneCmd">settings put system ringtone</string>
+ <string name="sharedPreferences">sharedPreferences</string>
+ <string name="textResId">ringtone_title</string>
+ <string name="uiObjectNotFoundMsg">Unable to find UiObject with %1$s text/id</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/src/android/security/cts/CVE_2022_20353/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/src/android/security/cts/CVE_2022_20353/DeviceTest.java
new file mode 100644
index 00000000000..af1f9782ab0
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/src/android/security/cts/CVE_2022_20353/DeviceTest.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.CVE_2022_20353;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.content.res.Resources;
+import android.provider.Settings;
+
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.UiScrollable;
+import androidx.test.uiautomator.UiSelector;
+import androidx.test.uiautomator.Until;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+ Resources mResources;
+ UiDevice mDevice;
+ Context mContext;
+
+ // Wait for UiObject to appear and click on the UiObject if it is visible
+ private boolean clickUiObject(BySelector selector) {
+ boolean objectFound =
+ mDevice.wait(Until.hasObject(selector), mResources.getInteger(R.integer.timeoutMs));
+ if (objectFound) {
+ mDevice.findObject(selector).click();
+ }
+ return objectFound;
+ }
+
+ @Test
+ public void testDefaultRingtonePreference() {
+ String defaultRingtone = null;
+ try {
+ mDevice = UiDevice.getInstance(getInstrumentation());
+ mContext = getInstrumentation().getContext();
+ mResources = mContext.getResources();
+ defaultRingtone =
+ mDevice.executeShellCommand(mContext.getString(R.string.getRingtoneCmd));
+
+ Intent intent = new Intent(Settings.ACTION_SOUND_SETTINGS);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(intent);
+
+ String settingsPackageName =
+ intent.resolveActivity(mContext.getPackageManager()).getPackageName();
+ Context settingsContext = mContext.createPackageContext(settingsPackageName,
+ Context.CONTEXT_IGNORE_SECURITY);
+ Resources res = settingsContext.getPackageManager()
+ .getResourcesForApplication(settingsPackageName);
+ String text = settingsContext
+ .getString(res.getIdentifier(mContext.getString(R.string.textResId),
+ mContext.getString(R.string.resType), settingsPackageName));
+ // scroll until text 'Phone ringtone' is visible
+ UiScrollable uiScrollable = new UiScrollable(new UiSelector().scrollable(true));
+ uiScrollable.scrollTextIntoView(text);
+ // click on 'Phone ringtone'
+ BySelector selector = By.text(text);
+ assumeTrue(mContext.getString(R.string.uiObjectNotFoundMsg, text),
+ clickUiObject(selector));
+ // select CTS PoC app
+ text = mContext.getString(R.string.appName);
+ selector = By.text(text);
+ assumeTrue(mContext.getString(R.string.uiObjectNotFoundMsg, text),
+ clickUiObject(selector));
+ // select 'Always'
+ String resId = mContext.getString(R.string.alwaysButtonId);
+ selector = By.res(resId);
+ assumeTrue(mContext.getString(R.string.uiObjectNotFoundMsg, resId),
+ clickUiObject(selector));
+
+ SharedPreferences sharedPrefs = mContext.getSharedPreferences(
+ mContext.getString(R.string.sharedPreferences), Context.MODE_APPEND);
+ Semaphore preferenceChanged = new Semaphore(0);
+ OnSharedPreferenceChangeListener sharedPrefListener =
+ new OnSharedPreferenceChangeListener() {
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+ String key) {
+ if (key.equals(mContext.getString(R.string.resultKey))) {
+ preferenceChanged.release();
+ }
+ }
+ };
+ sharedPrefs.registerOnSharedPreferenceChangeListener(sharedPrefListener);
+ // wait for PocActivity to complete
+ assumeTrue(preferenceChanged.tryAcquire(mResources.getInteger(R.integer.timeoutMs),
+ TimeUnit.MILLISECONDS));
+ int result = sharedPrefs.getInt(mContext.getString(R.string.resultKey),
+ mResources.getInteger(R.integer.assumptionFailure));
+ String message = sharedPrefs.getString(mContext.getString(R.string.messageKey),
+ mContext.getString(R.string.defaultSemaphoreMsg));
+ assumeTrue(message, result != mResources.getInteger(R.integer.assumptionFailure));
+
+ String ringtoneUri = "";
+ boolean isVulnerable = false;
+ long startTime = System.currentTimeMillis();
+ while ((System.currentTimeMillis() - startTime) < mResources
+ .getInteger(R.integer.timeoutMs)) {
+ ringtoneUri =
+ mDevice.executeShellCommand(mContext.getString(R.string.getRingtoneCmd));
+ if (ringtoneUri.contains(mContext.getString(R.string.fileName))) {
+ isVulnerable = true;
+ break;
+ }
+ }
+ assertFalse(mContext.getString(R.string.failureMessage), isVulnerable);
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ // reset ringtone to default (other than 'null') present before test
+ mDevice.executeShellCommand(
+ mContext.getString(R.string.setRingtoneCmd) + " " + defaultRingtone);
+ mDevice.pressHome();
+ } catch (Exception e) {
+ // ignore exception here
+ }
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/src/android/security/cts/CVE_2022_20353/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/src/android/security/cts/CVE_2022_20353/PocActivity.java
new file mode 100644
index 00000000000..977e647d2e2
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/src/android/security/cts/CVE_2022_20353/PocActivity.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.CVE_2022_20353;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.media.RingtoneManager;
+import android.net.Uri;
+import android.os.Bundle;
+
+/* PocActivity is required in this test since it is required that CTS PoC app is selected when */
+/* choosing an app for setting default ringtone. RingtonePicker appears due to actions done in */
+/* DeviceTest. */
+public class PocActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ try {
+ super.onCreate(savedInstanceState);
+ Intent intent = new Intent();
+ /* set NOTICE.html file uri as EXTRA_RINGTONE_PICKED_URI which sets NOTICE.html as */
+ /* default ringtone if vulnerability is present */
+ intent.putExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI,
+ Uri.parse(getString(R.string.noticeUri)));
+ setResult(Activity.RESULT_OK, intent);
+ finish();
+ sendTestResult(getResources().getInteger(R.integer.success), "");
+ } catch (Exception e) {
+ sendTestResult(getResources().getInteger(R.integer.assumptionFailure), e.getMessage());
+ }
+ }
+
+ void sendTestResult(int result, String message) {
+ try {
+ SharedPreferences sh = getSharedPreferences(getString(R.string.sharedPreferences),
+ Context.MODE_PRIVATE);
+ SharedPreferences.Editor edit = sh.edit();
+ edit.putInt(getString(R.string.resultKey), result);
+ edit.putString(getString(R.string.messageKey), message);
+ edit.commit();
+ } catch (Exception e) {
+ // ignore exception here
+ }
+ }
+
+}
diff --git a/hostsidetests/statsdatom/src/android/cts/statsdatom/lib/ConfigUtils.java b/hostsidetests/statsdatom/src/android/cts/statsdatom/lib/ConfigUtils.java
index be665ba4013..7f29d44673c 100644
--- a/hostsidetests/statsdatom/src/android/cts/statsdatom/lib/ConfigUtils.java
+++ b/hostsidetests/statsdatom/src/android/cts/statsdatom/lib/ConfigUtils.java
@@ -69,10 +69,6 @@ public final class ConfigUtils {
.addAllowedLogSource("AID_SYSTEM")
.addAllowedLogSource("AID_BLUETOOTH")
.addAllowedLogSource("com.android.bluetooth")
- // TODO(b/236681553): Remove this.
- .addAllowedLogSource("com.android.bluetooth.services")
- // TODO(b/236681553): Remove this.
- .addAllowedLogSource("com.google.android.bluetooth.services")
.addAllowedLogSource("AID_LMKD")
.addAllowedLogSource("AID_MEDIA")
.addAllowedLogSource("AID_RADIO")
diff --git a/tests/camera/Android.bp b/tests/camera/Android.bp
index aae58c689b7..c2334fc3b4c 100644
--- a/tests/camera/Android.bp
+++ b/tests/camera/Android.bp
@@ -65,6 +65,7 @@ android_test {
"truth-prebuilt",
"androidx.heifwriter_heifwriter",
"androidx.test.rules",
+ "MediaPerformanceClassCommon",
],
jni_libs: [
"libctscamera2_jni",
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 feb5567963f..772e7a599cb 100644
--- a/tests/camera/api31test/src/android/camera/cts/api31test/SPerfClassTest.java
+++ b/tests/camera/api31test/src/android/camera/cts/api31test/SPerfClassTest.java
@@ -36,6 +36,7 @@ import android.hardware.camera2.params.SessionConfiguration;
import android.hardware.camera2.TotalCaptureResult;
import android.media.Image;
import android.media.ImageReader;
+import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.test.AndroidTestCase;
@@ -210,8 +211,9 @@ public class SPerfClassTest extends AndroidTestCase {
* Version.MEDIA_PERFORMANCE_CLASS
*/
public void testSPerfClassJpegSizes() throws Exception {
- boolean isSPerfClass = CameraTestUtils.isSPerfClass();
- if (!isSPerfClass) {
+ final boolean isAtLeastSPerfClass =
+ (Build.VERSION.MEDIA_PERFORMANCE_CLASS >= Build.VERSION_CODES.S);
+ if (!isAtLeastSPerfClass) {
return;
}
diff --git a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
index 6af7758c533..d7dd63d1ff2 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
@@ -55,6 +55,10 @@ import android.hardware.camera2.params.DynamicRangeProfiles;
import android.hardware.camera2.params.RecommendedStreamConfigurationMap;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.hardware.cts.helpers.CameraUtils;
+import android.mediapc.cts.common.Requirement;
+import android.mediapc.cts.common.RequiredMeasurement;
+import android.mediapc.cts.common.RequirementConstants;
+import android.mediapc.cts.common.PerformanceClassEvaluator;
import android.media.CamcorderProfile;
import android.media.ImageReader;
import android.os.Build;
@@ -74,15 +78,11 @@ import android.view.WindowMetrics;
import androidx.test.rule.ActivityTestRule;
-import androidx.test.InstrumentationRegistry;
-
import com.android.compatibility.common.util.CddTest;
-import com.android.compatibility.common.util.DeviceReportLog;
-import com.android.compatibility.common.util.ResultType;
-import com.android.compatibility.common.util.ResultUnit;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.TestName;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -92,12 +92,10 @@ import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
+import java.util.function.BiPredicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import static android.hardware.camera2.cts.CameraTestUtils.MPC_REPORT_LOG_NAME;
-import static android.hardware.camera2.cts.CameraTestUtils.MPC_STREAM_NAME;
-
/**
* Extended tests for static camera characteristics.
*/
@@ -113,6 +111,9 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
*/
private static final int MIN_ALLOWABLE_WHITELEVEL = 32; // must have sensor bit depth > 5
+ @Rule
+ public final TestName mTestName = new TestName();
+
private List<CameraCharacteristics> mCharacteristics;
private static final Size FULLHD = new Size(1920, 1080);
@@ -131,10 +132,6 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
private static final long PREVIEW_RUN_MS = 500;
private static final long FRAME_DURATION_30FPS_NSEC = (long) 1e9 / 30;
- private static final long MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION = 12000000;
- private static final long MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION = 5000000;
- private static final long MIN_FRONT_SENSOR_R_PERF_CLASS_RESOLUTION = 4000000;
-
private static final long MIN_UHR_SENSOR_RESOLUTION = 24000000;
/*
* HW Levels short hand
@@ -2857,28 +2854,70 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
}
/**
- * Update performance class level based on condition
- *
- * @param condition whether the condition is met for passLevel
- * @param passLevel the highest performance class level when condition is true
- * @param failLevel the performance class when condition is false
+ * Camera hardware level requirement for Media Performance Class
*/
- private int updatePerfClassLevel(boolean condition, int passLevel, int failLevel) {
- return condition ? passLevel : failLevel;
- }
+ public static class PrimaryCameraHwLevelReq extends Requirement {
+ private static final String TAG = PrimaryCameraHwLevelReq.class.getSimpleName();
+
+ /**
+ * Creates a >= predicate for camera hardware level
+ */
+ private static BiPredicate<Integer, Integer> camHwLevelGte() {
+ return new BiPredicate<Integer, Integer>() {
+ @Override
+ public boolean test(Integer actual, Integer expected) {
+ return StaticMetadata.hardwareLevelPredicate(actual, expected);
+ }
- /**
- * Update perf class level based on meetSPerfClass and meetRPerfClass.
- */
- private int updatePerfClassLevelRS(boolean meetSPerfClass, boolean meetRPerfClass,
- int perfClassLevel) {
- if (!meetRPerfClass) {
- return CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
- } else if (!meetSPerfClass &&
- perfClassLevel > CameraTestUtils.PERFORMANCE_CLASS_R) {
- return Math.min(CameraTestUtils.PERFORMANCE_CLASS_R, perfClassLevel);
- }
- return perfClassLevel;
+ @Override
+ public String toString() {
+ return "Camera Hardware Level Greater than or equal to";
+ }
+ };
+ }
+ private static final BiPredicate<Integer, Integer> CAM_HW_LEVEL_GTE = camHwLevelGte();
+ private PrimaryCameraHwLevelReq(String id, RequiredMeasurement<?> ... reqs) {
+ super(id, reqs);
+ }
+
+ public void setPrimaryRearCameraHwlLevel(Integer hwLevel) {
+ this.setMeasuredValue(RequirementConstants.REAR_CAMERA_HWL_LEVEL, hwLevel);
+ }
+
+ public void setPrimaryFrontCameraHwlLevel(Integer hwLevel) {
+ this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_HWL_LEVEL, hwLevel);
+ }
+
+ /**
+ * [2.2.7.2/7.5/H-1-3] MUST support android.info.supportedHardwareLevel property as FULL or
+ * better for back primary and LIMITED or better for front primary camera.
+ */
+ public static PrimaryCameraHwLevelReq createPrimaryCameraHwLevelReq() {
+ RequiredMeasurement<Integer> rearCameraHwlLevel = RequiredMeasurement
+ .<Integer>builder()
+ .setId(RequirementConstants.REAR_CAMERA_HWL_LEVEL)
+ .setPredicate(CAM_HW_LEVEL_GTE)
+ .addRequiredValue(Build.VERSION_CODES.R,
+ CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL)
+ .addRequiredValue(Build.VERSION_CODES.S,
+ CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU,
+ CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL)
+ .build();
+ RequiredMeasurement<Integer> frontCameraHwlLevel = RequiredMeasurement
+ .<Integer>builder()
+ .setId(RequirementConstants.FRONT_CAMERA_HWL_LEVEL)
+ .setPredicate(CAM_HW_LEVEL_GTE)
+ .addRequiredValue(Build.VERSION_CODES.R,
+ CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED)
+ .addRequiredValue(Build.VERSION_CODES.S,
+ CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU,
+ CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL)
+ .build();
+ return new PrimaryCameraHwLevelReq(RequirementConstants.R7_5__H_1_3,
+ rearCameraHwlLevel, frontCameraHwlLevel);
+ }
}
/**
@@ -2893,30 +2932,31 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
// ids.
return;
}
- boolean assertRPerfClass = CameraTestUtils.isRPerfClass();
- boolean assertSPerfClass = CameraTestUtils.isSPerfClass();
- boolean assertTPerfClass = CameraTestUtils.isTPerfClass();
- boolean assertPerfClass = (assertRPerfClass || assertSPerfClass || assertTPerfClass);
-
- // R & S Performance Class
- int perfClassLevelH11 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
- int perfClassLevelH12 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
- int perfClassLevelH13 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
- int perfClassLevelH14 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
- int perfClassLevelH18 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
-
- // T Performance Class
- int perfClassLevelH19 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
- int perfClassLevelH110 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
- int perfClassLevelH111 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
- int perfClassLevelH112 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
- int perfClassLevelH113 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
- int perfClassLevelH114 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT;
-
- DeviceReportLog reportLog = new DeviceReportLog(MPC_REPORT_LOG_NAME, MPC_STREAM_NAME);
-
- String primaryRearId = null;
- String primaryFrontId = null;
+ PerformanceClassEvaluator pce = new PerformanceClassEvaluator(this.mTestName);
+ PerformanceClassEvaluator.PrimaryCameraRequirement primaryRearReq =
+ pce.addPrimaryRearCameraReq();
+ PerformanceClassEvaluator.PrimaryCameraRequirement primaryFrontReq =
+ pce.addPrimaryFrontCameraReq();
+ PrimaryCameraHwLevelReq hwLevelReq = pce.addRequirement(
+ PrimaryCameraHwLevelReq.createPrimaryCameraHwLevelReq());
+ PerformanceClassEvaluator.CameraTimestampSourceRequirement timestampSourceReq =
+ pce.addR7_5__H_1_4();
+ PerformanceClassEvaluator.CameraRawRequirement rearRawReq =
+ pce.addR7_5__H_1_8();
+ PerformanceClassEvaluator.Camera240FpsRequirement hfrReq =
+ pce.addR7_5__H_1_9();
+ PerformanceClassEvaluator.UltraWideZoomRatioRequirement ultrawideZoomRatioReq =
+ pce.addR7_5__H_1_10();
+ PerformanceClassEvaluator.ConcurrentRearFrontRequirement concurrentRearFrontReq =
+ pce.addR7_5__H_1_11();
+ PerformanceClassEvaluator.PreviewStabilizationRequirement previewStabilizationReq =
+ pce.addR7_5__H_1_12();
+ PerformanceClassEvaluator.LogicalMultiCameraRequirement logicalMultiCameraReq =
+ pce.addR7_5__H_1_13();
+ PerformanceClassEvaluator.StreamUseCaseRequirement streamUseCaseReq =
+ pce.addR7_5__H_1_14();
+
+ HashSet<String> primaryCameras = new HashSet<String>();
for (int i = 0; i < mCameraIdsUnderTest.length; i++) {
String cameraId = mCameraIdsUnderTest[i];
boolean isPrimaryRear = CameraTestUtils.isPrimaryRearFacingCamera(
@@ -2940,42 +2980,27 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
List<Size> videoSizes = CameraTestUtils.getSupportedVideoSizes(cameraId,
mCameraManager, null /*bound*/);
+ Integer timestampSource = c.get(CameraCharacteristics.SENSOR_INFO_TIMESTAMP_SOURCE);
if (isPrimaryRear) {
- primaryRearId = cameraId;
- if (sensorResolution < MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION) {
- mCollector.expectTrue("Primary rear camera resolution should be at least " +
- MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION + " pixels, is "+
- sensorResolution, !assertPerfClass);
- perfClassLevelH11 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
- }
- reportLog.addValue("rear camera resolution", sensorResolution,
- ResultType.NEUTRAL, ResultUnit.NONE);
+ primaryCameras.add(cameraId);
+ primaryRearReq.setPrimaryCameraSupported(true);
+ primaryRearReq.setResolution(sensorResolution);
+ hwLevelReq.setPrimaryRearCameraHwlLevel(staticInfo.getHardwareLevelChecked());
+ timestampSourceReq.setRearCameraTimestampSource(timestampSource);
// 4K @ 30fps
boolean supportUHD = videoSizes.contains(UHD);
boolean supportDC4K = videoSizes.contains(DC4K);
- reportLog.addValue("rear camera 4k support", supportUHD | supportDC4K,
- ResultType.NEUTRAL, ResultUnit.NONE);
- if (!supportUHD && !supportDC4K) {
- mCollector.expectTrue("Primary rear camera should support 4k video recording",
- !assertPerfClass);
- perfClassLevelH11 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
- } else {
+ boolean support4K = (supportUHD || supportDC4K);
+ primaryRearReq.setVideoSizeReqSatisfied(support4K);
+ if (support4K) {
long minFrameDuration = config.getOutputMinFrameDuration(
android.media.MediaRecorder.class, supportDC4K ? DC4K : UHD);
- reportLog.addValue("rear camera 4k frame duration", minFrameDuration,
- ResultType.NEUTRAL, ResultUnit.NONE);
- if (minFrameDuration >= (1e9 / 29.9)) {
- mCollector.expectTrue("Primary rear camera should support 4k video @ 30fps",
- !assertPerfClass);
- perfClassLevelH11 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
- }
+ primaryRearReq.setVideoFps(1e9 / minFrameDuration);
}
// H-1-9
boolean supportHighSpeed = staticInfo.isCapabilitySupported(CONSTRAINED_HIGH_SPEED);
- mCollector.expectTrue("Primary rear camera should support high speed recording",
- !assertTPerfClass || supportHighSpeed);
boolean support240Fps = false;
if (supportHighSpeed) {
Size[] availableHighSpeedSizes = config.getHighSpeedVideoSizes();
@@ -2995,101 +3020,29 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
break;
}
}
- mCollector.expectTrue("Primary rear camera should support HD or FULLHD @ 240",
- !assertTPerfClass || support240Fps);
}
- perfClassLevelH19 = updatePerfClassLevel(support240Fps,
- perfClassLevelH19, CameraTestUtils.PERFORMANCE_CLASS_S);
- reportLog.addValue("rear camera 720p/1080p @ 240fps support", support240Fps,
- ResultType.NEUTRAL, ResultUnit.NONE);
+ hfrReq.setRear240FpsSupported(support240Fps);
} else {
- primaryFrontId = cameraId;
- if (sensorResolution < MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION) {
- mCollector.expectTrue("Primary front camera resolution should be at least "
- + MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION + " pixels, is "
- + sensorResolution, !(assertSPerfClass || assertTPerfClass));
- perfClassLevelH12 = Math.min(
- perfClassLevelH12, CameraTestUtils.PERFORMANCE_CLASS_R);
- }
- if (sensorResolution < MIN_FRONT_SENSOR_R_PERF_CLASS_RESOLUTION) {
- mCollector.expectTrue("Primary front camera resolution should be at least " +
- MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION + " pixels, is "+
- sensorResolution, !assertRPerfClass);
- perfClassLevelH12 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
- }
- reportLog.addValue("front camera resolution", sensorResolution,
- ResultType.NEUTRAL, ResultUnit.NONE);
+ primaryCameras.add(cameraId);
+ primaryFrontReq.setPrimaryCameraSupported(true);
+ primaryFrontReq.setResolution(sensorResolution);
+ hwLevelReq.setPrimaryFrontCameraHwlLevel(staticInfo.getHardwareLevelChecked());
+ timestampSourceReq.setFrontCameraTimestampSource(timestampSource);
// 1080P @ 30fps
boolean supportFULLHD = videoSizes.contains(FULLHD);
- reportLog.addValue("front camera 1080p support", supportFULLHD,
- ResultType.NEUTRAL, ResultUnit.NONE);
- if (!supportFULLHD) {
- mCollector.expectTrue(
- "Primary front camera should support 1080P video recording",
- !assertPerfClass);
- perfClassLevelH12 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
- } else {
+ primaryFrontReq.setVideoSizeReqSatisfied(supportFULLHD);
+ if (supportFULLHD) {
long minFrameDuration = config.getOutputMinFrameDuration(
android.media.MediaRecorder.class, FULLHD);
- if (minFrameDuration >= (1e9 / 29.9)) {
- mCollector.expectTrue(
- "Primary front camera should support 1080P video @ 30fps",
- !assertPerfClass);
- perfClassLevelH12 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
- }
- reportLog.addValue("front camera 1080p frame duration", minFrameDuration,
- ResultType.NEUTRAL, ResultUnit.NONE);
+ primaryFrontReq.setVideoFps(1e9 / minFrameDuration);
}
}
- String facingString = isPrimaryRear ? "rear" : "front";
- // H-1-3
- if (assertTPerfClass || assertSPerfClass || (assertRPerfClass && isPrimaryRear)) {
- mCollector.expectTrue("Primary " + facingString +
- " camera should be at least FULL, but is " +
- toStringHardwareLevel(staticInfo.getHardwareLevelChecked()),
- staticInfo.isHardwareLevelAtLeastFull());
- } else if (assertRPerfClass) {
- mCollector.expectTrue("Primary " + facingString +
- " camera should be at least LIMITED, but is " +
- toStringHardwareLevel(staticInfo.getHardwareLevelChecked()),
- staticInfo.isHardwareLevelAtLeastLimited());
- }
-
- reportLog.addValue(facingString + " camera hardware level",
- staticInfo.getHardwareLevelChecked(), ResultType.NEUTRAL, ResultUnit.NONE);
- if (isPrimaryRear) {
- perfClassLevelH13 = updatePerfClassLevel(staticInfo.isHardwareLevelAtLeastFull(),
- perfClassLevelH13, CameraTestUtils.PERFORMANCE_CLASS_NOT_MET);
- } else {
- perfClassLevelH13 = updatePerfClassLevelRS(staticInfo.isHardwareLevelAtLeastFull(),
- staticInfo.isHardwareLevelAtLeastLimited(), perfClassLevelH13);
- }
-
- // H-1-4
- Integer timestampSource = c.get(CameraCharacteristics.SENSOR_INFO_TIMESTAMP_SOURCE);
- reportLog.addValue(facingString + " timestampSource",
- timestampSource, ResultType.NEUTRAL, ResultUnit.NONE);
- boolean realtimeTimestamp = (timestampSource != null &&
- timestampSource.equals(CameraMetadata.SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME));
- mCollector.expectTrue(
- "Primary " + facingString + " camera should support real-time timestamp source",
- !assertPerfClass || realtimeTimestamp);
- perfClassLevelH14 = updatePerfClassLevel(realtimeTimestamp, perfClassLevelH14,
- CameraTestUtils.PERFORMANCE_CLASS_NOT_MET);
-
// H-1-8
if (isPrimaryRear) {
boolean supportRaw = staticInfo.isCapabilitySupported(RAW);
- reportLog.addValue(facingString + " camera raw support",
- supportRaw, ResultType.NEUTRAL, ResultUnit.NONE);
- if (assertSPerfClass || assertTPerfClass) {
- mCollector.expectTrue("Primary rear camera should support RAW capability",
- supportRaw);
- }
- perfClassLevelH18 = updatePerfClassLevel(supportRaw, perfClassLevelH18,
- CameraTestUtils.PERFORMANCE_CLASS_R);
+ rearRawReq.setRearRawSupported(supportRaw);
}
// H-1-10
@@ -3098,96 +3051,45 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
Range<Float> zoomRatioRange = staticInfo.getZoomRatioRangeChecked();
boolean meetH110 = (primaryToMaxFovRatio >= 1.0f - FOV_THRESHOLD)
|| (zoomRatioRange.getLower() < 1.0f - FOV_THRESHOLD);
- mCollector.expectTrue("Primary " + facingString + " camera must support zoomRatio < "
- + "1.0f if there is an ultrawide lens with the same facing",
- !assertTPerfClass || meetH110);
- perfClassLevelH110 = updatePerfClassLevel(meetH110, perfClassLevelH110,
- CameraTestUtils.PERFORMANCE_CLASS_S);
- reportLog.addValue(facingString + " camera supports maximum FOV using zoom ratio",
- meetH110, ResultType.NEUTRAL, ResultUnit.NONE);
+ if (isPrimaryRear) {
+ ultrawideZoomRatioReq.setRearUltraWideZoomRatioReqMet(meetH110);
+ } else {
+ ultrawideZoomRatioReq.setFrontUltraWideZoomRatioReqMet(meetH110);
+ }
// H-1-12
- boolean meetH112 = staticInfo.isPreviewStabilizationSupported();
- mCollector.expectTrue("Primary " + facingString + " camera must support preview "
- + "stabilization", !assertTPerfClass || meetH112);
- perfClassLevelH112 = updatePerfClassLevel(meetH112, perfClassLevelH112,
- CameraTestUtils.PERFORMANCE_CLASS_S);
- reportLog.addValue(facingString + " camera preview stabilization", meetH112,
- ResultType.NEUTRAL, ResultUnit.NONE);
+ boolean previewStab = staticInfo.isPreviewStabilizationSupported();
+ if (isPrimaryRear) {
+ previewStabilizationReq.setRearPreviewStabilizationSupported(previewStab);
+ } else {
+ previewStabilizationReq.setFrontPreviewStabilizationSupported(previewStab);
+ }
// H-1-13
int facing = staticInfo.getLensFacingChecked();
int numOfPhysicalRgbCameras = getNumberOfRgbPhysicalCameras(facing);
- boolean meetH113 = (numOfPhysicalRgbCameras <= 1) || staticInfo.isLogicalMultiCamera();
- mCollector.expectTrue("Primary " + facingString + " camera must be LOGICAL_MULTI_CAMERA"
- + " in case of multiple RGB cameras with same facing",
- !assertTPerfClass || meetH113);
- perfClassLevelH113 = updatePerfClassLevel(meetH113, perfClassLevelH113,
- CameraTestUtils.PERFORMANCE_CLASS_S);
- reportLog.addValue(facingString + " camera is LOGICAL_MULTI_CAMERA in case of multiple "
- + "RGB cameras with same facing", meetH113, ResultType.NEUTRAL,
- ResultUnit.NONE);
+ boolean logicalMultiCameraReqMet =
+ (numOfPhysicalRgbCameras <= 1) || staticInfo.isLogicalMultiCamera();
+ if (isPrimaryRear) {
+ logicalMultiCameraReq.setRearLogicalMultiCameraReqMet(logicalMultiCameraReqMet);
+ } else {
+ logicalMultiCameraReq.setFrontLogicalMultiCameraReqMet(logicalMultiCameraReqMet);
+ }
// H-1-14
- boolean meetH114 = staticInfo.isStreamUseCaseSupported();
- mCollector.expectTrue("Primary " + facingString + " camera must support stream "
- + "use case", !assertTPerfClass || meetH114);
- perfClassLevelH114 = updatePerfClassLevel(meetH114, perfClassLevelH114,
- CameraTestUtils.PERFORMANCE_CLASS_S);
- reportLog.addValue(facingString + " camera stream use case", meetH114,
- ResultType.NEUTRAL, ResultUnit.NONE);
- }
- HashSet<String> primaryCameras = new HashSet<String>();
- if (primaryRearId == null) {
- mCollector.expectTrue("There must be a primary rear camera for performance class.",
- !assertPerfClass);
- perfClassLevelH11 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
- } else {
- primaryCameras.add(primaryRearId);
- }
- if (primaryFrontId == null) {
- mCollector.expectTrue("There must be a primary front camera for performance class.",
- !assertPerfClass);
- perfClassLevelH12 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET;
- } else {
- primaryCameras.add(primaryFrontId);
+ boolean streamUseCaseSupported = staticInfo.isStreamUseCaseSupported();
+ if (isPrimaryRear) {
+ streamUseCaseReq.setRearStreamUseCaseSupported(streamUseCaseSupported);
+ } else {
+ streamUseCaseReq.setFrontStreamUseCaseSupported(streamUseCaseSupported);
+ }
}
-
// H-1-11
Set<Set<String>> concurrentCameraIds = mCameraManager.getConcurrentCameraIds();
boolean supportPrimaryFrontBack = concurrentCameraIds.contains(primaryCameras);
- mCollector.expectTrue("Concurrent primary front and primary back streaming must be "
- + "supported", !assertTPerfClass || supportPrimaryFrontBack);
- perfClassLevelH111 = updatePerfClassLevel(supportPrimaryFrontBack,
- perfClassLevelH111, CameraTestUtils.PERFORMANCE_CLASS_S);
- reportLog.addValue("concurrent front back support", supportPrimaryFrontBack,
- ResultType.NEUTRAL, ResultUnit.NONE);
-
- reportLog.addValue("Version", "0.0.1", ResultType.NEUTRAL, ResultUnit.NONE);
- final String PERF_CLASS_REQ_NUM_PREFIX = "2.2.7.2/7.5/";
- reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-1",
- perfClassLevelH11, ResultType.NEUTRAL, ResultUnit.NONE);
- reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-2",
- perfClassLevelH12, ResultType.NEUTRAL, ResultUnit.NONE);
- reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-3",
- perfClassLevelH13, ResultType.NEUTRAL, ResultUnit.NONE);
- reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-4",
- perfClassLevelH14, ResultType.NEUTRAL, ResultUnit.NONE);
- reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-8",
- perfClassLevelH18, ResultType.NEUTRAL, ResultUnit.NONE);
- reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-9",
- perfClassLevelH19, ResultType.NEUTRAL, ResultUnit.NONE);
- reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-10",
- perfClassLevelH110, ResultType.NEUTRAL, ResultUnit.NONE);
- reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-11",
- perfClassLevelH111, ResultType.NEUTRAL, ResultUnit.NONE);
- reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-12",
- perfClassLevelH112, ResultType.NEUTRAL, ResultUnit.NONE);
- reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-13",
- perfClassLevelH113, ResultType.NEUTRAL, ResultUnit.NONE);
- reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-14",
- perfClassLevelH114, ResultType.NEUTRAL, ResultUnit.NONE);
- reportLog.submit(InstrumentationRegistry.getInstrumentation());
+ concurrentRearFrontReq.setConcurrentRearFrontSupported(supportPrimaryFrontBack);
+
+ pce.submitAndCheck();
}
/**
diff --git a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
index 3c88a3a445c..c9c28eac4bf 100644
--- a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
@@ -1234,8 +1234,13 @@ public class RecordingTest extends Camera2SurfaceViewTestCase {
mOutMediaFileName = mDebugFileNameBase + "/test_cslowMo_video_" +
captureRate + "fps_" + id + "_" + size.toString() + ".mp4";
- Log.v(TAG, "previewFrameRate:" + previewFrameRate);
- prepareRecording(size, previewFrameRate, captureRate);
+
+ // b/239101664 It appears that video frame rates higher than 30 fps may not
+ // trigger slow motion recording consistently.
+ int videoFrameRate = previewFrameRate > VIDEO_FRAME_RATE ?
+ VIDEO_FRAME_RATE : previewFrameRate;
+ Log.v(TAG, "videoFrameRate:" + videoFrameRate);
+ prepareRecording(size, videoFrameRate, captureRate);
SystemClock.sleep(PREVIEW_DURATION_MS);
@@ -1243,7 +1248,7 @@ public class RecordingTest extends Camera2SurfaceViewTestCase {
SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
// Start recording
- startSlowMotionRecording(/*useMediaRecorder*/true, previewFrameRate,
+ startSlowMotionRecording(/*useMediaRecorder*/true, videoFrameRate,
captureRate, fpsRange, resultListener,
/*useHighSpeedSession*/true);
@@ -1256,7 +1261,7 @@ public class RecordingTest extends Camera2SurfaceViewTestCase {
startConstrainedPreview(fpsRange, previewResultListener);
// Convert number of frames camera produced into the duration in unit of ms.
- float frameDurationMs = 1000.0f / previewFrameRate;
+ float frameDurationMs = 1000.0f / videoFrameRate;
float durationMs = resultListener.getTotalNumFrames() * frameDurationMs;
// Validation.
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 e8d616880e7..4a86b49e51a 100644
--- a/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
+++ b/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
@@ -142,8 +142,6 @@ public class CameraTestUtils extends Assert {
public static final String OFFLINE_CAMERA_ID = "offline_camera_id";
public static final String REPORT_LOG_NAME = "CtsCameraTestCases";
- public static final String MPC_REPORT_LOG_NAME = "MediaPerformanceClassLogs";
- public static final String MPC_STREAM_NAME = "CameraCts";
private static final int EXIF_DATETIME_LENGTH = 19;
private static final int EXIF_DATETIME_ERROR_MARGIN_SEC = 60;
@@ -3815,33 +3813,6 @@ public class CameraTestUtils extends Assert {
return zoomRatios;
}
- public static final int PERFORMANCE_CLASS_NOT_MET = 0;
- public static final int PERFORMANCE_CLASS_R = Build.VERSION_CODES.R;
- public static final int PERFORMANCE_CLASS_S = Build.VERSION_CODES.R + 1;
- public static final int PERFORMANCE_CLASS_T = Build.VERSION_CODES.S + 2;
- public static final int PERFORMANCE_CLASS_CURRENT = PERFORMANCE_CLASS_T;
-
- /**
- * Check whether this mobile device is R performance class as defined in CDD
- */
- public static boolean isRPerfClass() {
- return Build.VERSION.MEDIA_PERFORMANCE_CLASS == PERFORMANCE_CLASS_R;
- }
-
- /**
- * Check whether this mobile device is S performance class as defined in CDD
- */
- public static boolean isSPerfClass() {
- return Build.VERSION.MEDIA_PERFORMANCE_CLASS == PERFORMANCE_CLASS_S;
- }
-
- /**
- * Check whether this mobile device is T performance class as defined in CDD
- */
- public static boolean isTPerfClass() {
- return Build.VERSION.MEDIA_PERFORMANCE_CLASS == PERFORMANCE_CLASS_T;
- }
-
/**
* Check whether a camera Id is a primary rear facing camera
*/
diff --git a/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java b/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
index fc8c4db5164..f1886859d67 100644
--- a/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
+++ b/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
@@ -229,6 +229,13 @@ public class StaticMetadata {
* at least the desired one (but could be higher)
*/
public boolean isHardwareLevelAtLeast(int level) {
+ int deviceLevel = getHardwareLevelChecked();
+
+ return hardwareLevelPredicate(deviceLevel, level);
+ }
+
+ // Return true if level1 is at least level2
+ public static boolean hardwareLevelPredicate(int level1, int level2) {
final int[] sortedHwLevels = {
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY,
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL,
@@ -236,19 +243,19 @@ public class StaticMetadata {
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL,
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3
};
- int deviceLevel = getHardwareLevelChecked();
- if (level == deviceLevel) {
+
+ if (level1 == level2) {
return true;
}
for (int sortedlevel : sortedHwLevels) {
- if (sortedlevel == level) {
+ if (sortedlevel == level2) {
return true;
- } else if (sortedlevel == deviceLevel) {
+ } else if (sortedlevel == level1) {
return false;
}
}
- Assert.fail("Unknown hardwareLevel " + level + " and device hardware level " + deviceLevel);
+ Assert.fail("Unknown hardwareLevel " + level1 + " and device hardware level " + level2);
return false;
}
diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagementRoleHolderTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagementRoleHolderTest.java
index 286ccae00a8..eee4b10d821 100644
--- a/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagementRoleHolderTest.java
+++ b/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagementRoleHolderTest.java
@@ -65,6 +65,7 @@ import com.android.bedstead.nene.utils.Poll;
import com.android.bedstead.remotedpc.RemoteDpc;
import com.android.bedstead.testapp.TestApp;
import com.android.bedstead.testapp.TestAppInstance;
+import com.android.compatibility.common.util.CddTest;
import com.android.eventlib.truth.EventLogsSubject;
import com.android.queryable.queries.ActivityQuery;
@@ -140,6 +141,7 @@ public class DevicePolicyManagementRoleHolderTest {
@EnsureHasNoDpc
@EnsureHasNoSecondaryUser
@Test
+ @CddTest(requirements = {"3.9.4/C-3-1"})
public void createAndProvisionManagedProfile_roleHolderIsInWorkProfile()
throws ProvisioningException, InterruptedException {
UserHandle profile = null;
@@ -173,6 +175,7 @@ public class DevicePolicyManagementRoleHolderTest {
@RequireRunOnPrimaryUser
@EnsureHasNoSecondaryUser
@Test
+ @CddTest(requirements = {"3.9.4/C-3-1"})
public void createAndManageUser_roleHolderIsInManagedUser() throws InterruptedException {
UserHandle managedUser = null;
String roleHolderPackageName = null;
diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/UserControlDisabledPackagesTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/UserControlDisabledPackagesTest.java
index fcf71d0a19c..dfe77fb4121 100644
--- a/tests/devicepolicy/src/android/devicepolicy/cts/UserControlDisabledPackagesTest.java
+++ b/tests/devicepolicy/src/android/devicepolicy/cts/UserControlDisabledPackagesTest.java
@@ -45,6 +45,7 @@ import com.android.bedstead.harrier.policies.UserControlDisabledPackages;
import com.android.bedstead.metricsrecorder.EnterpriseMetricsRecorder;
import com.android.bedstead.nene.TestApis;
import com.android.bedstead.nene.packages.Package;
+import com.android.bedstead.nene.utils.Poll;
import com.android.bedstead.testapp.TestApp;
import com.android.bedstead.testapp.TestAppInstance;
import com.android.queryable.queries.StringQuery;
@@ -235,6 +236,11 @@ public final class UserControlDisabledPackagesTest {
private void assertPackageStopped(String packageName)
throws Exception {
+ Poll.forValue("Package " + packageName + " stopped", () -> isPackageStopped(packageName))
+ .toBeEqualTo(true)
+ .errorOnFail()
+ .await();
+
assertWithMessage("Package %s not stopped", packageName)
.that(isPackageStopped(packageName)).isTrue();
}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/TaskFragmentTrustedModeTest.java b/tests/framework/base/windowmanager/src/android/server/wm/TaskFragmentTrustedModeTest.java
index c13c4eec7f8..9fd1a41a416 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/TaskFragmentTrustedModeTest.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/TaskFragmentTrustedModeTest.java
@@ -21,6 +21,7 @@ import static android.server.wm.jetpack.second.Components.SECOND_UNTRUSTED_EMBED
import static android.server.wm.jetpack.utils.ActivityEmbeddingUtil.assumeActivityEmbeddingSupportedDevice;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -33,6 +34,7 @@ import android.content.Intent;
import android.graphics.Rect;
import android.os.Binder;
import android.os.IBinder;
+import android.platform.test.annotations.Presubmit;
import android.server.wm.WindowManagerState.Task;
import android.window.TaskFragmentCreationParams;
import android.window.TaskFragmentInfo;
@@ -49,6 +51,7 @@ import org.junit.Test;
* Build/Install/Run:
* atest CtsWindowManagerDeviceTestCases:TaskFragmentTrustedModeTest
*/
+@Presubmit
public class TaskFragmentTrustedModeTest extends TaskFragmentOrganizerTestBase {
private final ComponentName mTranslucentActivity = new ComponentName(mContext,
@@ -248,7 +251,7 @@ public class TaskFragmentTrustedModeTest extends TaskFragmentOrganizerTestBase {
*/
@Test
public void testUntrustedModeTaskFragment_startActivityInTaskFragmentOutsideOfParentBounds() {
- final Task parentTask = mWmState.getRootTask(mOwnerTaskId);
+ Task parentTask = mWmState.getRootTask(mOwnerTaskId);
final Rect parentBounds = new Rect(parentTask.getBounds());
final IBinder errorCallbackToken = new Binder();
final WindowContainerTransaction wct = new WindowContainerTransaction()
@@ -263,8 +266,11 @@ public class TaskFragmentTrustedModeTest extends TaskFragmentOrganizerTestBase {
// It is disallowed to start activity to TaskFragment with bounds outside of its parent
// in untrusted mode.
assertTaskFragmentError(errorCallbackToken, SecurityException.class);
- mWmState.waitForAppTransitionIdleOnDisplay(mOwnerActivity.getDisplayId());
- mWmState.assertNotExist(SECOND_UNTRUSTED_EMBEDDING_ACTIVITY);
+
+ parentTask = mWmState.getRootTask(mOwnerTaskId);
+ assertWithMessage("Activity must be started in parent Task because it's not"
+ + " allowed to be embedded").that(parentTask.mActivities).contains(
+ mWmState.getActivity(SECOND_UNTRUSTED_EMBEDDING_ACTIVITY));
}
/**
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsControllerTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsControllerTests.java
index 65465b27895..8dc33b1f745 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsControllerTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsControllerTests.java
@@ -59,6 +59,7 @@ import android.app.AlertDialog;
import android.app.Instrumentation;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.content.res.Resources;
import android.os.Bundle;
import android.os.SystemClock;
import android.platform.test.annotations.Presubmit;
@@ -226,6 +227,11 @@ public class WindowInsetsControllerTests extends WindowManagerTestBase {
final Instrumentation instrumentation = getInstrumentation();
assumeThat(MockImeSession.getUnavailabilityReason(instrumentation.getContext()),
nullValue());
+ final Resources resources = instrumentation.getContext().getResources();
+ final boolean isHideNavBarForKeyboardEnabled = resources.getBoolean(
+ resources.getIdentifier("config_hideNavBarForKeyboard", "bool", "android"));
+ assumeFalse("Device is configured to not show navigation bar for keyboard",
+ isHideNavBarForKeyboardEnabled);
final MockImeSession imeSession = MockImeHelper.createManagedMockImeSession(this);
final ImeEventStream stream = imeSession.openEventStream();
final TestActivity activity = startActivityInWindowingModeFullScreen(TestActivity.class);
diff --git a/tests/inputmethod/mockime/src/com/android/cts/mockime/Watermark.java b/tests/inputmethod/mockime/src/com/android/cts/mockime/Watermark.java
index ccd8659e3de..8855dee537b 100644
--- a/tests/inputmethod/mockime/src/com/android/cts/mockime/Watermark.java
+++ b/tests/inputmethod/mockime/src/com/android/cts/mockime/Watermark.java
@@ -32,7 +32,7 @@ public final class Watermark {
*
* <p>See Bug 174534092 about why we ended up having this.</p>
*/
- private static final int TOLERANCE = 4;
+ private static final int TOLERANCE = 6;
/**
* A utility class that represents A8R8G8B bitmap as an integer array.
diff --git a/tests/media/src/android/mediav2/cts/CodecInfoTest.java b/tests/media/src/android/mediav2/cts/CodecInfoTest.java
index 5f9aa09c891..39b90fff698 100644
--- a/tests/media/src/android/mediav2/cts/CodecInfoTest.java
+++ b/tests/media/src/android/mediav2/cts/CodecInfoTest.java
@@ -158,10 +158,10 @@ public class CodecInfoTest {
.noneMatch(x -> x == COLOR_FormatSurface));
}
- // For devices launching with Android T, if a codec supports an HDR profile, it must
- // advertise P010 support
+ // For devices launching with Android T, if a codec supports an HDR profile and device
+ // supports HDR display, it must advertise P010 support
int[] HdrProfileArray = mProfileHdrMap.get(mMediaType);
- if (FIRST_SDK_IS_AT_LEAST_T && HdrProfileArray != null) {
+ if (FIRST_SDK_IS_AT_LEAST_T && HdrProfileArray != null && DISPLAY_HDR_TYPES.length > 0) {
for (CodecProfileLevel pl : caps.profileLevels) {
if (IntStream.of(HdrProfileArray).anyMatch(x -> x == pl.profile)) {
assertFalse(mCodecInfo.getName() + " supports HDR profile " + pl.profile + "," +
diff --git a/tests/mediapc/common/src/android/mediapc/cts/common/PerformanceClassEvaluator.java b/tests/mediapc/common/src/android/mediapc/cts/common/PerformanceClassEvaluator.java
index 327fb9cf6c9..d3fd2921d5a 100644
--- a/tests/mediapc/common/src/android/mediapc/cts/common/PerformanceClassEvaluator.java
+++ b/tests/mediapc/common/src/android/mediapc/cts/common/PerformanceClassEvaluator.java
@@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assume.assumeTrue;
+import android.hardware.camera2.CameraMetadata;
import android.media.MediaFormat;
import android.os.Build;
@@ -849,7 +850,493 @@ public class PerformanceClassEvaluator {
}
}
- private <R extends Requirement> R addRequirement(R req) {
+ public static class PrimaryCameraRequirement extends Requirement {
+ private static final long MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION = 12000000;
+ private static final long MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION = 5000000;
+ private static final long MIN_FRONT_SENSOR_R_PERF_CLASS_RESOLUTION = 4000000;
+ private static final String TAG = PrimaryCameraRequirement.class.getSimpleName();
+
+ private PrimaryCameraRequirement(String id, RequiredMeasurement<?> ... reqs) {
+ super(id, reqs);
+ }
+
+ public void setPrimaryCameraSupported(boolean hasPrimaryCamera) {
+ this.setMeasuredValue(RequirementConstants.PRIMARY_CAMERA_AVAILABLE,
+ hasPrimaryCamera);
+ }
+
+ public void setResolution(long resolution) {
+ this.setMeasuredValue(RequirementConstants.PRIMARY_CAMERA_RESOLUTION,
+ resolution);
+ }
+
+ public void setVideoSizeReqSatisfied(boolean videoSizeReqSatisfied) {
+ this.setMeasuredValue(RequirementConstants.PRIMARY_CAMERA_VIDEO_SIZE_REQ_SATISFIED,
+ videoSizeReqSatisfied);
+ }
+
+ public void setVideoFps(double videoFps) {
+ this.setMeasuredValue(RequirementConstants.PRIMARY_CAMERA_VIDEO_FPS, videoFps);
+ }
+
+ /**
+ * [2.2.7.2/7.5/H-1-1] MUST have a primary rear facing camera with a resolution of at
+ * least 12 megapixels supporting video capture at 4k@30fps
+ */
+ public static PrimaryCameraRequirement createRearPrimaryCamera() {
+ RequiredMeasurement<Boolean> hasPrimaryCamera = RequiredMeasurement
+ .<Boolean>builder()
+ .setId(RequirementConstants.PRIMARY_CAMERA_AVAILABLE)
+ .setPredicate(RequirementConstants.BOOLEAN_EQ)
+ .addRequiredValue(Build.VERSION_CODES.R, true)
+ .addRequiredValue(Build.VERSION_CODES.S, true)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+ .build();
+
+ RequiredMeasurement<Long> cameraResolution = RequiredMeasurement
+ .<Long>builder()
+ .setId(RequirementConstants.PRIMARY_CAMERA_RESOLUTION)
+ .setPredicate(RequirementConstants.LONG_GTE)
+ .addRequiredValue(Build.VERSION_CODES.R, MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION)
+ .addRequiredValue(Build.VERSION_CODES.S, MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION)
+ .build();
+
+ RequiredMeasurement<Boolean> videoSizeReqSatisfied = RequiredMeasurement
+ .<Boolean>builder()
+ .setId(RequirementConstants.PRIMARY_CAMERA_VIDEO_SIZE_REQ_SATISFIED)
+ .setPredicate(RequirementConstants.BOOLEAN_EQ)
+ .addRequiredValue(Build.VERSION_CODES.R, true)
+ .addRequiredValue(Build.VERSION_CODES.S, true)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+ .build();
+
+ RequiredMeasurement<Double> videoFps = RequiredMeasurement
+ .<Double>builder()
+ .setId(RequirementConstants.PRIMARY_CAMERA_VIDEO_FPS)
+ .setPredicate(RequirementConstants.DOUBLE_GTE)
+ .addRequiredValue(Build.VERSION_CODES.R, 29.9)
+ .addRequiredValue(Build.VERSION_CODES.S, 29.9)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 29.9)
+ .build();
+
+ return new PrimaryCameraRequirement(RequirementConstants.R7_5__H_1_1,
+ hasPrimaryCamera, cameraResolution, videoSizeReqSatisfied,
+ videoFps);
+ }
+
+ /**
+ * [2.2.7.2/7.5/H-1-2] MUST have a primary front facing camera with a resolution of
+ * at least 4 megapixels supporting video capture at 1080p@30fps.
+ */
+ public static PrimaryCameraRequirement createFrontPrimaryCamera() {
+ RequiredMeasurement<Boolean> hasPrimaryCamera = RequiredMeasurement
+ .<Boolean>builder()
+ .setId(RequirementConstants.PRIMARY_CAMERA_AVAILABLE)
+ .setPredicate(RequirementConstants.BOOLEAN_EQ)
+ .addRequiredValue(Build.VERSION_CODES.R, true)
+ .addRequiredValue(Build.VERSION_CODES.S, true)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+ .build();
+
+ RequiredMeasurement<Long> cameraResolution = RequiredMeasurement
+ .<Long>builder()
+ .setId(RequirementConstants.PRIMARY_CAMERA_RESOLUTION)
+ .setPredicate(RequirementConstants.LONG_GTE)
+ .addRequiredValue(Build.VERSION_CODES.R, MIN_FRONT_SENSOR_R_PERF_CLASS_RESOLUTION)
+ .addRequiredValue(Build.VERSION_CODES.S, MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU,
+ MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION)
+ .build();
+
+ RequiredMeasurement<Boolean> videoSizeReqSatisfied = RequiredMeasurement
+ .<Boolean>builder()
+ .setId(RequirementConstants.PRIMARY_CAMERA_VIDEO_SIZE_REQ_SATISFIED)
+ .setPredicate(RequirementConstants.BOOLEAN_EQ)
+ .addRequiredValue(Build.VERSION_CODES.R, true)
+ .addRequiredValue(Build.VERSION_CODES.S, true)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+ .build();
+
+ RequiredMeasurement<Double> videoFps = RequiredMeasurement
+ .<Double>builder()
+ .setId(RequirementConstants.PRIMARY_CAMERA_VIDEO_FPS)
+ .setPredicate(RequirementConstants.DOUBLE_GTE)
+ .addRequiredValue(Build.VERSION_CODES.R, 29.9)
+ .addRequiredValue(Build.VERSION_CODES.S, 29.9)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 29.9)
+ .build();
+
+ return new PrimaryCameraRequirement(RequirementConstants.R7_5__H_1_2,
+ hasPrimaryCamera, cameraResolution, videoSizeReqSatisfied,
+ videoFps);
+ }
+ }
+
+ public static class CameraTimestampSourceRequirement extends Requirement {
+ private static final String TAG = CameraTimestampSourceRequirement.class.getSimpleName();
+ private static final int TIMESTAMP_REALTIME =
+ CameraMetadata.SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME;
+
+ private CameraTimestampSourceRequirement(String id, RequiredMeasurement<?> ... reqs) {
+ super(id, reqs);
+ }
+
+ public void setRearCameraTimestampSource(Integer timestampSource) {
+ this.setMeasuredValue(RequirementConstants.REAR_CAMERA_TIMESTAMP_SOURCE,
+ timestampSource);
+ }
+
+ public void setFrontCameraTimestampSource(Integer timestampSource) {
+ this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_TIMESTAMP_SOURCE,
+ timestampSource);
+ }
+ /**
+ * [2.2.7.2/7.5/H-1-4] MUST support CameraMetadata.SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME
+ * for both primary cameras.
+ */
+ public static CameraTimestampSourceRequirement createTimestampSourceReq() {
+ RequiredMeasurement<Integer> rearTimestampSource = RequiredMeasurement
+ .<Integer>builder()
+ .setId(RequirementConstants.REAR_CAMERA_TIMESTAMP_SOURCE)
+ .setPredicate(RequirementConstants.INTEGER_EQ)
+ .addRequiredValue(Build.VERSION_CODES.R, TIMESTAMP_REALTIME)
+ .addRequiredValue(Build.VERSION_CODES.S, TIMESTAMP_REALTIME)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, TIMESTAMP_REALTIME)
+ .build();
+ RequiredMeasurement<Integer> frontTimestampSource = RequiredMeasurement
+ .<Integer>builder()
+ .setId(RequirementConstants.FRONT_CAMERA_TIMESTAMP_SOURCE)
+ .setPredicate(RequirementConstants.INTEGER_EQ)
+ .addRequiredValue(Build.VERSION_CODES.R, TIMESTAMP_REALTIME)
+ .addRequiredValue(Build.VERSION_CODES.S, TIMESTAMP_REALTIME)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, TIMESTAMP_REALTIME)
+ .build();
+
+ return new CameraTimestampSourceRequirement(RequirementConstants.R7_5__H_1_4,
+ rearTimestampSource, frontTimestampSource);
+ }
+ }
+
+ public static class CameraLatencyRequirement extends Requirement {
+ private static final String TAG = CameraTimestampSourceRequirement.class.getSimpleName();
+
+ private CameraLatencyRequirement(String id, RequiredMeasurement<?> ... reqs) {
+ super(id, reqs);
+ }
+
+ public void setRearCameraLatency(float latency) {
+ this.setMeasuredValue(RequirementConstants.REAR_CAMERA_LATENCY, latency);
+ }
+
+ public void setFrontCameraLatency(float latency) {
+ this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_LATENCY, latency);
+ }
+
+ /**
+ * [2.2.7.2/7.5/H-1-5] MUST have camera2 JPEG capture latency < 1000ms for 1080p resolution
+ * as measured by the CTS camera PerformanceTest under ITS lighting conditions
+ * (3000K) for both primary cameras.
+ */
+ public static CameraLatencyRequirement createJpegLatencyReq() {
+ RequiredMeasurement<Float> rearJpegLatency = RequiredMeasurement
+ .<Float>builder()
+ .setId(RequirementConstants.REAR_CAMERA_LATENCY)
+ .setPredicate(RequirementConstants.FLOAT_LTE)
+ .addRequiredValue(Build.VERSION_CODES.R, 1000.0f)
+ .addRequiredValue(Build.VERSION_CODES.S, 1000.0f)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1000.0f)
+ .build();
+ RequiredMeasurement<Float> frontJpegLatency = RequiredMeasurement
+ .<Float>builder()
+ .setId(RequirementConstants.FRONT_CAMERA_LATENCY)
+ .setPredicate(RequirementConstants.FLOAT_LTE)
+ .addRequiredValue(Build.VERSION_CODES.R, 1000.0f)
+ .addRequiredValue(Build.VERSION_CODES.S, 1000.0f)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1000.0f)
+ .build();
+
+ return new CameraLatencyRequirement(RequirementConstants.R7_5__H_1_5,
+ rearJpegLatency, frontJpegLatency);
+ }
+
+ /**
+ * [2.2.7.2/7.5/H-1-6] MUST have camera2 startup latency (open camera to first
+ * preview frame) < 600ms as measured by the CTS camera PerformanceTest under ITS lighting
+ * conditions (3000K) for both primary cameras.
+ */
+ public static CameraLatencyRequirement createLaunchLatencyReq() {
+ RequiredMeasurement<Float> rearLaunchLatency = RequiredMeasurement
+ .<Float>builder()
+ .setId(RequirementConstants.REAR_CAMERA_LATENCY)
+ .setPredicate(RequirementConstants.FLOAT_LTE)
+ .addRequiredValue(Build.VERSION_CODES.R, 600.0f)
+ .addRequiredValue(Build.VERSION_CODES.S, 600.0f)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 600.0f)
+ .build();
+ RequiredMeasurement<Float> frontLaunchLatency = RequiredMeasurement
+ .<Float>builder()
+ .setId(RequirementConstants.FRONT_CAMERA_LATENCY)
+ .setPredicate(RequirementConstants.FLOAT_LTE)
+ .addRequiredValue(Build.VERSION_CODES.R, 600.0f)
+ .addRequiredValue(Build.VERSION_CODES.S, 600.0f)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 600.0f)
+ .build();
+
+ return new CameraLatencyRequirement(RequirementConstants.R7_5__H_1_6,
+ rearLaunchLatency, frontLaunchLatency);
+ }
+ }
+
+ public static class CameraRawRequirement extends Requirement {
+ private static final String TAG = CameraRawRequirement.class.getSimpleName();
+
+ private CameraRawRequirement(String id, RequiredMeasurement<?> ... reqs) {
+ super(id, reqs);
+ }
+
+ public void setRearRawSupported(boolean rearRawSupported) {
+ this.setMeasuredValue(RequirementConstants.REAR_CAMERA_RAW_SUPPORTED,
+ rearRawSupported);
+ }
+
+ /**
+ * [2.2.7.2/7.5/H-1-8] MUST support CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_RAW and
+ * android.graphics.ImageFormat.RAW_SENSOR for the primary back camera.
+ */
+ public static CameraRawRequirement createRawReq() {
+ RequiredMeasurement<Boolean> requirement = RequiredMeasurement
+ .<Boolean>builder()
+ .setId(RequirementConstants.REAR_CAMERA_RAW_SUPPORTED)
+ .setPredicate(RequirementConstants.BOOLEAN_EQ)
+ .addRequiredValue(Build.VERSION_CODES.S, true)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+ .build();
+
+ return new CameraRawRequirement(RequirementConstants.R7_5__H_1_8, requirement);
+ }
+ }
+
+ public static class Camera240FpsRequirement extends Requirement {
+ private static final String TAG = Camera240FpsRequirement.class.getSimpleName();
+
+ private Camera240FpsRequirement(String id, RequiredMeasurement<?> ... reqs) {
+ super(id, reqs);
+ }
+
+ public void setRear240FpsSupported(boolean rear240FpsSupported) {
+ this.setMeasuredValue(RequirementConstants.REAR_CAMERA_240FPS_SUPPORTED,
+ rear240FpsSupported);
+ }
+
+ /**
+ * [2.2.7.2/7.5/H-1-9] MUST have a rear-facing primary camera supporting 720p or 1080p @ 240fps.
+ */
+ public static Camera240FpsRequirement create240FpsReq() {
+ RequiredMeasurement<Boolean> requirement = RequiredMeasurement
+ .<Boolean>builder()
+ .setId(RequirementConstants.REAR_CAMERA_240FPS_SUPPORTED)
+ .setPredicate(RequirementConstants.BOOLEAN_EQ)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+ .build();
+
+ return new Camera240FpsRequirement(RequirementConstants.R7_5__H_1_9, requirement);
+ }
+ }
+
+ public static class UltraWideZoomRatioRequirement extends Requirement {
+ private static final String TAG =
+ UltraWideZoomRatioRequirement.class.getSimpleName();
+
+ private UltraWideZoomRatioRequirement(String id, RequiredMeasurement<?> ... reqs) {
+ super(id, reqs);
+ }
+
+ public void setRearUltraWideZoomRatioReqMet(boolean ultrawideZoomRatioReqMet) {
+ this.setMeasuredValue(RequirementConstants.REAR_CAMERA_ULTRAWIDE_ZOOMRATIO_REQ_MET,
+ ultrawideZoomRatioReqMet);
+ }
+
+ public void setFrontUltraWideZoomRatioReqMet(boolean ultrawideZoomRatioReqMet) {
+ this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_ULTRAWIDE_ZOOMRATIO_REQ_MET,
+ ultrawideZoomRatioReqMet);
+ }
+
+ /**
+ * [2.2.7.2/7.5/H-1-10] MUST have min ZOOM_RATIO < 1.0 for the primary cameras if
+ * there is an ultrawide RGB camera facing the same direction.
+ */
+ public static UltraWideZoomRatioRequirement createUltrawideZoomRatioReq() {
+ RequiredMeasurement<Boolean> rearRequirement = RequiredMeasurement
+ .<Boolean>builder()
+ .setId(RequirementConstants.REAR_CAMERA_ULTRAWIDE_ZOOMRATIO_REQ_MET)
+ .setPredicate(RequirementConstants.BOOLEAN_EQ)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+ .build();
+ RequiredMeasurement<Boolean> frontRequirement = RequiredMeasurement
+ .<Boolean>builder()
+ .setId(RequirementConstants.FRONT_CAMERA_ULTRAWIDE_ZOOMRATIO_REQ_MET)
+ .setPredicate(RequirementConstants.BOOLEAN_EQ)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+ .build();
+
+ return new UltraWideZoomRatioRequirement(RequirementConstants.R7_5__H_1_10,
+ rearRequirement, frontRequirement);
+ }
+ }
+
+ public static class ConcurrentRearFrontRequirement extends Requirement {
+ private static final String TAG = ConcurrentRearFrontRequirement.class.getSimpleName();
+
+ private ConcurrentRearFrontRequirement(String id, RequiredMeasurement<?> ... reqs) {
+ super(id, reqs);
+ }
+
+ public void setConcurrentRearFrontSupported(boolean concurrentRearFrontSupported) {
+ this.setMeasuredValue(RequirementConstants.CONCURRENT_REAR_FRONT_SUPPORTED,
+ concurrentRearFrontSupported);
+ }
+
+ /**
+ * [2.2.7.2/7.5/H-1-11] MUST implement concurrent front-back streaming on primary cameras.
+ */
+ public static ConcurrentRearFrontRequirement createConcurrentRearFrontReq() {
+ RequiredMeasurement<Boolean> requirement = RequiredMeasurement
+ .<Boolean>builder()
+ .setId(RequirementConstants.CONCURRENT_REAR_FRONT_SUPPORTED)
+ .setPredicate(RequirementConstants.BOOLEAN_EQ)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+ .build();
+
+ return new ConcurrentRearFrontRequirement(RequirementConstants.R7_5__H_1_11,
+ requirement);
+ }
+ }
+
+ public static class PreviewStabilizationRequirement extends Requirement {
+ private static final String TAG =
+ PreviewStabilizationRequirement.class.getSimpleName();
+
+ private PreviewStabilizationRequirement(String id, RequiredMeasurement<?> ... reqs) {
+ super(id, reqs);
+ }
+
+ public void setRearPreviewStabilizationSupported(boolean supported) {
+ this.setMeasuredValue(RequirementConstants.REAR_CAMERA_PREVIEW_STABILIZATION_SUPPORTED,
+ supported);
+ }
+
+ public void setFrontPreviewStabilizationSupported(boolean supported) {
+ this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_PREVIEW_STABILIZATION_SUPPORTED,
+ supported);
+ }
+
+ /**
+ * [2.2.7.2/7.5/H-1-12] MUST support CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION
+ * for both primary front and primary back camera.
+ */
+ public static PreviewStabilizationRequirement createPreviewStabilizationReq() {
+ RequiredMeasurement<Boolean> rearRequirement = RequiredMeasurement
+ .<Boolean>builder()
+ .setId(RequirementConstants.REAR_CAMERA_PREVIEW_STABILIZATION_SUPPORTED)
+ .setPredicate(RequirementConstants.BOOLEAN_EQ)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+ .build();
+ RequiredMeasurement<Boolean> frontRequirement = RequiredMeasurement
+ .<Boolean>builder()
+ .setId(RequirementConstants.FRONT_CAMERA_PREVIEW_STABILIZATION_SUPPORTED)
+ .setPredicate(RequirementConstants.BOOLEAN_EQ)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+ .build();
+
+ return new PreviewStabilizationRequirement(RequirementConstants.R7_5__H_1_12,
+ rearRequirement, frontRequirement);
+ }
+ }
+
+ public static class LogicalMultiCameraRequirement extends Requirement {
+ private static final String TAG =
+ LogicalMultiCameraRequirement.class.getSimpleName();
+
+ private LogicalMultiCameraRequirement(String id, RequiredMeasurement<?> ... reqs) {
+ super(id, reqs);
+ }
+
+ public void setRearLogicalMultiCameraReqMet(boolean reqMet) {
+ this.setMeasuredValue(RequirementConstants.REAR_CAMERA_LOGICAL_MULTI_CAMERA_REQ_MET,
+ reqMet);
+ }
+
+ public void setFrontLogicalMultiCameraReqMet(boolean reqMet) {
+ this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_LOGICAL_MULTI_CAMERA_REQ_MET,
+ reqMet);
+ }
+
+ /**
+ * [2.2.7.2/7.5/H-1-13] MUST support LOGICAL_MULTI_CAMERA capability for the primary
+ * cameras if there are greater than 1 RGB cameras facing the same direction.
+ */
+ public static LogicalMultiCameraRequirement createLogicalMultiCameraReq() {
+ RequiredMeasurement<Boolean> rearRequirement = RequiredMeasurement
+ .<Boolean>builder()
+ .setId(RequirementConstants.REAR_CAMERA_LOGICAL_MULTI_CAMERA_REQ_MET)
+ .setPredicate(RequirementConstants.BOOLEAN_EQ)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+ .build();
+ RequiredMeasurement<Boolean> frontRequirement = RequiredMeasurement
+ .<Boolean>builder()
+ .setId(RequirementConstants.FRONT_CAMERA_LOGICAL_MULTI_CAMERA_REQ_MET)
+ .setPredicate(RequirementConstants.BOOLEAN_EQ)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+ .build();
+
+ return new LogicalMultiCameraRequirement(RequirementConstants.R7_5__H_1_13,
+ rearRequirement, frontRequirement);
+ }
+ }
+
+ public static class StreamUseCaseRequirement extends Requirement {
+ private static final String TAG =
+ StreamUseCaseRequirement.class.getSimpleName();
+
+ private StreamUseCaseRequirement(String id, RequiredMeasurement<?> ... reqs) {
+ super(id, reqs);
+ }
+
+ public void setRearStreamUseCaseSupported(boolean supported) {
+ this.setMeasuredValue(RequirementConstants.REAR_CAMERA_STREAM_USECASE_SUPPORTED,
+ supported);
+ }
+
+ public void setFrontStreamUseCaseSupported(boolean supported) {
+ this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_STREAM_USECASE_SUPPORTED,
+ supported);
+ }
+
+ /**
+ * [2.2.7.2/7.5/H-1-14] MUST support STREAM_USE_CASE capability for both primary
+ * front and primary back camera.
+ */
+ public static StreamUseCaseRequirement createStreamUseCaseReq() {
+ RequiredMeasurement<Boolean> rearRequirement = RequiredMeasurement
+ .<Boolean>builder()
+ .setId(RequirementConstants.REAR_CAMERA_STREAM_USECASE_SUPPORTED)
+ .setPredicate(RequirementConstants.BOOLEAN_EQ)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+ .build();
+ RequiredMeasurement<Boolean> frontRequirement = RequiredMeasurement
+ .<Boolean>builder()
+ .setId(RequirementConstants.FRONT_CAMERA_STREAM_USECASE_SUPPORTED)
+ .setPredicate(RequirementConstants.BOOLEAN_EQ)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+ .build();
+
+ return new StreamUseCaseRequirement(RequirementConstants.R7_5__H_1_14,
+ rearRequirement, frontRequirement);
+ }
+ }
+
+ public <R extends Requirement> R addRequirement(R req) {
if (!this.mRequirements.add(req)) {
throw new IllegalStateException("Requirement " + req.id() + " already added");
}
@@ -1000,16 +1487,69 @@ public class PerformanceClassEvaluator {
return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_10());
}
+ public PrimaryCameraRequirement addPrimaryRearCameraReq() {
+ return this.addRequirement(PrimaryCameraRequirement.createRearPrimaryCamera());
+ }
+
+ public PrimaryCameraRequirement addPrimaryFrontCameraReq() {
+ return this.addRequirement(PrimaryCameraRequirement.createFrontPrimaryCamera());
+ }
+
+ public CameraTimestampSourceRequirement addR7_5__H_1_4() {
+ return this.addRequirement(CameraTimestampSourceRequirement.createTimestampSourceReq());
+ }
+
+ public CameraLatencyRequirement addR7_5__H_1_5() {
+ return this.addRequirement(CameraLatencyRequirement.createJpegLatencyReq());
+ }
+
+ public CameraLatencyRequirement addR7_5__H_1_6() {
+ return this.addRequirement(CameraLatencyRequirement.createLaunchLatencyReq());
+ }
+
+ public CameraRawRequirement addR7_5__H_1_8() {
+ return this.addRequirement(CameraRawRequirement.createRawReq());
+ }
+
+ public Camera240FpsRequirement addR7_5__H_1_9() {
+ return this.addRequirement(Camera240FpsRequirement.create240FpsReq());
+ }
+
+ public UltraWideZoomRatioRequirement addR7_5__H_1_10() {
+ return this.addRequirement(UltraWideZoomRatioRequirement.createUltrawideZoomRatioReq());
+ }
+
+ public ConcurrentRearFrontRequirement addR7_5__H_1_11() {
+ return this.addRequirement(ConcurrentRearFrontRequirement.createConcurrentRearFrontReq());
+ }
+
+ public PreviewStabilizationRequirement addR7_5__H_1_12() {
+ return this.addRequirement(PreviewStabilizationRequirement.createPreviewStabilizationReq());
+ }
+
+ public LogicalMultiCameraRequirement addR7_5__H_1_13() {
+ return this.addRequirement(LogicalMultiCameraRequirement.createLogicalMultiCameraReq());
+ }
+
+ public StreamUseCaseRequirement addR7_5__H_1_14() {
+ return this.addRequirement(StreamUseCaseRequirement.createStreamUseCaseReq());
+ }
+
public void submitAndCheck() {
- boolean perfClassMet = true;
- for (Requirement req: this.mRequirements) {
- perfClassMet &= req.writeLogAndCheck(this.mTestName);
- }
+ boolean perfClassMet = submit();
// check performance class
assumeTrue("Build.VERSION.MEDIA_PERFORMANCE_CLASS is not declared", Utils.isPerfClass());
assertThat(perfClassMet).isTrue();
+ }
+ public boolean submit() {
+ boolean perfClassMet = true;
+ for (Requirement req: this.mRequirements) {
+ perfClassMet &= req.writeLogAndCheck(this.mTestName);
+ }
this.mRequirements.clear(); // makes sure report isn't submitted twice
+ return perfClassMet;
}
+
}
diff --git a/tests/mediapc/common/src/android/mediapc/cts/common/RequirementConstants.java b/tests/mediapc/common/src/android/mediapc/cts/common/RequirementConstants.java
index d93cb2e0a00..ad0d0d5694f 100644
--- a/tests/mediapc/common/src/android/mediapc/cts/common/RequirementConstants.java
+++ b/tests/mediapc/common/src/android/mediapc/cts/common/RequirementConstants.java
@@ -16,8 +16,6 @@
package android.mediapc.cts.common;
-import android.os.Build;
-
import java.util.function.BiPredicate;
public class RequirementConstants {
@@ -54,8 +52,13 @@ public class RequirementConstants {
public static final String R7_5__H_1_4 = "r7_5__h_1_4"; // 7.5/H-1-4
public static final String R7_5__H_1_5 = "r7_5__h_1_5"; // 7.5/H-1-5
public static final String R7_5__H_1_6 = "r7_5__h_1_6"; // 7.5/H-1-6
- public static final String R7_5__H_1_7 = "r7_5__h_1_7"; // 7.5/H-1-7
public static final String R7_5__H_1_8 = "r7_5__h_1_8"; // 7.5/H-1-8
+ public static final String R7_5__H_1_9 = "r7_5__h_1_9"; // 7.5/H-1-9
+ public static final String R7_5__H_1_10 = "r7_5__h_1_10"; // 7.5/H-1-10
+ public static final String R7_5__H_1_11 = "r7_5__h_1_11"; // 7.5/H-1-11
+ public static final String R7_5__H_1_12 = "r7_5__h_1_12"; // 7.5/H-1-12
+ public static final String R7_5__H_1_13 = "r7_5__h_1_13"; // 7.5/H-1-13
+ public static final String R7_5__H_1_14 = "r7_5__h_1_14"; // 7.5/H-1-14
public static final String R7_1_1_1__H_1_1 = "r7_1_1_1__h_1_1"; // 7.1.1.1/H-1-1
public static final String R7_1_1_3__H_1_1 = "r7_1_1_3__h_1_1"; // 7.1.1.3/H-1-1
public static final String R7_6_1__H_1_1 = "r7_6_1__h_1_1"; // 7.6.1/H-1-1
@@ -90,14 +93,50 @@ public class RequirementConstants {
public static final String NUM_CRYPTO_HW_SECURE_ALL_SUPPORT =
"number_crypto_hw_secure_all_support";
+ public static final String PRIMARY_CAMERA_AVAILABLE = "primary_camera_available";
+ public static final String PRIMARY_CAMERA_RESOLUTION = "primary_camera_resolution";
+ public static final String PRIMARY_CAMERA_VIDEO_SIZE_REQ_SATISFIED =
+ "primary_camera_video_size_req_satisfied";
+ public static final String PRIMARY_CAMERA_VIDEO_FPS =
+ "primary_camera_video_fps";
+ public static final String REAR_CAMERA_HWL_LEVEL = "rear_primary_camera_hwl_level";
+ public static final String FRONT_CAMERA_HWL_LEVEL = "front_primary_camera_hwl_level";
+ public static final String REAR_CAMERA_TIMESTAMP_SOURCE =
+ "rear_primary_camera_timestamp_source";
+ public static final String FRONT_CAMERA_TIMESTAMP_SOURCE =
+ "front_primary_camera_timestamp_source";
+ public static final String REAR_CAMERA_LATENCY = "rear_camera_latency";
+ public static final String FRONT_CAMERA_LATENCY = "front_camera_latency";
+ public static final String REAR_CAMERA_RAW_SUPPORTED = "rear_camera_raw_supported";
+ public static final String REAR_CAMERA_240FPS_SUPPORTED = "rear_camera_240fps_supported";
+ public static final String REAR_CAMERA_ULTRAWIDE_ZOOMRATIO_REQ_MET =
+ "rear_camera_ultrawide_zoom_req_met";
+ public static final String FRONT_CAMERA_ULTRAWIDE_ZOOMRATIO_REQ_MET =
+ "front_camera_ultrawide_zoom_req_met";
+ public static final String CONCURRENT_REAR_FRONT_SUPPORTED = "rear_front_concurrent_camera";
+ public static final String REAR_CAMERA_PREVIEW_STABILIZATION_SUPPORTED =
+ "rear_camera_preview_stabilization_supported";
+ public static final String FRONT_CAMERA_PREVIEW_STABILIZATION_SUPPORTED =
+ "front_camera_preview_stabilization_supported";
+ public static final String REAR_CAMERA_LOGICAL_MULTI_CAMERA_REQ_MET =
+ "rear_camera_logical_multi_camera_req_met";
+ public static final String FRONT_CAMERA_LOGICAL_MULTI_CAMERA_REQ_MET =
+ "front_camera_logical_multi_camera_req_met";
+ public static final String REAR_CAMERA_STREAM_USECASE_SUPPORTED =
+ "rear_camera_stream_usecase_supported";
+ public static final String FRONT_CAMERA_STREAM_USECASE_SUPPORTED =
+ "front_camera_stream_usecase_supported";
+
public enum Result {
NA, MET, UNMET
}
public static final BiPredicate<Long, Long> LONG_GTE = RequirementConstants.gte();
public static final BiPredicate<Long, Long> LONG_LTE = RequirementConstants.lte();
+ public static final BiPredicate<Float, Float> FLOAT_LTE = RequirementConstants.lte();
public static final BiPredicate<Integer, Integer> INTEGER_GTE = RequirementConstants.gte();
public static final BiPredicate<Integer, Integer> INTEGER_LTE = RequirementConstants.lte();
+ public static final BiPredicate<Integer, Integer> INTEGER_EQ = RequirementConstants.eq();
public static final BiPredicate<Double, Double> DOUBLE_EQ = RequirementConstants.eq();
public static final BiPredicate<Boolean, Boolean> BOOLEAN_EQ = RequirementConstants.eq();
public static final BiPredicate<Double, Double> DOUBLE_GTE = RequirementConstants.gte();
diff --git a/tests/mediapc/common/src/android/mediapc/cts/common/Utils.java b/tests/mediapc/common/src/android/mediapc/cts/common/Utils.java
index ac03705a1a2..28a122b4521 100644
--- a/tests/mediapc/common/src/android/mediapc/cts/common/Utils.java
+++ b/tests/mediapc/common/src/android/mediapc/cts/common/Utils.java
@@ -73,16 +73,24 @@ public class Utils {
Context context = InstrumentationRegistry.getInstrumentation().getContext();
DisplayMetrics metrics = new DisplayMetrics();
- WindowManager windowManager = context.getSystemService(WindowManager.class);
- windowManager.getDefaultDisplay().getMetrics(metrics);
- DISPLAY_DPI = metrics.densityDpi;
- DISPLAY_LONG_PIXELS = Math.max(metrics.widthPixels, metrics.heightPixels);
- DISPLAY_SHORT_PIXELS = Math.min(metrics.widthPixels, metrics.heightPixels);
-
- ActivityManager activityManager = context.getSystemService(ActivityManager.class);
- ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
- activityManager.getMemoryInfo(memoryInfo);
- TOTAL_MEMORY_MB = memoryInfo.totalMem / 1024 / 1024;
+ // When used from ItsService, context will be null
+ if (context != null) {
+ WindowManager windowManager = context.getSystemService(WindowManager.class);
+ windowManager.getDefaultDisplay().getMetrics(metrics);
+ DISPLAY_DPI = metrics.densityDpi;
+ DISPLAY_LONG_PIXELS = Math.max(metrics.widthPixels, metrics.heightPixels);
+ DISPLAY_SHORT_PIXELS = Math.min(metrics.widthPixels, metrics.heightPixels);
+
+ ActivityManager activityManager = context.getSystemService(ActivityManager.class);
+ ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
+ activityManager.getMemoryInfo(memoryInfo);
+ TOTAL_MEMORY_MB = memoryInfo.totalMem / 1024 / 1024;
+ } else {
+ DISPLAY_DPI = 0;
+ DISPLAY_LONG_PIXELS = 0;
+ DISPLAY_SHORT_PIXELS = 0;
+ TOTAL_MEMORY_MB = 0;
+ }
}
/**
diff --git a/tests/tests/assist/common/src/android/assist/common/Utils.java b/tests/tests/assist/common/src/android/assist/common/Utils.java
index 0ffcb271093..98e857689cf 100755
--- a/tests/tests/assist/common/src/android/assist/common/Utils.java
+++ b/tests/tests/assist/common/src/android/assist/common/Utils.java
@@ -56,6 +56,7 @@ public class Utils {
public static final String COMPARE_SCREENSHOT_KEY = "compare_screenshot";
public static final String DISPLAY_WIDTH_KEY = "display_width";
public static final String DISPLAY_HEIGHT_KEY = "dislay_height";
+ public static final String DISPLAY_AREA_BOUNDS_KEY = "display_area_bounds";
public static final String SCROLL_X_POSITION = "scroll_x_position";
public static final String SCROLL_Y_POSITION = "scroll_y_position";
public static final String SHOW_SESSION_FLAGS_TO_SET = "show_session_flags_to_set";
diff --git a/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java b/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java
index 7f35367333a..25c080b9c0c 100644
--- a/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java
+++ b/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java
@@ -56,6 +56,7 @@ public class MainInteractionSession extends VoiceInteractionSession {
private int mCurColor;
private int mDisplayHeight;
private int mDisplayWidth;
+ private Rect mDisplayAreaBounds;
private BroadcastReceiver mReceiver;
private String mTestName;
private View mContentView;
@@ -106,7 +107,7 @@ public class MainInteractionSession extends VoiceInteractionSession {
public void onPrepareShow(Bundle args, int showFlags) {
if (Utils.LIFECYCLE_NOUI.equals(args.getString(Utils.TESTCASE_TYPE, ""))) {
setUiEnabled(false);
- } else {
+ } else {
setUiEnabled(true);
}
}
@@ -122,6 +123,7 @@ public class MainInteractionSession extends VoiceInteractionSession {
mCurColor = args.getInt(Utils.SCREENSHOT_COLOR_KEY);
mDisplayHeight = args.getInt(Utils.DISPLAY_HEIGHT_KEY);
mDisplayWidth = args.getInt(Utils.DISPLAY_WIDTH_KEY);
+ mDisplayAreaBounds = args.getParcelable(Utils.DISPLAY_AREA_BOUNDS_KEY);
mRemoteCallback = args.getParcelable(Utils.EXTRA_REMOTE_CALLBACK);
super.onShow(args, showFlags);
if (mContentView == null) return; // Happens when ui is not enabled.
@@ -256,6 +258,11 @@ public class MainInteractionSession extends VoiceInteractionSession {
int[] pixels = new int[size.x * size.y];
screenshot.getPixels(pixels, 0, size.x, 0, 0, size.x, size.y);
+ // screenshot bitmap contains the screenshot for the entire physical display. A single
+ // physical display could have multiple display area with different applications.
+ // Let's grab the region of the display area from the original screenshot.
+ Bitmap displayAreaScreenshot = Bitmap.createBitmap(screenshot, mDisplayAreaBounds.left,
+ mDisplayAreaBounds.top, mDisplayAreaBounds.width(), mDisplayAreaBounds.height());
int expectedColor = 0;
for (int pixel : pixels) {
// Check for roughly the same because there are rounding errors converting from the
@@ -267,7 +274,7 @@ public class MainInteractionSession extends VoiceInteractionSession {
}
}
- int pixelCount = screenshot.getWidth() * screenshot.getHeight();
+ int pixelCount = displayAreaScreenshot.getWidth() * displayAreaScreenshot.getHeight();
double colorRatio = (double) expectedColor / pixelCount;
Log.i(TAG, "the ratio is " + colorRatio);
return colorRatio >= 0.6;
diff --git a/tests/tests/assist/src/android/assist/cts/AssistTestBase.java b/tests/tests/assist/src/android/assist/cts/AssistTestBase.java
index 44a3109a740..c89119bdea1 100644
--- a/tests/tests/assist/src/android/assist/cts/AssistTestBase.java
+++ b/tests/tests/assist/src/android/assist/cts/AssistTestBase.java
@@ -35,9 +35,9 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Point;
+import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
-import android.os.HandlerThread;
import android.os.LocaleList;
import android.os.RemoteCallback;
import android.provider.Settings;
@@ -341,6 +341,8 @@ abstract class AssistTestBase {
Display.Mode dMode = mTestActivity.getWindowManager().getDefaultDisplay().getMode();
mDisplaySize = new Point(dMode.getPhysicalWidth(), dMode.getPhysicalHeight());
}
+ Rect bounds = mTestActivity.getWindowManager().getMaximumWindowMetrics().getBounds();
+ intent.putExtra(Utils.DISPLAY_AREA_BOUNDS_KEY, bounds);
intent.putExtra(Utils.DISPLAY_WIDTH_KEY, mDisplaySize.x);
intent.putExtra(Utils.DISPLAY_HEIGHT_KEY, mDisplaySize.y);
}
diff --git a/tests/tests/bluetooth/AndroidTest.xml b/tests/tests/bluetooth/AndroidTest.xml
index 9a3075beee6..98189620bab 100644
--- a/tests/tests/bluetooth/AndroidTest.xml
+++ b/tests/tests/bluetooth/AndroidTest.xml
@@ -33,6 +33,6 @@
<!-- Only run Cts Tests in MTS if the Bluetooth Mainline module is installed. -->
<object type="module_controller"
class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
- <option name="mainline-module-package-name" value="com.google.android.bluetooth" />
+ <option name="mainline-module-package-name" value="com.android.btservices" />
</object>
</configuration>
diff --git a/tests/tests/content/CtsSyncAccountAccessOtherCertTests/src/com/android/cts/content/CtsSyncAccountAccessOtherCertTestCases.java b/tests/tests/content/CtsSyncAccountAccessOtherCertTests/src/com/android/cts/content/CtsSyncAccountAccessOtherCertTestCases.java
index 49b72549b7e..8bd1bb8fb33 100644
--- a/tests/tests/content/CtsSyncAccountAccessOtherCertTests/src/com/android/cts/content/CtsSyncAccountAccessOtherCertTestCases.java
+++ b/tests/tests/content/CtsSyncAccountAccessOtherCertTests/src/com/android/cts/content/CtsSyncAccountAccessOtherCertTestCases.java
@@ -43,6 +43,9 @@ import android.content.res.Configuration;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.support.test.uiautomator.UiScrollable;
+import android.support.test.uiautomator.UiSelector;
import android.support.test.uiautomator.Until;
import android.util.Log;
@@ -140,7 +143,7 @@ public class CtsSyncAccountAccessOtherCertTestCases {
} catch (Throwable t) {
if (scrollUps < 10) {
// The notification we search for is below the fold, scroll to find it
- swipeUp(uiDevice);
+ scrollNotifications();
scrollUps++;
continue;
}
@@ -200,6 +203,18 @@ public class CtsSyncAccountAccessOtherCertTestCases {
50 /* numberOfSteps */);
}
+ private boolean scrollNotifications() {
+ UiScrollable scrollable = new UiScrollable(new UiSelector().scrollable(true));
+ if (!scrollable.exists()) {
+ return false;
+ }
+ try {
+ return scrollable.scrollForward(50);
+ } catch (UiObjectNotFoundException e) {
+ return false;
+ }
+ }
+
private boolean isRunningInVR() {
final Context context = InstrumentationRegistry.getTargetContext();
return ((context.getResources().getConfiguration().uiMode &
diff --git a/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTest.java b/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTest.java
index a424edbd8c5..0b8c50598b1 100644
--- a/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTest.java
+++ b/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTest.java
@@ -124,10 +124,10 @@ public class DecoderTest extends MediaTestBase {
private static final int CONFIG_MODE_NONE = 0;
private static final int CONFIG_MODE_QUEUE = 1;
- private static final int CODEC_ALL = 0; // All codecs must support
- private static final int CODEC_ANY = 1; // At least one codec must support
- private static final int CODEC_DEFAULT = 2; // Default codec must support
- private static final int CODEC_OPTIONAL = 3; // Codec support is optional
+ public static final int CODEC_ALL = 0; // All codecs must support
+ public static final int CODEC_ANY = 1; // At least one codec must support
+ public static final int CODEC_DEFAULT = 2; // Default codec must support
+ public static final int CODEC_OPTIONAL = 3; // Codec support is optional
short[] mMasterBuffer;
static final String mInpPrefix = WorkDir.getMediaDirString();
diff --git a/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTestAacFormat.java b/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTestAacFormat.java
index f34f9e23146..0857809211e 100644
--- a/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTestAacFormat.java
+++ b/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTestAacFormat.java
@@ -81,9 +81,9 @@ public class DecoderTestAacFormat {
AudioFormat.CHANNEL_OUT_QUAD | AudioFormat.CHANNEL_OUT_FRONT_CENTER},
{"noise_6ch_44khz_aot5_dr_sbr_sig2_mp4.m4a", 6, AudioFormat.CHANNEL_OUT_5POINT1},
};
-
- for (Object [] sample: samples) {
- for (String codecName : DecoderTest.codecsFor((String)sample[0] /* resource */)) {
+ for (Object[] sample: samples) {
+ for (String codecName : DecoderTest.codecsFor((String)sample[0] /* resource */,
+ DecoderTest.CODEC_DEFAULT)) {
// verify correct number of channels is observed without downmixing
AudioParameter chanParams = new AudioParameter();
decodeUpdateFormat(codecName, (String) sample[0] /*resource*/, chanParams,
diff --git a/tests/tests/permission/src/android/permission/cts/SafetyCenterUtils.kt b/tests/tests/permission/src/android/permission/cts/SafetyCenterUtils.kt
index f057b21a849..931ecd1bc6b 100644
--- a/tests/tests/permission/src/android/permission/cts/SafetyCenterUtils.kt
+++ b/tests/tests/permission/src/android/permission/cts/SafetyCenterUtils.kt
@@ -67,7 +67,7 @@ object SafetyCenterUtils {
@JvmStatic
fun assertSafetyCenterStarted() {
// CollapsingToolbar title can't be found by text, so using description instead.
- waitFindObject(By.desc("Security & Privacy"))
+ waitFindObject(By.desc("Security & privacy"))
}
@JvmStatic
diff --git a/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt b/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt
index 598a59a1727..872a243ce2e 100644
--- a/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt
+++ b/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt
@@ -78,6 +78,8 @@ private const val IDLE_TIMEOUT_MILLIS: Long = 1000
private const val UNEXPECTED_TIMEOUT_MILLIS = 1000
private const val TIMEOUT_MILLIS: Long = 20000
private const val TV_MIC_INDICATOR_WINDOW_TITLE = "MicrophoneCaptureIndicator"
+private const val MIC_LABEL_NAME = "microphone_toggle_label_qs"
+private const val CAMERA_LABEL_NAME = "camera_toggle_label_qs"
class CameraMicIndicatorsPermissionTest {
private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
@@ -90,11 +92,9 @@ class CameraMicIndicatorsPermissionTest {
private val isTv = packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
private val isCar = packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
+ private val micLabel = getPermissionControllerString(MIC_LABEL_NAME)
+ private val cameraLabel = getPermissionControllerString(CAMERA_LABEL_NAME)
private var wasEnabled = false
- private val micLabel = packageManager.getPermissionGroupInfo(
- Manifest.permission_group.MICROPHONE, 0).loadLabel(packageManager).toString()
- private val cameraLabel = packageManager.getPermissionGroupInfo(
- Manifest.permission_group.CAMERA, 0).loadLabel(packageManager).toString()
private var isScreenOn = false
private var screenTimeoutBeforeTest: Long = 0L
@@ -520,4 +520,18 @@ class CameraMicIndicatorsPermissionTest {
automatorMethod(remainingTime)
}
}
+
+ private fun getPermissionControllerString(resourceName: String): String {
+ val permissionControllerPkg = context.packageManager.permissionControllerPackageName
+ try {
+ val permissionControllerContext =
+ context.createPackageContext(permissionControllerPkg, 0)
+ val resourceId =
+ permissionControllerContext.resources.getIdentifier(
+ resourceName, "string", "com.android.permissioncontroller")
+ return permissionControllerContext.getString(resourceId)
+ } catch (e: PackageManager.NameNotFoundException) {
+ throw RuntimeException(e)
+ }
+ }
} \ No newline at end of file
diff --git a/tests/tests/permission5/src/android/permission5/cts/RuntimePermissionsAppOpTrackingTest.kt b/tests/tests/permission5/src/android/permission5/cts/RuntimePermissionsAppOpTrackingTest.kt
index 8cff38a67a9..67fa1bc3207 100644
--- a/tests/tests/permission5/src/android/permission5/cts/RuntimePermissionsAppOpTrackingTest.kt
+++ b/tests/tests/permission5/src/android/permission5/cts/RuntimePermissionsAppOpTrackingTest.kt
@@ -25,6 +25,7 @@ import android.content.Context
import android.content.ContextParams
import android.content.Intent
import android.content.pm.PackageManager.FEATURE_LEANBACK
+import android.content.pm.PackageManager.FEATURE_TELEPHONY
import android.net.Uri
import android.os.Bundle
import android.os.Process
@@ -44,6 +45,7 @@ import com.android.compatibility.common.util.SystemUtil
import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Assume.assumeFalse
+import org.junit.Assume.assumeTrue
import org.junit.Before
import org.junit.Test
import org.mockito.ArgumentMatcher
@@ -105,6 +107,7 @@ class RuntimePermissionsAppOpTrackingTest {
@Throws(Exception::class)
fun testSelfSmsAccess() {
assumeNotTv()
+ assumeHasTelephony()
testSelfAccess(Telephony.Sms.CONTENT_URI,
Manifest.permission.READ_SMS)
}
@@ -178,6 +181,7 @@ class RuntimePermissionsAppOpTrackingTest {
@Throws(Exception::class)
fun testUntrustedSmsAccessAttributeToAnother() {
assumeNotTv()
+ assumeHasTelephony()
testUntrustedAccessAttributeToAnother(Telephony.Sms.CONTENT_URI,
Manifest.permission.READ_SMS)
}
@@ -225,6 +229,7 @@ class RuntimePermissionsAppOpTrackingTest {
@Throws(Exception::class)
fun testUntrustedSmsAccessAttributeToAnotherThroughIntermediary() {
assumeNotTv()
+ assumeHasTelephony()
testUntrustedAccessAttributeToAnotherThroughIntermediary(
Telephony.Sms.CONTENT_URI,
Manifest.permission.READ_SMS)
@@ -323,6 +328,7 @@ class RuntimePermissionsAppOpTrackingTest {
@Throws(Exception::class)
fun testTrustedAccessSmsAttributeToAnother() {
assumeNotTv()
+ assumeHasTelephony()
testTrustedAccessAttributeToAnother(Telephony.Sms.CONTENT_URI,
Manifest.permission.READ_SMS)
}
@@ -666,6 +672,7 @@ class RuntimePermissionsAppOpTrackingTest {
get() = InstrumentationRegistry.getInstrumentation()
private val isTv = context.packageManager.hasSystemFeature(FEATURE_LEANBACK)
+ private val isTel = context.packageManager.hasSystemFeature(FEATURE_TELEPHONY)
fun ensureAuxiliaryAppsNotRunningAndNoResidualProcessState() {
SystemUtil.runShellCommand("am force-stop $RECEIVER_PACKAGE_NAME")
@@ -1178,5 +1185,6 @@ class RuntimePermissionsAppOpTrackingTest {
}
private fun assumeNotTv() = assumeFalse(isTv)
+ private fun assumeHasTelephony() = assumeTrue(isTel)
}
}
diff --git a/tests/tests/preference/src/android/preference/cts/PreferenceActivityLegacyFlowTest.java b/tests/tests/preference/src/android/preference/cts/PreferenceActivityLegacyFlowTest.java
index 29cf672a829..782f30c6508 100644
--- a/tests/tests/preference/src/android/preference/cts/PreferenceActivityLegacyFlowTest.java
+++ b/tests/tests/preference/src/android/preference/cts/PreferenceActivityLegacyFlowTest.java
@@ -103,7 +103,8 @@ public class PreferenceActivityLegacyFlowTest {
}
private void assertScreenshotsAreEqual(Bitmap before, Bitmap after) {
- assertTrue("Screenshots do not match!", BitmapUtils.compareBitmaps(before, after));
+ // TODO(b/227553681): remove the precision=0.99 arg so it does a pixel-by-pixel check
+ assertTrue("Screenshots do not match!", BitmapUtils.compareBitmaps(before, after, 0.99));
}
private void assertTextShown(String text) {
diff --git a/tests/tests/security/src/android/security/cts/LocationDisabledAppOpsTest.java b/tests/tests/security/src/android/security/cts/LocationDisabledAppOpsTest.java
new file mode 100644
index 00000000000..c6b7e35b4ef
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/LocationDisabledAppOpsTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.OPSTR_FINE_LOCATION;
+
+import static com.android.compatibility.common.util.SystemUtil.eventually;
+import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
+
+import android.app.ActivityManager;
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.location.LocationManager;
+import android.os.PackageTagsList;
+import android.os.Process;
+import android.os.UserHandle;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+public class LocationDisabledAppOpsTest extends StsExtraBusinessLogicTestCase {
+
+ private final Context mContext = InstrumentationRegistry.getContext();
+ private LocationManager mLm;
+ private AppOpsManager mAom;
+
+ @Before
+ public void setUp() {
+ mLm = mContext.getSystemService(LocationManager.class);
+ mAom = mContext.getSystemService(AppOpsManager.class);
+ }
+
+ @Test
+ @AsbSecurityTest(cveBugId = 231496105)
+ public void testLocationAppOpIsIgnoredForAppsWhenLocationIsDisabled() {
+ PackageTagsList ignoreList = mLm.getIgnoreSettingsAllowlist();
+
+ UserHandle[] userArr = {UserHandle.SYSTEM};
+ runWithShellPermissionIdentity(() -> {
+ userArr[0] = UserHandle.of(ActivityManager.getCurrentUser());
+ });
+
+ UserHandle user = userArr[0];
+
+ boolean wasEnabled = mLm.isLocationEnabledForUser(user);
+
+ try {
+ runWithShellPermissionIdentity(() -> {
+ mLm.setLocationEnabledForUser(false, user);
+ });
+ List<PackageInfo> pkgs =
+ mContext.getPackageManager().getInstalledPackagesAsUser(
+ 0, user.getIdentifier());
+
+ eventually(() -> {
+ List<String> bypassedNoteOps = new ArrayList<>();
+ List<String> bypassedCheckOps = new ArrayList<>();
+ for (PackageInfo pi : pkgs) {
+ ApplicationInfo ai = pi.applicationInfo;
+ if (ai.uid != Process.SYSTEM_UID) {
+ final int[] mode = {MODE_ALLOWED};
+ runWithShellPermissionIdentity(() -> {
+ mode[0] = mAom.noteOpNoThrow(
+ OPSTR_FINE_LOCATION, ai.uid, ai.packageName);
+ });
+ if (mode[0] == MODE_ALLOWED && !ignoreList.containsAll(pi.packageName)) {
+ bypassedNoteOps.add(pi.packageName);
+ }
+
+
+ mode[0] = MODE_ALLOWED;
+ runWithShellPermissionIdentity(() -> {
+ mode[0] = mAom
+ .checkOpNoThrow(OPSTR_FINE_LOCATION, ai.uid, ai.packageName);
+ });
+ if (mode[0] == MODE_ALLOWED && !ignoreList.includes(pi.packageName)) {
+ bypassedCheckOps.add(pi.packageName);
+ }
+
+ }
+ }
+
+ String msg = "";
+ if (!bypassedNoteOps.isEmpty()) {
+ msg += "Apps which still have access from noteOp " + bypassedNoteOps;
+ }
+ if (!bypassedCheckOps.isEmpty()) {
+ msg += (msg.isEmpty() ? "" : "\n\n")
+ + "Apps which still have access from checkOp " + bypassedCheckOps;
+ }
+ if (!msg.isEmpty()) {
+ Assert.fail(msg);
+ }
+ });
+ } finally {
+ runWithShellPermissionIdentity(() -> {
+ mLm.setLocationEnabledForUser(wasEnabled, user);
+ });
+ }
+ }
+
+}
+
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java
index 7d73da9dad1..f00f0b13b5c 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java
@@ -125,6 +125,8 @@ public class ExactCanvasTests extends ActivityTestBase {
canvas.drawColor(Color.WHITE);
p.setColor(Color.BLACK);
p.setAntiAlias(false);
+ // ensure the lines do not hit pixel edges
+ canvas.translate(0.05f, 0.05f);
float[] pts = {
0, 0, 80, 80, 80, 0, 0, 80, 40, 50, 60, 50
};
diff --git a/tests/tests/wifi/src/android/net/wifi/cts/ConcurrencyTest.java b/tests/tests/wifi/src/android/net/wifi/cts/ConcurrencyTest.java
index f7322dde5e1..464fb4c40b8 100644
--- a/tests/tests/wifi/src/android/net/wifi/cts/ConcurrencyTest.java
+++ b/tests/tests/wifi/src/android/net/wifi/cts/ConcurrencyTest.java
@@ -274,6 +274,29 @@ public class ConcurrencyTest extends WifiJUnit3TestBase {
new LinkedList<Integer>(Arrays.asList(waitSingleSync)));
}
+ private NetworkInfo.DetailedState waitForNextNetworkState() {
+ assertTrue(waitForBroadcasts(MySync.NETWORK_INFO));
+ assertNotNull(mMySync.expectedNetworkInfo);
+ return mMySync.expectedNetworkInfo.getDetailedState();
+ }
+
+ private boolean waitForConnectedNetworkState() {
+ // The possible orders of network states are:
+ // * IDLE > CONNECTING > CONNECTED for lazy initialization
+ // * DISCONNECTED > CONNECTING > CONNECTED for previous group removal
+ // * CONNECTING > CONNECTED
+ NetworkInfo.DetailedState state = waitForNextNetworkState();
+ if (state == NetworkInfo.DetailedState.IDLE
+ || state == NetworkInfo.DetailedState.DISCONNECTED) {
+ state = waitForNextNetworkState();
+ }
+ if (state != NetworkInfo.DetailedState.CONNECTING) {
+ return false;
+ }
+ state = waitForNextNetworkState();
+ return state == NetworkInfo.DetailedState.CONNECTED;
+ }
+
private boolean waitForServiceResponse(MyResponse waitResponse) {
synchronized (waitResponse) {
long timeout = System.currentTimeMillis() + TIMEOUT_MSEC;
@@ -508,21 +531,7 @@ public class ConcurrencyTest extends WifiJUnit3TestBase {
mWifiP2pManager.createGroup(mWifiP2pChannel, mActionListener);
assertTrue(waitForServiceResponse(mMyResponse));
assertTrue(mMyResponse.success);
-
- // The first network state might be IDLE due to
- // lazy initialization, but not CONNECTED.
- for (int i = 0; i < 2; i++) {
- assertTrue(waitForBroadcasts(MySync.NETWORK_INFO));
- assertNotNull(mMySync.expectedNetworkInfo);
- if (NetworkInfo.DetailedState.CONNECTED ==
- mMySync.expectedNetworkInfo.getDetailedState()) {
- break;
- }
- assertEquals(NetworkInfo.DetailedState.IDLE,
- mMySync.expectedNetworkInfo.getDetailedState());
- }
- assertEquals(NetworkInfo.DetailedState.CONNECTED,
- mMySync.expectedNetworkInfo.getDetailedState());
+ assertTrue(waitForConnectedNetworkState());
resetResponse(mMyResponse);
mWifiP2pManager.requestNetworkInfo(mWifiP2pChannel,
@@ -660,21 +669,7 @@ public class ConcurrencyTest extends WifiJUnit3TestBase {
mWifiP2pManager.createGroup(mWifiP2pChannel, mActionListener);
assertTrue(waitForServiceResponse(mMyResponse));
assertTrue(mMyResponse.success);
-
- // The first network state might be IDLE due to
- // lazy initialization, but not CONNECTED.
- for (int i = 0; i < 2; i++) {
- assertTrue(waitForBroadcasts(MySync.NETWORK_INFO));
- assertNotNull(mMySync.expectedNetworkInfo);
- if (NetworkInfo.DetailedState.CONNECTED ==
- mMySync.expectedNetworkInfo.getDetailedState()) {
- break;
- }
- assertEquals(NetworkInfo.DetailedState.IDLE,
- mMySync.expectedNetworkInfo.getDetailedState());
- }
- assertEquals(NetworkInfo.DetailedState.CONNECTED,
- mMySync.expectedNetworkInfo.getDetailedState());
+ assertTrue(waitForConnectedNetworkState());
resetResponse(mMyResponse);
mWifiP2pManager.removeGroup(mWifiP2pChannel, mActionListener);
@@ -707,10 +702,7 @@ public class ConcurrencyTest extends WifiJUnit3TestBase {
mWifiP2pManager.createGroup(mWifiP2pChannel, mActionListener);
assertTrue(waitForServiceResponse(mMyResponse));
assertTrue(mMyResponse.success);
- assertTrue(waitForBroadcasts(MySync.NETWORK_INFO));
- assertNotNull(mMySync.expectedNetworkInfo);
- assertEquals(NetworkInfo.DetailedState.CONNECTED,
- mMySync.expectedNetworkInfo.getDetailedState());
+ assertTrue(waitForConnectedNetworkState());
resetResponse(mMyResponse);
mWifiP2pManager.removeGroup(mWifiP2pChannel, mActionListener);
@@ -812,21 +804,7 @@ public class ConcurrencyTest extends WifiJUnit3TestBase {
mWifiP2pManager.createGroup(mWifiP2pChannel, mActionListener);
assertTrue(waitForServiceResponse(mMyResponse));
assertTrue(mMyResponse.success);
-
- // The first network state might be IDLE due to
- // lazy initialization, but not CONNECTED.
- for (int i = 0; i < 2; i++) {
- assertTrue(waitForBroadcasts(MySync.NETWORK_INFO));
- assertNotNull(mMySync.expectedNetworkInfo);
- if (NetworkInfo.DetailedState.CONNECTED
- == mMySync.expectedNetworkInfo.getDetailedState()) {
- break;
- }
- assertEquals(NetworkInfo.DetailedState.IDLE,
- mMySync.expectedNetworkInfo.getDetailedState());
- }
- assertEquals(NetworkInfo.DetailedState.CONNECTED,
- mMySync.expectedNetworkInfo.getDetailedState());
+ assertTrue(waitForConnectedNetworkState());
resetResponse(mMyResponse);
MacAddress peerMacAddress = MacAddress.fromString(mTestWifiP2pPeerConfig.deviceAddress);