summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-06-10 16:16:42 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-06-10 16:16:42 +0000
commitf77a00c53f15ee8499c32a72fcd9d7cf9f003b0c (patch)
tree8e7dbd9b66a5162d98b2bb1d8e260aba6d8124b5
parent3c6bfa5771c64232370c967d240f032afc281d81 (diff)
parentfb9a587335ce035687ca8a7bffb1acf5ee6c0aee (diff)
downloadcts-android13-mainline-go-adservices-release.tar.gz
Snap for 8708169 from fb9a587335ce035687ca8a7bffb1acf5ee6c0aee to mainline-go-adservices-releaseaml_go_ads_330915100aml_go_ads_330915000aml_go_ads_330913000android13-mainline-go-adservices-release
Change-Id: I88653d47cd2d686036c0957a51c7ad5605903853
-rw-r--r--apps/CameraITS/build/scripts/gpylint_rcfile3
-rw-r--r--apps/CameraITS/tests/its_base_test.py1
-rw-r--r--apps/CameraITS/tests/scene1_1/test_ae_af.py4
-rw-r--r--apps/CameraITS/tests/scene1_1/test_capture_result.py2
-rw-r--r--apps/CameraITS/tests/scene1_2/test_raw_exposure.py9
-rw-r--r--apps/CameraITS/tests/scene1_2/test_raw_sensitivity.py1
-rw-r--r--apps/CameraITS/tests/scene2_a/test_format_combos.py2
-rw-r--r--apps/CameraITS/tests/scene4/test_preview_stabilization_fov.py2
-rw-r--r--apps/CameraITS/tests/scene4/test_video_aspect_ratio_and_crop.py20
-rw-r--r--apps/CameraITS/tests/scene6/test_zoom.py4
-rw-r--r--apps/CameraITS/tests/sensor_fusion/test_preview_stabilization.py29
-rw-r--r--apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py2
-rw-r--r--apps/CameraITS/tests/sensor_fusion/test_video_stabilization.py21
-rw-r--r--apps/CameraITS/utils/image_processing_utils.py10
-rw-r--r--apps/CameraITS/utils/its_session_utils.py15
-rw-r--r--apps/CameraITS/utils/sensor_fusion_utils.py5
-rw-r--r--apps/CameraITS/utils/video_processing_utils.py5
-rw-r--r--apps/CtsVerifier/AndroidManifest.xml4
-rw-r--r--apps/CtsVerifier/res/layout-port/camera_video.xml136
-rw-r--r--apps/CtsVerifier/res/layout/audio_dev_notify.xml6
-rw-r--r--apps/CtsVerifier/res/values/strings.xml5
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/Utils.java38
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioInputDeviceNotificationsActivity.java13
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioInputRoutingNotificationsActivity.java3
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioOutputDeviceNotificationsActivity.java13
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioOutputRoutingNotificationsActivity.java2
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioWiredDeviceBaseActivity.java2
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/camera/fov/PhotoCaptureActivity.java71
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java8
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/presence/PresenceTestActivity.java30
-rw-r--r--common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/InputDeviceInfo.kt14
-rw-r--r--hostsidetests/compilation/src/android/compilation/cts/BackgroundDexOptimizationTest.java10
-rw-r--r--hostsidetests/cpptools/Android.bp6
-rw-r--r--hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java3
-rw-r--r--hostsidetests/graphics/gpuprofiling/Android.bp5
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2022-20147/Android.bp44
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2022-20147/poc.cpp67
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0954.java2
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20147.java63
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java2
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/DeviceTest.java8
-rw-r--r--hostsidetests/statsdatom/src/android/cts/statsdatom/appcompatstate/AppCompatStateStatsTests.java11
-rw-r--r--hostsidetests/statsdatom/src/android/cts/statsdatom/appops/AppOpsTests.java13
-rw-r--r--hostsidetests/statsdatom/src/android/cts/statsdatom/sizecompatrestartbutton/SizeCompatRestartButtonStatsTests.java10
-rw-r--r--hostsidetests/sustainedperf/Android.bp6
-rw-r--r--tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagerTest.java1
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/ActivityTransitionTests.java46
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/TaskFragmentOrganizerTest.java2
-rw-r--r--tests/framework/base/windowmanager/src/android/server/wm/WindowInputTests.java20
-rw-r--r--tests/inputmethod/src/android/view/inputmethod/cts/StylusHandwritingTest.java4
-rw-r--r--tests/location/location_fine/src/android/location/cts/fine/LocationManagerFineTest.java1
-rw-r--r--tests/location/location_none/src/android/location/cts/none/LocationDisabledAppOpsTest.java120
-rw-r--r--tests/media/src/android/mediav2/cts/CodecEncoderValidationTest.java4
-rw-r--r--tests/media/src/android/mediav2/cts/CodecInfoTest.java45
-rw-r--r--tests/media/src/android/mediav2/cts/CodecTestBase.java3
-rw-r--r--tests/media/src/android/mediav2/cts/EncoderColorAspectsTest.java149
-rw-r--r--tests/media/src/android/mediav2/cts/EncoderHDRInfoTest.java5
-rw-r--r--tests/mediapc/common/src/android/mediapc/cts/common/PerformanceClassEvaluator.java581
-rw-r--r--tests/mediapc/common/src/android/mediapc/cts/common/RequirementConstants.java21
-rw-r--r--tests/mediapc/src/android/mediapc/cts/CodecInitializationLatencyTest.java36
-rw-r--r--tests/mediapc/src/android/mediapc/cts/MultiCodecPerfTestBase.java48
-rw-r--r--tests/mediapc/src/android/mediapc/cts/MultiDecoderPairPerfTest.java163
-rw-r--r--tests/mediapc/src/android/mediapc/cts/MultiDecoderPerfTest.java102
-rw-r--r--tests/mediapc/src/android/mediapc/cts/MultiEncoderPairPerfTest.java48
-rw-r--r--tests/mediapc/src/android/mediapc/cts/MultiEncoderPerfTest.java46
-rw-r--r--tests/mediapc/src/android/mediapc/cts/MultiTranscoderPerfTest.java54
-rw-r--r--tests/mediapc/src/android/mediapc/cts/PerformanceClassTest.java84
-rw-r--r--tests/mediapc/src/android/mediapc/cts/VideoCodecRequirementsTest.java7
-rw-r--r--tests/musicrecognition/Android.bp4
-rw-r--r--tests/net/src/android/net/cts/LocalSocketTest.java5
-rw-r--r--tests/providerui/src/android/providerui/cts/MediaStoreUiTest.java3
-rw-r--r--tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java9
-rw-r--r--tests/tests/carrierapi/src/android/carrierapi/cts/CarrierApiTest.java13
-rw-r--r--tests/tests/companion/common/src/android/companion/cts/common/TestBase.kt3
-rw-r--r--tests/tests/content/src/android/content/pm/cts/ChecksumsTest.java16
-rw-r--r--tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandMultiUserTest.kt18
-rw-r--r--tests/tests/dreams/src/android/service/dreams/cts/DreamServiceTest.java5
-rw-r--r--tests/tests/graphics/AndroidManifest.xml17
-rw-r--r--tests/tests/graphics/res/xml/valid_themes.xml12
-rw-r--r--tests/tests/graphics/src/android/graphics/cts/AnimatorLeakTest.java255
-rw-r--r--tests/tests/graphics/src/android/graphics/cts/EmptyActivity.java36
-rw-r--r--tests/tests/graphics/src/android/graphics/cts/EmptyActivity2.java37
-rw-r--r--tests/tests/hardware/src/android/hardware/input/cts/tests/VirtualDeviceTestCase.java8
-rw-r--r--tests/tests/hardware/src/android/hardware/input/cts/tests/VirtualMouseTest.java82
-rw-r--r--tests/tests/keystore/src/android/keystore/cts/BlockCipherTestBase.java62
-rw-r--r--tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java4
-rw-r--r--tests/tests/media/common/src/android/media/cts/MediaCodecTunneledPlayer.java3
-rw-r--r--tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTest.java337
-rw-r--r--tests/tests/media/misc/src/android/media/misc/cts/CamcorderProfileTest.java2
-rw-r--r--tests/tests/os/UffdGc/jni/android_os_cts_uffdgc_UserfaultfdTest.cc23
-rw-r--r--tests/tests/os/UffdGc/src/android/os/cts/uffdgc/UserfaultfdTest.java3
-rw-r--r--tests/tests/permission/Android.bp50
-rw-r--r--tests/tests/permission3/src/android/permission3/cts/PermissionAttributionTest.kt14
-rw-r--r--tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt29
-rw-r--r--tests/tests/security/AndroidManifest.xml7
-rw-r--r--tests/tests/security/src/android/security/cts/CVE_2022_20143/CVE_2022_20143.java117
-rw-r--r--tests/tests/security/src/android/security/cts/CVE_2022_20143/PocActivity.java22
-rw-r--r--tests/tests/security/src/android/security/cts/StagefrightTest.java61
-rwxr-xr-xtests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java97
-rw-r--r--tools/cts-tradefed/res/config/cts-known-failures.xml6
-rw-r--r--tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml2
101 files changed, 2651 insertions, 1031 deletions
diff --git a/apps/CameraITS/build/scripts/gpylint_rcfile b/apps/CameraITS/build/scripts/gpylint_rcfile
index fe9f3d1175a..38c169344b5 100644
--- a/apps/CameraITS/build/scripts/gpylint_rcfile
+++ b/apps/CameraITS/build/scripts/gpylint_rcfile
@@ -61,9 +61,6 @@ test-mode=test
# Inject some known modules.
inject-known-modules=no
-# The import path resolver
-resolver=blaze
-
[REPORTS]
diff --git a/apps/CameraITS/tests/its_base_test.py b/apps/CameraITS/tests/its_base_test.py
index 0240682be2c..9b29ab72365 100644
--- a/apps/CameraITS/tests/its_base_test.py
+++ b/apps/CameraITS/tests/its_base_test.py
@@ -171,6 +171,7 @@ class ItsBaseTest(base_test.BaseTestClass):
self.tablet.adb.shell('am force-stop com.google.android.apps.photos')
self.tablet.adb.shell('am force-stop com.android.gallery3d')
self.tablet.adb.shell('am force-stop com.sec.android.gallery3d')
+ self.tablet.adb.shell('am force-stop com.miui.gallery')
def set_tablet_landscape_orientation(self):
"""Sets the screen orientation to landscape.
diff --git a/apps/CameraITS/tests/scene1_1/test_ae_af.py b/apps/CameraITS/tests/scene1_1/test_ae_af.py
index 09a1470c234..852c7867582 100644
--- a/apps/CameraITS/tests/scene1_1/test_ae_af.py
+++ b/apps/CameraITS/tests/scene1_1/test_ae_af.py
@@ -67,8 +67,8 @@ class SingleATest(its_base_test.ItsBaseTest):
do_awb=three_a_req[2],
mono_camera=mono_camera)
- except error_util.CameraItsError:
- raise AssertionError(f'{k} did not converge.')
+ except error_util.CameraItsError as e_util:
+ raise AssertionError(f'{k} did not converge.') from e_util
logging.debug('AWB gains: %s, xform: %s', str(awb_gains),
str(awb_xform))
diff --git a/apps/CameraITS/tests/scene1_1/test_capture_result.py b/apps/CameraITS/tests/scene1_1/test_capture_result.py
index 304a7376c02..f3a9e9d994a 100644
--- a/apps/CameraITS/tests/scene1_1/test_capture_result.py
+++ b/apps/CameraITS/tests/scene1_1/test_capture_result.py
@@ -213,7 +213,7 @@ def test_manual(cam, props, log_path):
metadata['android.tonemap.curve']['green'],
metadata['android.tonemap.curve']['blue']]
logging.debug('Tonemap: %s', str(curves[0][1::16]))
- for j, c in enumerate(curves):
+ for _, c in enumerate(curves):
if not c:
raise AssertionError('c in curves is empty.')
if not all([np.isclose(c[i], c[i+1], atol=ISCLOSE_ATOL)
diff --git a/apps/CameraITS/tests/scene1_2/test_raw_exposure.py b/apps/CameraITS/tests/scene1_2/test_raw_exposure.py
index 5bd44e8f1a5..bcf426d8cfc 100644
--- a/apps/CameraITS/tests/scene1_2/test_raw_exposure.py
+++ b/apps/CameraITS/tests/scene1_2/test_raw_exposure.py
@@ -85,15 +85,16 @@ def create_plot(exps, means, sens, log_path):
gb = [m[2] for m in means[1:]]
b = [m[3] for m in means[1:]]
pylab.figure('%s_%s' % (NAME, sens))
- pylab.plot(exps, r, 'r.-')
- pylab.plot(exps, b, 'b.-')
- pylab.plot(exps, gr, 'g.-')
- pylab.plot(exps, gb, 'k.-')
+ pylab.plot(exps, r, 'r.-', label='R')
+ pylab.plot(exps, gr, 'g.-', label='Gr')
+ pylab.plot(exps, gb, 'k.-', label='Gb')
+ pylab.plot(exps, b, 'b.-', label='B')
pylab.xscale('log')
pylab.yscale('log')
pylab.title('%s ISO=%d' % (NAME, sens))
pylab.xlabel('Exposure time (ms)')
pylab.ylabel('Center patch pixel mean')
+ pylab.legend(loc='lower right', numpoints=1, fancybox=True)
matplotlib.pyplot.savefig(
'%s_s=%d.png' % (os.path.join(log_path, NAME), sens))
pylab.clf()
diff --git a/apps/CameraITS/tests/scene1_2/test_raw_sensitivity.py b/apps/CameraITS/tests/scene1_2/test_raw_sensitivity.py
index 8c542ab9cc4..62a017b8f68 100644
--- a/apps/CameraITS/tests/scene1_2/test_raw_sensitivity.py
+++ b/apps/CameraITS/tests/scene1_2/test_raw_sensitivity.py
@@ -63,7 +63,6 @@ class RawSensitivityTest(its_base_test.ItsBaseTest):
camera_properties_utils.per_frame_control(props) and
not camera_properties_utils.mono_camera(props))
name_with_log_path = os.path.join(self.log_path, NAME)
- camera_fov = float(cam.calc_camera_fov(props))
# Load chart for scene (chart_distance=0 for no chart scaling)
its_session_utils.load_scene(
diff --git a/apps/CameraITS/tests/scene2_a/test_format_combos.py b/apps/CameraITS/tests/scene2_a/test_format_combos.py
index 7568da796e2..c05301b261b 100644
--- a/apps/CameraITS/tests/scene2_a/test_format_combos.py
+++ b/apps/CameraITS/tests/scene2_a/test_format_combos.py
@@ -147,7 +147,7 @@ class FormatCombosTest(its_base_test.ItsBaseTest):
if STOP_AT_FIRST_FAILURE:
raise AssertionError(
f'Capture fail at combo req: {req_str}, fmt: {fmt_combo}, '
- f'burst: {burst_len}')
+ f'burst: {burst_len}') from e
n += 1
num_fail = len(failures)
diff --git a/apps/CameraITS/tests/scene4/test_preview_stabilization_fov.py b/apps/CameraITS/tests/scene4/test_preview_stabilization_fov.py
index e77a702d3b3..3959b42ef27 100644
--- a/apps/CameraITS/tests/scene4/test_preview_stabilization_fov.py
+++ b/apps/CameraITS/tests/scene4/test_preview_stabilization_fov.py
@@ -148,7 +148,7 @@ class PreviewStabilizationFoVTest(its_base_test.ItsBaseTest):
camera_properties_utils.skip_unless(
first_api_level >= its_session_utils.ANDROID13_API_LEVEL,
'First API level should be {} or higher. Found {}.'.format(
- its_session_utils.ANDROID13_API_LEVEL, first_api_level))
+ its_session_utils.ANDROID13_API_LEVEL, first_api_level))
supported_stabilization_modes = props[
'android.control.availableVideoStabilizationModes'
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 eca64ef9b5c..06f3f129f53 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
@@ -182,7 +182,8 @@ class VideoAspectRatioAndCropTest(its_base_test.ItsBaseTest):
for hlg10_param in hlg10_params:
video_recording_obj = cam.do_basic_recording(
- profile_id, quality, _VIDEO_RECORDING_DURATION_SECONDS, 0, hlg10_param)
+ profile_id, quality, _VIDEO_RECORDING_DURATION_SECONDS, 0,
+ hlg10_param)
logging.debug('video_recording_obj: %s', video_recording_obj)
# TODO(ruchamk): Modify video recording object to send videoFrame
# width and height instead of videoSize to avoid string operation
@@ -196,7 +197,8 @@ class VideoAspectRatioAndCropTest(its_base_test.ItsBaseTest):
self.log_path])
logging.debug('Recorded video is available at: %s',
self.log_path)
- video_file_name = video_recording_obj['recordedOutputPath'].split('/')[-1]
+ video_file_name = video_recording_obj[
+ 'recordedOutputPath'].split('/')[-1]
logging.debug('video_file_name: %s', video_file_name)
key_frame_files = []
@@ -208,7 +210,8 @@ class VideoAspectRatioAndCropTest(its_base_test.ItsBaseTest):
last_key_frame_file = video_processing_utils.get_key_frame_to_process(
key_frame_files)
logging.debug('last_key_frame: %s', last_key_frame_file)
- last_key_frame_path = os.path.join(self.log_path, last_key_frame_file)
+ last_key_frame_path = os.path.join(
+ self.log_path, last_key_frame_file)
# Convert lastKeyFrame to numpy array
np_image = image_processing_utils.convert_image_to_numpy_array(
@@ -222,7 +225,7 @@ class VideoAspectRatioAndCropTest(its_base_test.ItsBaseTest):
max_img_value = _MAX_8BIT_IMGS
if hlg10_param:
- max_img_value = _MAX_10BIT_IMGS
+ max_img_value = _MAX_10BIT_IMGS
# Check pass/fail for fov coverage for all fmts in AR_CHECKED
fov_chk_msg = image_fov_utils.check_fov(
@@ -232,7 +235,8 @@ class VideoAspectRatioAndCropTest(its_base_test.ItsBaseTest):
os.path.join(self.log_path, _NAME), quality, width, height)
fov_chk_quality_msg = f'Quality: {quality} {fov_chk_msg}'
failed_fov.append(fov_chk_quality_msg)
- image_processing_utils.write_image(np_image/max_img_value, img_name, True)
+ image_processing_utils.write_image(
+ np_image/max_img_value, img_name, True)
# Check pass/fail for aspect ratio.
ar_chk_msg = image_fov_utils.check_ar(
@@ -242,14 +246,16 @@ class VideoAspectRatioAndCropTest(its_base_test.ItsBaseTest):
img_name = '%s_%s_w%d_h%d_ar.png' % (
os.path.join(self.log_path, _NAME), quality, width, height)
failed_ar.append(ar_chk_msg)
- image_processing_utils.write_image(np_image/max_img_value, img_name, True)
+ image_processing_utils.write_image(
+ np_image/max_img_value, img_name, True)
# Check pass/fail for crop.
if run_crop_test:
# Normalize the circle size to 1/4 of the image size, so that
# circle size won't affect the crop test result
crop_thresh_factor = ((min(ref_fov['w'], ref_fov['h']) / 4.0) /
- max(ref_fov['circle_w'], ref_fov['circle_h']))
+ max(ref_fov['circle_w'],
+ ref_fov['circle_h']))
crop_chk_msg = image_fov_utils.check_crop(
circle, cc_ct_gt, width, height,
f'{quality}', crop_thresh_factor)
diff --git a/apps/CameraITS/tests/scene6/test_zoom.py b/apps/CameraITS/tests/scene6/test_zoom.py
index c828ad5798b..d4fa21c3c29 100644
--- a/apps/CameraITS/tests/scene6/test_zoom.py
+++ b/apps/CameraITS/tests/scene6/test_zoom.py
@@ -273,13 +273,13 @@ class ZoomTest(its_base_test.ItsBaseTest):
if circle_cropped(circle, size):
logging.debug('zoom %.2f is too large! Skip further captures', z)
break
- except AssertionError:
+ except AssertionError as e:
if z/z_list[0] >= ZOOM_MAX_THRESH:
break
else:
raise AssertionError(
f'No circle was detected for zoom ratio <= {ZOOM_MAX_THRESH}. '
- 'Please take pictures according to instructions carefully!')
+ 'Take pictures according to instructions carefully!') from e
test_data[i] = {'z': z, 'circle': circle, 'r_tol': radius_tol,
'o_tol': offset_tol, 'fl': cap_fl}
diff --git a/apps/CameraITS/tests/sensor_fusion/test_preview_stabilization.py b/apps/CameraITS/tests/sensor_fusion/test_preview_stabilization.py
index 64b22d908ce..c6b852c5378 100644
--- a/apps/CameraITS/tests/sensor_fusion/test_preview_stabilization.py
+++ b/apps/CameraITS/tests/sensor_fusion/test_preview_stabilization.py
@@ -20,9 +20,9 @@ import time
from mobly import test_runner
+import its_base_test
import camera_properties_utils
import image_processing_utils
-import its_base_test
import its_session_utils
import sensor_fusion_utils
import video_processing_utils
@@ -33,11 +33,11 @@ _ARDUINO_SERVO_SPEED = 10
_IMG_FORMAT = 'png'
_MIN_PHONE_MOVEMENT_ANGLE = 5 # degrees
_NAME = os.path.splitext(os.path.basename(__file__))[0]
-_NUM_ROTATIONS = 25
+_NUM_ROTATIONS = 12
_START_FRAME = 30 # give 3A some frames to warm up
_VIDEO_DELAY_TIME = 5.5 # seconds
_VIDEO_DURATION = 5.5 # seconds
-_VIDEO_STABILIZATION_FACTOR = 0.6 # 60% of gyro movement allowed
+_VIDEO_STABILIZATION_FACTOR = 0.7 # 70% of gyro movement allowed
_PREVIEW_STABILIZATION_MODE_PREVIEW = 2
@@ -86,7 +86,7 @@ def _collect_data(cam, video_size, rot_rig):
return recording_obj
-class PreviewStabilityTest(its_base_test.ItsBaseTest):
+class PreviewStabilizationTest(its_base_test.ItsBaseTest):
"""Tests if preview is stabilized.
Camera is moved in sensor fusion rig on an arc of 15 degrees.
@@ -115,7 +115,7 @@ class PreviewStabilityTest(its_base_test.ItsBaseTest):
camera_properties_utils.skip_unless(
first_api_level >= its_session_utils.ANDROID13_API_LEVEL,
'First API level should be {} or higher. Found {}.'.format(
- its_session_utils.ANDROID13_API_LEVEL, first_api_level))
+ its_session_utils.ANDROID13_API_LEVEL, first_api_level))
supported_stabilization_modes = props[
'android.control.availableVideoStabilizationModes'
@@ -124,7 +124,7 @@ class PreviewStabilityTest(its_base_test.ItsBaseTest):
camera_properties_utils.skip_unless(
supported_stabilization_modes is not None
and _PREVIEW_STABILIZATION_MODE_PREVIEW
- in supported_stabilization_modes,
+ in supported_stabilization_modes,
'Preview Stabilization not supported',
)
@@ -137,9 +137,12 @@ class PreviewStabilityTest(its_base_test.ItsBaseTest):
# Initialize rotation rig
rot_rig['cntl'] = self.rotator_cntl
rot_rig['ch'] = self.rotator_ch
+ if rot_rig['cntl'].lower() != 'arduino':
+ raise AssertionError(f'You must use the arduino controller for {_NAME}.')
# List of video resolutions to test
supported_preview_sizes = cam.get_supported_preview_sizes(self.camera_id)
+ supported_preview_sizes.remove(video_processing_utils.QCIF_SIZE)
logging.debug('Supported preview resolutions: %s',
supported_preview_sizes)
@@ -201,10 +204,9 @@ class PreviewStabilityTest(its_base_test.ItsBaseTest):
sensor_fusion_utils.calc_max_rotation_angle(gyro_rots, 'Gyro')
)
logging.debug(
- 'Max deflection (degrees): gyro: %.2f, camera: %.2f',
- max_gyro_angles[-1],
- max_camera_angles[-1],
- )
+ 'Max deflection (degrees) %s: video: %.3f, gyro: %.3f ratio: %.4f',
+ video_size, max_camera_angles[-1], max_gyro_angles[-1],
+ max_camera_angles[-1] / max_gyro_angles[-1])
# Assert phone is moved enough during test
if max_gyro_angles[-1] < _MIN_PHONE_MOVEMENT_ANGLE:
@@ -218,9 +220,10 @@ class PreviewStabilityTest(its_base_test.ItsBaseTest):
if max_camera_angle >= max_gyro_angles[i] * _VIDEO_STABILIZATION_FACTOR:
test_failures.append(
f'{supported_preview_sizes[i]} video not stabilized enough! '
- f'Max gyro angle: {max_gyro_angles[i]:.2f}, Max camera angle: '
- f'{max_camera_angle:.2f}, stabilization factor THRESH: '
- f'{_VIDEO_STABILIZATION_FACTOR}.')
+ f'Max video angle: {max_camera_angle:.3f}, '
+ f'Max gyro angle: {max_gyro_angles[i]:.3f}, '
+ f'ratio: {max_camera_angle/max_gyro_angles[i]:.4f} '
+ f'THRESH: {_VIDEO_STABILIZATION_FACTOR}.')
if test_failures:
raise AssertionError(test_failures)
diff --git a/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py b/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
index e6eec9fa48a..193993524de 100644
--- a/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
+++ b/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
@@ -337,7 +337,7 @@ class SensorFusionTest(its_base_test.ItsBaseTest):
" smaller values of 'w', 'h', 'fps', or 'test_length'.")
if replay:
- events, frames, _, h = load_data()
+ events, frames, _, _ = load_data()
else:
with its_session_utils.ItsSession(
device_id=self.dut.serial,
diff --git a/apps/CameraITS/tests/sensor_fusion/test_video_stabilization.py b/apps/CameraITS/tests/sensor_fusion/test_video_stabilization.py
index 3a71fda4c32..0be38b56d11 100644
--- a/apps/CameraITS/tests/sensor_fusion/test_video_stabilization.py
+++ b/apps/CameraITS/tests/sensor_fusion/test_video_stabilization.py
@@ -22,9 +22,9 @@ import time
from mobly import test_runner
import numpy as np
+import its_base_test
import camera_properties_utils
import image_processing_utils
-import its_base_test
import its_session_utils
import sensor_fusion_utils
import video_processing_utils
@@ -35,7 +35,7 @@ _ARDUINO_SERVO_SPEED = 10
_IMG_FORMAT = 'png'
_MIN_PHONE_MOVEMENT_ANGLE = 5 # degrees
_NAME = os.path.splitext(os.path.basename(__file__))[0]
-_NUM_ROTATIONS = 25
+_NUM_ROTATIONS = 12
_RADS_TO_DEGS = 180/math.pi
_SEC_TO_NSEC = 1E9
_START_FRAME = 30 # give 3A 1s to warm up
@@ -115,7 +115,7 @@ def _collect_data(cam, video_profile, video_quality, rot_rig):
return recording_obj
-class VideoStabilityTest(its_base_test.ItsBaseTest):
+class VideoStabilizationTest(its_base_test.ItsBaseTest):
"""Tests if video is stabilized.
Camera is moved in sensor fusion rig on an arc of 15 degrees.
@@ -156,6 +156,8 @@ class VideoStabilityTest(its_base_test.ItsBaseTest):
# Initialize rotation rig
rot_rig['cntl'] = self.rotator_cntl
rot_rig['ch'] = self.rotator_ch
+ if rot_rig['cntl'].lower() != 'arduino':
+ raise AssertionError(f'You must use the arduino controller for {_NAME}.')
# Create list of video qualities to test
supported_video_qualities = cam.get_supported_video_qualities(
@@ -220,8 +222,10 @@ class VideoStabilityTest(its_base_test.ItsBaseTest):
gyro_rots = _conv_acceleration_to_movement(gyro_events)
max_gyro_angles.append(sensor_fusion_utils.calc_max_rotation_angle(
gyro_rots, 'Gyro'))
- logging.debug('Max deflection (degrees): gyro: %.2f, camera: %.2f',
- max_gyro_angles[-1], max_camera_angles[-1])
+ logging.debug(
+ 'Max deflection (degrees) %s: video: %.3f, gyro: %.3f, ratio: %.4f',
+ video_quality, max_camera_angles[-1], max_gyro_angles[-1],
+ max_camera_angles[-1] / max_gyro_angles[-1])
# Assert phone is moved enough during test
if max_gyro_angles[-1] < _MIN_PHONE_MOVEMENT_ANGLE:
@@ -235,9 +239,10 @@ class VideoStabilityTest(its_base_test.ItsBaseTest):
if max_camera_angle >= max_gyro_angles[i] * _VIDEO_STABILIZATION_FACTOR:
test_failures.append(
f'{tested_video_qualities[i]} video not stabilized enough! '
- f'Max gyro angle: {max_gyro_angles[i]:.2f}, Max camera angle: '
- f'{max_camera_angle:.2f}, stabilization factor THRESH: '
- f'{_VIDEO_STABILIZATION_FACTOR}.')
+ f'Max video angle: {max_camera_angle:.3f}, '
+ f'Max gyro angle: {max_gyro_angles[i]:.3f}, '
+ f'ratio: {max_camera_angle}/{max_gyro_angles[-1]:.3f}, '
+ f'THRESH: {_VIDEO_STABILIZATION_FACTOR}.')
if test_failures:
raise AssertionError(test_failures)
diff --git a/apps/CameraITS/utils/image_processing_utils.py b/apps/CameraITS/utils/image_processing_utils.py
index d0bf08e5e6e..19d76c3fa88 100644
--- a/apps/CameraITS/utils/image_processing_utils.py
+++ b/apps/CameraITS/utils/image_processing_utils.py
@@ -137,7 +137,7 @@ def unpack_raw10_image(img):
# Cut out the 4x2b LSBs and put each in bits [1:0] of their own 8b words.
lsbs = img[::, 4::5].reshape(h, w // 4)
lsbs = numpy.right_shift(
- numpy.packbits(numpy.unpackbits(lsbs).reshape(h, w // 4, 4, 2), 3), 6)
+ numpy.packbits(numpy.unpackbits(lsbs).reshape((h, w // 4, 4, 2)), 3), 6)
# Pair the LSB bits group to 0th pixel instead of 3rd pixel
lsbs = lsbs.reshape(h, w // 4, 4)[:, :, ::-1]
lsbs = lsbs.reshape(h, w)
@@ -190,7 +190,7 @@ def unpack_raw12_image(img):
# Cut out the 2x4b LSBs and put each in bits [3:0] of their own 8b words.
lsbs = img[::, 2::3].reshape(h, w // 2)
lsbs = numpy.right_shift(
- numpy.packbits(numpy.unpackbits(lsbs).reshape(h, w // 2, 2, 4), 3), 4)
+ numpy.packbits(numpy.unpackbits(lsbs).reshape((h, w // 2, 2, 4)), 3), 4)
# Pair the LSB bits group to pixel 0 instead of pixel 1
lsbs = lsbs.reshape(h, w // 2, 2)[:, :, ::-1]
lsbs = lsbs.reshape(h, w)
@@ -243,7 +243,7 @@ def decompress_jpeg_to_rgb_image(jpeg_buffer):
img = Image.open(io.BytesIO(jpeg_buffer))
w = img.size[0]
h = img.size[1]
- return numpy.array(img).reshape(h, w, 3) / 255.0
+ return numpy.array(img).reshape((h, w, 3)) / 255.0
def convert_image_to_numpy_array(image_path):
@@ -453,7 +453,7 @@ def convert_raw_to_rgb_image(r_plane, gr_plane, gb_plane, b_plane, props,
img = (((img.reshape(h, w, 3) - black_levels) * scale) * gains).clip(0.0, 1.0)
if apply_ccm_raw_to_rgb:
img = numpy.dot(
- img.reshape(w * h, 3), ccm.T).reshape(h, w, 3).clip(0.0, 1.0)
+ img.reshape(w * h, 3), ccm.T).reshape((h, w, 3)).clip(0.0, 1.0)
return img
@@ -938,7 +938,7 @@ class ImageProcessingUtilsTest(unittest.TestCase):
ref_image = [0.1, 0.2, 0.3]
lut_max = 65536
lut = numpy.array([i*2 for i in range(lut_max)])
- x = numpy.array(ref_image).reshape(1, 1, 3)
+ x = numpy.array(ref_image).reshape((1, 1, 3))
y = apply_lut_to_image(x, lut).reshape(3).tolist()
y_ref = [i*2 for i in ref_image]
self.assertTrue(numpy.allclose(y, y_ref, atol=1/lut_max))
diff --git a/apps/CameraITS/utils/its_session_utils.py b/apps/CameraITS/utils/its_session_utils.py
index 722f5860bdc..4a6cbf9af01 100644
--- a/apps/CameraITS/utils/its_session_utils.py
+++ b/apps/CameraITS/utils/its_session_utils.py
@@ -134,10 +134,10 @@ class ItsSession(object):
try:
socket_lock.bind((ItsSession.IPADDR, ItsSession.LOCK_PORT))
break
- except (socket.error, socket.timeout):
+ except (socket.error, socket.timeout) as socket_issue:
if i == num_retries - 1:
- raise error_util.CameraItsError(self._device_id,
- 'socket lock returns error')
+ raise error_util.CameraItsError(
+ self._device_id, 'socket lock returns error') from socket_issue
else:
time.sleep(retry_wait_time_sec)
@@ -545,8 +545,9 @@ class ItsSession(object):
VideoRecordingObject: {
'tag': 'recordingResponse',
'objValue': {
- 'recordedOutputPath': '/storage/emulated/0/Android/data/com.android.cts.verifier'
- '/files/VideoITS/VID_20220324_080414_0_CIF_352x288.mp4',
+ 'recordedOutputPath': '/storage/emulated/0/Android/data/'
+ 'com.android.cts.verifier/files/VideoITS/'
+ 'VID_20220324_080414_0_CIF_352x288.mp4',
'quality': 'preview',
'videoSize': '352x288'
}
@@ -1478,8 +1479,8 @@ def get_build_sdk_version(device_id):
try:
build_sdk_version = int(subprocess.check_output(cmd.split()).rstrip())
logging.debug('Build SDK version: %d', build_sdk_version)
- except (subprocess.CalledProcessError, ValueError):
- raise AssertionError('No build_sdk_version.')
+ except (subprocess.CalledProcessError, ValueError) as exp_errors:
+ raise AssertionError('No build_sdk_version.') from exp_errors
return build_sdk_version
diff --git a/apps/CameraITS/utils/sensor_fusion_utils.py b/apps/CameraITS/utils/sensor_fusion_utils.py
index 0f83af96cda..327b2333e52 100644
--- a/apps/CameraITS/utils/sensor_fusion_utils.py
+++ b/apps/CameraITS/utils/sensor_fusion_utils.py
@@ -146,8 +146,9 @@ def canakit_cmd_send(canakit_serial_port, cmd_str):
time.sleep(CANAKIT_CMD_TIME) # This is critical for relay.
canakit_serial_port.write(cmd_str.encode())
- except IOError:
- raise IOError(f'Port {CANAKIT_VID}:{CANAKIT_PID} is not open!')
+ except IOError as io_error:
+ raise IOError(
+ f'Port {CANAKIT_VID}:{CANAKIT_PID} is not open!') from io_error
def canakit_set_relay_channel_state(canakit_port, ch, state):
diff --git a/apps/CameraITS/utils/video_processing_utils.py b/apps/CameraITS/utils/video_processing_utils.py
index b82e6c557fb..98d930bc90b 100644
--- a/apps/CameraITS/utils/video_processing_utils.py
+++ b/apps/CameraITS/utils/video_processing_utils.py
@@ -33,6 +33,7 @@ ITS_SUPPORTED_QUALITIES = (
'LOW',
'VGA'
)
+QCIF_SIZE = '176x144'
def extract_key_frames_from_video(log_path, video_file_name):
@@ -83,7 +84,7 @@ def extract_key_frames_from_video(log_path, video_file_name):
logging.debug('Extracted key frames: %s', key_frame_files)
logging.debug('Length of key_frame_files: %d', len(key_frame_files))
- if not len(key_frame_files):
+ if not key_frame_files:
raise AssertionError('No key frames extracted. Check source video.')
return key_frame_files
@@ -142,7 +143,7 @@ def extract_all_frames_from_video(log_path, video_file_name, img_format):
file_list = sorted(
[_ for _ in os.listdir(log_path) if (_.endswith(img_format)
and ffmpeg_image_name in _)])
- if not len(file_list):
+ if not file_list:
raise AssertionError('No frames extracted. Check source video.')
return file_list
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 0b3e811b9fb..35afa207584 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -105,7 +105,9 @@
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />
<!-- Needed for Wi-Fi Direct tests from T -->
- <uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" />
+ <uses-permission
+ android:name="android.permission.NEARBY_WIFI_DEVICES"
+ android:usesPermissionFlags="neverForLocation" />
<!-- READ_LOGS User Consent Test from T -->
<uses-permission android:name="android.permission.READ_LOGS" />
diff --git a/apps/CtsVerifier/res/layout-port/camera_video.xml b/apps/CtsVerifier/res/layout-port/camera_video.xml
new file mode 100644
index 00000000000..2a90e67530a
--- /dev/null
+++ b/apps/CtsVerifier/res/layout-port/camera_video.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1" >
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="0dp"
+ android:layout_height="fill_parent"
+ android:layout_weight="2" >
+
+ <Spinner
+ android:id="@+id/cameras_selection"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"/>
+ <Spinner
+ android:id="@+id/resolution_selection"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"/>
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1" >
+
+ <Button
+ android:id="@+id/record_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/record_button_text"/>
+ <Button
+ android:id="@+id/next_button"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:text="@string/next_button_text" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="2" >
+
+ <TextView
+ android:id="@+id/status_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/status_ready"
+ android:padding="2dp"
+ android:textSize="16sp"
+ android:gravity="center" />
+ </LinearLayout>
+
+ </LinearLayout>
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1" >
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="0dp"
+ android:layout_height="fill_parent"
+ android:layout_weight="3"
+ android:gravity="center" >
+
+ <TextureView
+ android:id="@+id/video_capture"
+ android:layout_height="0dp"
+ android:layout_width="fill_parent"
+ android:layout_weight="3" />
+ <TextView
+ android:id="@+id/camera_video_capture_label"
+ android:layout_height="wrap_content"
+ android:layout_width="fill_parent"
+ android:text="@string/video_capture_label"
+ android:padding="2dp"
+ android:textSize="16sp"
+ android:gravity="center" />
+
+ </LinearLayout>
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="0dp"
+ android:layout_height="fill_parent"
+ android:layout_weight="3"
+ android:gravity="center" >
+
+ <VideoView
+ android:id="@+id/video_playback"
+ android:layout_height="0dp"
+ android:layout_width="fill_parent"
+ android:layout_weight="3" />
+ <TextView
+ android:id="@+id/camera_video_playback_label"
+ android:layout_height="wrap_content"
+ android:layout_width="fill_parent"
+ android:text="@string/video_playback_label"
+ android:padding="2dp"
+ android:textSize="16sp"
+ android:gravity="center" />
+
+ </LinearLayout>
+
+ </LinearLayout>
+
+ <include layout="@layout/pass_fail_buttons" />
+
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/audio_dev_notify.xml b/apps/CtsVerifier/res/layout/audio_dev_notify.xml
index e8f49ceaa93..6fa178df62a 100644
--- a/apps/CtsVerifier/res/layout/audio_dev_notify.xml
+++ b/apps/CtsVerifier/res/layout/audio_dev_notify.xml
@@ -38,6 +38,12 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
+ <Button
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:id="@+id/audio_dev_notification_connect_clearmsgs_btn"
+ android:text="@string/audio_dev_notification_clearmsgs"/>
+
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index fd5eab1e781..d595bef2e78 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -6590,6 +6590,11 @@ Follow the instructions on the screen to measure the frequency response for the
The Presence tests check whether or not a device is properly calibrated for BLE, NAN and UWB based on Presence requirements.
\nAll tests are required to pass on every device, if the radio technology is supported
</string>
+ <string name="presence_test_tv_info">
+ The Presence tests check whether or not a device is properly calibrated for BLE, NAN and UWB based on Presence requirements.
+ \nAll tests are required to pass on all Android T+ launched TV devices, if the radio technology is supported.
+ \nIf the TV device is launched on older Android letters, all tests will be disabled. Press Pass to pass this case.
+ </string>
<string name="uwb_precision">Uwb Precision Test</string>
<string name="uwb_short_range">Uwb Short Range Test</string>
<string name="uwb_precision_instruction">
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/Utils.java b/apps/CtsVerifier/src/com/android/cts/verifier/Utils.java
new file mode 100644
index 00000000000..b6071d87be1
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/Utils.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.verifier;
+
+import android.content.ComponentName;
+
+/**
+ * Provides common helper methods.
+ */
+public final class Utils {
+
+ /**
+ * Helper to get {@link #flattenToShortString()} in a {@link ComponentName} reference that can
+ * be {@code null}.
+ *
+ * @hide
+ */
+ public static String flattenToShortString(ComponentName componentName) {
+ return componentName == null ? null : componentName.flattenToShortString();
+ }
+
+ private Utils() {
+ throw new UnsupportedOperationException("contains only static methods");
+ }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioInputDeviceNotificationsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioInputDeviceNotificationsActivity.java
index a6709e786ad..9a5f314f07a 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioInputDeviceNotificationsActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioInputDeviceNotificationsActivity.java
@@ -81,6 +81,17 @@ public class AudioInputDeviceNotificationsActivity extends AudioWiredDeviceBaseA
mInfoView.setText(mContext.getResources().getString(
R.string.audio_devices_notification_instructions));
+ findViewById(R.id.audio_dev_notification_connect_clearmsgs_btn)
+ .setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ mConnectView.setText("");
+ mConnectReceived = false;
+ mDisconnectView.setText("");
+ mDisconnectReceived = false;
+ calculatePass();
+ }
+ });
+
AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
audioManager.registerAudioDeviceCallback(new TestAudioDeviceCallback(), null);
@@ -90,6 +101,8 @@ public class AudioInputDeviceNotificationsActivity extends AudioWiredDeviceBaseA
setInfoResources(R.string.audio_in_devices_notifications_test,
R.string.audio_in_devices_infotext, -1);
setPassFailButtonClickListeners();
+
+ calculatePass();
}
@Override
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioInputRoutingNotificationsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioInputRoutingNotificationsActivity.java
index 7399f33faeb..38d99b4b827 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioInputRoutingNotificationsActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioInputRoutingNotificationsActivity.java
@@ -129,6 +129,7 @@ public class AudioInputRoutingNotificationsActivity extends AudioWiredDeviceBase
AudioDeviceInfo routedDevice = audioRecord.getRoutedDevice();
CharSequence deviceName = routedDevice != null ? routedDevice.getProductName() : "none";
mConnectedPeripheralName = deviceName.toString();
+
int deviceType = routedDevice != null ? routedDevice.getType() : -1;
textView.setText(msg + " - " +
deviceName + " [0x" + Integer.toHexString(deviceType) + "]" +
@@ -156,8 +157,6 @@ public class AudioInputRoutingNotificationsActivity extends AudioWiredDeviceBase
R.id.audio_routingnotification_testresult)).setText(
"Test PASSES - No peripheral support");
}
-
- stopRecording();
}
protected void storeTestResults() {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioOutputDeviceNotificationsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioOutputDeviceNotificationsActivity.java
index c0f98d1c6b3..5fb51c4ebb0 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioOutputDeviceNotificationsActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioOutputDeviceNotificationsActivity.java
@@ -81,6 +81,17 @@ public class AudioOutputDeviceNotificationsActivity extends AudioWiredDeviceBase
mInfoView.setText(mContext.getResources().getString(
R.string.audio_devices_notification_instructions));
+ findViewById(R.id.audio_dev_notification_connect_clearmsgs_btn)
+ .setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ mConnectView.setText("");
+ mConnectReceived = false;
+ mDisconnectView.setText("");
+ mDisconnectReceived = false;
+ calculatePass();
+ }
+ });
+
AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
audioManager.registerAudioDeviceCallback(new TestAudioDeviceCallback(), null);
@@ -90,6 +101,8 @@ public class AudioOutputDeviceNotificationsActivity extends AudioWiredDeviceBase
setInfoResources(R.string.audio_out_devices_notifications_test,
R.string.audio_out_devices_infotext, -1);
setPassFailButtonClickListeners();
+
+ calculatePass();
}
@Override
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioOutputRoutingNotificationsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioOutputRoutingNotificationsActivity.java
index e23ee17f25d..591fe9b6bd4 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioOutputRoutingNotificationsActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioOutputRoutingNotificationsActivity.java
@@ -160,8 +160,6 @@ public class AudioOutputRoutingNotificationsActivity extends AudioWiredDeviceBas
R.id.audio_routingnotification_testresult)).setText(
"Test PASSES - No peripheral support");
}
-
- stopPlayback();
}
protected void storeTestResults() {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioWiredDeviceBaseActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioWiredDeviceBaseActivity.java
index 834839398e6..97813afe874 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioWiredDeviceBaseActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioWiredDeviceBaseActivity.java
@@ -35,7 +35,7 @@ abstract class AudioWiredDeviceBaseActivity extends PassFailButtons.Activity {
private Button mSupportsBtn;
private Button mDoesntSupportBtn;
- protected boolean mSupportsWiredPeripheral;
+ protected boolean mSupportsWiredPeripheral = true;
protected String mConnectedPeripheralName;
protected abstract void enableTestButtons(boolean enabled);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/fov/PhotoCaptureActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/fov/PhotoCaptureActivity.java
index 406a3051c5d..e27ae0a0f11 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/fov/PhotoCaptureActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/fov/PhotoCaptureActivity.java
@@ -23,6 +23,7 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
+import android.graphics.Matrix;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
@@ -183,8 +184,9 @@ public class PhotoCaptureActivity extends Activity
SelectableResolution resolution = mSupportedResolutions.get(position);
switchToCamera(resolution, false);
- // It should be guaranteed that the FOV is correctly updated after setParameters().
- mReportedFovPrePictureTaken = mCamera.getParameters().getHorizontalViewAngle();
+ // It should be guaranteed that the FOV is correctly updated after
+ // setParameters().
+ mReportedFovPrePictureTaken = getCameraFov(resolution.cameraId);
mResolutionSpinnerIndex = position;
startPreview();
@@ -271,8 +273,8 @@ public class PhotoCaptureActivity extends Activity
@Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getPictureFile(this);
- Camera.Parameters params = mCamera.getParameters();
- mReportedFovDegrees = params.getHorizontalViewAngle();
+
+ mReportedFovDegrees = getCameraFov(mSelectedResolution.cameraId);
// Show error if FOV does not match the value reported before takePicture().
if (mReportedFovPrePictureTaken != mReportedFovDegrees) {
@@ -436,6 +438,36 @@ public class PhotoCaptureActivity extends Activity
initializeCamera(true);
}
+ private void setPreviewTransform(Size previewSize) {
+ int sensorRotation = mPreviewOrientation;
+ float selectedPreviewAspectRatio;
+ if (sensorRotation == 0 || sensorRotation == 180) {
+ selectedPreviewAspectRatio = (float) previewSize.width
+ / (float) previewSize.height;
+ } else {
+ selectedPreviewAspectRatio = (float) previewSize.height
+ / (float) previewSize.width;
+ }
+
+ Matrix transform = new Matrix();
+ float viewAspectRatio = (float) mPreviewView.getMeasuredWidth()
+ / (float) mPreviewView.getMeasuredHeight();
+ float scaleX = 1.0f, scaleY = 1.0f;
+ float translateX = 0, translateY = 0;
+ if (selectedPreviewAspectRatio > viewAspectRatio) {
+ scaleY = viewAspectRatio / selectedPreviewAspectRatio;
+ translateY = (float) mPreviewView.getMeasuredHeight() / 2
+ - (float) mPreviewView.getMeasuredHeight() * scaleY / 2;
+ } else {
+ scaleX = selectedPreviewAspectRatio / viewAspectRatio;
+ translateX = (float) mPreviewView.getMeasuredWidth() / 2
+ - (float) mPreviewView.getMeasuredWidth() * scaleX / 2;
+ }
+ transform.postScale(scaleX, scaleY);
+ transform.postTranslate(translateX, translateY);
+ mPreviewView.setTransform(transform);
+ }
+
private void initializeCamera(boolean startPreviewAfterInit) {
if (mCamera == null || mPreviewTexture == null) {
return;
@@ -470,6 +502,7 @@ public class PhotoCaptureActivity extends Activity
if (selectedPreviewSize != null) {
params.setPreviewSize(selectedPreviewSize.width, selectedPreviewSize.height);
mCamera.setParameters(params);
+ setPreviewTransform(selectedPreviewSize);
mCameraInitialized = true;
}
@@ -561,21 +594,25 @@ public class PhotoCaptureActivity extends Activity
return result;
}
+ private int getDisplayRotation() {
+ int displayRotation = getDisplay().getRotation();
+ int displayRotationDegrees = 0;
+ switch (displayRotation) {
+ case Surface.ROTATION_0: displayRotationDegrees = 0; break;
+ case Surface.ROTATION_90: displayRotationDegrees = 90; break;
+ case Surface.ROTATION_180: displayRotationDegrees = 180; break;
+ case Surface.ROTATION_270: displayRotationDegrees = 270; break;
+ }
+ return displayRotationDegrees;
+ }
+
private void calculateOrientations(Activity activity,
int cameraId, android.hardware.Camera camera) {
android.hardware.Camera.CameraInfo info =
new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
- int rotation = activity.getWindowManager().getDefaultDisplay()
- .getRotation();
- int degrees = 0;
- switch (rotation) {
- case Surface.ROTATION_0: degrees = 0; break;
- case Surface.ROTATION_90: degrees = 90; break;
- case Surface.ROTATION_180: degrees = 180; break;
- case Surface.ROTATION_270: degrees = 270; break;
- }
+ int degrees = getDisplayRotation();
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
mJpegOrientation = (info.orientation + degrees) % 360;
mPreviewOrientation = (360 - mJpegOrientation) % 360; // compensate the mirror
@@ -603,4 +640,12 @@ public class PhotoCaptureActivity extends Activity
}
return false;
}
+
+ private float getCameraFov(int cameraId) {
+ if (mPreviewOrientation == 0 || mPreviewOrientation == 180) {
+ return mCamera.getParameters().getHorizontalViewAngle();
+ } else {
+ return mCamera.getParameters().getVerticalViewAngle();
+ }
+ }
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java
index 5706610df0b..ef66b533a0e 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java
@@ -20,6 +20,8 @@ import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_HOME;
import static android.app.admin.DevicePolicyManager.MAKE_USER_EPHEMERAL;
import static android.app.admin.DevicePolicyManager.SKIP_SETUP_WIZARD;
+import static com.android.cts.verifier.Utils.flattenToShortString;
+
import android.Manifest;
import android.app.Activity;
import android.app.ActivityManager;
@@ -262,9 +264,9 @@ public class CommandReceiverActivity extends Activity {
} break;
case COMMAND_SET_STATUSBAR_DISABLED: {
boolean enforced = intent.getBooleanExtra(EXTRA_ENFORCED, false);
- Log.d(TAG, "calling setStatusBarDisabled("
- + ComponentName.flattenToShortString(mAdmin) + ", " + enforced
- + ") using " + mDpm + " on user " + UserHandle.myUserId());
+ Log.d(TAG, "calling setStatusBarDisabled(" + flattenToShortString(mAdmin)
+ + ", " + enforced + ") using " + mDpm + " on user "
+ + UserHandle.myUserId());
mDpm.setStatusBarDisabled(mAdmin, enforced);
} break;
case COMMAND_SET_LOCK_TASK_FEATURES: {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/PresenceTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/presence/PresenceTestActivity.java
index e8a0cccfdab..67766931591 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/presence/PresenceTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/presence/PresenceTestActivity.java
@@ -16,12 +16,18 @@
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
@@ -29,8 +35,26 @@ public class PresenceTestActivity extends PassFailButtons.TestListActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.pass_fail_list);
setPassFailButtonClickListeners();
- setInfoResources(R.string.presence_test, R.string.presence_test_info, -1);
- setTestListAdapter(
- new ManifestTestListAdapter(this, PresenceTestActivity.class.getName()));
+
+ 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/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/InputDeviceInfo.kt b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/InputDeviceInfo.kt
index 2d109ba7a02..a3e391d231a 100644
--- a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/InputDeviceInfo.kt
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/InputDeviceInfo.kt
@@ -16,9 +16,7 @@
package com.android.compatibility.common.deviceinfo
import android.content.Context
-
import androidx.test.core.app.ApplicationProvider
-
import com.android.compatibility.common.util.DeviceConfigStateManager
import com.android.compatibility.common.util.DeviceInfoStore
@@ -35,10 +33,11 @@ public final class InputDeviceInfo : DeviceInfo() {
collectInputInfo(store, "input")
}
- private fun readDeviceConfig(namespace: String, name: String): String {
+ private fun readDeviceConfig(namespace: String, name: String, default: String): String {
val context: Context = ApplicationProvider.getApplicationContext()
val stateManager = DeviceConfigStateManager(context, namespace, name)
- return stateManager.get()!!
+ val value = stateManager.get()
+ return if (value != null) value else default
}
/**
@@ -47,10 +46,15 @@ public final class InputDeviceInfo : DeviceInfo() {
private fun collectInputInfo(store: DeviceInfoStore, groupName: String) {
store.startGroup(groupName)
- val palmRejectionValue = readDeviceConfig("input_native_boot", "palm_rejection_enabled")
+ val palmRejectionValue = readDeviceConfig("input_native_boot", "palm_rejection_enabled", "")
val palmRejectionEnabled = palmRejectionValue == "1" || palmRejectionValue == "true"
store.addResult("palm_rejection_enabled", palmRejectionEnabled)
+ val velocityTrackerStrategyValue = readDeviceConfig(
+ "input_native_boot", "velocitytracker_strategy", "default"
+ )
+ store.addResult("velocitytracker_strategy", velocityTrackerStrategyValue)
+
store.endGroup()
}
}
diff --git a/hostsidetests/compilation/src/android/compilation/cts/BackgroundDexOptimizationTest.java b/hostsidetests/compilation/src/android/compilation/cts/BackgroundDexOptimizationTest.java
index e7d954fa23a..9affccb9e35 100644
--- a/hostsidetests/compilation/src/android/compilation/cts/BackgroundDexOptimizationTest.java
+++ b/hostsidetests/compilation/src/android/compilation/cts/BackgroundDexOptimizationTest.java
@@ -82,6 +82,8 @@ public final class BackgroundDexOptimizationTest extends BaseHostJUnit4Test {
// Uses internal consts defined in BackgroundDexOptService only for testing purpose.
private static final int STATUS_OK = 0;
private static final int STATUS_CANCELLED = 1;
+ // We allow package level failure in dexopt, which will lead into this error state.
+ private static final int STATUS_DEX_OPT_FAILED = 5;
private ITestDevice mDevice;
@@ -124,7 +126,7 @@ public final class BackgroundDexOptimizationTest extends BaseHostJUnit4Test {
() -> getLastExecutionTime().duration >= 0);
int status = getLastDexOptStatus();
- assertThat(status).isAnyOf(STATUS_OK, STATUS_CANCELLED);
+ assertThat(status).isAnyOf(STATUS_OK, STATUS_DEX_OPT_FAILED, STATUS_CANCELLED);
if (status == STATUS_CANCELLED) {
assertThat(checkFinishedPostBootUpdate()).isFalse();
// If cancelled, we can complete it by running it again.
@@ -177,7 +179,7 @@ public final class BackgroundDexOptimizationTest extends BaseHostJUnit4Test {
() -> getLastExecutionTime().duration >= 0);
int status = getLastDexOptStatus();
- assertThat(status).isAnyOf(STATUS_OK, STATUS_CANCELLED);
+ assertThat(status).isAnyOf(STATUS_OK, STATUS_DEX_OPT_FAILED, STATUS_CANCELLED);
if (status == STATUS_CANCELLED) {
// If cancelled, we can complete it by running it again.
completeIdleOptimization();
@@ -204,7 +206,7 @@ public final class BackgroundDexOptimizationTest extends BaseHostJUnit4Test {
assertThat(timeAfter.startTime).isAtLeast(timeBefore.deviceCurrentTime);
assertThat(timeAfter.duration).isAtLeast(0);
int status = getLastDexOptStatus();
- assertThat(status).isEqualTo(STATUS_OK);
+ assertThat(status).isAnyOf(STATUS_OK, STATUS_DEX_OPT_FAILED);
}
private void completeIdleOptimization() throws Exception {
@@ -220,7 +222,7 @@ public final class BackgroundDexOptimizationTest extends BaseHostJUnit4Test {
});
int status = getLastDexOptStatus();
- assertThat(status).isEqualTo(STATUS_OK);
+ assertThat(status).isAnyOf(STATUS_OK, STATUS_DEX_OPT_FAILED);
}
@After
diff --git a/hostsidetests/cpptools/Android.bp b/hostsidetests/cpptools/Android.bp
index 90bf3a75ea2..f2a9ee5ec69 100644
--- a/hostsidetests/cpptools/Android.bp
+++ b/hostsidetests/cpptools/Android.bp
@@ -29,4 +29,10 @@ java_test_host {
"cts",
"general-tests",
],
+ data: [
+ ":CtsCppToolsApp",
+ ":CtsDomainSocket",
+ ],
+ data_device_bins_both: ["connector"],
+ per_testcase_directory: true,
}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
index 0d0bd8f899a..c87a7f8d7f4 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
@@ -32,6 +32,7 @@ import android.stats.devicepolicy.EventId;
import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
import com.android.cts.devicepolicy.DeviceAdminFeaturesCheckerRule.RequiresAdditionalFeatures;
+import com.android.cts.devicepolicy.DeviceAdminFeaturesCheckerRule.TemporarilyIgnoreOnHeadlessSystemUserMode;
import com.android.cts.devicepolicy.metrics.DevicePolicyEventWrapper;
import com.android.tradefed.log.LogUtil.CLog;
@@ -342,6 +343,8 @@ public class DeviceOwnerTest extends BaseDeviceOwnerTest {
executeCreateAndManageUserTest("testCreateAndManageUser_RemoveRestrictionSet");
}
+ @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "220386262",
+ reason = "Often fails on automotive due to race condition")
@Test
public void testCreateAndManageUser_newUserDisclaimer() throws Exception {
assumeCanStartNewUser();
diff --git a/hostsidetests/graphics/gpuprofiling/Android.bp b/hostsidetests/graphics/gpuprofiling/Android.bp
index ff441bc21ac..b57dc9dd7e3 100644
--- a/hostsidetests/graphics/gpuprofiling/Android.bp
+++ b/hostsidetests/graphics/gpuprofiling/Android.bp
@@ -30,4 +30,9 @@ java_test_host {
"perfetto_config-full",
"platform-test-annotations-host",
],
+ data: [
+ ":CtsGraphicsProfilingDataApp",
+ ],
+ data_device_bins_both: ["ctsgraphicsgpucountersinit"],
+ per_testcase_directory: true,
}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2022-20147/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2022-20147/Android.bp
new file mode 100644
index 00000000000..62741e711c5
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2022-20147/Android.bp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+ name: "CVE-2022-20147",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ compile_multilib: "64",
+ shared_libs: [
+ "libnfc-nci",
+ ],
+ include_dirs: [
+ "system/nfc/src/nfa/include/",
+ "system/nfc/src/nfc/include/",
+ "system/nfc/src/include/",
+ "system/nfc/src/gki/common/",
+ "system/nfc/src/gki/ulinux/",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ "-DENABLE_SELECTIVE_OVERLOADING",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2022-20147/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2022-20147/poc.cpp
new file mode 100644
index 00000000000..3d114e2592c
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2022-20147/poc.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "../includes/common.h"
+#include "../includes/memutils.h"
+
+#include <nfa_dm_int.h>
+#include <rw_int.h>
+#include <unistd.h>
+
+constexpr size_t kBufferSize = 2;
+constexpr size_t kLengthVal = 0x30;
+char enable_selective_overload = ENABLE_NONE;
+bool testInProgress = false;
+
+struct sigaction new_action, old_action;
+
+void sigsegv_handler(int signum, siginfo_t *info, void *context) {
+ if (testInProgress && info->si_signo == SIGSEGV) {
+ (*old_action.sa_sigaction)(signum, info, context);
+ return;
+ }
+ _exit(EXIT_FAILURE);
+}
+
+void poc_cback(tRW_EVENT, tRW_DATA*) {
+}
+
+int main() {
+ sigemptyset(&new_action.sa_mask);
+ new_action.sa_flags = SA_SIGINFO;
+ new_action.sa_sigaction = sigsegv_handler;
+ sigaction(SIGSEGV, &new_action, &old_action);
+
+ tNFC_ACTIVATE_DEVT p_activate_params = { };
+ p_activate_params.protocol = NFC_PROTOCOL_ISO_DEP;
+ p_activate_params.rf_tech_param.mode = NFC_DISCOVERY_TYPE_POLL_A;
+ RW_SetActivatedTagType(&p_activate_params, &poc_cback);
+ FAIL_CHECK(rw_cb.p_cback == &poc_cback);
+
+ enable_selective_overload = ENABLE_ALL;
+ uint8_t *buffer = (uint8_t *)malloc(kBufferSize * sizeof(uint8_t));
+ FAIL_CHECK(buffer);
+ buffer[0] = NFC_PMID_ATR_RES_GEN_BYTES;
+ buffer[1] = kLengthVal;
+
+ testInProgress = true;
+ nfa_dm_check_set_config(kBufferSize, buffer, false);
+ enable_selective_overload = ENABLE_FREE_CHECK | ENABLE_REALLOC_CHECK;
+ testInProgress = false;
+
+ free(buffer);
+
+ return EXIT_SUCCESS;
+}
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 b2ed808c2f5..5532e4602a4 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0954.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0954.java
@@ -53,6 +53,6 @@ public class CVE_2021_0954 extends BaseHostJUnit4Test {
installPackage(TEST_APP);
AdbUtils.runCommandLine("pm grant " + TEST_PKG + " android.permission.SYSTEM_ALERT_WINDOW",
device);
- Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, "testVulnerableActivityPresence"));
+ runDeviceTests(TEST_PKG, TEST_CLASS, "testVulnerableActivityPresence");
}
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20147.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20147.java
new file mode 100644
index 00000000000..41a727f857e
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20147.java
@@ -0,0 +1,63 @@
+/*
+ * 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.compatibility.common.util.CrashUtils;
+import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import java.util.regex.Pattern;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2022_20147 extends SecurityTestCase {
+ /**
+ * b/221216105
+ * Vulnerability Behaviour: SIGSEGV in self
+ * Vulnerable Library: libnfc-nci (As per AOSP code)
+ * Vulnerable Function: nfa_dm_check_set_config (As per AOSP code)
+ */
+ @AsbSecurityTest(cveBugId = 221216105)
+ @Test
+ public void testPocCVE_2022_20147() {
+ try {
+ AdbUtils.assumeHasNfc(getDevice());
+ assumeIsSupportedNfcDevice(getDevice());
+ pocPusher.only64();
+ String signals[] = { CrashUtils.SIGSEGV };
+ String binaryName = "CVE-2022-20147";
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName,
+ getDevice());
+ testConfig.config = new CrashUtils.Config()
+ .setProcessPatterns(Pattern.compile(binaryName))
+ .setBacktraceIncludes(new BacktraceFilterPattern(
+ "libnfc-nci", "nfa_dm_check_set_config"));
+ testConfig.config.setBacktraceExcludes(
+ new BacktraceFilterPattern("libdl", "__cfi_slowpath"));
+ testConfig.config.setSignals(signals);
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java b/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
index 06cf21a7068..c4d37b0ecb5 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
@@ -238,7 +238,7 @@ public class TestMedia extends SecurityTestCase {
@Test
@AsbSecurityTest(cveBugId = 36104177)
public void testPocCVE_2017_0670() throws Exception {
- AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2017-0670", null, getDevice());
+ AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2017-0670", getDevice(), 60);
}
/**
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 6e36fb32b79..f98690625e9 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
@@ -20,7 +20,9 @@ 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.Assume.assumeNoException;
+import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.provider.Settings;
@@ -70,7 +72,11 @@ public class DeviceTest {
Intent intent = new Intent();
intent.setClassName(TEST_VULNERABLE_PKG, TEST_VULNERABLE_ACTIVITY);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- context.startActivity(intent);
+ try {
+ context.startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ assumeNoException("Activity not found on device", e);
+ }
}
@Before
diff --git a/hostsidetests/statsdatom/src/android/cts/statsdatom/appcompatstate/AppCompatStateStatsTests.java b/hostsidetests/statsdatom/src/android/cts/statsdatom/appcompatstate/AppCompatStateStatsTests.java
index e192e72c5d7..9648d8cd4f9 100644
--- a/hostsidetests/statsdatom/src/android/cts/statsdatom/appcompatstate/AppCompatStateStatsTests.java
+++ b/hostsidetests/statsdatom/src/android/cts/statsdatom/appcompatstate/AppCompatStateStatsTests.java
@@ -183,8 +183,9 @@ public class AppCompatStateStatsTests extends DeviceTestCase implements IBuildRe
private void testAppCompatFlow(String activity, @Nullable String secondActivity,
boolean switchToOpened, List<AppCompatStateChanged.State>... expectedStatesOptions)
throws Exception {
- if (!isOpenedDeviceStateAvailable()) {
- CLog.i("Device doesn't support OPENED device state.");
+ if (!isDeviceStateAvailable(DEVICE_STATE_OPENED)
+ || !isDeviceStateAvailable(DEVICE_STATE_CLOSED)) {
+ CLog.i("Device doesn't support OPENED or CLOSED device states.");
return;
}
@@ -238,10 +239,10 @@ public class AppCompatStateStatsTests extends DeviceTestCase implements IBuildRe
return result;
}
- private boolean isOpenedDeviceStateAvailable() throws Exception {
+ private boolean isDeviceStateAvailable(int state) throws Exception {
return Arrays.stream(
getDevice().executeShellCommand(CMD_GET_AVAILABLE_DEVICE_STATES).split(","))
.map(Integer::valueOf)
- .anyMatch(state -> state == DEVICE_STATE_OPENED);
+ .anyMatch(availableState -> availableState == state);
}
-} \ No newline at end of file
+}
diff --git a/hostsidetests/statsdatom/src/android/cts/statsdatom/appops/AppOpsTests.java b/hostsidetests/statsdatom/src/android/cts/statsdatom/appops/AppOpsTests.java
index c7feda651c3..f07f9d34e64 100644
--- a/hostsidetests/statsdatom/src/android/cts/statsdatom/appops/AppOpsTests.java
+++ b/hostsidetests/statsdatom/src/android/cts/statsdatom/appops/AppOpsTests.java
@@ -61,12 +61,13 @@ public class AppOpsTests extends DeviceTestCase implements IBuildReceiver {
protected void setUp() throws Exception {
super.setUp();
- mTransformedFromOp.clear();
- // The hotword op is allowed to all UIDs on TV and Auto devices.
- if (!(DeviceUtils.hasFeature(getDevice(), FEATURE_AUTOMOTIVE)
- || DeviceUtils.hasFeature(getDevice(), FEATURE_LEANBACK_ONLY))) {
- mTransformedFromOp.put(APP_OP_RECORD_AUDIO, APP_OP_RECORD_AUDIO_HOTWORD);
- }
+ // Temporarily commented out until the Trusted Hotword requirement is enforced again.
+ // mTransformedFromOp.clear();
+ // // The hotword op is allowed to all UIDs on TV and Auto devices.
+ // if (!(DeviceUtils.hasFeature(getDevice(), FEATURE_AUTOMOTIVE)
+ // || DeviceUtils.hasFeature(getDevice(), FEATURE_LEANBACK_ONLY))) {
+ // mTransformedFromOp.put(APP_OP_RECORD_AUDIO, APP_OP_RECORD_AUDIO_HOTWORD);
+ // }
assertThat(mCtsBuild).isNotNull();
ConfigUtils.removeConfig(getDevice());
diff --git a/hostsidetests/statsdatom/src/android/cts/statsdatom/sizecompatrestartbutton/SizeCompatRestartButtonStatsTests.java b/hostsidetests/statsdatom/src/android/cts/statsdatom/sizecompatrestartbutton/SizeCompatRestartButtonStatsTests.java
index b797e687cd7..a6aaebf9916 100644
--- a/hostsidetests/statsdatom/src/android/cts/statsdatom/sizecompatrestartbutton/SizeCompatRestartButtonStatsTests.java
+++ b/hostsidetests/statsdatom/src/android/cts/statsdatom/sizecompatrestartbutton/SizeCompatRestartButtonStatsTests.java
@@ -98,8 +98,9 @@ public class SizeCompatRestartButtonStatsTests extends DeviceTestCase implements
}
public void testSizeCompatRestartButtonAppearedButNotClicked() throws Exception {
- if (!isOpenedDeviceStateAvailable()) {
- CLog.i("Device doesn't support OPENED device state.");
+ if (!isDeviceStateAvailable(DEVICE_STATE_OPENED)
+ || !isDeviceStateAvailable(DEVICE_STATE_CLOSED)) {
+ CLog.i("Device doesn't support OPENED or CLOSED device states.");
return;
}
@@ -120,11 +121,10 @@ public class SizeCompatRestartButtonStatsTests extends DeviceTestCase implements
assertThat(atom.getEvent()).isEqualTo(Event.APPEARED);
}
- private boolean isOpenedDeviceStateAvailable() throws Exception {
+ private boolean isDeviceStateAvailable(int state) throws Exception {
return Arrays.stream(
getDevice().executeShellCommand(CMD_GET_AVAILABLE_DEVICE_STATES).split(","))
.map(Integer::valueOf)
- .anyMatch(state -> state == DEVICE_STATE_OPENED);
+ .anyMatch(availableState -> availableState == state);
}
}
-
diff --git a/hostsidetests/sustainedperf/Android.bp b/hostsidetests/sustainedperf/Android.bp
index 4d887e13ef6..97e101f239c 100644
--- a/hostsidetests/sustainedperf/Android.bp
+++ b/hostsidetests/sustainedperf/Android.bp
@@ -30,4 +30,10 @@ java_test_host {
"tradefed",
"compatibility-host-util",
],
+ data: [
+ ":CtsSustainedPerformanceDeviceTestApp",
+ ":CtsSustainedPerformanceTestCases",
+ ],
+ data_device_bins_both: ["dhry"],
+ per_testcase_directory: true,
}
diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagerTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagerTest.java
index 7507d0abb7d..11b5fd40842 100644
--- a/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagerTest.java
+++ b/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagerTest.java
@@ -1177,6 +1177,7 @@ public final class DevicePolicyManagerTest {
@Test
@EnsureHasPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS)
@RequireDoesNotHaveFeature(FEATURE_MANAGED_USERS)
+ @RequireFeature(FEATURE_DEVICE_ADMIN)
public void checkProvisioningPreCondition_actionPO_withoutManagedUserFeature_returnsManagedUsersNotSupported() {
assertThat(
sDevicePolicyManager.checkProvisioningPrecondition(
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/ActivityTransitionTests.java b/tests/framework/base/windowmanager/src/android/server/wm/ActivityTransitionTests.java
index 31bb8bf7f49..7e87fb40134 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/ActivityTransitionTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/ActivityTransitionTests.java
@@ -304,7 +304,7 @@ public class ActivityTransitionTests extends ActivityManagerTestBase {
EdgeExtensionActivity.class, extras);
final Rect appBounds = getTopAppBounds();
assertColorChangeXIndex(screenshots,
- (appBounds.left + appBounds.right) / 4 * 3, testBounds);
+ appBounds.left + (appBounds.right - appBounds.left) * 3 / 4, testBounds);
}
/**
@@ -355,7 +355,7 @@ public class ActivityTransitionTests extends ActivityManagerTestBase {
EdgeExtensionActivity.class, extras);
final Rect appBounds = getTopAppBounds();
assertColorChangeXIndex(screenshots,
- (appBounds.left + appBounds.right) / 4, testBounds);
+ appBounds.left + (appBounds.right - appBounds.left) / 4, testBounds);
}
/**
@@ -422,9 +422,7 @@ public class ActivityTransitionTests extends ActivityManagerTestBase {
boolean isTransitioning;
do {
getWmState().computeState();
- isTransitioning =
- getWmState().getDefaultDisplayLastTransition().equals("TRANSIT_ACTIVITY_OPEN")
- && getWmState().getDefaultDisplayAppTransitionState()
+ isTransitioning = getWmState().getDefaultDisplayAppTransitionState()
.equals("APP_STATE_RUNNING");
SystemClock.sleep(10);
} while (!isTransitioning);
@@ -530,11 +528,15 @@ public class ActivityTransitionTests extends ActivityManagerTestBase {
}
private boolean arrayEquals(float[] array1, float[] array2) {
+ return arrayEquals(array1, array2, COLOR_VALUE_VARIANCE_TOLERANCE);
+ }
+
+ private boolean arrayEquals(float[] array1, float[] array2, float varianceTolerance) {
if (array1.length != array2.length) {
return true;
}
for (int i = 0; i < array1.length; i++) {
- if (Math.abs(array1[i] - array2[i]) > COLOR_VALUE_VARIANCE_TOLERANCE) {
+ if (Math.abs(array1[i] - array2[i]) > varianceTolerance) {
return true;
}
}
@@ -593,13 +595,6 @@ public class ActivityTransitionTests extends ActivityManagerTestBase {
private AssertionResult assertColorChangeXIndex(Bitmap screen, int xIndex,
TestBounds testBounds) {
- final int colorChangeXIndex = getColorChangeXIndex(screen);
-
- if (xIndex != colorChangeXIndex) {
- return new AssertionResult(true, "Expected color to change at x index " + xIndex
- + " instead of " + colorChangeXIndex);
- }
-
// The activity we are extending is a half red, half blue.
// We are scaling the activity in the animation so if the extension doesn't work we should
// have a blue, then red, then black section, and if it does work we should see on a blue,
@@ -631,9 +626,13 @@ public class ActivityTransitionTests extends ActivityManagerTestBase {
sRgbColor = rawColor;
}
+ // Increase tolerance on edge pixels since blending might occur there
+ final float varianceTolerance = Math.abs(x - xIndex) <= 1
+ ? 0.5f : COLOR_VALUE_VARIANCE_TOLERANCE;
if (arrayEquals(new float[]{
expectedColor.red(), expectedColor.green(), expectedColor.blue()},
- new float[]{sRgbColor.red(), sRgbColor.green(), sRgbColor.blue()})) {
+ new float[]{sRgbColor.red(), sRgbColor.green(), sRgbColor.blue()},
+ varianceTolerance)) {
return new ColorCheckResult(new Point(x, y), expectedColor, sRgbColor);
}
}
@@ -642,25 +641,6 @@ public class ActivityTransitionTests extends ActivityManagerTestBase {
return AssertionResult.SUCCESS;
}
- private int getColorChangeXIndex(Bitmap screen) {
- // Look for color changing index at middle of app
- final int y =
- (getTopAppBounds().top + getTopAppBounds().bottom) / 2;
-
- Color prevColor = screen.getColor(0, y)
- .convert(ColorSpace.get(ColorSpace.Named.SRGB));
- for (int x = 0; x < screen.getWidth(); x++) {
- final Color c = screen.getColor(x, y)
- .convert(ColorSpace.get(ColorSpace.Named.SRGB));
-
- if (!colorsEqual(prevColor, c)) {
- return x;
- }
- }
-
- return -1;
- }
-
private boolean colorsEqual(Color c1, Color c2) {
return almostEquals(c1.red(), c2.red(), COLOR_VALUE_VARIANCE_TOLERANCE)
&& almostEquals(c1.green(), c2.green(), COLOR_VALUE_VARIANCE_TOLERANCE)
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/TaskFragmentOrganizerTest.java b/tests/framework/base/windowmanager/src/android/server/wm/TaskFragmentOrganizerTest.java
index a667c9644e0..6e9d910d7e0 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/TaskFragmentOrganizerTest.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/TaskFragmentOrganizerTest.java
@@ -24,6 +24,7 @@ import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertThrows;
+import static org.junit.Assume.assumeTrue;
import android.app.Activity;
import android.content.ComponentName;
@@ -62,6 +63,7 @@ public class TaskFragmentOrganizerTest extends TaskFragmentOrganizerTestBase {
*/
@Test
public void testCreateTaskFragment() {
+ assumeTrue("MultiWindow is not supported.", supportsMultiWindow());
mWmState.computeState(mOwnerActivityName);
Task parentTask = mWmState.getRootTask(mOwnerActivity.getTaskId());
final int originalTaskFragCount = parentTask.getTaskFragments().size();
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowInputTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowInputTests.java
index 669594d8428..e73ae81999d 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInputTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInputTests.java
@@ -756,8 +756,16 @@ public class WindowInputTests {
final ExecutorService executor = Executors.newSingleThreadExecutor();
boolean[] securityExceptionCaught = new boolean[1];
+ Exception[] illegalArgumentException = new Exception[1];
executor.execute(() -> {
- mInstrumentation.sendPointerSync(eventDown);
+ try {
+ mInstrumentation.sendPointerSync(eventDown);
+ } catch (IllegalArgumentException e) {
+ // InputManagerService throws IllegalArgumentException when input target mismatch.
+ // Store the exception, and raise test failure later to avoid cts thread crash.
+ illegalArgumentException[0] = e;
+ return;
+ }
for (int i = 0; i < 20; i++) {
final long eventTime = SystemClock.uptimeMillis();
final MotionEvent eventMove = MotionEvent.obtain(
@@ -766,8 +774,13 @@ public class WindowInputTests {
mInstrumentation.sendPointerSync(eventMove);
} catch (SecurityException e) {
securityExceptionCaught[0] = true;
+ return;
+ } catch (IllegalArgumentException e) {
+ illegalArgumentException[0] = e;
+ return;
}
}
+
});
// Launch another activity, should not crash the process.
@@ -783,6 +796,11 @@ public class WindowInputTests {
// so the failure is thrown in the test thread.
fail("Should be allowed to inject event.");
}
+
+ if (illegalArgumentException[0] != null) {
+ fail("Failed to inject event due to input target mismatch: "
+ + illegalArgumentException[0].getMessage());
+ }
}
private void waitForWindow(String name) {
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/StylusHandwritingTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/StylusHandwritingTest.java
index 63956791808..8cc0b8efb54 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/StylusHandwritingTest.java
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/StylusHandwritingTest.java
@@ -582,8 +582,8 @@ public class StylusHandwritingTest extends EndToEndImeTestBase {
NOT_EXPECT_TIMEOUT);
final int touchSlop = getTouchSlop();
- final int startX = 50;
- final int startY = 50;
+ final int startX = editText.getWidth() / 2;
+ final int startY = editText.getHeight() / 2;
final int endX = startX + 2 * touchSlop;
final int endY = startY + 2 * touchSlop;
final int number = 5;
diff --git a/tests/location/location_fine/src/android/location/cts/fine/LocationManagerFineTest.java b/tests/location/location_fine/src/android/location/cts/fine/LocationManagerFineTest.java
index a687b6b46f8..a8d7947f98b 100644
--- a/tests/location/location_fine/src/android/location/cts/fine/LocationManagerFineTest.java
+++ b/tests/location/location_fine/src/android/location/cts/fine/LocationManagerFineTest.java
@@ -1036,6 +1036,7 @@ public class LocationManagerFineTest {
}
@Test
+ @AppModeFull(reason = "Instant apps can't hold INTERACT_ACROSS_USERS permission")
public void testAddProviderRequestListener() throws Exception {
InstrumentationRegistry.getInstrumentation().getUiAutomation()
.adoptShellPermissionIdentity(Manifest.permission.LOCATION_HARDWARE);
diff --git a/tests/location/location_none/src/android/location/cts/none/LocationDisabledAppOpsTest.java b/tests/location/location_none/src/android/location/cts/none/LocationDisabledAppOpsTest.java
new file mode 100644
index 00000000000..990d1deb11f
--- /dev/null
+++ b/tests/location/location_none/src/android/location/cts/none/LocationDisabledAppOpsTest.java
@@ -0,0 +1,120 @@
+/*
+ * 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.location.cts.none;
+
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.OPSTR_FINE_LOCATION;
+
+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.content.pm.PackageManager;
+import android.location.LocationManager;
+import android.os.PackageTagsList;
+import android.os.Process;
+import android.os.UserHandle;
+
+import androidx.test.InstrumentationRegistry;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LocationDisabledAppOpsTest {
+
+ 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
+ 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<String> bypassedNoteOps = new ArrayList<>();
+ List<String> bypassedCheckOps = new ArrayList<>();
+ for (PackageInfo pi : mContext.getPackageManager().getInstalledPackagesAsUser(
+ 0, user.getIdentifier())) {
+ 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/media/src/android/mediav2/cts/CodecEncoderValidationTest.java b/tests/media/src/android/mediav2/cts/CodecEncoderValidationTest.java
index 5f176783d59..932af636d95 100644
--- a/tests/media/src/android/mediav2/cts/CodecEncoderValidationTest.java
+++ b/tests/media/src/android/mediav2/cts/CodecEncoderValidationTest.java
@@ -142,6 +142,10 @@ public class CodecEncoderValidationTest extends CodecEncoderTestBase {
if (!mIsAudio) {
int colorFormat = mFormats.get(0).getInteger(MediaFormat.KEY_COLOR_FORMAT);
Assume.assumeTrue(hasSupportForColorFormat(mCodecName, mMime, colorFormat));
+ if (mUseHBD) {
+ Assume.assumeTrue("Codec doesn't support high bit depth profile encoding",
+ doesCodecSupportHDRProfile(mCodecName, mMime));
+ }
}
checkFormatSupport(mCodecName, mMime, true, mFormats, null, CODEC_OPTIONAL);
setUpSource(inputFile);
diff --git a/tests/media/src/android/mediav2/cts/CodecInfoTest.java b/tests/media/src/android/mediav2/cts/CodecInfoTest.java
index 945a7dbf890..5f9aa09c891 100644
--- a/tests/media/src/android/mediav2/cts/CodecInfoTest.java
+++ b/tests/media/src/android/mediav2/cts/CodecInfoTest.java
@@ -91,40 +91,31 @@ public class CodecInfoTest {
/**
* Tests if the devices on T or later, if decoder for a mediaType supports HDR profiles then
- * it should be capable of displaying the same
+ * it should be capable of displaying the same. Since HLG profiles can't be distinguished from
+ * default 10-bit profiles, those are excluded from this test.
*/
@Test
- @Ignore("TODO(b/228237404) Enable once display capabilities can be queried at codec2 level")
public void testHDRDisplayCapabilities() {
Assume.assumeTrue("Test needs Android 13", IS_AT_LEAST_T);
Assume.assumeTrue("Test is applicable for video codecs", mMediaType.startsWith("video/"));
- Assume.assumeTrue("Test is applicable for codecs with HDR profiles",
- mProfileHdrMap.containsKey(mMediaType));
- int[] HdrProfiles = mProfileHdrMap.get(mMediaType);
+ int[] Hdr10Profiles = mProfileHdr10Map.get(mMediaType);
+ int[] Hdr10PlusProfiles = mProfileHdr10PlusMap.get(mMediaType);
+ Assume.assumeTrue("Test is applicable for codecs with HDR10/HDR10+ profiles",
+ Hdr10Profiles != null || Hdr10PlusProfiles != null);
+
MediaCodecInfo.CodecCapabilities caps = mCodecInfo.getCapabilitiesForType(mMediaType);
for (CodecProfileLevel pl : caps.profileLevels) {
- if (IntStream.of(HdrProfiles).anyMatch(x -> x == pl.profile)) {
- if (pl.profile == AV1ProfileMain10 || pl.profile == AVCProfileHigh10 ||
- pl.profile == HEVCProfileMain10 || pl.profile == VP9Profile2) {
- assertTrue("Advertises support for HLG technology without HLG display",
- IntStream.of(DISPLAY_HDR_TYPES).anyMatch(x -> x == HDR_TYPE_HLG));
- } else if (pl.profile == AV1ProfileMain10HDR10 ||
- pl.profile == HEVCProfileMain10HDR10 || pl.profile == VP9Profile2HDR) {
- assertTrue(mCodecInfo.getName() + " Advertises support for HDR10 profile " +
- pl.profile + " without HDR10 display",
- IntStream.of(DISPLAY_HDR_TYPES).anyMatch(x -> x == HDR_TYPE_HDR10));
- } else if (pl.profile == AV1ProfileMain10HDR10Plus ||
- pl.profile == HEVCProfileMain10HDR10Plus ||
- pl.profile == VP9Profile2HDR10Plus) {
- assertTrue(mCodecInfo.getName() + " Advertises support for HDR10+ profile " +
- pl.profile + " without HDR10+ display",
- IntStream.of(DISPLAY_HDR_TYPES)
- .anyMatch(x -> x == HDR_TYPE_HDR10_PLUS));
- } else {
- fail("Unhandled HDR profile" + pl.profile + " for type " + mMediaType);
- }
+ boolean isHdr10Profile = Hdr10Profiles != null &&
+ IntStream.of(Hdr10Profiles).anyMatch(x -> x == pl.profile);
+ boolean isHdr10PlusProfile = Hdr10PlusProfiles != null &&
+ IntStream.of(Hdr10PlusProfiles).anyMatch(x -> x == pl.profile);
+ // TODO (b/228237404) Once there is a way to query support for HDR10/HDR10+ display at
+ // native level, separate the following to independent checks for HDR10 and HDR10+
+ if (isHdr10Profile || isHdr10PlusProfile) {
+ assertTrue(mCodecInfo.getName() + " Advertises support for HDR10/HDR10+ profile " +
+ pl.profile + " without any HDR display", DISPLAY_HDR_TYPES.length > 0);
}
}
}
@@ -160,8 +151,8 @@ public class CodecInfoTest {
// COLOR_FormatSurface support is an existing requirement, but we did not
// test for it before T. We can not retroactively apply the higher standard to
- // devices that are already certified, so only test on T or later devices.
- if (IS_AT_LEAST_T) {
+ // devices that are already certified, so only test on VNDK T or later devices.
+ if (VNDK_IS_AT_LEAST_T) {
assertFalse(mCodecInfo.getName() + " does not support COLOR_FormatSurface",
IntStream.of(caps.colorFormats)
.noneMatch(x -> x == COLOR_FormatSurface));
diff --git a/tests/media/src/android/mediav2/cts/CodecTestBase.java b/tests/media/src/android/mediav2/cts/CodecTestBase.java
index 11057991cb1..0368d882d36 100644
--- a/tests/media/src/android/mediav2/cts/CodecTestBase.java
+++ b/tests/media/src/android/mediav2/cts/CodecTestBase.java
@@ -32,6 +32,7 @@ import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.os.Build;
import android.os.PersistableBundle;
+import android.os.SystemProperties;
import android.util.Log;
import android.util.Pair;
import android.view.Display;
@@ -597,6 +598,8 @@ abstract class CodecTestBase {
// TIRAMISU is set correctly
public static final boolean FIRST_SDK_IS_AT_LEAST_T =
ApiLevelUtil.isFirstApiAfter(Build.VERSION_CODES.S_V2);
+ public static final boolean VNDK_IS_AT_LEAST_T =
+ SystemProperties.getInt("ro.vndk.version", 0) > Build.VERSION_CODES.S_V2;
private static final String LOG_TAG = CodecTestBase.class.getSimpleName();
enum SupportClass {
CODEC_ALL, // All codecs must support
diff --git a/tests/media/src/android/mediav2/cts/EncoderColorAspectsTest.java b/tests/media/src/android/mediav2/cts/EncoderColorAspectsTest.java
index e9a74faa359..9c722c4f03c 100644
--- a/tests/media/src/android/mediav2/cts/EncoderColorAspectsTest.java
+++ b/tests/media/src/android/mediav2/cts/EncoderColorAspectsTest.java
@@ -20,8 +20,11 @@ import android.media.MediaCodec;
import android.media.MediaCodecList;
import android.media.MediaFormat;
import android.media.MediaMuxer;
+import android.opengl.GLES20;
import android.os.Build;
import android.util.Log;
+import android.util.Pair;
+import android.view.Surface;
import androidx.test.filters.SmallTest;
@@ -39,7 +42,9 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface;
import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUVP010;
+import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_Format32bitABGR2101010;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -54,22 +59,31 @@ public class EncoderColorAspectsTest extends CodecEncoderTestBase {
private int mStandard;
private int mTransferCurve;
private boolean mUseHighBitDepth;
+ private boolean mSurfaceMode;
+
+ private Surface mInpSurface;
+ private EGLWindowSurface mEGLWindowInpSurface;
private MediaFormat mConfigFormat;
private MediaMuxer mMuxer;
private int mTrackID = -1;
+ private int mLatency;
+ private boolean mReviseLatency;
+
private ArrayList<String> mCheckESList = new ArrayList<>();
private static boolean sIsAtLeastR = ApiLevelUtil.isAtLeast(Build.VERSION_CODES.R);
public EncoderColorAspectsTest(String encoderName, String mime, int width, int height,
- int range, int standard, int transferCurve, boolean useHighBitDepth) {
+ int range, int standard, int transferCurve, boolean useHighBitDepth,
+ boolean surfaceMode) {
super(encoderName, mime, new int[]{64000}, new int[]{width}, new int[]{height});
mRange = range;
mStandard = standard;
mTransferCurve = transferCurve;
mUseHighBitDepth = useHighBitDepth;
+ mSurfaceMode = surfaceMode;
mWidth = width;
mHeight = height;
setUpParams(1);
@@ -113,7 +127,10 @@ public class EncoderColorAspectsTest extends CodecEncoderTestBase {
if (!stringArgsList.contains(currentObject)) {
exhaustiveArgsList
.add(new Object[]{mediaType, 176, 144, range, standard,
- transfer, useHighBitDepth});
+ transfer, useHighBitDepth, false});
+ exhaustiveArgsList
+ .add(new Object[]{mediaType, 176, 144, range, standard,
+ transfer, useHighBitDepth, true});
stringArgsList.add(currentObject);
}
}
@@ -122,7 +139,7 @@ public class EncoderColorAspectsTest extends CodecEncoderTestBase {
}
}
- @Parameterized.Parameters(name = "{index}({0}_{1}_{4}_{5}_{6})")
+ @Parameterized.Parameters(name = "{index}({0}_{1}_{4}_{5}_{6}_{7}_{8})")
public static Collection<Object[]> input() {
final boolean isEncoder = true;
final boolean needAudio = false;
@@ -170,19 +187,109 @@ public class EncoderColorAspectsTest extends CodecEncoderTestBase {
return CodecTestBase
.prepareParamList(exhaustiveArgsList, isEncoder, needAudio, needVideo, false);
}
+ private long computePresentationTime(int frameIndex) {
+ return frameIndex * 1000000 / mFrameRate;
+ }
+
+ private void generateSurfaceFrame() {
+ GLES20.glViewport(0, 0, mWidth, mHeight);
+ GLES20.glEnable(GLES20.GL_SCISSOR_TEST);
+ GLES20.glClearColor(128.0f, 128.0f, 128.0f, 1.0f);
+ GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
+ }
+
+ private void tryEncoderOutput(long timeOutUs) throws InterruptedException {
+ if (!mAsyncHandle.hasSeenError() && !mSawOutputEOS) {
+ int retry = 0;
+ while (mReviseLatency) {
+ if (mAsyncHandle.hasOutputFormatChanged()) {
+ mReviseLatency = false;
+ int actualLatency = mAsyncHandle.getOutputFormat()
+ .getInteger(MediaFormat.KEY_LATENCY, mLatency);
+ if (mLatency < actualLatency) {
+ mLatency = actualLatency;
+ return;
+ }
+ } else {
+ if (retry > RETRY_LIMIT) {
+ throw new InterruptedException(
+ "did not receive output format changed for encoder after " +
+ Q_DEQ_TIMEOUT_US * RETRY_LIMIT + " us");
+ }
+ Thread.sleep(Q_DEQ_TIMEOUT_US / 1000);
+ retry++;
+ }
+ }
+ Pair<Integer, MediaCodec.BufferInfo> element = mAsyncHandle.getOutput();
+ if (element != null) {
+ dequeueOutput(element.first, element.second);
+ }
+ }
+ }
+
+ void queueEOS() throws InterruptedException {
+ if (!mSurfaceMode) {
+ super.queueEOS();
+ } else {
+ if (!mAsyncHandle.hasSeenError() && !mSawInputEOS) {
+ mCodec.signalEndOfInputStream();
+ mSawInputEOS = true;
+ if (ENABLE_LOGS) Log.d(LOG_TAG, "signalled end of stream");
+ }
+ }
+ }
+
+ void doWork(int frameLimit) throws IOException, InterruptedException {
+ if (!mSurfaceMode) {
+ super.doWork(frameLimit);
+ } else {
+ while (!mAsyncHandle.hasSeenError() && !mSawInputEOS &&
+ mInputCount < frameLimit) {
+ if (mInputCount - mOutputCount > mLatency) {
+ tryEncoderOutput(CodecTestBase.Q_DEQ_TIMEOUT_US);
+ }
+ mEGLWindowInpSurface.makeCurrent();
+ generateSurfaceFrame();
+ mEGLWindowInpSurface
+ .setPresentationTime(computePresentationTime(mInputCount) * 1000);
+ if (ENABLE_LOGS) Log.d(LOG_TAG, "inputSurface swapBuffers");
+ mEGLWindowInpSurface.swapBuffers();
+ mInputCount++;
+ }
+ }
+ }
@SmallTest
@Test(timeout = PER_TEST_TIMEOUT_SMALL_TEST_MS)
public void testColorAspects() throws IOException, InterruptedException {
Assume.assumeTrue("Test introduced with Android 11", sIsAtLeastR);
- String inputTestFile = mInputFile;
if (mUseHighBitDepth) {
- Assume.assumeTrue(hasSupportForColorFormat(mCodecName, mMime, COLOR_FormatYUVP010));
- mConfigFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, COLOR_FormatYUVP010);
- mBytesPerSample = 2;
- inputTestFile = INPUT_VIDEO_FILE_HBD;
+ // Check if encoder is capable of supporting HDR profiles.
+ // Previous check doesn't verify this as profile isn't set in the format
+ Assume.assumeTrue(mCodecName + " doesn't support HDR encoding",
+ CodecTestBase.doesCodecSupportHDRProfile(mCodecName, mMime));
+
+ // Encoder surface mode tests are to be enabled only if an encoder supports
+ // COLOR_Format32bitABGR2101010
+ if (mSurfaceMode) {
+ Assume.assumeTrue(mCodecName + " doesn't support RGBA1010102",
+ hasSupportForColorFormat(mCodecName, mMime, COLOR_Format32bitABGR2101010));
+ }
+ }
+
+ if (mSurfaceMode) {
+ mConfigFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, COLOR_FormatSurface);
+ } else {
+ String inputTestFile = mInputFile;
+ if (mUseHighBitDepth) {
+ Assume.assumeTrue(hasSupportForColorFormat(mCodecName, mMime, COLOR_FormatYUVP010));
+ mConfigFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, COLOR_FormatYUVP010);
+ mBytesPerSample = 2;
+ inputTestFile = INPUT_VIDEO_FILE_HBD;
+ }
+ setUpSource(inputTestFile);
}
- setUpSource(inputTestFile);
+
mOutputBuff = new OutputManager();
{
mCodec = MediaCodec.createByCodecName(mCodecName);
@@ -205,7 +312,19 @@ public class EncoderColorAspectsTest extends CodecEncoderTestBase {
tmpFile = File.createTempFile("tmp" + (mUseHighBitDepth ? "10bit" : ""), ".mp4");
}
mMuxer = new MediaMuxer(tmpFile.getAbsolutePath(), muxerFormat);
- configureCodec(mConfigFormat, false, true, true);
+ // When in surface mode, encoder needs to be configured in async mode
+ boolean isAsync = mSurfaceMode;
+ configureCodec(mConfigFormat, isAsync, true, true);
+
+ if (mSurfaceMode) {
+ mInpSurface = mCodec.createInputSurface();
+ assertTrue("Surface is not valid", mInpSurface.isValid());
+ mEGLWindowInpSurface = new EGLWindowSurface(mInpSurface, mUseHighBitDepth);
+ if (mCodec.getInputFormat().containsKey(MediaFormat.KEY_LATENCY)) {
+ mReviseLatency = true;
+ mLatency = mCodec.getInputFormat().getInteger(MediaFormat.KEY_LATENCY);
+ }
+ }
mCodec.start();
doWork(4);
queueEOS();
@@ -218,6 +337,16 @@ public class EncoderColorAspectsTest extends CodecEncoderTestBase {
mMuxer.release();
mMuxer = null;
}
+
+ if (mEGLWindowInpSurface != null) {
+ mEGLWindowInpSurface.release();
+ mEGLWindowInpSurface = null;
+ }
+ if (mInpSurface != null) {
+ mInpSurface.release();
+ mInpSurface = null;
+ }
+
assertTrue(log + "unexpected error", !mAsyncHandle.hasSeenError());
assertTrue(log + "no input sent", 0 != mInputCount);
assertTrue(log + "output received", 0 != mOutputCount);
diff --git a/tests/media/src/android/mediav2/cts/EncoderHDRInfoTest.java b/tests/media/src/android/mediav2/cts/EncoderHDRInfoTest.java
index a6a36882fd6..26c6eb55920 100644
--- a/tests/media/src/android/mediav2/cts/EncoderHDRInfoTest.java
+++ b/tests/media/src/android/mediav2/cts/EncoderHDRInfoTest.java
@@ -82,11 +82,12 @@ public class EncoderHDRInfoTest extends CodecEncoderTestBase {
super.enqueueInput(bufferIndex);
}
void dequeueOutput(int bufferIndex, MediaCodec.BufferInfo info) {
+ MediaFormat bufferFormat = mCodec.getOutputFormat(bufferIndex);
if (info.size > 0) {
ByteBuffer buf = mCodec.getOutputBuffer(bufferIndex);
if (mMuxer != null) {
if (mTrackID == -1) {
- mTrackID = mMuxer.addTrack(mCodec.getOutputFormat());
+ mTrackID = mMuxer.addTrack(bufferFormat);
mMuxer.start();
}
mMuxer.writeSampleData(mTrackID, buf, info);
@@ -95,7 +96,7 @@ public class EncoderHDRInfoTest extends CodecEncoderTestBase {
super.dequeueOutput(bufferIndex, info);
// verify if the out fmt contains HDR Dynamic metadata as expected
if (mTestDynamicMetadata && mOutputCount > 0) {
- validateHDRDynamicMetaData(mCodec.getOutputFormat(),
+ validateHDRDynamicMetaData(bufferFormat,
ByteBuffer.wrap(loadByteArrayFromString(HDR_DYNAMIC_INFO[mOutputCount - 1])));
}
}
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 1c3a4ddfc83..327fb9cf6c9 100644
--- a/tests/mediapc/common/src/android/mediapc/cts/common/PerformanceClassEvaluator.java
+++ b/tests/mediapc/common/src/android/mediapc/cts/common/PerformanceClassEvaluator.java
@@ -20,10 +20,13 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assume.assumeTrue;
+import android.media.MediaFormat;
import android.os.Build;
import com.google.common.base.Preconditions;
+import java.util.ArrayList;
+import java.util.Arrays;
import org.junit.rules.TestName;
import java.util.HashSet;
@@ -90,36 +93,17 @@ public class PerformanceClassEvaluator {
.setId(RequirementConstants.LONG_RESOLUTION)
.setPredicate(RequirementConstants.INTEGER_GTE)
.addRequiredValue(Build.VERSION_CODES.S, 1920)
- .build();
- RequiredMeasurement<Integer> short_resolution = RequiredMeasurement
- .<Integer>builder()
- .setId(RequirementConstants.SHORT_RESOLUTION)
- .setPredicate(RequirementConstants.INTEGER_GTE)
- .addRequiredValue(Build.VERSION_CODES.S, 1080)
- .build();
-
- return new ResolutionRequirement(RequirementConstants.R7_1_1_1__H_2_1, long_resolution,
- short_resolution);
- }
-
- /**
- * [7.1.1.1/?] MUST have screen resolution of at least 1080p.
- */
- public static ResolutionRequirement createR7_1_1_1__TBD1() {
- RequiredMeasurement<Integer> long_resolution = RequiredMeasurement
- .<Integer>builder()
- .setId(RequirementConstants.LONG_RESOLUTION)
- .setPredicate(RequirementConstants.INTEGER_GTE)
.addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1920)
.build();
RequiredMeasurement<Integer> short_resolution = RequiredMeasurement
.<Integer>builder()
.setId(RequirementConstants.SHORT_RESOLUTION)
.setPredicate(RequirementConstants.INTEGER_GTE)
+ .addRequiredValue(Build.VERSION_CODES.S, 1080)
.addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1080)
.build();
- return new ResolutionRequirement(RequirementConstants.RTBD, long_resolution,
+ return new ResolutionRequirement(RequirementConstants.R7_1_1_1__H_2_1, long_resolution,
short_resolution);
}
}
@@ -159,27 +143,14 @@ public class PerformanceClassEvaluator {
.setId(RequirementConstants.DISPLAY_DENSITY)
.setPredicate(RequirementConstants.INTEGER_GTE)
.addRequiredValue(Build.VERSION_CODES.S, 400)
- .build();
-
- return new DensityRequirement(RequirementConstants.R7_1_1_3__H_2_1, display_density);
- }
-
- /**
- * [7.1.1.3/?] MUST have screen density of at least 400 dpi.
- */
- public static DensityRequirement createR7_1_1_3__TBD2() {
- RequiredMeasurement<Integer> display_density = RequiredMeasurement
- .<Integer>builder()
- .setId(RequirementConstants.DISPLAY_DENSITY)
- .setPredicate(RequirementConstants.INTEGER_GTE)
.addRequiredValue(Build.VERSION_CODES.TIRAMISU, 400)
.build();
- return new DensityRequirement(RequirementConstants.RTBD, display_density);
+ return new DensityRequirement(RequirementConstants.R7_1_1_3__H_2_1, display_density);
}
}
- // used for requirements [7.6.1/H-1-1], [7.6.1/H-2-1], [7.6.1/H-3-1]
+ // used for requirements [7.6.1/H-1-1], [7.6.1/H-2-1]
public static class MemoryRequirement extends Requirement {
private static final String TAG = MemoryRequirement.class.getSimpleName();
@@ -208,39 +179,23 @@ public class PerformanceClassEvaluator {
}
/**
- * [7.6.1/H-2-1] MUST have at least 6 GB of physical memory.
+ * [7.6.1/H-2-1] MUST have at least 6/8 GB of physical memory.
*/
public static MemoryRequirement createR7_6_1__H_2_1() {
RequiredMeasurement<Long> physical_memory = RequiredMeasurement
.<Long>builder()
.setId(RequirementConstants.PHYSICAL_MEMORY)
.setPredicate(RequirementConstants.LONG_GTE)
- // Media performance requires 6 GB minimum RAM, but keeping the following to 5 GB
- // as activityManager.getMemoryInfo() returns around 5.4 GB on a 6 GB device.
+ // Media performance requires 6/8 GB minimum RAM, but keeping the following to
+ // 5/7 GB as activityManager.getMemoryInfo() returns around 5.4 GB on a 6 GB device.
.addRequiredValue(Build.VERSION_CODES.S, 5L * 1024L)
- .build();
-
- return new MemoryRequirement(RequirementConstants.R7_6_1__H_2_1, physical_memory);
- }
-
- /**
- * [7.6.1/H-3-1] MUST have at least 8 GB of physical memory.
- */
- public static MemoryRequirement createR7_6_1__H_3_1() {
- RequiredMeasurement<Long> physical_memory = RequiredMeasurement
- .<Long>builder()
- .setId(RequirementConstants.PHYSICAL_MEMORY)
- .setPredicate(RequirementConstants.LONG_GTE)
- // Media performance requires 8 GB minimum RAM, but keeping the following to 7 GB
- // as activityManager.getMemoryInfo() returns around 7.4 GB on a 8 GB device.
.addRequiredValue(Build.VERSION_CODES.TIRAMISU, 7L * 1024L)
.build();
- return new MemoryRequirement(RequirementConstants.R7_6_1__H_3_1, physical_memory);
+ return new MemoryRequirement(RequirementConstants.R7_6_1__H_2_1, physical_memory);
}
}
- // used for requirements [2.2.7.1/5.1/H-1-7], [2.2.7.1/5.1/H-1-8], [2.2.7.1/5.1/H-1-?]
public static class CodecInitLatencyRequirement extends Requirement {
private static final String TAG = CodecInitLatencyRequirement.class.getSimpleName();
@@ -293,40 +248,38 @@ public class PerformanceClassEvaluator {
codec_init_latency);
}
- // TODO(b/218771970): Update CDD section, change RequirementConstants.RTBD to appropirate
- // requirement id once finalized, ex: RequirementConstants.R5_1__H_1_<something>
/**
- * [2.2.7.1/5.1/H-1-?] Codec initialization latency of 40ms or less for a 1080p or
+ * [2.2.7.1/5.1/H-1-12] Codec initialization latency of 40ms or less for a 1080p or
* smaller video decoding session for all hardware video encoders when under load. Load
* here is defined as a concurrent 1080p to 720p video-only transcoding session using
* hardware video codecs together with the 1080p audio-video recording initialization.
*/
- public static CodecInitLatencyRequirement createR5_1__H_1_TBD1() {
+ public static CodecInitLatencyRequirement createR5_1__H_1_12() {
RequiredMeasurement<Long> codec_init_latency =
RequiredMeasurement.<Long>builder().setId(RequirementConstants.CODEC_INIT_LATENCY)
.setPredicate(RequirementConstants.LONG_LTE)
.addRequiredValue(Build.VERSION_CODES.TIRAMISU, 40L)
.build();
- return new CodecInitLatencyRequirement(RequirementConstants.RTBD, codec_init_latency);
+ return new CodecInitLatencyRequirement(RequirementConstants.R5_1__H_1_12,
+ codec_init_latency);
}
- // TODO(b/218771970): Update CDD section, change RequirementConstants.RTBD to appropirate
- // requirement id once finalized, ex: RequirementConstants.R5_1__H_1_<something>
/**
- * [2.2.7.1/5.1/H-1-?] Codec initialization latency of 30ms or less for a 128kbps or
+ * [2.2.7.1/5.1/H-1-13] Codec initialization latency of 30ms or less for a 128kbps or
* lower bitrate audio decoding session for all audio encoders when under load. Load here
* is defined as a concurrent 1080p to 720p video-only transcoding session using hardware
* video codecs together with the 1080p audio-video recording initialization.
*/
- public static CodecInitLatencyRequirement createR5_1__H_1_TBD2() {
+ public static CodecInitLatencyRequirement createR5_1__H_1_13() {
RequiredMeasurement<Long> codec_init_latency =
RequiredMeasurement.<Long>builder().setId(RequirementConstants.CODEC_INIT_LATENCY)
.setPredicate(RequirementConstants.LONG_LTE)
.addRequiredValue(Build.VERSION_CODES.TIRAMISU, 30L)
.build();
- return new CodecInitLatencyRequirement(RequirementConstants.RTBD, codec_init_latency);
+ return new CodecInitLatencyRequirement(RequirementConstants.R5_1__H_1_13,
+ codec_init_latency);
}
}
@@ -455,9 +408,6 @@ public class PerformanceClassEvaluator {
}
}
- // TODO(b/218771970): Add cdd annotation, change RequirementConstants.RTBD to appropirate
- // requirement id once finalized
- // used for requirements [?]
public static class VideoCodecRequirement extends Requirement {
private static final String TAG = VideoCodecRequirement.class.getSimpleName();
@@ -478,7 +428,7 @@ public class PerformanceClassEvaluator {
}
/**
- * [?] Must have at least 1 HW video decoder supporting 4K60
+ * [2.2.7.1/5.1/H-1-15] Must have at least 1 HW video decoder supporting 4K60
*/
public static VideoCodecRequirement createR4k60HwDecoder() {
RequiredMeasurement<Integer> requirement = RequiredMeasurement
@@ -488,11 +438,11 @@ public class PerformanceClassEvaluator {
.addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1)
.build();
- return new VideoCodecRequirement(RequirementConstants.RTBD, requirement);
+ return new VideoCodecRequirement(RequirementConstants.R5_1__H_1_15, requirement);
}
/**
- * [?] Must have at least 1 HW video encoder supporting 4K60
+ * [2.2.7.1/5.1/H-1-16] Must have at least 1 HW video encoder supporting 4K60
*/
public static VideoCodecRequirement createR4k60HwEncoder() {
RequiredMeasurement<Integer> requirement = RequiredMeasurement
@@ -502,11 +452,11 @@ public class PerformanceClassEvaluator {
.addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1)
.build();
- return new VideoCodecRequirement(RequirementConstants.RTBD, requirement);
+ return new VideoCodecRequirement(RequirementConstants.R5_1__H_1_16, requirement);
}
/**
- * [?] AV1 Hardware decoder: Main 10, Level 4.1, Film Grain
+ * [2.2.7.1/5.1/H-1-14] AV1 Hardware decoder: Main 10, Level 4.1, Film Grain
*/
public static VideoCodecRequirement createRAV1DecoderReq() {
RequiredMeasurement<Boolean> requirement = RequiredMeasurement
@@ -516,87 +466,378 @@ public class PerformanceClassEvaluator {
.addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
.build();
- return new VideoCodecRequirement(RequirementConstants.RTBD, requirement);
+ return new VideoCodecRequirement(RequirementConstants.R5_1__H_1_14, requirement);
}
}
- // TODO(b/218771970): Add cdd annotation
- // used for requirements [?]
- public static class SecureCodecRequirement extends Requirement {
- private static final String TAG = SecureCodecRequirement.class.getSimpleName();
+ // used for requirements [2.2.7.1/5.1/H-1-1], [2.2.7.1/5.1/H-1-2], [2.2.7.1/5.1/H-1-3],
+ // [2.2.7.1/5.1/H-1-4], [2.2.7.1/5.1/H-1-5], [2.2.7.1/5.1/H-1-6], [2.2.7.1/5.1/H-1-9],
+ // [2.2.7.1/5.1/H-1-10]
+ public static class ConcurrentCodecRequirement extends Requirement {
+ private static final String TAG = ConcurrentCodecRequirement.class.getSimpleName();
+ // allowed tolerance in measured fps vs expected fps in percentage, i.e. codecs achieving
+ // fps that is greater than (FPS_TOLERANCE_FACTOR * expectedFps) will be considered as
+ // passing the test
+ private static final double FPS_TOLERANCE_FACTOR = 0.95;
+ private static final double FPS_30_TOLERANCE = 30.0 * FPS_TOLERANCE_FACTOR;
+ static final int REQUIRED_MIN_CONCURRENT_INSTANCES = 6;
+ static final int REQUIRED_MIN_CONCURRENT_INSTANCES_FOR_VP9 = 2;
- private SecureCodecRequirement(String id, RequiredMeasurement<?> ... reqs) {
+ private ConcurrentCodecRequirement(String id, RequiredMeasurement<?> ... reqs) {
super(id, reqs);
}
- public void setSecureReqSatisfied(boolean secureReqSatisfied) {
- this.setMeasuredValue(RequirementConstants.SECURE_REQ_SATISFIED, secureReqSatisfied);
+ public void setConcurrentInstances(int concurrentInstances) {
+ this.setMeasuredValue(RequirementConstants.CONCURRENT_SESSIONS,
+ concurrentInstances);
+ }
+
+ public void setConcurrentFps(double achievedFps) {
+ this.setMeasuredValue(RequirementConstants.CONCURRENT_FPS, achievedFps);
+ }
+
+ // copied from android.mediapc.cts.getReqMinConcurrentInstances due to build issues on aosp
+ public static int getReqMinConcurrentInstances(int performanceClass, String mimeType1,
+ String mimeType2, int resolution) {
+ ArrayList<String> MEDIAPC_CONCURRENT_CODECS_R = new ArrayList<>(
+ Arrays.asList(MediaFormat.MIMETYPE_VIDEO_AVC, MediaFormat.MIMETYPE_VIDEO_HEVC));
+ ArrayList<String> MEDIAPC_CONCURRENT_CODECS = new ArrayList<>(Arrays
+ .asList(MediaFormat.MIMETYPE_VIDEO_AVC, MediaFormat.MIMETYPE_VIDEO_HEVC,
+ MediaFormat.MIMETYPE_VIDEO_VP9, MediaFormat.MIMETYPE_VIDEO_AV1));
+
+ if (performanceClass >= Build.VERSION_CODES.TIRAMISU) {
+ return resolution >= 1080 ? REQUIRED_MIN_CONCURRENT_INSTANCES : 0;
+ } else if (performanceClass == Build.VERSION_CODES.S) {
+ if (resolution >= 1080) {
+ return 0;
+ }
+ if (MEDIAPC_CONCURRENT_CODECS.contains(mimeType1) && MEDIAPC_CONCURRENT_CODECS
+ .contains(mimeType2)) {
+ if (MediaFormat.MIMETYPE_VIDEO_VP9.equalsIgnoreCase(mimeType1)
+ || MediaFormat.MIMETYPE_VIDEO_VP9.equalsIgnoreCase(mimeType2)) {
+ return REQUIRED_MIN_CONCURRENT_INSTANCES_FOR_VP9;
+ } else {
+ return REQUIRED_MIN_CONCURRENT_INSTANCES;
+ }
+ } else {
+ return 0;
+ }
+ } else if (performanceClass == Build.VERSION_CODES.R) {
+ if (resolution >= 1080) {
+ return 0;
+ }
+ if (MEDIAPC_CONCURRENT_CODECS_R.contains(mimeType1) && MEDIAPC_CONCURRENT_CODECS_R
+ .contains(mimeType2)) {
+ return REQUIRED_MIN_CONCURRENT_INSTANCES;
+ } else {
+ return 0;
+ }
+ } else {
+ return 0;
+ }
+ }
+
+ private static double getReqMinConcurrentFps(int performanceClass, String mimeType1,
+ String mimeType2, int resolution) {
+ return FPS_30_TOLERANCE * getReqMinConcurrentInstances(performanceClass, mimeType1,
+ mimeType2, resolution);
}
- public void setWidevineSupported(boolean isWidevineSupported) {
- this.setMeasuredValue(RequirementConstants.WIDEWINE_SUPPORT, isWidevineSupported);
+ /**
+ * [2.2.7.1/5.1/H-1-1] MUST advertise the maximum number of hardware video decoder
+ * sessions that can be run concurrently in any codec combination via the
+ * CodecCapabilities.getMaxSupportedInstances() and VideoCapabilities
+ * .getSupportedPerformancePoints() methods.
+ */
+ public static ConcurrentCodecRequirement createR5_1__H_1_1_720p(String mimeType1,
+ String mimeType2, int resolution) {
+ RequiredMeasurement<Integer> maxInstances = RequiredMeasurement.<Integer>builder()
+ .setId(RequirementConstants.CONCURRENT_SESSIONS)
+ .setPredicate(RequirementConstants.INTEGER_GTE)
+ .addRequiredValue(Build.VERSION_CODES.R,
+ getReqMinConcurrentInstances(Build.VERSION_CODES.R, mimeType1, mimeType2,
+ resolution))
+ .addRequiredValue(Build.VERSION_CODES.S,
+ getReqMinConcurrentInstances(Build.VERSION_CODES.S, mimeType1, mimeType2,
+ resolution))
+ .build();
+
+ return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_1, maxInstances);
}
- public void setWidevineL1Supported(boolean isL1Supported) {
- this.setMeasuredValue(RequirementConstants.WIDEWINE_L1, isL1Supported);
+ /**
+ * [2.2.7.1/5.1/H-1-1] MUST advertise the maximum number of hardware video decoder
+ * sessions that can be run concurrently in any codec combination via the
+ * CodecCapabilities.getMaxSupportedInstances() and VideoCapabilities
+ * .getSupportedPerformancePoints() methods.
+ */
+ public static ConcurrentCodecRequirement createR5_1__H_1_1_1080p() {
+ RequiredMeasurement<Integer> maxInstances = RequiredMeasurement.<Integer>builder()
+ .setId(RequirementConstants.CONCURRENT_SESSIONS)
+ .setPredicate(RequirementConstants.INTEGER_GTE)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 6)
+ .build();
+
+ return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_1, maxInstances);
}
- public void setWidevineL1Tier3Supported(boolean isL1Tier3Supported) {
- this.setMeasuredValue(RequirementConstants.WIDEWINE_L1_TIER3, isL1Tier3Supported);
+ /**
+ * [2.2.7.1/5.1/H-1-2] MUST support 6 instances of hardware video decoder sessions (AVC,
+ * HEVC, VP9* or later) in any codec combination running concurrently at 720p(R,S)
+ * resolution@30 fps.
+ */
+ public static ConcurrentCodecRequirement createR5_1__H_1_2_720p(String mimeType1,
+ String mimeType2, int resolution) {
+ RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
+ .setId(RequirementConstants.CONCURRENT_FPS)
+ .setPredicate(RequirementConstants.DOUBLE_GTE)
+ .addRequiredValue(Build.VERSION_CODES.R,
+ getReqMinConcurrentFps(Build.VERSION_CODES.R, mimeType1, mimeType2, resolution))
+ .addRequiredValue(Build.VERSION_CODES.S,
+ getReqMinConcurrentFps(Build.VERSION_CODES.S, mimeType1, mimeType2, resolution))
+ .build();
+
+ return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_2,
+ reqConcurrentFps);
}
- public void setOemCrypto17Plus(boolean isOemCrypto17Plus) {
- this.setMeasuredValue(RequirementConstants.OEM_CRYPTO_17_PLUS, isOemCrypto17Plus);
+ /**
+ * [2.2.7.1/5.1/H-1-2] MUST support 6 instances of hardware video decoder sessions (AVC,
+ * HEVC, VP9* or later) in any codec combination running concurrently at 1080p(T)
+ * resolution@30 fps.
+ */
+ public static ConcurrentCodecRequirement createR5_1__H_1_2_1080p() {
+ RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
+ .setId(RequirementConstants.CONCURRENT_FPS)
+ .setPredicate(RequirementConstants.DOUBLE_GTE)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 6 * FPS_30_TOLERANCE)
+ .build();
+
+ return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_2,
+ reqConcurrentFps);
}
- public void setWidevineCdm17Plus(boolean isWidevineCdm17Plus) {
- this.setMeasuredValue(RequirementConstants.WIDEWINE_CDM_17_PLUS, isWidevineCdm17Plus);
+ /**
+ * [2.2.7.1/5.1/H-1-3] MUST advertise the maximum number of hardware video encoder
+ * sessions that can be run concurrently in any codec combination via the
+ * CodecCapabilities.getMaxSupportedInstances() and VideoCapabilities
+ * .getSupportedPerformancePoints() methods.
+ */
+ public static ConcurrentCodecRequirement createR5_1__H_1_3_720p(String mimeType1,
+ String mimeType2, int resolution) {
+ RequiredMeasurement<Integer> maxInstances = RequiredMeasurement.<Integer>builder()
+ .setId(RequirementConstants.CONCURRENT_SESSIONS)
+ .setPredicate(RequirementConstants.INTEGER_GTE)
+ .addRequiredValue(Build.VERSION_CODES.R,
+ getReqMinConcurrentInstances(Build.VERSION_CODES.R, mimeType1, mimeType2,
+ resolution))
+ .addRequiredValue(Build.VERSION_CODES.S,
+ getReqMinConcurrentInstances(Build.VERSION_CODES.S, mimeType1, mimeType2,
+ resolution))
+ .build();
+
+ return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_3, maxInstances);
}
/**
- * [?] Support for Widevine L1 Tier 3, WidevineCdmVersion >= 17, OemCryptoVersion >= 17
+ * [2.2.7.1/5.1/H-1-3] MUST advertise the maximum number of hardware video encoder
+ * sessions that can be run concurrently in any codec combination via the
+ * CodecCapabilities.getMaxSupportedInstances() and VideoCapabilities
+ * .getSupportedPerformancePoints() methods.
*/
- public static SecureCodecRequirement createRWidevineSupport() {
- RequiredMeasurement<Boolean> widevineSupport = RequiredMeasurement
- .<Boolean>builder()
- .setId(RequirementConstants.WIDEWINE_SUPPORT)
- .setPredicate(RequirementConstants.BOOLEAN_EQ)
- .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+ public static ConcurrentCodecRequirement createR5_1__H_1_3_1080p() {
+ RequiredMeasurement<Integer> maxInstances = RequiredMeasurement.<Integer>builder()
+ .setId(RequirementConstants.CONCURRENT_SESSIONS)
+ .setPredicate(RequirementConstants.INTEGER_GTE)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 6)
.build();
- RequiredMeasurement<Boolean> widevineL1 =
- RequiredMeasurement.<Boolean>builder().setId(RequirementConstants.WIDEWINE_L1)
- .setPredicate(RequirementConstants.BOOLEAN_EQ)
- .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
- .build();
+ return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_3, maxInstances);
+ }
- RequiredMeasurement<Boolean> widevineL1Tier3 =
- RequiredMeasurement.<Boolean>builder().setId(RequirementConstants.WIDEWINE_L1_TIER3)
- .setPredicate(RequirementConstants.BOOLEAN_EQ)
- .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
- .build();
+ /**
+ * [2.2.7.1/5.1/H-1-4] MUST support 6 instances of hardware video encoder sessions (AVC,
+ * HEVC, VP9* or later) in any codec combination running concurrently at 720p(R,S)
+ * resolution@30 fps.
+ */
+ public static ConcurrentCodecRequirement createR5_1__H_1_4_720p() {
+ RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
+ .setId(RequirementConstants.CONCURRENT_FPS)
+ .setPredicate(RequirementConstants.DOUBLE_GTE)
+ // Requirement not asserted since encoder test runs in byte buffer mode
+ .addRequiredValue(Build.VERSION_CODES.R, 0.0)
+ .addRequiredValue(Build.VERSION_CODES.S, 0.0)
+ .build();
- RequiredMeasurement<Boolean> oemCryptoReq = RequiredMeasurement.<Boolean>builder()
- .setId(RequirementConstants.OEM_CRYPTO_17_PLUS)
- .setPredicate(RequirementConstants.BOOLEAN_EQ)
- .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+ return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_4,
+ reqConcurrentFps);
+ }
+
+ /**
+ * [2.2.7.1/5.1/H-1-4] MUST support 6 instances of hardware video encoder sessions (AVC,
+ * HEVC, VP9* or later) in any codec combination running concurrently at 1080p(T)
+ * resolution@30 fps.
+ */
+ public static ConcurrentCodecRequirement createR5_1__H_1_4_1080p() {
+ RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
+ .setId(RequirementConstants.CONCURRENT_FPS)
+ .setPredicate(RequirementConstants.DOUBLE_GTE)
+ // Requirement not asserted since encoder test runs in byte buffer mode
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 0.0)
.build();
- RequiredMeasurement<Boolean> widevineCdmReq = RequiredMeasurement.<Boolean>builder()
- .setId(RequirementConstants.WIDEWINE_CDM_17_PLUS)
- .setPredicate(RequirementConstants.BOOLEAN_EQ)
- .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
+ return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_4,
+ reqConcurrentFps);
+ }
+
+ /**
+ * [2.2.7.1/5.1/H-1-5] MUST advertise the maximum number of hardware video encoder and
+ * decoder sessions that can be run concurrently in any codec combination via the
+ * CodecCapabilities.getMaxSupportedInstances() and VideoCapabilities
+ * .getSupportedPerformancePoints() methods.
+ */
+ public static ConcurrentCodecRequirement createR5_1__H_1_5_720p(String mimeType1,
+ String mimeType2, int resolution) {
+ RequiredMeasurement<Integer> maxInstances = RequiredMeasurement.<Integer>builder()
+ .setId(RequirementConstants.CONCURRENT_SESSIONS)
+ .setPredicate(RequirementConstants.INTEGER_GTE)
+ .addRequiredValue(Build.VERSION_CODES.R,
+ getReqMinConcurrentInstances(Build.VERSION_CODES.R, mimeType1, mimeType2,
+ resolution))
+ .addRequiredValue(Build.VERSION_CODES.S,
+ getReqMinConcurrentInstances(Build.VERSION_CODES.S, mimeType1, mimeType2,
+ resolution))
+ .build();
+
+ return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_5, maxInstances);
+ }
+
+ /**
+ * [2.2.7.1/5.1/H-1-5] MUST advertise the maximum number of hardware video encoder and
+ * decoder sessions that can be run concurrently in any codec combination via the
+ * CodecCapabilities.getMaxSupportedInstances() and VideoCapabilities
+ * .getSupportedPerformancePoints() methods.
+ */
+ public static ConcurrentCodecRequirement createR5_1__H_1_5_1080p() {
+ RequiredMeasurement<Integer> maxInstances = RequiredMeasurement.<Integer>builder()
+ .setId(RequirementConstants.CONCURRENT_SESSIONS)
+ .setPredicate(RequirementConstants.INTEGER_GTE)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 6)
+ .build();
+
+ return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_5, maxInstances);
+ }
+
+ /**
+ * [2.2.7.1/5.1/H-1-6] Support 6 instances of hardware video decoder and hardware video
+ * encoder sessions (AVC, HEVC, VP9 or AV1) in any codec combination running concurrently
+ * at 720p(R,S) /1080p(T) @30fps resolution.
+ */
+ public static ConcurrentCodecRequirement createR5_1__H_1_6_720p(String mimeType1,
+ String mimeType2, int resolution) {
+ RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
+ .setId(RequirementConstants.CONCURRENT_FPS)
+ .setPredicate(RequirementConstants.DOUBLE_GTE)
+ // Test transcoding, fps calculated for encoder and decoder combined so req / 2
+ .addRequiredValue(Build.VERSION_CODES.R,
+ getReqMinConcurrentFps(Build.VERSION_CODES.R, mimeType1, mimeType2, resolution)
+ / 2)
+ .addRequiredValue(Build.VERSION_CODES.S,
+ getReqMinConcurrentFps(Build.VERSION_CODES.S, mimeType1, mimeType2, resolution)
+ / 2)
+ .build();
+
+ return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_6,
+ reqConcurrentFps);
+ }
+
+ /**
+ * [2.2.7.1/5.1/H-1-6] Support 6 instances of hardware video decoder and hardware video
+ * encoder sessions (AVC, HEVC, VP9 or AV1) in any codec combination running concurrently
+ * at 720p(R,S) /1080p(T) @30fps resolution.
+ */
+ public static ConcurrentCodecRequirement createR5_1__H_1_6_1080p() {
+ RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
+ .setId(RequirementConstants.CONCURRENT_FPS)
+ .setPredicate(RequirementConstants.DOUBLE_GTE)
+ // Test transcoding, fps calculated for encoder and decoder combined so req / 2
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 6 * FPS_30_TOLERANCE / 2)
+ .build();
+
+ return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_6,
+ reqConcurrentFps);
+ }
+
+ /**
+ * [2.2.7.1/5.1/H-1-9] Support 2 instances of secure hardware video decoder sessions
+ * (AVC, HEVC, VP9 or AV1) in any codec combination running concurrently at 1080p
+ * resolution@30fps.
+ */
+ public static ConcurrentCodecRequirement createR5_1__H_1_9() {
+ RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
+ .setId(RequirementConstants.CONCURRENT_FPS)
+ .setPredicate(RequirementConstants.DOUBLE_GTE)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 2 * FPS_30_TOLERANCE)
+ .build();
+
+ return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_9,
+ reqConcurrentFps);
+ }
+
+ /**
+ * [2.2.7.1/5.1/H-1-10] Support 3 instances of non-secure hardware video decoder sessions
+ * together with 1 instance of secure hardware video decoder session (4 instances total)
+ * (AVC, HEVC, VP9 or AV1) in any codec combination running concurrently at 1080p
+ * resolution@30fps.
+ */
+ public static ConcurrentCodecRequirement createR5_1__H_1_10() {
+ RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
+ .setId(RequirementConstants.CONCURRENT_FPS)
+ .setPredicate(RequirementConstants.DOUBLE_GTE)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 4 * FPS_30_TOLERANCE)
+ .build();
+
+ return new ConcurrentCodecRequirement(RequirementConstants.R5_1__H_1_10,
+ reqConcurrentFps);
+ }
+ }
+
+ // used for requirements [2.2.7.1/5.1/H-1-11], [2.2.7.1/5.7/H-1-2]
+ public static class SecureCodecRequirement extends Requirement {
+ private static final String TAG = SecureCodecRequirement.class.getSimpleName();
+
+ private SecureCodecRequirement(String id, RequiredMeasurement<?> ... reqs) {
+ super(id, reqs);
+ }
+
+ public void setSecureReqSatisfied(boolean secureReqSatisfied) {
+ this.setMeasuredValue(RequirementConstants.SECURE_REQ_SATISFIED, secureReqSatisfied);
+ }
+
+ public void setNumCryptoHwSecureAllDec(int numCryptoHwSecureAllDec) {
+ this.setMeasuredValue(RequirementConstants.NUM_CRYPTO_HW_SECURE_ALL_SUPPORT,
+ numCryptoHwSecureAllDec);
+ }
+
+ /**
+ * [2.2.7.1/5.7/H-1-2] MUST support MediaDrm.SECURITY_LEVEL_HW_SECURE_ALL with the below
+ * content decryption capabilities.
+ */
+ public static SecureCodecRequirement createR5_7__H_1_2() {
+ RequiredMeasurement<Integer> hw_secure_all = RequiredMeasurement.<Integer>builder()
+ .setId(RequirementConstants.NUM_CRYPTO_HW_SECURE_ALL_SUPPORT)
+ .setPredicate(RequirementConstants.INTEGER_GTE)
+ .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1)
.build();
- return new SecureCodecRequirement(RequirementConstants.RTBD, widevineSupport,
- widevineL1, widevineL1Tier3, oemCryptoReq, widevineCdmReq);
+ return new SecureCodecRequirement(RequirementConstants.R5_7__H_1_2, hw_secure_all);
}
/**
- * [?] Must support secure decoder when a corresponding AVC/VP9/HEVC or AV1 hardware
- * decoder is available
+ * [2.2.7.1/5.1/H-1-11] Must support secure decoder when a corresponding AVC/VP9/HEVC or AV1
+ * hardware decoder is available
*/
- public static SecureCodecRequirement createRSecureDecodeSupport() {
+ public static SecureCodecRequirement createR5_1__H_1_11() {
RequiredMeasurement<Boolean> requirement = RequiredMeasurement
.<Boolean>builder()
.setId(RequirementConstants.SECURE_REQ_SATISFIED)
@@ -604,7 +845,7 @@ public class PerformanceClassEvaluator {
.addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
.build();
- return new SecureCodecRequirement(RequirementConstants.RTBD, requirement);
+ return new SecureCodecRequirement(RequirementConstants.R5_1__H_1_11, requirement);
}
}
@@ -633,25 +874,13 @@ public class PerformanceClassEvaluator {
ResolutionRequirement.createR7_1_1_1__H_2_1());
}
- public ResolutionRequirement addR7_1_1_1__TBD1() {
- return this.<ResolutionRequirement>addRequirement(
- ResolutionRequirement.createR7_1_1_1__TBD1());
- }
-
public DensityRequirement addR7_1_1_3__H_2_1() {
return this.<DensityRequirement>addRequirement(DensityRequirement.createR7_1_1_3__H_2_1());
}
- public DensityRequirement addR7_1_1_3__TBD2() {
- return this.<DensityRequirement>addRequirement(DensityRequirement.createR7_1_1_3__TBD2());
- }
-
public MemoryRequirement addR7_6_1__H_2_1() {
return this.<MemoryRequirement>addRequirement(MemoryRequirement.createR7_6_1__H_2_1());
}
- public MemoryRequirement addR7_6_1__H_3_1() {
- return this.<MemoryRequirement>addRequirement(MemoryRequirement.createR7_6_1__H_3_1());
- }
public FrameDropRequirement addR5_3__H_1_1_R() {
return this.addRequirement(FrameDropRequirement.createR5_3__H_1_1_R());
@@ -677,12 +906,12 @@ public class PerformanceClassEvaluator {
return this.addRequirement(CodecInitLatencyRequirement.createR5_1__H_1_8());
}
- public CodecInitLatencyRequirement addR5_1__H_1_TBD1() {
- return this.addRequirement(CodecInitLatencyRequirement.createR5_1__H_1_TBD1());
+ public CodecInitLatencyRequirement addR5_1__H_1_12() {
+ return this.addRequirement(CodecInitLatencyRequirement.createR5_1__H_1_12());
}
- public CodecInitLatencyRequirement addR5_1__H_1_TBD2() {
- return this.addRequirement(CodecInitLatencyRequirement.createR5_1__H_1_TBD2());
+ public CodecInitLatencyRequirement addR5_1__H_1_13() {
+ return this.addRequirement(CodecInitLatencyRequirement.createR5_1__H_1_13());
}
public VideoCodecRequirement addR4k60HwEncoder() {
@@ -697,12 +926,78 @@ public class PerformanceClassEvaluator {
return this.addRequirement(VideoCodecRequirement.createRAV1DecoderReq());
}
- public SecureCodecRequirement addRSecureDecodeSupport() {
- return this.addRequirement(SecureCodecRequirement.createRSecureDecodeSupport());
+ public SecureCodecRequirement addR5_1__H_1_11() {
+ return this.addRequirement(SecureCodecRequirement.createR5_1__H_1_11());
+ }
+
+ public SecureCodecRequirement addR5_7__H_1_2() {
+ return this.addRequirement(SecureCodecRequirement.createR5_7__H_1_2());
+ }
+
+ public ConcurrentCodecRequirement addR5_1__H_1_1_720p(String mimeType1, String mimeType2,
+ int resolution) {
+ return this.addRequirement(
+ ConcurrentCodecRequirement.createR5_1__H_1_1_720p(mimeType1, mimeType2, resolution));
+ }
+
+ public ConcurrentCodecRequirement addR5_1__H_1_1_1080p() {
+ return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_1_1080p());
+ }
+
+ public ConcurrentCodecRequirement addR5_1__H_1_2_720p(String mimeType1, String mimeType2,
+ int resolution) {
+ return this.addRequirement(
+ ConcurrentCodecRequirement.createR5_1__H_1_2_720p(mimeType1, mimeType2, resolution));
+ }
+
+ public ConcurrentCodecRequirement addR5_1__H_1_2_1080p() {
+ return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_2_1080p());
+ }
+
+ public ConcurrentCodecRequirement addR5_1__H_1_3_720p(String mimeType1, String mimeType2,
+ int resolution) {
+ return this.addRequirement(
+ ConcurrentCodecRequirement.createR5_1__H_1_3_720p(mimeType1, mimeType2, resolution));
+ }
+
+ public ConcurrentCodecRequirement addR5_1__H_1_3_1080p() {
+ return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_3_1080p());
+ }
+
+ public ConcurrentCodecRequirement addR5_1__H_1_4_720p() {
+ return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_4_720p());
+ }
+
+ public ConcurrentCodecRequirement addR5_1__H_1_4_1080p() {
+ return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_4_1080p());
+ }
+
+ public ConcurrentCodecRequirement addR5_1__H_1_5_720p(String mimeType1, String mimeType2,
+ int resolution) {
+ return this.addRequirement(
+ ConcurrentCodecRequirement.createR5_1__H_1_5_720p(mimeType1, mimeType2, resolution));
+ }
+
+ public ConcurrentCodecRequirement addR5_1__H_1_5_1080p() {
+ return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_5_1080p());
+ }
+
+ public ConcurrentCodecRequirement addR5_1__H_1_6_720p(String mimeType1, String mimeType2,
+ int resolution) {
+ return this.addRequirement(
+ ConcurrentCodecRequirement.createR5_1__H_1_6_720p(mimeType1, mimeType2, resolution));
+ }
+
+ public ConcurrentCodecRequirement addR5_1__H_1_6_1080p() {
+ return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_6_1080p());
+ }
+
+ public ConcurrentCodecRequirement addR5_1__H_1_9() {
+ return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_9());
}
- public SecureCodecRequirement addRWidevineSupport() {
- return this.addRequirement(SecureCodecRequirement.createRWidevineSupport());
+ public ConcurrentCodecRequirement addR5_1__H_1_10() {
+ return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_10());
}
public void submitAndCheck() {
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 0de6a99d610..d93cb2e0a00 100644
--- a/tests/mediapc/common/src/android/mediapc/cts/common/RequirementConstants.java
+++ b/tests/mediapc/common/src/android/mediapc/cts/common/RequirementConstants.java
@@ -35,9 +35,19 @@ public class RequirementConstants {
public static final String R5_1__H_1_6 = "r5_1__h_1_6"; // 5.1/H-1-6
public static final String R5_1__H_1_7 = "r5_1__h_1_7"; // 5.1/H-1-7
public static final String R5_1__H_1_8 = "r5_1__h_1_8"; // 5.1/H-1-8
+ public static final String R5_1__H_1_9 = "r5_1__h_1_9"; // 5.1/H-1-9
+ public static final String R5_1__H_1_10 = "r5_1__h_1_10"; // 5.1/H-1-10
+ public static final String R5_1__H_1_11 = "r5_1__h_1_11"; // 5.1/H-1-11
+ public static final String R5_1__H_1_12 = "r5_1__h_1_12"; // 5.1/H-1-12
+ public static final String R5_1__H_1_13 = "r5_1__h_1_13"; // 5.1/H-1-13
+ public static final String R5_1__H_1_14 = "r5_1__h_1_14"; // 5.1/H-1-14
+ public static final String R5_1__H_1_15 = "r5_1__h_1_15"; // 5.1/H-1-16
+ public static final String R5_1__H_1_16 = "r5_1__h_1_16"; // 5.1/H-1-16
public static final String R5_3__H_1_1 = "r5_3__h_1_1"; // 5.3/H-1-1
public static final String R5_3__H_1_2 = "r5_3__h_1_2"; // 5.3/H-1-2
public static final String R5_6__H_1_1 = "r5_6__h_1_1"; // 5.6/H-1-1
+ public static final String R5_7__H_1_1 = "r5_7__h_1_1"; // 5.7/H-1-1
+ public static final String R5_7__H_1_2 = "r5_7__h_1_2"; // 5.7/H-1-2
public static final String R7_5__H_1_1 = "r7_5__h_1_1"; // 7.5/H-1-1
public static final String R7_5__H_1_2 = "r7_5__h_1_2"; // 7.5/H-1-2
public static final String R7_5__H_1_3 = "r7_5__h_1_3"; // 7.5/H-1-3
@@ -63,7 +73,8 @@ public class RequirementConstants {
public static final String R8_2__H_2_4 = "r8_2__h_2_4"; // 8.2/H-2-4
public static final String RTBD = "tbd"; // placeholder for requirements without a set id
- public static final String MAX_CONCURRENT_SESSIONS = "max_concurrent_sessions";
+ public static final String CONCURRENT_SESSIONS = "concurrent_sessions";
+ public static final String CONCURRENT_FPS = "concurrent_fps";
public static final String SUPPORTED_PERFORMANCE_POINTS = "supported_performance_points";
public static final String FRAMES_DROPPED = "frame_drops_per_30sec";
public static final String FRAME_RATE = "frame_rate";
@@ -76,11 +87,8 @@ public class RequirementConstants {
public static final String NUM_4k_HW_DEC = "number_4k_hw_decoders";
public static final String NUM_4k_HW_ENC = "number_4k_hw_encoders";
public static final String SECURE_REQ_SATISFIED = "secure_requirement_satisfied_boolean";
- public static final String WIDEWINE_SUPPORT = "widevine_support_boolean";
- public static final String WIDEWINE_L1 = "widevine_l1_support_boolean";
- public static final String WIDEWINE_L1_TIER3 = "widevine_l1_tier3_support_boolean";
- public static final String OEM_CRYPTO_17_PLUS = "oem_crypto_version_17plus_boolean";
- public static final String WIDEWINE_CDM_17_PLUS = "widevine_cdm_version_17plus_boolean";
+ public static final String NUM_CRYPTO_HW_SECURE_ALL_SUPPORT =
+ "number_crypto_hw_secure_all_support";
public enum Result {
NA, MET, UNMET
@@ -92,6 +100,7 @@ public class RequirementConstants {
public static final BiPredicate<Integer, Integer> INTEGER_LTE = RequirementConstants.lte();
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();
/**
* Creates a >= predicate.
diff --git a/tests/mediapc/src/android/mediapc/cts/CodecInitializationLatencyTest.java b/tests/mediapc/src/android/mediapc/cts/CodecInitializationLatencyTest.java
index 03790901307..5a4822dd281 100644
--- a/tests/mediapc/src/android/mediapc/cts/CodecInitializationLatencyTest.java
+++ b/tests/mediapc/src/android/mediapc/cts/CodecInitializationLatencyTest.java
@@ -37,6 +37,7 @@ import android.media.MediaFormat;
import android.media.MediaRecorder;
import android.mediapc.cts.common.PerformanceClassEvaluator;
import android.mediapc.cts.common.Utils;
+import android.os.SystemClock;
import android.util.Log;
import android.util.Pair;
import android.view.Surface;
@@ -269,7 +270,6 @@ public class CodecInitializationLatencyTest {
}
}
- // TODO(b/218771970): Add cdd annotation
/**
* This test validates the initialization latency (time for codec create + configure) for
* audio and hw video codecs.
@@ -282,7 +282,9 @@ public class CodecInitializationLatencyTest {
@Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS)
@CddTest(requirements = {
"2.2.7.1/5.1/H-1-7",
- "2.2.7.1/5.1/H-1-8",})
+ "2.2.7.1/5.1/H-1-8",
+ "2.2.7.1/5.1/H-1-12",
+ "2.2.7.1/5.1/H-1-13",})
public void testInitializationLatency() throws Exception {
MediaCodec codec = MediaCodec.createByCodecName(mCodecName);
boolean isEncoder = codec.getCodecInfo().isEncoder();
@@ -347,7 +349,7 @@ public class CodecInitializationLatencyTest {
PerformanceClassEvaluator pce = new PerformanceClassEvaluator(this.mTestName);
PerformanceClassEvaluator.CodecInitLatencyRequirement r5_1__H_1_Latency =
isEncoder ? isAudio ? pce.addR5_1__H_1_8() : pce.addR5_1__H_1_7()
- : isAudio ? pce.addR5_1__H_1_TBD2() : pce.addR5_1__H_1_TBD1();
+ : isAudio ? pce.addR5_1__H_1_13() : pce.addR5_1__H_1_12();
r5_1__H_1_Latency.setCodecInitLatencyMs(initializationLatency);
@@ -435,14 +437,14 @@ public class CodecInitializationLatencyTest {
MediaCodec.BufferInfo outInfo = new MediaCodec.BufferInfo();
long enqueueTimeStamp = 0;
long dequeueTimeStamp = 0;
- long baseTimeStamp = System.nanoTime();
+ long baseTimeStamp = SystemClock.elapsedRealtimeNanos();
mCodec = MediaCodec.createByCodecName(mEncoderName);
resetContext(mIsAsync, false);
mAsyncHandle.setCallBack(mCodec, mIsAsync);
mCodec.configure(format, null, MediaCodec.CONFIGURE_FLAG_ENCODE, null);
- long configureTimeStamp = System.nanoTime();
+ long configureTimeStamp = SystemClock.elapsedRealtimeNanos();
mCodec.start();
- long startTimeStamp = System.nanoTime();
+ long startTimeStamp = SystemClock.elapsedRealtimeNanos();
if (mIsAsync) {
// We will keep on feeding the input to encoder until we see the first dequeued
// frame.
@@ -452,12 +454,12 @@ public class CodecInitializationLatencyTest {
int bufferID = element.first;
MediaCodec.BufferInfo info = element.second;
if (info != null) {
- dequeueTimeStamp = System.nanoTime();
+ dequeueTimeStamp = SystemClock.elapsedRealtimeNanos();
dequeueOutput(bufferID, info);
break;
} else {
if (enqueueTimeStamp == 0) {
- enqueueTimeStamp = System.nanoTime();
+ enqueueTimeStamp = SystemClock.elapsedRealtimeNanos();
}
enqueueInput(bufferID);
}
@@ -469,14 +471,14 @@ public class CodecInitializationLatencyTest {
int inputBufferId = mCodec.dequeueInputBuffer(Q_DEQ_TIMEOUT_US);
if (inputBufferId > 0) {
if (enqueueTimeStamp == 0) {
- enqueueTimeStamp = System.nanoTime();
+ enqueueTimeStamp = SystemClock.elapsedRealtimeNanos();
}
enqueueInput(inputBufferId);
}
}
int outputBufferId = mCodec.dequeueOutputBuffer(outInfo, Q_DEQ_TIMEOUT_US);
if (outputBufferId >= 0) {
- dequeueTimeStamp = System.nanoTime();
+ dequeueTimeStamp = SystemClock.elapsedRealtimeNanos();
dequeueOutput(outputBufferId, outInfo);
break;
}
@@ -531,14 +533,14 @@ public class CodecInitializationLatencyTest {
MediaFormat format = setUpSource(mTestFile);
long enqueueTimeStamp = 0;
long dequeueTimeStamp = 0;
- long baseTimeStamp = System.nanoTime();
+ long baseTimeStamp = SystemClock.elapsedRealtimeNanos();
mCodec = MediaCodec.createByCodecName(mDecoderName);
resetContext(mIsAsync, false);
mAsyncHandle.setCallBack(mCodec, mIsAsync);
mCodec.configure(format, mSurface, 0, null);
- long configureTimeStamp = System.nanoTime();
+ long configureTimeStamp = SystemClock.elapsedRealtimeNanos();
mCodec.start();
- long startTimeStamp = System.nanoTime();
+ long startTimeStamp = SystemClock.elapsedRealtimeNanos();
if (mIsAsync) {
// We will keep on feeding the input to decoder until we see the first dequeued
// frame.
@@ -548,12 +550,12 @@ public class CodecInitializationLatencyTest {
int bufferID = element.first;
MediaCodec.BufferInfo info = element.second;
if (info != null) {
- dequeueTimeStamp = System.nanoTime();
+ dequeueTimeStamp = SystemClock.elapsedRealtimeNanos();
dequeueOutput(bufferID, info);
break;
} else {
if (enqueueTimeStamp == 0) {
- enqueueTimeStamp = System.nanoTime();
+ enqueueTimeStamp = SystemClock.elapsedRealtimeNanos();
}
enqueueInput(bufferID);
}
@@ -565,14 +567,14 @@ public class CodecInitializationLatencyTest {
int inputBufferId = mCodec.dequeueInputBuffer(Q_DEQ_TIMEOUT_US);
if (inputBufferId >= 0) {
if (enqueueTimeStamp == 0) {
- enqueueTimeStamp = System.nanoTime();
+ enqueueTimeStamp = SystemClock.elapsedRealtimeNanos();
}
enqueueInput(inputBufferId);
}
}
int outputBufferId = mCodec.dequeueOutputBuffer(outInfo, Q_DEQ_TIMEOUT_US);
if (outputBufferId >= 0) {
- dequeueTimeStamp = System.nanoTime();
+ dequeueTimeStamp = SystemClock.elapsedRealtimeNanos();
dequeueOutput(outputBufferId, outInfo);
break;
}
diff --git a/tests/mediapc/src/android/mediapc/cts/MultiCodecPerfTestBase.java b/tests/mediapc/src/android/mediapc/cts/MultiCodecPerfTestBase.java
index 98c33475065..ca7a17a1484 100644
--- a/tests/mediapc/src/android/mediapc/cts/MultiCodecPerfTestBase.java
+++ b/tests/mediapc/src/android/mediapc/cts/MultiCodecPerfTestBase.java
@@ -44,10 +44,7 @@ public class MultiCodecPerfTestBase {
static final int REQUIRED_MIN_CONCURRENT_INSTANCES = 6;
static final int REQUIRED_MIN_CONCURRENT_INSTANCES_FOR_VP9 = 2;
static final int REQUIRED_MIN_CONCURRENT_SECURE_INSTANCES = 2;
- // allowed tolerance in measured fps vs expected fps in percentage, i.e. codecs achieving fps
- // that is greater than (FPS_TOLERANCE_FACTOR * expectedFps) will be considered as
- // passing the test
- static final double FPS_TOLERANCE_FACTOR = 0.95;
+
static ArrayList<String> mMimeList = new ArrayList<>();
static Map<String, String> mTestFiles = new HashMap<>();
static Map<String, String> m720pTestFiles = new HashMap<>();
@@ -89,8 +86,6 @@ public class MultiCodecPerfTestBase {
String mTestFile;
final boolean mIsAsync;
- double mMaxFrameRate;
-
@Before
public void isPerformanceClassCandidate() {
Utils.assumeDeviceMeetsPerformanceClassPreconditions();
@@ -120,9 +115,11 @@ public class MultiCodecPerfTestBase {
}
// Returns the max number of 30 fps instances that the given list of mimeCodecPairs
- // supports. It also checks that the each codec supports 180 fps PerformancePoint.
+ // supports. It also checks that the each codec supports a PerformancePoint that covers
+ // required number of 30 fps instances.
public int checkAndGetMaxSupportedInstancesForCodecCombinations(int height, int width,
- ArrayList<Pair<String, String>> mimeCodecPairs) throws IOException {
+ ArrayList<Pair<String, String>> mimeCodecPairs, int requiredMinInstances)
+ throws IOException {
int[] maxInstances = new int[mimeCodecPairs.size()];
int[] maxFrameRates = new int[mimeCodecPairs.size()];
int[] maxMacroBlockRates = new int[mimeCodecPairs.size()];
@@ -135,8 +132,7 @@ public class MultiCodecPerfTestBase {
assertTrue(pps.size() > 0);
boolean hasVP9 = mimeCodecPair.first.equals(MediaFormat.MIMETYPE_VIDEO_VP9);
- int requiredFrameRate = getRequiredMinConcurrentInstances(hasVP9, mimeCodecPair.second,
- mimeCodecPair.first) * 30;
+ int requiredFrameRate = requiredMinInstances * 30;
maxInstances[loopCount] = cap.getMaxSupportedInstances();
PerformancePoint PPRes = new PerformancePoint(width, height, requiredFrameRate);
@@ -168,26 +164,13 @@ public class MultiCodecPerfTestBase {
int minOfMaxFrameRates = maxFrameRates[0];
int minOfMaxMacroBlockRates = maxMacroBlockRates[0];
- // Allow a tolerance in expected frame rate
- mMaxFrameRate = minOfMaxFrameRates * FPS_TOLERANCE_FACTOR;
-
// Calculate how many 30fps max instances it can support from it's mMaxFrameRate
// amd maxMacroBlockRate. (assuming 16x16 macroblocks)
return Math.min(minOfMaxInstances, Math.min((int) (minOfMaxFrameRates / 30.0),
(int) (minOfMaxMacroBlockRates / ((width / 16) * (height / 16)) / 30.0)));
}
- public int getRequiredMinConcurrentInstances(boolean hasVP9) throws IOException {
- return getRequiredMinConcurrentInstances(hasVP9, null, null);
- }
-
- public int getRequiredMinConcurrentInstances(boolean hasVP9, String codecName, String mime)
- throws IOException {
- if (codecName != null && mime != null) {
- if (isSecureSupportedCodec(codecName, mime)) {
- return REQUIRED_MIN_CONCURRENT_SECURE_INSTANCES;
- }
- }
+ public int getRequiredMinConcurrentInstances720p(boolean hasVP9) throws IOException {
// Below T, VP9 requires 60 fps at 720p and minimum of 2 instances
if (!Utils.isTPerfClass() && hasVP9) {
return REQUIRED_MIN_CONCURRENT_INSTANCES_FOR_VP9;
@@ -203,21 +186,4 @@ public class MultiCodecPerfTestBase {
codec.release();
return isSecureSupported;
}
-
- boolean codecSupportsPP(String codecName, String mime, PerformancePoint reqPP)
- throws IOException {
- MediaCodec codec = MediaCodec.createByCodecName(codecName);
- List<PerformancePoint> suppPPs =
- codec.getCodecInfo().getCapabilitiesForType(mime).getVideoCapabilities()
- .getSupportedPerformancePoints();
- assertTrue("Performance point not published by codec: " + codecName, suppPPs != null);
- boolean codecSupportsReqPP = false;
- for (PerformancePoint pp : suppPPs) {
- if (pp.covers(reqPP)) {
- codecSupportsReqPP = true;
- }
- }
- codec.release();
- return codecSupportsReqPP;
- }
}
diff --git a/tests/mediapc/src/android/mediapc/cts/MultiDecoderPairPerfTest.java b/tests/mediapc/src/android/mediapc/cts/MultiDecoderPairPerfTest.java
index 6694a46a41c..0c69346825a 100644
--- a/tests/mediapc/src/android/mediapc/cts/MultiDecoderPairPerfTest.java
+++ b/tests/mediapc/src/android/mediapc/cts/MultiDecoderPairPerfTest.java
@@ -20,8 +20,8 @@ import static org.junit.Assert.assertTrue;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
+import android.mediapc.cts.common.PerformanceClassEvaluator;
import android.mediapc.cts.common.Utils;
-import android.os.Build;
import android.util.Pair;
import androidx.test.filters.LargeTest;
@@ -33,7 +33,9 @@ import com.android.compatibility.common.util.ResultType;
import com.android.compatibility.common.util.ResultUnit;
import org.junit.Assume;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.TestName;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -68,6 +70,9 @@ public class MultiDecoderPairPerfTest extends MultiCodecPerfTestBase {
mSecondPair = secondPair;
}
+ @Rule
+ public final TestName mTestName = new TestName();
+
// Returns the list of params with two hardware (mime - decoder) pairs in both
// sync and async modes.
// Parameters {0}_{1}_{2} -- Pair(Mime DecoderName)_Pair(Mime DecoderName)_isAsync
@@ -110,7 +115,7 @@ public class MultiDecoderPairPerfTest extends MultiCodecPerfTestBase {
boolean hasVP9 = mFirstPair.first.equals(MediaFormat.MIMETYPE_VIDEO_VP9) ||
mSecondPair.first.equals(MediaFormat.MIMETYPE_VIDEO_VP9);
- int requiredMinInstances = getRequiredMinConcurrentInstances(hasVP9);
+ int requiredMinInstances = getRequiredMinConcurrentInstances720p(hasVP9);
testCodec(m720pTestFiles, 720, 1280, requiredMinInstances);
}
@@ -122,99 +127,25 @@ public class MultiDecoderPairPerfTest extends MultiCodecPerfTestBase {
*/
@LargeTest
@Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS)
- @CddTest(requirement = "2.2.7.1/5.1/H-1-1,H-1-2")
+ @CddTest(requirements = {
+ "2.2.7.1/5.1/H-1-1",
+ "2.2.7.1/5.1/H-1-2",
+ "2.2.7.1/5.1/H-1-9",
+ "2.2.7.1/5.1/H-1-10",})
public void test1080p() throws Exception {
Assume.assumeTrue(Utils.isTPerfClass() || !Utils.isPerfClass());
- Assume.assumeFalse("Skipping regular performance tests for secure codecs",
- isSecureSupportedCodec(mFirstPair.second, mFirstPair.first) ||
- isSecureSupportedCodec(mSecondPair.second, mSecondPair.first));
- testCodec(m1080pTestFiles, 1080, 1920, REQUIRED_MIN_CONCURRENT_INSTANCES);
- }
-
- /**
- * Validates if hardware decoder pairs where one supports secure decode and required
- * perf are present and tests with concurrent unsecure decoders
- */
- @LargeTest
- @Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS)
- // TODO(b/218771970) Add @CddTest annotation
- public void testReqSecureWithUnsecureDecodeSupport() throws Exception {
- Assume.assumeTrue(Utils.isTPerfClass() || !Utils.isPerfClass());
- Assume.assumeTrue("Testing if only one of the pair is secure",
- isSecureSupportedCodec(mFirstPair.second, mFirstPair.first) ^
- isSecureSupportedCodec(mSecondPair.second, mSecondPair.first));
-
- MediaCodecInfo.VideoCapabilities.PerformancePoint reqSecurePP =
- new MediaCodecInfo.VideoCapabilities.PerformancePoint(1920, 1080, 30);
-
- MediaCodecInfo.VideoCapabilities.PerformancePoint reqNonSecurePP =
- new MediaCodecInfo.VideoCapabilities.PerformancePoint(1920, 1080,
- 30 * REQUIRED_CONCURRENT_NON_SECURE_INSTANCES_WITH_SECURE);
-
- boolean codecSupportsReqPP = codecSupportsPP(mFirstPair.second, mFirstPair.first,
- isSecureSupportedCodec(mFirstPair.second, mFirstPair.first) ? reqSecurePP :
- reqNonSecurePP);
-
- codecSupportsReqPP &= codecSupportsPP(mSecondPair.second, mSecondPair.first,
- isSecureSupportedCodec(mSecondPair.second, mSecondPair.first) ? reqSecurePP :
- reqNonSecurePP);
-
- testCodec(m1080pTestFiles, 1080, 1920,
- REQUIRED_CONCURRENT_NON_SECURE_INSTANCES_WITH_SECURE + 1, true);
-
- if (Utils.isTPerfClass()) {
- assertTrue(
- "Required Secure Decode Support required for MPC >= Android T, unsupported " +
- "codec pair: " + mFirstPair.second + "," + mSecondPair.second,
- codecSupportsReqPP);
- } else {
- DeviceReportLog log =
- new DeviceReportLog("MediaPerformanceClassLogs", "SecureDecodeSupport");
- log.addValue("Req Secure Decode Support pair: " + mFirstPair.second + "," +
- mSecondPair.second, codecSupportsReqPP, ResultType.NEUTRAL, ResultUnit.NONE);
- // TODO(b/218771970) Log CDD sections
- log.setSummary("MPC 13: Secure Decode requirements", 0, ResultType.NEUTRAL,
- ResultUnit.NONE);
- log.submit(InstrumentationRegistry.getInstrumentation());
- }
- }
-
- /**
- * Validates if hardware decoder pairs where both supports secure decode and required
- * perf is present
- */
- @LargeTest
- @Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS)
- // TODO(b/218771970) Add @CddTest annotation
- public void testReqMultiSecureDecodeSupport() throws Exception {
- Assume.assumeTrue(Utils.isTPerfClass() || !Utils.isPerfClass());
- Assume.assumeTrue("Run test if both are secure codecs",
- isSecureSupportedCodec(mFirstPair.second, mFirstPair.first) &&
- isSecureSupportedCodec(mSecondPair.second, mSecondPair.first));
-
- MediaCodecInfo.VideoCapabilities.PerformancePoint reqSecurePP =
- new MediaCodecInfo.VideoCapabilities.PerformancePoint(1920, 1080, 30);
-
- boolean codecSupportsReqPP =
- codecSupportsPP(mFirstPair.second, mFirstPair.first, reqSecurePP);
- codecSupportsReqPP &= codecSupportsPP(mSecondPair.second, mSecondPair.first, reqSecurePP);
-
- testCodec(null, 1080, 1920, REQUIRED_MIN_CONCURRENT_SECURE_INSTANCES);
-
- if (Utils.isTPerfClass()) {
- assertTrue(
- "Required Secure Decode Support required for MPC >= Android T, unsupported " +
- "codec pair: " + mFirstPair.second + "," + mSecondPair.second,
- codecSupportsReqPP);
+ boolean isFirstSecure = isSecureSupportedCodec(mFirstPair.second, mFirstPair.first);
+ boolean isSecondSecure = isSecureSupportedCodec(mSecondPair.second, mSecondPair.first);
+ boolean onlyOneSecure = isFirstSecure ^ isSecondSecure;
+ boolean bothSecure = isFirstSecure & isSecondSecure;
+
+ if (bothSecure) {
+ testCodec(null, 1080, 1920, REQUIRED_MIN_CONCURRENT_SECURE_INSTANCES);
+ } else if (onlyOneSecure) {
+ testCodec(m1080pTestFiles, 1080, 1920,
+ REQUIRED_CONCURRENT_NON_SECURE_INSTANCES_WITH_SECURE + 1, true);
} else {
- DeviceReportLog log =
- new DeviceReportLog("MediaPerformanceClassLogs", "SecureDecodeSupport");
- log.addValue("Req Secure Decode Support pair: " + mFirstPair.second + "," +
- mSecondPair.second, codecSupportsReqPP, ResultType.NEUTRAL, ResultUnit.NONE);
- // TODO(b/218771970) Log CDD sections
- log.setSummary("MPC 13: Secure Decode requirements", 0, ResultType.NEUTRAL,
- ResultUnit.NONE);
- log.submit(InstrumentationRegistry.getInstrumentation());
+ testCodec(m1080pTestFiles, 1080, 1920, REQUIRED_MIN_CONCURRENT_INSTANCES);
}
}
@@ -229,8 +160,9 @@ public class MultiDecoderPairPerfTest extends MultiCodecPerfTestBase {
ArrayList<Pair<String, String>> mimeDecoderPairs = new ArrayList<>();
mimeDecoderPairs.add(mFirstPair);
mimeDecoderPairs.add(mSecondPair);
+ boolean bothSecure = true;
int maxInstances = checkAndGetMaxSupportedInstancesForCodecCombinations(height, width,
- mimeDecoderPairs);
+ mimeDecoderPairs, requiredMinInstances);
double achievedFrameRate = 0.0;
// secure test should not reach this point if secure codec doesn't support PP
if (maxInstances >= requiredMinInstances || secureWithUnsecure) {
@@ -245,6 +177,7 @@ public class MultiDecoderPairPerfTest extends MultiCodecPerfTestBase {
List<Decode> testList = new ArrayList<>();
for (int i = 0; i < firstPairInstances; i++) {
boolean isSecure = isSecureSupportedCodec(mFirstPair.second, mFirstPair.first);
+ bothSecure &= isSecure;
String testFile = isSecure ? m1080pWidevineTestFiles.get(mFirstPair.first) :
mTestFiles.get(mFirstPair.first);
Assume.assumeTrue("Add " + (isSecure ? "secure" : "") + " test vector for mime: " +
@@ -254,6 +187,7 @@ public class MultiDecoderPairPerfTest extends MultiCodecPerfTestBase {
}
for (int i = 0; i < secondPairInstances; i++) {
boolean isSecure = isSecureSupportedCodec(mSecondPair.second, mSecondPair.first);
+ bothSecure &= isSecure;
String testFile = isSecure ? m1080pWidevineTestFiles.get(mSecondPair.first) :
mTestFiles.get(mSecondPair.first);
Assume.assumeTrue("Add " + (isSecure ? "secure" : "") + " test vector for mime: " +
@@ -267,29 +201,30 @@ public class MultiDecoderPairPerfTest extends MultiCodecPerfTestBase {
achievedFrameRate += result.get();
}
}
- if (Utils.isPerfClass()) {
- assertTrue("Decoder pair " + mFirstPair.second + " and " + mSecondPair.second
- + " unable to support minimum concurrent " +
- "instances. act/exp: " + maxInstances + "/" + requiredMinInstances,
- maxInstances >= requiredMinInstances);
- assertTrue("Unable to achieve the maxFrameRate supported. act/exp: " + achievedFrameRate
- + "/" + mMaxFrameRate + " for " + maxInstances + " instances.",
- achievedFrameRate >= mMaxFrameRate);
+ PerformanceClassEvaluator pce = new PerformanceClassEvaluator(this.mTestName);
+ if (secureWithUnsecure) {
+ PerformanceClassEvaluator.ConcurrentCodecRequirement r5_1__H_1_10 =
+ pce.addR5_1__H_1_10();
+ r5_1__H_1_10.setConcurrentFps(achievedFrameRate);
+ } else if (bothSecure) {
+ PerformanceClassEvaluator.ConcurrentCodecRequirement r5_1__H_1_9 = pce.addR5_1__H_1_9();
+ r5_1__H_1_9.setConcurrentFps(achievedFrameRate);
} else {
- int pc = maxInstances >= requiredMinInstances && achievedFrameRate >= mMaxFrameRate
- ? Build.VERSION_CODES.R : 0;
- DeviceReportLog log = new DeviceReportLog("MediaPerformanceClassLogs",
- "MultiDecoderPairPerf_" + mFirstPair.second);
- log.addValue("decoders",
- mFirstPair.first + "_" + mFirstPair.second + "_" + mSecondPair.first + "_"
- + mSecondPair.second, ResultType.NEUTRAL, ResultUnit.NONE);
- log.addValue("achieved_framerate", achievedFrameRate, ResultType.HIGHER_BETTER,
- ResultUnit.NONE);
- log.addValue("expected_framerate", mMaxFrameRate, ResultType.NEUTRAL, ResultUnit.NONE);
- log.setSummary("CDD 2.2.7.1/5.1/H-1-1,H-1-2 performance_class", pc, ResultType.NEUTRAL,
- ResultUnit.NONE);
- log.submit(InstrumentationRegistry.getInstrumentation());
+ PerformanceClassEvaluator.ConcurrentCodecRequirement r5_1__H_1_1;
+ PerformanceClassEvaluator.ConcurrentCodecRequirement r5_1__H_1_2;
+ if (height >= 1080) {
+ r5_1__H_1_1 = pce.addR5_1__H_1_1_1080p();
+ r5_1__H_1_2 = pce.addR5_1__H_1_2_1080p();
+ r5_1__H_1_1.setConcurrentInstances(maxInstances);
+ r5_1__H_1_2.setConcurrentFps(achievedFrameRate);
+ } else {
+ r5_1__H_1_1 = pce.addR5_1__H_1_1_720p(mMime, mMime, height);
+ r5_1__H_1_2 = pce.addR5_1__H_1_2_720p(mMime, mMime, height);
+ r5_1__H_1_1.setConcurrentInstances(maxInstances);
+ r5_1__H_1_2.setConcurrentFps(achievedFrameRate);
+ }
}
+ pce.submitAndCheck();
}
}
diff --git a/tests/mediapc/src/android/mediapc/cts/MultiDecoderPerfTest.java b/tests/mediapc/src/android/mediapc/cts/MultiDecoderPerfTest.java
index 62c7f832142..13203cc77ce 100644
--- a/tests/mediapc/src/android/mediapc/cts/MultiDecoderPerfTest.java
+++ b/tests/mediapc/src/android/mediapc/cts/MultiDecoderPerfTest.java
@@ -18,10 +18,9 @@ package android.mediapc.cts;
import static org.junit.Assert.assertTrue;
-import android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint;
import android.media.MediaFormat;
+import android.mediapc.cts.common.PerformanceClassEvaluator;
import android.mediapc.cts.common.Utils;
-import android.os.Build;
import android.util.Pair;
import androidx.test.filters.LargeTest;
@@ -33,7 +32,9 @@ import com.android.compatibility.common.util.ResultType;
import com.android.compatibility.common.util.ResultUnit;
import org.junit.Assume;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.TestName;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -62,6 +63,9 @@ public class MultiDecoderPerfTest extends MultiCodecPerfTestBase {
mDecoderName = decoderName;
}
+ @Rule
+ public final TestName mTestName = new TestName();
+
// Returns the params list with the mime and corresponding hardware decoders in
// both sync and async modes.
// Parameters {0}_{1}_{2} -- Mime_DecoderName_isAsync
@@ -92,56 +96,28 @@ public class MultiDecoderPerfTest extends MultiCodecPerfTestBase {
Assume.assumeFalse("Skipping regular performance tests for secure codecs",
isSecureSupportedCodec(mDecoderName, mMime));
boolean hasVP9 = mMime.equals(MediaFormat.MIMETYPE_VIDEO_VP9);
- int requiredMinInstances = getRequiredMinConcurrentInstances(hasVP9);
+ int requiredMinInstances = getRequiredMinConcurrentInstances720p(hasVP9);
testCodec(m720pTestFiles, 720, 1280, requiredMinInstances);
}
/**
- * This test validates that the decoder can support at least 6 concurrent 1080p 30fps
- * decoder instances. Also ensures that all the concurrent sessions succeed in decoding
- * with meeting the expected frame rate.
+ * This test validates that the decoder can support at least 6 non-secure/2 secure concurrent
+ * 1080p 30fps decoder instances. Also ensures that all the concurrent sessions succeed in
+ * decoding with meeting the expected frame rate.
*/
@LargeTest
@Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS)
- @CddTest(requirement = "2.2.7.1/5.1/H-1-1,H-1-2")
+ @CddTest(requirements = {
+ "2.2.7.1/5.1/H-1-1",
+ "2.2.7.1/5.1/H-1-2",
+ "2.2.7.1/5.1/H-1-9",})
public void test1080p() throws Exception {
Assume.assumeTrue(Utils.isTPerfClass() || !Utils.isPerfClass());
- Assume.assumeFalse("Skipping regular performance tests for secure codecs",
- isSecureSupportedCodec(mDecoderName, mMime));
- testCodec(m1080pTestFiles, 1080, 1920, REQUIRED_MIN_CONCURRENT_INSTANCES);
- }
-
- /**
- * Validates if hardware decoder that supports required secure decode perf is present
- */
- @LargeTest
- @Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS)
- // TODO(b/218771970) Add @CddTest annotation
- public void testReqSecureDecodeSupport() throws Exception {
- Assume.assumeTrue(Utils.isTPerfClass() || !Utils.isPerfClass());
- Assume.assumeTrue("Skipping secure decode support tests for non-secure codecs",
- isSecureSupportedCodec(mDecoderName, mMime));
-
- PerformancePoint reqPP =
- new PerformancePoint(1920, 1080, 30 * REQUIRED_MIN_CONCURRENT_SECURE_INSTANCES);
-
- boolean codecSupportsReqPP = codecSupportsPP(mDecoderName, mMime, reqPP);
-
- testCodec(m1080pWidevineTestFiles, 1080, 1920, REQUIRED_MIN_CONCURRENT_SECURE_INSTANCES);
-
- if (Utils.isTPerfClass()) {
- assertTrue(
- "Required Secure Decode Support required for MPC >= Android T, unsupported " +
- "codec: " + mDecoderName, codecSupportsReqPP);
+ if (isSecureSupportedCodec(mDecoderName, mMime)) {
+ testCodec(m1080pWidevineTestFiles, 1080, 1920,
+ REQUIRED_MIN_CONCURRENT_SECURE_INSTANCES);
} else {
- DeviceReportLog log =
- new DeviceReportLog("MediaPerformanceClassLogs", "SecureDecodeSupport");
- log.addValue("Req Secure Decode Support: " + mDecoderName, codecSupportsReqPP,
- ResultType.NEUTRAL, ResultUnit.NONE);
- // TODO(b/218771970) Log CDD sections
- log.setSummary("MPC 13: Secure Decode requirements", 0, ResultType.NEUTRAL,
- ResultUnit.NONE);
- log.submit(InstrumentationRegistry.getInstrumentation());
+ testCodec(m1080pTestFiles, 1080, 1920, REQUIRED_MIN_CONCURRENT_INSTANCES);
}
}
@@ -151,15 +127,15 @@ public class MultiDecoderPerfTest extends MultiCodecPerfTestBase {
Assume.assumeTrue("Add test vector for mime: " + mMime, mTestFile != null);
ArrayList<Pair<String, String>> mimeDecoderPairs = new ArrayList<>();
mimeDecoderPairs.add(Pair.create(mMime, mDecoderName));
+ boolean isSecure = isSecureSupportedCodec(mDecoderName, mMime);
int maxInstances =
checkAndGetMaxSupportedInstancesForCodecCombinations(height, width,
- mimeDecoderPairs);
+ mimeDecoderPairs, requiredMinInstances);
double achievedFrameRate = 0.0;
if (maxInstances >= requiredMinInstances) {
ExecutorService pool = Executors.newFixedThreadPool(maxInstances);
List<Decode> testList = new ArrayList<>();
for (int i = 0; i < maxInstances; i++) {
- boolean isSecure = isSecureSupportedCodec(mDecoderName, mMime);
testList.add(new Decode(mMime, mTestFile, mDecoderName, mIsAsync, isSecure));
}
List<Future<Double>> resultList = pool.invokeAll(testList);
@@ -167,26 +143,26 @@ public class MultiDecoderPerfTest extends MultiCodecPerfTestBase {
achievedFrameRate += result.get();
}
}
- if (Utils.isPerfClass()) {
- assertTrue("Decoder " + mDecoderName + " unable to support minimum concurrent " +
- "instances. act/exp: " + maxInstances + "/" + requiredMinInstances,
- maxInstances >= requiredMinInstances);
- assertTrue("Unable to achieve the maxFrameRate supported. act/exp: " + achievedFrameRate
- + "/" + mMaxFrameRate + " for " + maxInstances + " instances.",
- achievedFrameRate >= mMaxFrameRate);
+
+ PerformanceClassEvaluator pce = new PerformanceClassEvaluator(this.mTestName);
+ if (isSecure) {
+ PerformanceClassEvaluator.ConcurrentCodecRequirement r5_1__H_1_9 = pce.addR5_1__H_1_9();
+ r5_1__H_1_9.setConcurrentFps(achievedFrameRate);
} else {
- int pc = maxInstances >= requiredMinInstances && achievedFrameRate >= mMaxFrameRate
- ? Build.VERSION_CODES.R : 0;
- DeviceReportLog log = new DeviceReportLog("MediaPerformanceClassLogs",
- "MultiDecoderPerf_" + mDecoderName);
- log.addValue("decoders", mMime + "_" + mDecoderName, ResultType.NEUTRAL,
- ResultUnit.NONE);
- log.addValue("achieved_framerate", achievedFrameRate, ResultType.HIGHER_BETTER,
- ResultUnit.NONE);
- log.addValue("expected_framerate", mMaxFrameRate, ResultType.NEUTRAL, ResultUnit.NONE);
- log.setSummary("CDD 2.2.7.1/5.1/H-1-1,H-1-2 performance_class", pc, ResultType.NEUTRAL,
- ResultUnit.NONE);
- log.submit(InstrumentationRegistry.getInstrumentation());
+ PerformanceClassEvaluator.ConcurrentCodecRequirement r5_1__H_1_1;
+ PerformanceClassEvaluator.ConcurrentCodecRequirement r5_1__H_1_2;
+ if (height >= 1080) {
+ r5_1__H_1_1 = pce.addR5_1__H_1_1_1080p();
+ r5_1__H_1_2 = pce.addR5_1__H_1_2_1080p();
+ r5_1__H_1_1.setConcurrentInstances(maxInstances);
+ r5_1__H_1_2.setConcurrentFps(achievedFrameRate);
+ } else {
+ r5_1__H_1_1 = pce.addR5_1__H_1_1_720p(mMime, mMime, height);
+ r5_1__H_1_2 = pce.addR5_1__H_1_2_720p(mMime, mMime, height);
+ r5_1__H_1_1.setConcurrentInstances(maxInstances);
+ r5_1__H_1_2.setConcurrentFps(achievedFrameRate);
+ }
}
+ pce.submitAndCheck();
}
}
diff --git a/tests/mediapc/src/android/mediapc/cts/MultiEncoderPairPerfTest.java b/tests/mediapc/src/android/mediapc/cts/MultiEncoderPairPerfTest.java
index 01e68d3b7e3..1997c6beac9 100644
--- a/tests/mediapc/src/android/mediapc/cts/MultiEncoderPairPerfTest.java
+++ b/tests/mediapc/src/android/mediapc/cts/MultiEncoderPairPerfTest.java
@@ -16,24 +16,19 @@
package android.mediapc.cts;
-import static org.junit.Assert.assertTrue;
-
import android.media.MediaFormat;
+import android.mediapc.cts.common.PerformanceClassEvaluator;
import android.mediapc.cts.common.Utils;
-import android.os.Build;
-import android.util.Log;
import android.util.Pair;
import androidx.test.filters.LargeTest;
-import androidx.test.platform.app.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.Assume;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.TestName;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -66,6 +61,9 @@ public class MultiEncoderPairPerfTest extends MultiCodecPerfTestBase {
mSecondPair = secondPair;
}
+ @Rule
+ public final TestName mTestName = new TestName();
+
// Returns the list of params with two hardware (mime - encoder) pairs in both
// sync and async modes.
// Parameters {0}_{1}_{2} -- Pair(Mime EncoderName)_Pair(Mime EncoderName)_isAsync
@@ -105,7 +103,7 @@ public class MultiEncoderPairPerfTest extends MultiCodecPerfTestBase {
boolean hasVP9 = mFirstPair.first.equals(MediaFormat.MIMETYPE_VIDEO_VP9) ||
mSecondPair.first.equals(MediaFormat.MIMETYPE_VIDEO_VP9);
- int requiredMinInstances = getRequiredMinConcurrentInstances(hasVP9);
+ int requiredMinInstances = getRequiredMinConcurrentInstances720p(hasVP9);
testCodec(720, 1280, 4000000, requiredMinInstances);
}
@@ -129,7 +127,7 @@ public class MultiEncoderPairPerfTest extends MultiCodecPerfTestBase {
mimeEncoderPairs.add(mFirstPair);
mimeEncoderPairs.add(mSecondPair);
int maxInstances = checkAndGetMaxSupportedInstancesForCodecCombinations(height, width,
- mimeEncoderPairs);
+ mimeEncoderPairs, requiredMinInstances);
double achievedFrameRate = 0.0;
if (maxInstances >= requiredMinInstances) {
int secondPairInstances = maxInstances / 2;
@@ -151,22 +149,22 @@ public class MultiEncoderPairPerfTest extends MultiCodecPerfTestBase {
achievedFrameRate += result.get();
}
}
- if (Utils.isPerfClass()) {
- assertTrue("Encoder pair " + mFirstPair.second + " and " + mSecondPair.second
- + " unable to support minimum concurrent instances. act/exp: " + maxInstances
- + "/" + requiredMinInstances, maxInstances >= requiredMinInstances);
- Log.v(LOG_TAG, "Achieved fps: " + achievedFrameRate +
- "\nAchieved frame rate is not compared as this test runs in byte buffer mode");
+ PerformanceClassEvaluator pce = new PerformanceClassEvaluator(this.mTestName);
+ PerformanceClassEvaluator.ConcurrentCodecRequirement r5_1__H_1_3;
+ PerformanceClassEvaluator.ConcurrentCodecRequirement r5_1__H_1_4;
+ // Achieved frame rate is not compared as this test runs in byte buffer mode.
+ if (height >= 1080) {
+ r5_1__H_1_3 = pce.addR5_1__H_1_3_1080p();
+ r5_1__H_1_4 = pce.addR5_1__H_1_4_1080p();
+ r5_1__H_1_3.setConcurrentInstances(maxInstances);
+ r5_1__H_1_4.setConcurrentFps(achievedFrameRate);
} else {
- int pc = maxInstances >= requiredMinInstances ? Build.VERSION_CODES.R : 0;
- DeviceReportLog log = new DeviceReportLog("MediaPerformanceClassLogs",
- "MultiEncoderPairPerf_" + mFirstPair.second);
- log.addValue("encoders",
- mFirstPair.first + "_" + mFirstPair.second + "_" + mSecondPair.first + "_"
- + mSecondPair.second, ResultType.NEUTRAL, ResultUnit.NONE);
- log.setSummary("CDD 2.2.7.1/5.1/H-1-3,H-1-4 performance_class", pc, ResultType.NEUTRAL,
- ResultUnit.NONE);
- log.submit(InstrumentationRegistry.getInstrumentation());
+ r5_1__H_1_3 = pce.addR5_1__H_1_3_720p(mMime, mMime, height);
+ r5_1__H_1_4 = pce.addR5_1__H_1_4_720p();
+ r5_1__H_1_3.setConcurrentInstances(maxInstances);
+ r5_1__H_1_4.setConcurrentFps(achievedFrameRate);
}
+
+ pce.submitAndCheck();
}
}
diff --git a/tests/mediapc/src/android/mediapc/cts/MultiEncoderPerfTest.java b/tests/mediapc/src/android/mediapc/cts/MultiEncoderPerfTest.java
index 28c7fbd9307..66afa892425 100644
--- a/tests/mediapc/src/android/mediapc/cts/MultiEncoderPerfTest.java
+++ b/tests/mediapc/src/android/mediapc/cts/MultiEncoderPerfTest.java
@@ -16,24 +16,19 @@
package android.mediapc.cts;
-import static org.junit.Assert.assertTrue;
-
import android.media.MediaFormat;
+import android.mediapc.cts.common.PerformanceClassEvaluator;
import android.mediapc.cts.common.Utils;
-import android.os.Build;
-import android.util.Log;
import android.util.Pair;
import androidx.test.filters.LargeTest;
-import androidx.test.platform.app.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.Assume;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.TestName;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -62,6 +57,9 @@ public class MultiEncoderPerfTest extends MultiCodecPerfTestBase {
mEncoderName = encoderName;
}
+ @Rule
+ public final TestName mTestName = new TestName();
+
// Returns the params list with the mime and their hardware encoders in
// both sync and async modes.
// Parameters {0}_{2}_{3} -- Mime_EncoderName_isAsync
@@ -90,7 +88,7 @@ public class MultiEncoderPerfTest extends MultiCodecPerfTestBase {
Assume.assumeTrue(Utils.isSPerfClass() || Utils.isRPerfClass() || !Utils.isPerfClass());
boolean hasVP9 = mMime.equals(MediaFormat.MIMETYPE_VIDEO_VP9);
- int requiredMinInstances = getRequiredMinConcurrentInstances(hasVP9);
+ int requiredMinInstances = getRequiredMinConcurrentInstances720p(hasVP9);
testCodec(720, 1280, 4000000, requiredMinInstances);
}
@@ -111,7 +109,7 @@ public class MultiEncoderPerfTest extends MultiCodecPerfTestBase {
ArrayList<Pair<String, String>> mimeEncoderPairs = new ArrayList<>();
mimeEncoderPairs.add(Pair.create(mMime, mEncoderName));
int maxInstances = checkAndGetMaxSupportedInstancesForCodecCombinations(height, width,
- mimeEncoderPairs);
+ mimeEncoderPairs, requiredMinInstances);
double achievedFrameRate = 0.0;
if (maxInstances >= requiredMinInstances) {
ExecutorService pool = Executors.newFixedThreadPool(maxInstances);
@@ -124,22 +122,22 @@ public class MultiEncoderPerfTest extends MultiCodecPerfTestBase {
achievedFrameRate += result.get();
}
}
+ PerformanceClassEvaluator pce = new PerformanceClassEvaluator(this.mTestName);
+ PerformanceClassEvaluator.ConcurrentCodecRequirement r5_1__H_1_3;
+ PerformanceClassEvaluator.ConcurrentCodecRequirement r5_1__H_1_4;
// Achieved frame rate is not compared as this test runs in byte buffer mode.
- if (Utils.isPerfClass()) {
- assertTrue("Encoder " + mEncoderName + " unable to support minimum concurrent " +
- "instances. act/exp: " + maxInstances + "/" + requiredMinInstances,
- maxInstances >= requiredMinInstances);
- Log.v(LOG_TAG, "Achieved fps: " + achievedFrameRate +
- "\nAchieved frame rate is not compared as this test runs in byte buffer mode");
+ if (height >= 1080) {
+ r5_1__H_1_3 = pce.addR5_1__H_1_3_1080p();
+ r5_1__H_1_4 = pce.addR5_1__H_1_4_1080p();
+ r5_1__H_1_3.setConcurrentInstances(maxInstances);
+ r5_1__H_1_4.setConcurrentFps(achievedFrameRate);
} else {
- int pc = maxInstances >= requiredMinInstances ? Build.VERSION_CODES.R : 0;
- DeviceReportLog log = new DeviceReportLog("MediaPerformanceClassLogs",
- "MultiEncoderPerf_" + mEncoderName);
- log.addValue("encoder", mMime + "_" + mEncoderName, ResultType.NEUTRAL,
- ResultUnit.NONE);
- log.setSummary("CDD 2.2.7.1/5.1/H-1-3,H-1-4 performance_class", pc, ResultType.NEUTRAL,
- ResultUnit.NONE);
- log.submit(InstrumentationRegistry.getInstrumentation());
+ r5_1__H_1_3 = pce.addR5_1__H_1_3_720p(mMime, mMime, height);
+ r5_1__H_1_4 = pce.addR5_1__H_1_4_720p();
+ r5_1__H_1_3.setConcurrentInstances(maxInstances);
+ r5_1__H_1_4.setConcurrentFps(achievedFrameRate);
}
+
+ pce.submitAndCheck();
}
}
diff --git a/tests/mediapc/src/android/mediapc/cts/MultiTranscoderPerfTest.java b/tests/mediapc/src/android/mediapc/cts/MultiTranscoderPerfTest.java
index 9312637450e..34ffc9b8814 100644
--- a/tests/mediapc/src/android/mediapc/cts/MultiTranscoderPerfTest.java
+++ b/tests/mediapc/src/android/mediapc/cts/MultiTranscoderPerfTest.java
@@ -19,23 +19,20 @@ package android.mediapc.cts;
import static org.junit.Assert.assertTrue;
import android.media.MediaFormat;
+import android.mediapc.cts.common.PerformanceClassEvaluator;
import android.mediapc.cts.common.Utils;
-import android.os.Build;
import android.util.Pair;
import android.view.Surface;
import androidx.test.filters.LargeTest;
-import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.rule.ActivityTestRule;
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.Assume;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.TestName;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -73,6 +70,9 @@ public class MultiTranscoderPerfTest extends MultiCodecPerfTestBase {
mEncoderPair = encoderPair;
}
+ @Rule
+ public final TestName mTestName = new TestName();
+
// Parameters {0}_{1}_{2} -- Pair(Mime DecoderName)_Pair(Mime EncoderName)_isAsync
@Parameterized.Parameters(name = "{index}({0}_{1}_{2})")
public static Collection<Object[]> inputParams() {
@@ -115,7 +115,7 @@ public class MultiTranscoderPerfTest extends MultiCodecPerfTestBase {
boolean hasVP9 = mDecoderPair.first.equals(MediaFormat.MIMETYPE_VIDEO_VP9)
|| mEncoderPair.first.equals(MediaFormat.MIMETYPE_VIDEO_VP9);
- int requiredMinInstances = getRequiredMinConcurrentInstances(hasVP9) / 2;
+ int requiredMinInstances = getRequiredMinConcurrentInstances720p(hasVP9);
testCodec(m720pTestFiles, 720, 1280, requiredMinInstances);
}
@@ -131,7 +131,7 @@ public class MultiTranscoderPerfTest extends MultiCodecPerfTestBase {
@CddTest(requirement = "2.2.7.1/5.1/H-1-5,H-1-6")
public void test1080p() throws Exception {
Assume.assumeTrue(Utils.isTPerfClass() || !Utils.isPerfClass());
- testCodec(m1080pTestFiles, 1080, 1920, REQUIRED_MIN_CONCURRENT_INSTANCES / 2);
+ testCodec(m1080pTestFiles, 1080, 1920, REQUIRED_MIN_CONCURRENT_INSTANCES);
}
private void testCodec(Map<String, String> testFiles, int height, int width,
@@ -141,7 +141,8 @@ public class MultiTranscoderPerfTest extends MultiCodecPerfTestBase {
mimeCodecPairs.add(mDecoderPair);
mimeCodecPairs.add(mEncoderPair);
int maxInstances =
- checkAndGetMaxSupportedInstancesForCodecCombinations(height, width, mimeCodecPairs);
+ checkAndGetMaxSupportedInstancesForCodecCombinations(height, width, mimeCodecPairs,
+ requiredMinInstances);
double achievedFrameRate = 0.0;
if (maxInstances >= requiredMinInstances) {
ExecutorService pool =
@@ -175,29 +176,22 @@ public class MultiTranscoderPerfTest extends MultiCodecPerfTestBase {
}
}
}
- if (Utils.isPerfClass()) {
- assertTrue("DecodeMime: " + mDecoderPair.first + ", Decoder " + mDecoderPair.second +
- ", EncodeMime: " + mEncoderPair.first + ", Encoder: " + mEncoderPair.second +
- ", unable to support minimum concurrent instances. act/exp: " + maxInstances +
- "/" + requiredMinInstances, maxInstances >= requiredMinInstances);
-
- assertTrue("Unable to achieve the maxFrameRate supported. act/exp: " + achievedFrameRate
- + "/" + mMaxFrameRate / 2 + " for " + maxInstances + " instances.",
- achievedFrameRate >= mMaxFrameRate / 2);
+
+ PerformanceClassEvaluator pce = new PerformanceClassEvaluator(this.mTestName);
+ PerformanceClassEvaluator.ConcurrentCodecRequirement r5_1__H_1_5;
+ PerformanceClassEvaluator.ConcurrentCodecRequirement r5_1__H_1_6;
+ if (height >= 1080) {
+ r5_1__H_1_5 = pce.addR5_1__H_1_5_1080p();
+ r5_1__H_1_6 = pce.addR5_1__H_1_6_1080p();
+ r5_1__H_1_5.setConcurrentInstances(maxInstances);
+ r5_1__H_1_6.setConcurrentFps(achievedFrameRate);
} else {
- int pc = maxInstances >= requiredMinInstances && achievedFrameRate >= mMaxFrameRate / 2
- ? Build.VERSION_CODES.R : 0;
- DeviceReportLog log = new DeviceReportLog("MediaPerformanceClassLogs",
- "MultiTranscoderPairPerf_" + mDecoderPair.second);
- log.addValue("decoders", mDecoderPair.first + "_" + mDecoderPair.second + "_"
- + mEncoderPair.first + "_" + mEncoderPair.second, ResultType.NEUTRAL,
- ResultUnit.NONE);
- log.addValue("achieved_framerate", achievedFrameRate, ResultType.HIGHER_BETTER,
- ResultUnit.NONE);
- log.addValue("expected_framerate", mMaxFrameRate, ResultType.NEUTRAL, ResultUnit.NONE);
- log.setSummary("CDD 2.2.7.1/5.1/H-1-5,H-1-6 performance_class", pc, ResultType.NEUTRAL,
- ResultUnit.NONE);
- log.submit(InstrumentationRegistry.getInstrumentation());
+ r5_1__H_1_5 = pce.addR5_1__H_1_5_720p(mDecoderPair.first, mEncoderPair.first, height);
+ r5_1__H_1_6 = pce.addR5_1__H_1_6_720p(mDecoderPair.first, mEncoderPair.first, height);
+ r5_1__H_1_5.setConcurrentInstances(maxInstances);
+ r5_1__H_1_6.setConcurrentFps(achievedFrameRate);
}
+
+ pce.submitAndCheck();
}
}
diff --git a/tests/mediapc/src/android/mediapc/cts/PerformanceClassTest.java b/tests/mediapc/src/android/mediapc/cts/PerformanceClassTest.java
index 24b22eae1b6..2508845049b 100644
--- a/tests/mediapc/src/android/mediapc/cts/PerformanceClassTest.java
+++ b/tests/mediapc/src/android/mediapc/cts/PerformanceClassTest.java
@@ -17,7 +17,7 @@
package android.mediapc.cts;
import static android.media.MediaCodecInfo.CodecCapabilities.FEATURE_SecurePlayback;
-
+import static android.media.MediaDrm.SECURITY_LEVEL_HW_SECURE_ALL;
import static org.junit.Assert.assertTrue;
import android.app.ActivityManager;
@@ -33,30 +33,26 @@ import android.mediapc.cts.common.Utils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.WindowManager;
-
import androidx.test.filters.SmallTest;
import androidx.test.platform.app.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 java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
import org.junit.Assume;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.UUID;
-
/**
* Tests the basic aspects of the media performance class.
*/
public class PerformanceClassTest {
private static final String TAG = "PerformanceClassTest";
- private static final UUID WIDEVINE_UUID = new UUID(0xEDEF8BA979D64ACEL, 0xA3C827DCD51D21EDL);
+ public static final String[] VIDEO_CONTAINER_MEDIA_TYPES =
+ {"video/mp4", "video/webm", "video/3gpp", "video/3gpp2", "video/avi", "video/x-ms-wmv",
+ "video/x-ms-asf"};
static ArrayList<String> mMimeSecureSupport = new ArrayList<>();
@Rule
@@ -83,8 +79,8 @@ public class PerformanceClassTest {
@SmallTest
@Test
- // TODO(b/218771970) Add @CddTest annotation
- public void testSecureHwDecodeSupport() throws IOException {
+ @CddTest(requirements = {"2.2.7.1/5.1/H-1-11"})
+ public void testSecureHwDecodeSupport() {
ArrayList<String> noSecureHwDecoderForMimes = new ArrayList<>();
for (String mime : mMimeSecureSupport) {
boolean isSecureHwDecoderFoundForMime = false;
@@ -110,46 +106,35 @@ public class PerformanceClassTest {
boolean secureDecodeSupportIfHwDecoderPresent = noSecureHwDecoderForMimes.isEmpty();
PerformanceClassEvaluator pce = new PerformanceClassEvaluator(this.mTestName);
- PerformanceClassEvaluator.SecureCodecRequirement rSecureDecodeSupport =
- pce.addRSecureDecodeSupport();
- rSecureDecodeSupport.setSecureReqSatisfied(secureDecodeSupportIfHwDecoderPresent);
+ PerformanceClassEvaluator.SecureCodecRequirement r5_1__H_1_11 = pce.addR5_1__H_1_11();
+ r5_1__H_1_11.setSecureReqSatisfied(secureDecodeSupportIfHwDecoderPresent);
pce.submitAndCheck();
}
@SmallTest
@Test
- // TODO(b/218771970) Add @CddTest annotation
- public void testWidevineSupport() throws UnsupportedSchemeException {
- boolean isWidevineSupported = MediaDrm.isCryptoSchemeSupported(WIDEVINE_UUID);
- boolean isL1Supported = false;
- boolean isL1Tier3Supported = false;
- boolean isOemCrypto17Plus = false;
- boolean isWidevineCdm17Plus = false;
- if (isWidevineSupported) {
- MediaDrm mediaDrm = new MediaDrm(WIDEVINE_UUID);
- isL1Supported = mediaDrm.getPropertyString("securityLevel").equals("L1");
- int tier = Integer.parseInt(mediaDrm.getPropertyString("resourceRatingTier"));
- isL1Tier3Supported = tier >= 3;
-
- String oemCryptoVersionProperty = mediaDrm.getPropertyString("oemCryptoApiVersion");
- int oemCryptoVersion = Integer.parseInt(oemCryptoVersionProperty);
- isOemCrypto17Plus = oemCryptoVersion >= 17;
-
- String cdmVersionProperty = mediaDrm.getPropertyString(MediaDrm.PROPERTY_VERSION);
- int cdmMajorVersion = Integer.parseInt(cdmVersionProperty.split("\\.", 2)[0]);
- isWidevineCdm17Plus = cdmMajorVersion >= 17;
+ @CddTest(requirements = {"2.2.7.1/5.7/H-1-2"})
+ public void testMediaDrmSecurityLevelHwSecureAll() throws UnsupportedSchemeException {
+ List<UUID> drmList = MediaDrm.getSupportedCryptoSchemes();
+ List<UUID> supportedHwSecureAllSchemes = new ArrayList<>();
+
+ for (UUID cryptoSchemeUUID : drmList) {
+ boolean cryptoSchemeSupportedForAtleastOneMediaType = false;
+ for (String mediaType : VIDEO_CONTAINER_MEDIA_TYPES) {
+ cryptoSchemeSupportedForAtleastOneMediaType |= MediaDrm
+ .isCryptoSchemeSupported(cryptoSchemeUUID, mediaType,
+ SECURITY_LEVEL_HW_SECURE_ALL);
+ }
+ if (cryptoSchemeSupportedForAtleastOneMediaType) {
+ supportedHwSecureAllSchemes.add(cryptoSchemeUUID);
+ }
}
PerformanceClassEvaluator pce = new PerformanceClassEvaluator(this.mTestName);
- PerformanceClassEvaluator.SecureCodecRequirement rWidevineReqSupport =
- pce.addRWidevineSupport();
+ PerformanceClassEvaluator.SecureCodecRequirement r5_7__H_1_2 = pce.addR5_7__H_1_2();
- rWidevineReqSupport.setWidevineSupported(isWidevineSupported);
- rWidevineReqSupport.setWidevineL1Supported(isL1Supported);
- rWidevineReqSupport.setWidevineL1Tier3Supported(isL1Tier3Supported);
- rWidevineReqSupport.setOemCrypto17Plus(isOemCrypto17Plus);
- rWidevineReqSupport.setWidevineCdm17Plus(isWidevineCdm17Plus);
+ r5_7__H_1_2.setNumCryptoHwSecureAllDec(supportedHwSecureAllSchemes.size());
pce.submitAndCheck();
}
@@ -190,19 +175,15 @@ public class PerformanceClassTest {
PerformanceClassEvaluator.DensityRequirement r7_1_1_3__h_1_1 = pce.addR7_1_1_3__H_1_1();
PerformanceClassEvaluator.ResolutionRequirement r7_1_1_1__h_2_1 = pce.addR7_1_1_1__H_2_1();
PerformanceClassEvaluator.DensityRequirement r7_1_1_3__h_2_1 = pce.addR7_1_1_3__H_2_1();
- PerformanceClassEvaluator.ResolutionRequirement r7_1_1_1__tbd1 = pce.addR7_1_1_1__TBD1();
- PerformanceClassEvaluator.DensityRequirement r7_1_1_3__tbd2 = pce.addR7_1_1_3__TBD2();
r7_1_1_1__h_1_1.setLongResolution(longPix);
r7_1_1_1__h_2_1.setLongResolution(longPix);
- r7_1_1_1__tbd1.setLongResolution(longPix);
+
r7_1_1_1__h_1_1.setShortResolution(shortPix);
r7_1_1_1__h_2_1.setShortResolution(shortPix);
- r7_1_1_1__tbd1.setShortResolution(shortPix);
r7_1_1_3__h_1_1.setDisplayDensity(density);
r7_1_1_3__h_2_1.setDisplayDensity(density);
- r7_1_1_3__tbd2.setDisplayDensity(density);
pce.submitAndCheck();
}
@@ -210,8 +191,7 @@ public class PerformanceClassTest {
@Test
@CddTest(requirements={
"2.2.7.3/7.6.1/H-1-1",
- "2.2.7.3/7.6.1/H-2-1",
- "2.2.7.3/7.6.1/H-3-1"})
+ "2.2.7.3/7.6.1/H-2-1",})
public void testMinimumMemory() {
Context context = InstrumentationRegistry.getInstrumentation().getContext();
@@ -224,11 +204,9 @@ public class PerformanceClassTest {
PerformanceClassEvaluator pce = new PerformanceClassEvaluator(this.mTestName);
PerformanceClassEvaluator.MemoryRequirement r7_6_1_h_1_1 = pce.addR7_6_1__H_1_1();
PerformanceClassEvaluator.MemoryRequirement r7_6_1_h_2_1 = pce.addR7_6_1__H_2_1();
- PerformanceClassEvaluator.MemoryRequirement r7_6_1_h_3_1 = pce.addR7_6_1__H_3_1();
r7_6_1_h_1_1.setPhysicalMemory(totalMemoryMb);
r7_6_1_h_2_1.setPhysicalMemory(totalMemoryMb);
- r7_6_1_h_3_1.setPhysicalMemory(totalMemoryMb);
pce.submitAndCheck();
}
diff --git a/tests/mediapc/src/android/mediapc/cts/VideoCodecRequirementsTest.java b/tests/mediapc/src/android/mediapc/cts/VideoCodecRequirementsTest.java
index 4a9d39f127d..bbe26dce0ac 100644
--- a/tests/mediapc/src/android/mediapc/cts/VideoCodecRequirementsTest.java
+++ b/tests/mediapc/src/android/mediapc/cts/VideoCodecRequirementsTest.java
@@ -29,6 +29,7 @@ import android.media.MediaFormat;
import android.mediapc.cts.common.PerformanceClassEvaluator;
import android.util.Log;
import androidx.test.filters.LargeTest;
+import com.android.compatibility.common.util.CddTest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
@@ -78,7 +79,7 @@ public class VideoCodecRequirementsTest {
*/
@LargeTest
@Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS)
- // TODO(b/218771970) Add @CddTest annotation
+ @CddTest(requirement = "2.2.7.1/5.1/H-1-14")
public void testAV1HwDecoderRequirements() throws Exception {
MediaFormat format = MediaFormat.createVideoFormat(MIMETYPE_VIDEO_AV1, 1920, 1080);
format.setInteger(MediaFormat.KEY_FRAME_RATE, 60);
@@ -107,7 +108,7 @@ public class VideoCodecRequirementsTest {
*/
@LargeTest
@Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS)
- // TODO(b/218771970) Add @CddTest annotation
+ @CddTest(requirement = "2.2.7.1/5.1/H-1-15")
public void test4k60Decoder() throws IOException {
Set<String> decoderSet = get4k60HwCodecSet(false);
@@ -123,7 +124,7 @@ public class VideoCodecRequirementsTest {
*/
@LargeTest
@Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS)
- // TODO(b/218771970) Add @CddTest annotation
+ @CddTest(requirement = "2.2.7.1/5.1/H-1-16")
public void test4k60Encoder() throws IOException {
Set<String> encoderSet = get4k60HwCodecSet(true);
diff --git a/tests/musicrecognition/Android.bp b/tests/musicrecognition/Android.bp
index 1b7298a6898..ecda10b2926 100644
--- a/tests/musicrecognition/Android.bp
+++ b/tests/musicrecognition/Android.bp
@@ -31,4 +31,8 @@ android_test {
"cts",
"general-tests",
],
+ data: [
+ ":CtsOutsideOfPackageService",
+ ],
+ per_testcase_directory: true,
}
diff --git a/tests/net/src/android/net/cts/LocalSocketTest.java b/tests/net/src/android/net/cts/LocalSocketTest.java
index 39b5dbcdb46..c302f818528 100644
--- a/tests/net/src/android/net/cts/LocalSocketTest.java
+++ b/tests/net/src/android/net/cts/LocalSocketTest.java
@@ -30,12 +30,9 @@ import android.net.Credentials;
import android.net.LocalServerSocket;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
-import android.os.ParcelFileDescriptor;
-import android.os.SystemClock;
import android.system.Os;
import android.system.OsConstants;
import android.system.StructTimeval;
-import android.system.UnixSocketAddress;
import androidx.test.runner.AndroidJUnit4;
@@ -196,7 +193,7 @@ public class LocalSocketTest {
}
// http://b/31205169
- @Test
+ @Test @IgnoreUpTo(SC_V2) // Crashes on pre-T due to a JNI bug. See http://r.android.com/2096720
public void testSetSoTimeout_readTimeout() throws Exception {
String address = ADDRESS_PREFIX + "_testSetSoTimeout_readTimeout";
diff --git a/tests/providerui/src/android/providerui/cts/MediaStoreUiTest.java b/tests/providerui/src/android/providerui/cts/MediaStoreUiTest.java
index 542b3aa9db6..0e1bcd1da66 100644
--- a/tests/providerui/src/android/providerui/cts/MediaStoreUiTest.java
+++ b/tests/providerui/src/android/providerui/cts/MediaStoreUiTest.java
@@ -405,7 +405,8 @@ public class MediaStoreUiTest {
private boolean supportsHardware() {
final PackageManager pm = mContext.getPackageManager();
return !pm.hasSystemFeature("android.hardware.type.television")
- && !pm.hasSystemFeature("android.hardware.type.watch");
+ && !pm.hasSystemFeature("android.hardware.type.watch")
+ && !pm.hasSystemFeature("android.hardware.type.automotive");
}
public File getVolumePath(String volumeName) {
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 671078dbdeb..7f35367333a 100644
--- a/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java
+++ b/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java
@@ -196,6 +196,15 @@ public class MainInteractionSession extends VoiceInteractionSession {
return;
}
+ if (structure != null && structure.isHomeActivity() && !state.isFocused()) {
+ // If the system has multiple display areas, the launcher may be visible and resumed
+ // when the tests are in progress, so the tests might fail if they receives unexpected
+ // state from the launcher. Ignore the states from unfocused launcher to avoid this
+ // failure.
+ Log.i(TAG, "Ignoring the state from unfocused launcher");
+ return;
+ }
+
// send to test to verify that this is accurate.
mAssistData.putBoolean(Utils.ASSIST_IS_ACTIVITY_ID_NULL, state.getActivityId() == null);
mAssistData.putParcelable(Utils.ASSIST_STRUCTURE_KEY, structure);
diff --git a/tests/tests/carrierapi/src/android/carrierapi/cts/CarrierApiTest.java b/tests/tests/carrierapi/src/android/carrierapi/cts/CarrierApiTest.java
index e4fbee6805d..5afdbb118a6 100644
--- a/tests/tests/carrierapi/src/android/carrierapi/cts/CarrierApiTest.java
+++ b/tests/tests/carrierapi/src/android/carrierapi/cts/CarrierApiTest.java
@@ -525,10 +525,9 @@ public class CarrierApiTest extends BaseCarrierApiTest {
mTelephonyManager.getServiceState();
mTelephonyManager.getManualNetworkSelectionPlmn();
mTelephonyManager.setForbiddenPlmns(new ArrayList<String>());
- int activeModemCount = mTelephonyManager.getActiveModemCount();
- for (int i = 0; i < activeModemCount; i++) {
- mTelephonyManager.isModemEnabledForSlot(i);
- }
+ // TODO(b/235490259): test all slots once TM#isModemEnabledForSlot allows
+ mTelephonyManager.isModemEnabledForSlot(
+ SubscriptionManager.getSlotIndex(mTelephonyManager.getSubscriptionId()));
} catch (SecurityException e) {
fail(NO_CARRIER_PRIVILEGES_FAILURE_MESSAGE);
}
@@ -1105,7 +1104,7 @@ public class CarrierApiTest extends BaseCarrierApiTest {
}
// Set subscription group with current sub Id.
- int subId = SubscriptionManager.getDefaultDataSubscriptionId();
+ int subId = SubscriptionManager.getDefaultSubscriptionId();
if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) return;
ParcelUuid uuid = ShellIdentityUtils.invokeMethodWithShellPermissions(mSubscriptionManager,
(sm) -> sm.createSubscriptionGroup(Arrays.asList(subId)));
@@ -1142,7 +1141,7 @@ public class CarrierApiTest extends BaseCarrierApiTest {
@Test
public void testAddSubscriptionToExistingGroupForEsim() {
// Set subscription group with current sub Id.
- int subId = SubscriptionManager.getDefaultDataSubscriptionId();
+ int subId = SubscriptionManager.getDefaultSubscriptionId();
if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) return;
ParcelUuid uuid = mSubscriptionManager.createSubscriptionGroup(Arrays.asList(subId));
@@ -1172,7 +1171,7 @@ public class CarrierApiTest extends BaseCarrierApiTest {
*/
@Test
public void testOpportunistic() {
- int subId = SubscriptionManager.getDefaultDataSubscriptionId();
+ int subId = SubscriptionManager.getDefaultSubscriptionId();
if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) return;
SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(subId);
boolean oldOpportunistic = info.isOpportunistic();
diff --git a/tests/tests/companion/common/src/android/companion/cts/common/TestBase.kt b/tests/tests/companion/common/src/android/companion/cts/common/TestBase.kt
index 8c03abd8c53..ef9d958dfb9 100644
--- a/tests/tests/companion/common/src/android/companion/cts/common/TestBase.kt
+++ b/tests/tests/companion/common/src/android/companion/cts/common/TestBase.kt
@@ -79,8 +79,7 @@ abstract class TestBase {
})
// Make sure CompanionDeviceServices are not bound.
- assertFalse(PrimaryCompanionService.isBound)
- assertFalse(SecondaryCompanionService.isBound)
+ assertValidCompanionDeviceServicesUnbind()
setUp()
}
diff --git a/tests/tests/content/src/android/content/pm/cts/ChecksumsTest.java b/tests/tests/content/src/android/content/pm/cts/ChecksumsTest.java
index 5cb59c24c3f..4359d7d171a 100644
--- a/tests/tests/content/src/android/content/pm/cts/ChecksumsTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/ChecksumsTest.java
@@ -52,10 +52,12 @@ import android.content.pm.PackageInstaller.SessionParams;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.content.pm.cts.util.AbandonAllPackageSessionsRule;
+import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
+import android.os.SystemProperties;
import android.platform.test.annotations.AppModeFull;
import android.util.ExceptionUtils;
@@ -71,6 +73,7 @@ import com.android.server.pm.PackageManagerShellCommandDataLoader.Metadata;
import org.junit.After;
import org.junit.Assert;
+import org.junit.Assume;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -152,6 +155,11 @@ public class ChecksumsTest {
new Checksum(TYPE_WHOLE_SHA256, hexStringToBytes(TEST_FIXED_APK_SHA256)),
new Checksum(TYPE_WHOLE_MD5, hexStringToBytes(TEST_FIXED_APK_MD5))};
+ /** Default is to not use fs-verity since it depends on kernel support. */
+ private static final int FSVERITY_DISABLED = 0;
+
+ /** Standard fs-verity. */
+ private static final int FSVERITY_ENABLED = 2;
private static final byte[] NO_SIGNATURE = null;
@@ -315,6 +323,7 @@ public class ChecksumsTest {
@LargeTest
@Test
public void testFixedFSVerityDefaultChecksums() throws Exception {
+ Assume.assumeTrue(isApkVerityEnabled());
installApkWithFSVerity(TEST_FIXED_APK_FSVERITY, TEST_FIXED_APK_FSVERITY_FSVSIG);
assertTrue(isAppInstalled(FIXED_FSVERITY_PACKAGE_NAME));
@@ -1513,6 +1522,13 @@ public class ChecksumsTest {
return getPackageManager().hasSystemFeature(PackageManager.FEATURE_INCREMENTAL_DELIVERY);
}
+ // From PackageManagerServiceUtils.
+ private static boolean isApkVerityEnabled() {
+ return Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.R
+ || SystemProperties.getInt("ro.apk_verity.mode", FSVERITY_DISABLED)
+ == FSVERITY_ENABLED;
+ }
+
private byte[] readSignature() throws IOException {
return readSignature(TEST_FIXED_APK_DIGESTS_SIGNATURE);
}
diff --git a/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandMultiUserTest.kt b/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandMultiUserTest.kt
index cf9dde09e22..416d19f7615 100644
--- a/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandMultiUserTest.kt
+++ b/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandMultiUserTest.kt
@@ -237,19 +237,21 @@ class PackageManagerShellCommandMultiUserTest {
val intentFilter = IntentFilter()
intentFilter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED)
intentFilter.addDataScheme("package")
- context.registerReceiver(
- broadcastReceiverForPrimaryUser,
- intentFilter,
- null,
- backgroundHandler,
- RECEIVER_EXPORTED
- )
uiAutomation.adoptShellPermissionIdentity(
Manifest.permission.INTERACT_ACROSS_USERS,
Manifest.permission.INTERACT_ACROSS_USERS_FULL
)
+ val contextPrimaryUser = context.createContextAsUser(primaryUser.userHandle(), 0)
+ val contextSecondaryUser = context.createContextAsUser(secondaryUser.userHandle(), 0)
try {
- context.createContextAsUser(secondaryUser.userHandle(), 0).registerReceiver(
+ contextPrimaryUser.registerReceiver(
+ broadcastReceiverForPrimaryUser,
+ intentFilter,
+ null,
+ backgroundHandler,
+ RECEIVER_EXPORTED
+ )
+ contextSecondaryUser.registerReceiver(
broadcastReceiverForSecondaryUser,
intentFilter,
null,
diff --git a/tests/tests/dreams/src/android/service/dreams/cts/DreamServiceTest.java b/tests/tests/dreams/src/android/service/dreams/cts/DreamServiceTest.java
index 227c81ec7ee..166227ab916 100644
--- a/tests/tests/dreams/src/android/service/dreams/cts/DreamServiceTest.java
+++ b/tests/tests/dreams/src/android/service/dreams/cts/DreamServiceTest.java
@@ -16,8 +16,10 @@
package android.service.dreams.cts;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assume.assumeFalse;
import android.content.ComponentName;
+import android.content.pm.PackageManager;
import android.server.wm.ActivityManagerTestBase;
import android.server.wm.DreamCoordinator;
import android.service.dreams.DreamService;
@@ -65,6 +67,9 @@ public class DreamServiceTest extends ActivityManagerTestBase {
@Test
public void testDreamInSeparateProcess() {
+ assumeFalse(mContext.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_AUTOMOTIVE));
+
final ComponentName dreamService =
ComponentName.unflattenFromString(DREAM_SERVICE_COMPONENT);
final ComponentName dreamActivity = mDreamCoordinator.setActiveDream(dreamService);
diff --git a/tests/tests/graphics/AndroidManifest.xml b/tests/tests/graphics/AndroidManifest.xml
index 64061339025..9a1c59142d6 100644
--- a/tests/tests/graphics/AndroidManifest.xml
+++ b/tests/tests/graphics/AndroidManifest.xml
@@ -55,6 +55,23 @@
<activity android:name="android.graphics.drawable.cts.DrawableStubActivity"
android:theme="@style/WhiteBackgroundNoWindowAnimation"
android:screenOrientation="locked"/>
+
+ <activity android:name="android.graphics.cts.EmptyActivity"
+ android:label="Empty Activity"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
+ <activity android:name="android.graphics.cts.EmptyActivity2"
+ android:label="Empty Activity 2"
+ android:exported="true">
+ <intent-filter>
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST"/>
+ </intent-filter>
+ </activity>
<activity android:name="android.graphics.drawable.cts.AnimatedImageActivity"
android:theme="@style/WhiteBackgroundNoWindowAnimation"
android:screenOrientation="locked">
diff --git a/tests/tests/graphics/res/xml/valid_themes.xml b/tests/tests/graphics/res/xml/valid_themes.xml
index a7619d46a56..a7e230417a3 100644
--- a/tests/tests/graphics/res/xml/valid_themes.xml
+++ b/tests/tests/graphics/res/xml/valid_themes.xml
@@ -19,7 +19,7 @@
<theme color="ffb9577a">
<spritz>ffffff,fffbff,ffecf0,f9dbe2,dcbfc6,c0a4ab,a48a90,887076,6f595e,564147,3e2b31,27171c,000000,ffffff,fffbff,ffecf0,f2dde1,d5c2c6,b9a7aa,9e8c90,827276,6a5b5e,514347,3a2d30,24191c,000000,ffffff,fffbff,ffecf0,ffd9e2,e3bdc6,c6a2ab,aa8891,8d6e76,74565f,5b3f47,422931,2b151c,000000,ffffff,fffbff,f7efef,e8e1e1,ccc5c5,b0aaaa,958f90,7a7575,625d5e,4a4646,332f30,1e1b1b,000000,ffffff,fffbff,f7efef,e8e1e1,ccc5c5,b0aaaa,958f90,7a7575,625d5e,4a4646,332f30,1e1b1b,000000</spritz>
<tonal_spot>ffffff,fffbff,ffecf0,ffd9e2,ffb1c8,e494ad,c67b92,a76178,8c4a60,703348,541d32,3a071d,000000,ffffff,fffbff,ffecf0,ffd9e2,e3bdc6,c6a2ab,aa8891,8d6e76,74565f,5b3f47,422931,2b151c,000000,ffffff,fffbff,ffeee2,ffdcc1,efbd94,d1a27b,b48862,976d4a,7c5635,613f20,48290b,2e1500,000000,ffffff,fffbff,faeeef,ebe0e1,cfc4c5,b3a9aa,988e90,7d7475,645c5e,4c4546,352f30,201a1b,000000,ffffff,fffbff,ffecf0,f2dde1,d5c2c6,b9a7aa,9e8c90,827276,6a5b5e,514347,3a2d30,24191c,000000</tonal_spot>
- <vibrant>ffffff,fffbff,ffecf0,ffd9e2,ffb1c8,ff84ae,ff4896,e5007b,b90063,8e004a,650033,3e001d,000000,ffffff,fffbff,ffedec,ffdad9,f5b7b7,d79c9c,ba8382,9c6968,815252,663b3b,4c2526,331112,000000,ffffff,fffbff,ffede8,ffdbd1,ffb59f,e49982,c67f6a,a76551,8b4e3c,6e3726,532212,370d02,000000,ffffff,fffbff,ffecf0,f2dde1,d5c2c6,b9a7aa,9e8c90,827276,6a5b5e,514347,3a2d30,24191c,000000,ffffff,fffbff,ffecf0,f9dbe2,dcbfc6,c0a4ab,a48a90,887076,6f595e,564147,3e2b31,27171c,000000</vibrant>
+ <vibrant>ffffff,fffbff,ffecf0,ffd9e2,ffb1c8,ff84ae,ff4896,e5007b,b90063,8e004a,650033,3e001d,000000,ffffff,fffbff,ffedec,ffdad9,f5b7b7,d79c9c,ba8382,9c6968,815252,663b3b,4c2526,331112,000000,ffffff,fffbff,ffede8,ffdbd1,ffb59f,e49982,c67f6a,a76551,8b4e3c,6e3726,532212,370d02,000000,ffffff,fffbff,ffecf0,f6dce2,d9c0c6,bca5ab,a18b90,857176,6c5a5e,534247,3c2c30,25181c,000000,ffffff,fffbff,ffecf0,f9dbe2,dcbfc6,c0a4ab,a48a90,887076,6f595e,564147,3e2b31,27171c,000000</vibrant>
<expressive>ffffff,fbfcff,e5f2ff,c8e6ff,8bcefd,6fb2e0,5298c4,337da8,0c648e,004c6d,00344d,001e2e,000000,ffffff,fffbff,ffede6,ffdbcb,f4ba9e,d69f85,b9856c,9b6b53,80543e,653d28,4b2714,311303,000000,ffffff,fcffdd,ebf8ad,dde9a0,c1cd86,a6b16e,8b9656,717b3e,596329,424b13,2c3400,181e00,000000,ffffff,fffbff,ffedec,f4dddd,d7c1c2,bba6a7,9f8c8c,847272,6b5a5b,524343,3b2d2d,241819,000000,ffffff,fffbff,ffedec,fcdbdb,debfc0,c2a4a5,a68a8b,8a7070,715859,584142,3f2b2c,281718,000000</expressive>
<rainbow>ffffff,fffbff,ffecf0,ffd9e2,ffb1c8,f48bae,d57193,b55779,984061,7b2949,5e1132,3e001d,000000,ffffff,fffbff,ffecf0,ffd9e2,e3bdc6,c6a2ab,aa8891,8d6e76,74565f,5b3f47,422931,2b151c,000000,ffffff,fffbff,ffeee2,ffdcc1,efbd94,d1a27b,b48862,976d4a,7c5635,613f20,48290b,2e1500,000000,ffffff,fcfcfc,f1f1f1,e2e2e2,c6c6c6,ababab,919191,767676,5e5e5e,474747,303030,1b1b1b,000000,ffffff,fcfcfc,f1f1f1,e2e2e2,c6c6c6,ababab,919191,767676,5e5e5e,474747,303030,1b1b1b,000000</rainbow>
<fruit_salad>ffffff,fffbff,f9ecff,f0dbff,dcb8ff,c598f1,a97ed4,8d64b7,744c9d,5b3383,431a6b,2c0051,000000,ffffff,fffbff,f9ecff,f0dbff,dab9f9,be9edc,a384c0,876aa4,6e528a,553b71,3e2459,280d42,000000,ffffff,fffbff,ffecf0,ffd9e2,ffb1c8,e494ad,c67b92,a76178,8c4a60,703348,541d32,3a071d,000000,ffffff,fffbff,ffecf0,f6dce2,d9c0c6,bca5ab,a18b90,857176,6c5a5e,534247,3c2c30,25181c,000000,ffffff,fffbff,ffecf0,ffd9e2,e3bdc6,c6a2ab,aa8891,8d6e76,74565f,5b3f47,422931,2b151c,000000</fruit_salad>
@@ -27,7 +27,7 @@
<theme color="ffb16407">
<spritz>ffffff,fffbff,ffeee2,f9ddc9,dcc2ae,c0a793,a48c7a,887261,6f5a4a,564334,3d2d1f,27190c,000000,ffffff,fffbff,ffeee2,f2dfd1,d6c3b6,b9a89b,9e8e82,827368,6a5c51,51443a,3a2e25,231a11,000000,ffffff,fffbff,ffeee2,ffdcc1,e2c0a5,c6a58b,a98b72,8d7159,735943,5a422d,412c19,2a1706,000000,ffffff,fffbff,f7efec,e8e1dd,ccc5c2,b0aaa7,95908d,7a7572,625d5b,4a4644,33302e,1e1b19,000000,ffffff,fffbff,f7efec,e8e1dd,ccc5c2,b0aaa7,95908d,7a7572,625d5b,4a4644,33302e,1e1b19,000000</spritz>
<tonal_spot>ffffff,fffbff,ffeee2,ffdcc1,ffb778,e09d60,c28349,a36931,87521c,6b3b04,4c2700,2e1500,000000,ffffff,fffbff,ffeee2,ffdcc1,e2c0a5,c6a58b,a98b72,8d7159,735943,5a422d,412c19,2a1706,000000,ffffff,fcffde,edf6bf,dfe7b2,c3cb98,a8b07e,8d9566,727a4d,5b6238,434a22,2d330e,181e00,000000,ffffff,fffbff,faefe8,ece0da,cfc4be,b3a9a3,988f89,7d746f,655d58,4c4541,352f2b,201b17,000000,ffffff,fffbff,ffeee2,f2dfd1,d6c3b6,b9a89b,9e8e82,827368,6a5c51,51443a,3a2e25,231a11,000000</tonal_spot>
- <vibrant>ffffff,fffbff,ffeee2,ffdcc1,ffb778,fd9000,d77900,b06200,8e4e00,6c3a00,4c2700,2e1500,000000,ffffff,fffbff,ffeedc,ffddb2,e6c08d,c9a574,ad8b5c,907144,76592f,5c421a,432c06,291800,000000,ffffff,fffbff,ffefcf,ffe090,e1c477,c4a85f,a88e48,8c7330,725c1a,584401,3d2e00,241a00,000000,ffffff,fffbff,ffeee2,f2dfd1,d6c3b6,b9a89b,9e8e82,827368,6a5c51,51443a,3a2e25,231a11,000000,ffffff,fffbff,ffeee2,f9ddc9,dcc2ae,c0a793,a48c7a,887261,6f5a4a,564334,3d2d1f,27190c,000000</vibrant>
+ <vibrant>ffffff,fffbff,ffeee2,ffdcc1,ffb778,fd9000,d77900,b06200,8e4e00,6c3a00,4c2700,2e1500,000000,ffffff,fffbff,ffeedc,ffddb2,e6c08d,c9a574,ad8b5c,907144,76592f,5c421a,432c06,291800,000000,ffffff,fffbff,ffefcf,ffe090,e1c477,c4a85f,a88e48,8c7330,725c1a,584401,3d2e00,241a00,000000,ffffff,fffbff,ffeee2,f6decd,d9c2b2,bda797,a18d7e,857364,6c5b4e,534437,3c2e22,25190f,000000,ffffff,fffbff,ffeee2,f9ddc9,dcc2ae,c0a793,a48c7a,887261,6f5a4a,564334,3d2d1f,27190c,000000</vibrant>
<expressive>ffffff,fffbff,f6edff,eaddff,d1bcff,b6a0e8,9b85cb,7f6baf,675395,4f3b7b,382463,220b4d,000000,ffffff,fffbff,fbf2b7,ece4aa,cfc890,b3ad77,98925f,7d7747,656031,4c481c,353107,1f1c00,000000,ffffff,fffbff,ffeed9,ffdeaa,ebc078,cda55f,b08b48,937030,79591b,5e4102,422c00,271900,000000,ffffff,fffbff,feeedd,efe0cf,d3c4b4,b7a99a,9b8f80,807466,675d50,4f4539,382f24,221a10,000000,ffffff,fffbff,ffeedc,f5dfc6,d8c3ab,bba891,a08e77,84735e,6b5c48,524432,3b2e1d,241a0a,000000</expressive>
<rainbow>ffffff,fffbff,ffeee2,ffdcc1,ffb778,ee9743,ce7d2b,ae640f,8e4e00,6c3a00,4c2700,2e1500,000000,ffffff,fffbff,ffeee2,ffdcc1,e2c0a5,c6a58b,a98b72,8d7159,735943,5a422d,412c19,2a1706,000000,ffffff,fcffde,edf6bf,dfe7b2,c3cb98,a8b07e,8d9566,727a4d,5b6238,434a22,2d330e,181e00,000000,ffffff,fcfcfc,f1f1f1,e2e2e2,c6c6c6,ababab,919191,767676,5e5e5e,474747,303030,1b1b1b,000000,ffffff,fcfcfc,f1f1f1,e2e2e2,c6c6c6,ababab,919191,767676,5e5e5e,474747,303030,1b1b1b,000000</rainbow>
<fruit_salad>ffffff,fffbff,ffeced,ffd9dd,ffb2bb,f98a9b,d97181,b95767,9b4051,7d293a,5f1125,400012,000000,ffffff,fffbff,ffeced,ffd9dd,ffb2bb,e8949f,c97a85,aa606b,8e4954,72333d,561d28,3b0714,000000,ffffff,fffbff,ffeee2,ffdcc1,ffb778,e09d60,c28349,a36931,87521c,6b3b04,4c2700,2e1500,000000,ffffff,fffbff,ffeee2,f6decd,d9c2b2,bda797,a18d7e,857364,6c5b4e,534437,3c2e22,25190f,000000,ffffff,fffbff,ffeee2,ffdcc1,e2c0a5,c6a58b,a98b72,8d7159,735943,5a422d,412c19,2a1706,000000</fruit_salad>
@@ -35,7 +35,7 @@
<theme color="ff6e7f10">
<spritz>ffffff,fdfee4,f1f3d8,e3e4cb,c6c8b0,abad95,90937c,757862,5d604c,464835,2f3220,1a1d0d,000000,ffffff,fefdec,f2f2e1,e4e3d3,c7c7b7,acac9d,919283,767769,5e5f52,46483b,303126,1b1c12,000000,ffffff,fcffdd,f0f4d0,e2e5c2,c5c9a8,aaae8e,8f9375,74795b,5d6145,45492f,2e321b,1a1d08,000000,ffffff,fcffdd,f4f0ec,e5e2de,c9c6c2,adaba7,92908d,777672,5f5e5b,474744,31302e,1c1c19,000000,ffffff,fcffdd,f4f0ec,e5e2de,c9c6c2,adaba7,92908d,777672,5f5e5b,474744,31302e,1c1c19,000000</spritz>
<tonal_spot>ffffff,fcffdd,eaf8a4,dcea97,c0ce7e,a5b265,8a974e,707c36,586420,414b08,2c3400,181e00,000000,ffffff,fcffdd,f0f4d0,e2e5c2,c5c9a8,aaae8e,8f9375,74795b,5d6145,45492f,2e321b,1a1d08,000000,ffffff,f3fffa,cbfbed,bdecdf,a2d0c3,87b4a8,6d998e,527e74,3a665c,224e45,05372f,00201a,000000,ffffff,fffcf4,f3f1e8,e5e2da,c8c7bf,adaba4,92918a,77766f,5f5f58,474741,31312b,1b1c17,000000,ffffff,fefdec,f2f2e1,e4e3d3,c7c7b7,acac9d,919283,767769,5e5f52,46483b,303126,1b1c12,000000</tonal_spot>
- <vibrant>ffffff,fcffdd,e9f99b,d0f100,b7d300,9db600,859a00,6c7e00,566500,404c00,2c3400,181e00,000000,ffffff,f9ffe9,e4f8c7,d6e9ba,bacd9f,9fb286,85976d,6a7c54,53643e,3c4c28,263514,111f03,000000,ffffff,f6ffef,d0fdc6,c2eeb9,a7d29e,8cb685,729b6c,588053,41673d,2a4f28,133813,002203,000000,ffffff,fefdec,f2f2e1,e4e3d3,c7c7b7,acac9d,919283,767769,5e5f52,46483b,303126,1b1c12,000000,ffffff,fdfee4,f1f3d8,e3e4cb,c6c8b0,abad95,90937c,757862,5d604c,464835,2f3220,1a1d0d,000000</vibrant>
+ <vibrant>ffffff,fcffdd,e9f99b,d0f100,b7d300,9db600,859a00,6c7e00,566500,404c00,2c3400,181e00,000000,ffffff,f9ffe9,e4f8c7,d6e9ba,bacd9f,9fb286,85976d,6a7c54,53643e,3c4c28,263514,111f03,000000,ffffff,f6ffef,d0fdc6,c2eeb9,a7d29e,8cb685,729b6c,588053,41673d,2a4f28,133813,002203,000000,ffffff,fdfee8,f2f2dd,e3e4cf,c7c8b3,abad99,91927f,767766,5e604f,464838,2f3223,1b1d10,000000,ffffff,fdfee4,f1f3d8,e3e4cb,c6c8b0,abad95,90937c,757862,5d604c,464835,2f3220,1a1d0d,000000</vibrant>
<expressive>ffffff,fffbff,ffecf0,ffd9e2,ffb1c8,e991ad,cb7893,ac5e78,904760,733049,581932,3c031d,000000,ffffff,f4fff6,d0fbe1,c2ecd4,a6d0b8,8bb49e,719984,577e6a,406653,284e3c,0f3726,002114,000000,ffffff,f7ffed,d5fcc1,c7eeb3,acd199,91b580,779a67,5d7f4f,466739,2f4e23,19370f,042100,000000,ffffff,fafeef,eff2e4,e0e4d6,c4c8ba,a9ada0,8e9286,73786c,5b6055,44483e,2d3228,191d14,000000,ffffff,f8ffeb,ebf4dd,dde6d0,c1cab4,a6ae9a,8b9480,717966,596150,414939,2b3324,171e10,000000</expressive>
<rainbow>ffffff,fcffdd,e9f99b,d9ec7b,bdd062,a2b44a,879932,6d7d17,566500,404c00,2c3400,181e00,000000,ffffff,fcffdd,f0f4d0,e2e5c2,c5c9a8,aaae8e,8f9375,74795b,5d6145,45492f,2e321b,1a1d08,000000,ffffff,f3fffa,cbfbed,bdecdf,a2d0c3,87b4a8,6d998e,527e74,3a665c,224e45,05372f,00201a,000000,ffffff,fcfcfc,f1f1f1,e2e2e2,c6c6c6,ababab,919191,767676,5e5e5e,474747,303030,1b1b1b,000000,ffffff,fcfcfc,f1f1f1,e2e2e2,c6c6c6,ababab,919191,767676,5e5e5e,474747,303030,1b1b1b,000000</rainbow>
<fruit_salad>ffffff,fffbff,ffeede,ffddb8,ffb960,e59c37,c7821d,a66800,865300,653e00,472a00,2b1700,000000,ffffff,fffbff,ffeede,ffddb8,f8bb71,daa059,bc8642,9e6c2a,825513,653e00,472a00,2b1700,000000,ffffff,fcffdd,eaf8a4,dcea97,c0ce7e,a5b265,8a974e,707c36,586420,414b08,2c3400,181e00,000000,ffffff,fdfee8,f2f2dd,e3e4cf,c7c8b3,abad99,91927f,767766,5e604f,464838,2f3223,1b1d10,000000,ffffff,fcffdd,f0f4d0,e2e5c2,c5c9a8,aaae8e,8f9375,74795b,5d6145,45492f,2e321b,1a1d08,000000</fruit_salad>
@@ -43,7 +43,7 @@
<theme color="ff008673">
<spritz>ffffff,f3fffa,e2f5ee,d4e7e0,b8cbc4,9dafa9,83958f,687a74,51625d,3a4a46,23342f,0e1e1b,000000,ffffff,f4fffa,e9f3ef,dbe5e0,bec9c5,a3ada9,89938f,6e7875,57605d,3f4946,293230,141d1b,000000,ffffff,f3fffa,dbf7ee,cde8e0,b1ccc4,96b1a9,7c968f,627b74,4a635d,334b45,1d352f,06201b,000000,ffffff,fdfcfa,f2f0ef,e3e2e1,c7c6c5,ababaa,91918f,767675,5e5e5d,464746,2f3130,1b1c1b,000000,ffffff,fdfcfa,f2f0ef,e3e2e1,c7c6c5,ababaa,91918f,767675,5e5e5d,464746,2f3130,1b1c1b,000000</spritz>
<tonal_spot>ffffff,f3fffa,b6ffed,a0f2de,84d6c2,69baa7,4d9f8d,2e8373,056b5b,005144,00382f,00201a,000000,ffffff,f3fffa,dbf7ee,cde8e0,b1ccc4,96b1a9,7c968f,627b74,4a635d,334b45,1d352f,06201b,000000,ffffff,fcfcff,e5f2ff,c8e6ff,abcae4,90afc8,7594ac,5b7a91,436278,2b4a5f,113348,001e2f,000000,ffffff,fafdfa,eff1ef,e0e3e1,c4c7c5,a9acaa,8e918f,737775,5c5f5d,444746,2e3130,191c1b,000000,ffffff,f4fffa,e9f3ef,dbe5e0,bec9c5,a3ada9,89938f,6e7875,57605d,3f4946,293230,141d1b,000000</tonal_spot>
- <vibrant>ffffff,f3fffa,b6ffed,00fedc,00dfc1,00c1a6,00a38c,008572,006b5b,005144,00382f,00201a,000000,ffffff,f1fffe,c9faf8,bbecea,a0cfce,85b4b2,6b9998,507e7d,386665,1e4e4d,003736,00201f,000000,ffffff,f6feff,d1f8ff,a9eefa,8dd1dd,72b6c1,579ba6,3a808b,1b6772,004f58,00363d,001f24,000000,ffffff,f4fffa,e9f3ef,dbe5e0,bec9c5,a3ada9,89938f,6e7875,57605d,3f4946,293230,141d1b,000000,ffffff,f3fffa,e2f5ee,d4e7e0,b8cbc4,9dafa9,83958f,687a74,51625d,3a4a46,23342f,0e1e1b,000000</vibrant>
+ <vibrant>ffffff,f3fffa,b6ffed,00fedc,00dfc1,00c1a6,00a38c,008572,006b5b,005144,00382f,00201a,000000,ffffff,f1fffe,c9faf8,bbecea,a0cfce,85b4b2,6b9998,507e7d,386665,1e4e4d,003736,00201f,000000,ffffff,f6feff,d1f8ff,a9eefa,8dd1dd,72b6c1,579ba6,3a808b,1b6772,004f58,00363d,001f24,000000,ffffff,f3fffa,e6f4ee,d7e6e0,bbcac4,a0aea9,86948f,6b7975,54615d,3c4946,26332f,111e1b,000000,ffffff,f3fffa,e2f5ee,d4e7e0,b8cbc4,9dafa9,83958f,687a74,51625d,3a4a46,23342f,0e1e1b,000000</vibrant>
<expressive>ffffff,fffbff,ffeee2,ffdcc1,ffb779,e59b57,c68140,a76728,8b5011,6c3a00,4c2700,2e1500,000000,ffffff,fafdff,def4ff,c0e9fb,a5cdde,8ab1c2,7096a7,557b8b,3d6473,244c5a,063543,001f29,000000,ffffff,f1ffff,bbfcff,a8eff2,8cd2d5,70b7ba,559c9f,388183,19686b,004f52,003739,002021,000000,ffffff,f4fefd,e8f3f2,dae5e3,bec9c8,a3adac,889392,6e7877,566060,3f4948,293232,141d1d,000000,ffffff,f1fffe,e2f5f3,d3e6e5,b8cac9,9dafae,829493,687979,506261,394a49,233333,0e1e1e,000000</expressive>
<rainbow>ffffff,f3fffa,b6ffed,78f8dd,59dbc1,35bfa6,00a38c,008572,006b5b,005144,00382f,00201a,000000,ffffff,f3fffa,dbf7ee,cde8e0,b1ccc4,96b1a9,7c968f,627b74,4a635d,334b45,1d352f,06201b,000000,ffffff,fcfcff,e5f2ff,c8e6ff,abcae4,90afc8,7594ac,5b7a91,436278,2b4a5f,113348,001e2f,000000,ffffff,fcfcfc,f1f1f1,e2e2e2,c6c6c6,ababab,919191,767676,5e5e5e,474747,303030,1b1b1b,000000,ffffff,fcfcfc,f1f1f1,e2e2e2,c6c6c6,ababab,919191,767676,5e5e5e,474747,303030,1b1b1b,000000</rainbow>
<fruit_salad>ffffff,f9ffe7,dafca7,c6f08a,abd471,90b759,779c41,5d8128,466810,324f00,213600,111f00,000000,ffffff,f9ffe7,ddfbaf,cfeda2,b3d088,98b56f,7e9a57,647e3f,4d662a,364e14,213600,111f00,000000,ffffff,f3fffa,b6ffed,a0f2de,84d6c2,69baa7,4d9f8d,2e8373,056b5b,005144,00382f,00201a,000000,ffffff,f3fffa,e6f4ee,d7e6e0,bbcac4,a0aea9,86948f,6b7975,54615d,3c4946,26332f,111e1b,000000,ffffff,f3fffa,dbf7ee,cde8e0,b1ccc4,96b1a9,7c968f,627b74,4a635d,334b45,1d352f,06201b,000000</fruit_salad>
@@ -51,7 +51,7 @@
<theme color="ff007fb4">
<spritz>ffffff,fbfcff,e6f2fe,d8e4ef,bcc8d3,a1adb7,86929d,6c7781,546069,3d4851,26323a,121d25,000000,ffffff,fbfcff,ebf1f8,dde3ea,c1c7ce,a6acb2,8b9198,70777d,595f65,41484d,2b3136,161c21,000000,ffffff,fbfcff,e5f2ff,d2e5f5,b7c9d8,9cadbd,8193a2,677886,4f606e,384956,21323f,0b1d29,000000,ffffff,fefcfc,f2f0f1,e4e2e3,c7c6c7,acabac,919091,767677,5e5e5f,464748,303031,1b1c1c,000000,ffffff,fefcfc,f2f0f1,e4e2e3,c7c6c7,acabac,919091,767677,5e5e5f,464748,303031,1b1c1c,000000</spritz>
<tonal_spot>ffffff,fbfcff,e5f2ff,c8e6ff,94cdf6,78b2da,5d97be,407ca1,246488,004c6d,00344d,001e2e,000000,ffffff,fbfcff,e5f2ff,d2e5f5,b7c9d8,9cadbd,8193a2,677886,4f606e,384956,21323f,0b1d29,000000,ffffff,fffbff,f6edff,e9ddff,cdc0e8,b2a5cc,978bb1,7c7095,63597c,4b4163,342b4b,1f1635,000000,ffffff,fcfcff,f0f0f3,e2e2e5,c5c6c9,aaabae,8f9193,747679,5d5e61,454749,2e3133,191c1e,000000,ffffff,fbfcff,ebf1f8,dde3ea,c1c7ce,a6acb2,8b9198,70777d,595f65,41484d,2b3136,161c21,000000</tonal_spot>
- <vibrant>ffffff,fbfcff,e5f2ff,c8e6ff,87ceff,0eb6ff,009ad9,007eb2,006590,004c6d,00344d,001e2e,000000,ffffff,fdfcff,ebf1ff,d4e3ff,b3c8e9,98accc,7e92b1,637795,4c5f7c,344863,1d314b,051c35,000000,ffffff,fefbff,efefff,dce1ff,b8c4fa,9da9dd,838ec1,6874a4,505c8b,384472,212e5a,0a1844,000000,ffffff,fbfcff,ebf1f8,dde3ea,c1c7ce,a6acb2,8b9198,70777d,595f65,41484d,2b3136,161c21,000000,ffffff,fbfcff,e6f2fe,d8e4ef,bcc8d3,a1adb7,86929d,6c7781,546069,3d4851,26323a,121d25,000000</vibrant>
+ <vibrant>ffffff,fbfcff,e5f2ff,c8e6ff,87ceff,0eb6ff,009ad9,007eb2,006590,004c6d,00344d,001e2e,000000,ffffff,fdfcff,ebf1ff,d4e3ff,b3c8e9,98accc,7e92b1,637795,4c5f7c,344863,1d314b,051c35,000000,ffffff,fefbff,efefff,dce1ff,b8c4fa,9da9dd,838ec1,6874a4,505c8b,384472,212e5a,0a1844,000000,ffffff,fbfcff,e9f2fb,dbe4ed,bfc8d0,a3acb5,89929a,6e777f,575f67,3f484f,293138,141d23,000000,ffffff,fbfcff,e6f2fe,d8e4ef,bcc8d3,a1adb7,86929d,6c7781,546069,3d4851,26323a,121d25,000000</vibrant>
<expressive>ffffff,fcffdd,e9f99a,dbeb8e,bfce75,a4b35c,8a9845,6f7c2d,586416,414c00,2c3400,191e00,000000,ffffff,fffbff,ffebfa,fed7f9,e0bbdd,c4a0c1,a886a6,8c6c8a,735572,593d59,412742,2a122c,000000,ffffff,fdfcff,eaf1ff,d2e4ff,a7c9f6,8caed9,7293bd,5778a1,3f6088,25496f,073257,001c37,000000,ffffff,fdfcff,edf1fa,dfe2eb,c3c6cf,a7abb4,8d9199,72767e,5a5f66,43474e,2c3137,171c22,000000,ffffff,fdfcff,eaf1ff,dbe3f1,bfc7d5,a4acb9,89919e,6f7783,575f6b,3f4753,29313c,141c26,000000</expressive>
<rainbow>ffffff,fbfcff,e5f2ff,c8e6ff,87ceff,55b4ed,3399d1,007eb2,006590,004c6d,00344d,001e2e,000000,ffffff,fbfcff,e5f2ff,d2e5f5,b7c9d8,9cadbd,8193a2,677886,4f606e,384956,21323f,0b1d29,000000,ffffff,fffbff,f6edff,e9ddff,cdc0e8,b2a5cc,978bb1,7c7095,63597c,4b4163,342b4b,1f1635,000000,ffffff,fcfcfc,f1f1f1,e2e2e2,c6c6c6,ababab,919191,767676,5e5e5e,474747,303030,1b1b1b,000000,ffffff,fcfcfc,f1f1f1,e2e2e2,c6c6c6,ababab,919191,767676,5e5e5e,474747,303030,1b1b1b,000000</rainbow>
<fruit_salad>ffffff,f2fffc,b1fff7,71f7ec,50dbd0,25beb5,00a299,00847d,006a64,00504b,003734,00201e,000000,ffffff,f2fffc,b1fff7,9df2e9,81d5cd,65b9b2,489e97,28837c,006a64,00504b,003734,00201e,000000,ffffff,fbfcff,e5f2ff,c8e6ff,94cdf6,78b2da,5d97be,407ca1,246488,004c6d,00344d,001e2e,000000,ffffff,fbfcff,e9f2fb,dbe4ed,bfc8d0,a3acb5,89929a,6e777f,575f67,3f484f,293138,141d23,000000,ffffff,fbfcff,e5f2ff,d2e5f5,b7c9d8,9cadbd,8193a2,677886,4f606e,384956,21323f,0b1d29,000000</fruit_salad>
@@ -59,7 +59,7 @@
<theme color="ff8267c2">
<spritz>ffffff,fffbff,f6edff,e8dff2,cbc3d5,afa8b9,958e9e,797383,615c6b,494453,332e3c,1d1a26,000000,ffffff,fffbff,f5eefa,e7e0eb,cac4cf,afa9b4,948f99,79747e,615d66,49454e,322f37,1d1a22,000000,ffffff,fffbff,f6edff,e8def8,ccc2db,b0a7bf,958da4,7a7289,625b70,4a4458,332d41,1e192b,000000,ffffff,fffbff,f4eff1,e6e1e3,c9c5c7,aeaaac,939092,787577,605e5f,484648,313031,1c1b1d,000000,ffffff,fffbff,f4eff1,e6e1e3,c9c5c7,aeaaac,939092,787577,605e5f,484648,313031,1c1b1d,000000</spritz>
<tonal_spot>ffffff,fffbff,f6edff,e9ddff,d0bcfe,b5a1e1,9987c4,7e6ca8,66558e,4e3d75,37265d,210f47,000000,ffffff,fffbff,f6edff,e8def8,ccc2db,b0a7bf,958da4,7a7289,625b70,4a4458,332d41,1e192b,000000,ffffff,fffbff,ffecef,ffd9e2,f0b8c7,d29dac,b58391,986977,7e525f,633b47,4a2531,31101c,000000,ffffff,fffbff,f5eff4,e6e1e6,cac5ca,aeaaae,938f94,787579,605d61,48464a,323033,1c1b1e,000000,ffffff,fffbff,f5eefa,e7e0eb,cac4cf,afa9b4,948f99,79747e,615d66,49454e,322f37,1d1a22,000000</tonal_spot>
- <vibrant>ffffff,fffbff,f6edff,e9ddff,d1bcff,b89bff,a078ff,884fff,7212ff,5700c9,3c0090,23005b,000000,ffffff,fffbff,fbecff,f4daff,d7bde4,bba2c8,a088ac,846e90,6c5778,533f5f,3b2947,251431,000000,ffffff,fffbff,ffebfa,ffd6fa,e9b6e6,cc9cc9,b082ae,936792,7a5079,603960,472348,2f0d32,000000,ffffff,fffbff,f5eefa,e7e0eb,cac4cf,afa9b4,948f99,79747e,615d66,49454e,322f37,1d1a22,000000,ffffff,fffbff,f6edff,e8dff2,cbc3d5,afa8b9,958e9e,797383,615c6b,494453,332e3c,1d1a26,000000</vibrant>
+ <vibrant>ffffff,fffbff,f6edff,e9ddff,d1bcff,b89bff,a078ff,884fff,7212ff,5700c9,3c0090,23005b,000000,ffffff,fffbff,fbecff,f4daff,d7bde4,bba2c8,a088ac,846e90,6c5778,533f5f,3b2947,251431,000000,ffffff,fffbff,ffebfa,ffd6fa,e9b6e6,cc9cc9,b082ae,936792,7a5079,603960,472348,2f0d32,000000,ffffff,fffbff,f6eefd,e7e0ee,cbc4d2,afa9b7,948e9c,797481,615c69,494551,322f3a,1d1a24,000000,ffffff,fffbff,f6edff,e8dff2,cbc3d5,afa8b9,958e9e,797383,615c6b,494453,332e3c,1d1a26,000000</vibrant>
<expressive>ffffff,f3fffa,b7ffed,94f4de,78d7c2,5bbba7,3da08d,168572,006b5b,005144,00382f,00201a,000000,ffffff,fffbff,ffecf4,ffd8ec,e9b9d3,cc9eb7,b0849c,936a81,795369,5f3c51,46263a,2f1124,000000,ffffff,fffbff,feebff,f8d8ff,e1b9ed,c49ed0,a984b5,8c6998,73527f,5a3b66,42244e,2b0e38,000000,ffffff,fffbff,f8edf8,eadfea,cdc3ce,b2a8b2,978e98,7b737d,635c65,4b454d,342e36,1f1a21,000000,ffffff,fffbff,fbecfe,ecdeef,d0c2d3,b4a7b7,998d9d,7d7281,655b69,4d4351,362d3a,201925,000000</expressive>
<rainbow>ffffff,fffbff,f6edff,e9ddff,d1bcff,b79cf7,9c82da,8167bd,684fa3,50378a,391e72,23005b,000000,ffffff,fffbff,f6edff,e8def8,ccc2db,b0a7bf,958da4,7a7289,625b70,4a4458,332d41,1e192b,000000,ffffff,fffbff,ffecef,ffd9e2,f0b8c7,d29dac,b58391,986977,7e525f,633b47,4a2531,31101c,000000,ffffff,fcfcfc,f1f1f1,e2e2e2,c6c6c6,ababab,919191,767676,5e5e5e,474747,303030,1b1b1b,000000,ffffff,fcfcfc,f1f1f1,e2e2e2,c6c6c6,ababab,919191,767676,5e5e5e,474747,303030,1b1b1b,000000</rainbow>
<fruit_salad>ffffff,fcfcff,e8f1ff,cfe5ff,99cbff,68b1f4,4a96d8,277bbb,00629e,004a78,003355,001d34,000000,ffffff,fcfcff,e8f1ff,cfe5ff,9dcbfb,82afdf,6794c2,4b7aa6,31628d,124a73,003355,001d34,000000,ffffff,fffbff,f6edff,e9ddff,d0bcfe,b5a1e1,9987c4,7e6ca8,66558e,4e3d75,37265d,210f47,000000,ffffff,fffbff,f6eefd,e7e0ee,cbc4d2,afa9b7,948e9c,797481,615c69,494551,322f3a,1d1a24,000000,ffffff,fffbff,f6edff,e8def8,ccc2db,b0a7bf,958da4,7a7289,625b70,4a4458,332d41,1e192b,000000</fruit_salad>
diff --git a/tests/tests/graphics/src/android/graphics/cts/AnimatorLeakTest.java b/tests/tests/graphics/src/android/graphics/cts/AnimatorLeakTest.java
new file mode 100644
index 00000000000..b21edd501b6
--- /dev/null
+++ b/tests/tests/graphics/src/android/graphics/cts/AnimatorLeakTest.java
@@ -0,0 +1,255 @@
+/*
+ * 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.graphics.cts;
+
+import static androidx.test.InstrumentationRegistry.getInstrumentation;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ValueAnimator;
+import android.support.test.uiautomator.UiDevice;
+
+import androidx.test.filters.MediumTest;
+import androidx.test.rule.ActivityTestRule;
+import androidx.test.runner.AndroidJUnit4;
+
+import junit.framework.Assert;
+
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class AnimatorLeakTest {
+
+ @Rule
+ public ActivityTestRule<EmptyActivity> mActivityRule =
+ new ActivityTestRule<>(EmptyActivity.class, false, true);
+ public ActivityTestRule<EmptyActivity2> mActivityRule2 =
+ new ActivityTestRule<>(EmptyActivity2.class, false, false);
+
+ boolean mPaused = false;
+ boolean mPausedSet = false;
+ boolean mFinitePaused = false;
+ boolean mFinitePausedSet = false;
+ boolean mResumed = false;
+
+ @After
+ public void cleanup() {
+ Animator.setAnimatorPausingEnabled(true);
+ }
+
+ /**
+ * The approach of this test is to start animators in the main activity for the test.
+ * That activity is forced into the background and the test checks whether the animators
+ * are paused appropriately. The activity is then forced back into the foreground again
+ * and the test checks whether the animators previously paused are resumed. There are also
+ * checks to make sure that animators which should not have been paused are handled
+ * correctly.
+ */
+ @Test
+ public void testPauseResume() {
+ // Latches used to wait for each of the appropriate lifecycle events
+ final CountDownLatch animatorStartedLatch = new CountDownLatch(1);
+ // There are 2 animators which should be paused and resumed, thus a countdown of 2
+ final CountDownLatch animatorPausedLatch = new CountDownLatch(2);
+ final CountDownLatch animatorResumedLatch = new CountDownLatch(2);
+
+ // The first of these (infinite) should get paused, the second (finite) should not
+ ValueAnimator infiniteAnimator = ValueAnimator.ofFloat(0f, 1f).setDuration(1000);
+ infiniteAnimator.setRepeatCount(ValueAnimator.INFINITE);
+ ValueAnimator finiteAnimator = ValueAnimator.ofFloat(0f, 1f).setDuration(5000);
+
+ // Now create infinite and finite AnimatorSets
+ // As above, the infinite set should get paused, the finite one should not
+ ValueAnimator infiniteAnimator1 = ValueAnimator.ofFloat(0f, 1f).setDuration(1000);
+ infiniteAnimator1.setRepeatCount(ValueAnimator.INFINITE);
+ AnimatorSet infiniteSet = new AnimatorSet();
+ infiniteSet.play(infiniteAnimator1);
+ ValueAnimator finiteAnimator1 = ValueAnimator.ofFloat(0f, 1f).setDuration(5000);
+ AnimatorSet finiteSet = new AnimatorSet();
+ finiteSet.play(finiteAnimator1);
+
+ // This listener tracks which animators get paused and resumed
+ AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ // Wait until animators start to trigger the lifecycle changes
+ animatorStartedLatch.countDown();
+ }
+
+ @Override
+ public void onAnimationPause(Animator animation) {
+ if (animation == infiniteAnimator) {
+ mPaused = true;
+ } else if (animation == infiniteSet) {
+ mPausedSet = true;
+ } else if (animation == finiteAnimator) {
+ mFinitePaused = true;
+ // end it to avoid having it interfere with future resume latch
+ animation.end();
+ return;
+ } else if (animation == finiteSet) {
+ mFinitePausedSet = true;
+ // end it to avoid having it interfere with future resume latch
+ animation.end();
+ return;
+ }
+ animatorPausedLatch.countDown();
+ }
+
+ @Override
+ public void onAnimationResume(Animator animation) {
+ mResumed = true;
+ animatorResumedLatch.countDown();
+ }
+ };
+ infiniteAnimator.addListener(listener);
+ infiniteAnimator.addPauseListener(listener);
+ finiteAnimator.addPauseListener(listener);
+ infiniteSet.addPauseListener(listener);
+ finiteSet.addPauseListener(listener);
+
+ getInstrumentation().runOnMainSync(new Runnable() {
+ public void run() {
+ Animator.setBackgroundPauseDelay(500);
+ try {
+ infiniteAnimator.start();
+ finiteAnimator.start();
+ infiniteSet.start();
+ finiteSet.start();
+ } catch (Throwable throwable) {
+ }
+ }
+ });
+ try {
+ // Wait until the animators are running to start changing the activity lifecycle
+ animatorStartedLatch.await(5, TimeUnit.SECONDS);
+
+ // First, test that animators are *not* paused when an activity goes to the background
+ // if there is another activity in the same process which is now in the foreground.
+ mActivityRule2.launchActivity(null);
+ animatorPausedLatch.await(1, TimeUnit.SECONDS);
+ Assert.assertFalse("Animator was paused", mPaused);
+ mActivityRule2.finishActivity();
+
+ // Send the activity to the background. This should cause the animators to be paused
+ // after Animator.getBackgroundPauseDelay()
+ UiDevice uiDevice = UiDevice.getInstance(getInstrumentation());
+ uiDevice.pressHome();
+
+ animatorPausedLatch.await(5, TimeUnit.SECONDS);
+
+ // It is not possible (or obvious) how to bring the activity back into the foreground.
+ // However, AnimationHandler pauses/resumes all animators for the process based on
+ // *any* visible activities in that process. So it is sufficient to launch a second
+ // activity, which should resume the animators paused when the first activity went
+ // into the background.
+ mActivityRule2.launchActivity(null);
+ animatorResumedLatch.await(5, TimeUnit.SECONDS);
+ } catch (Exception e) { }
+ Assert.assertTrue("Animator was not paused", mPaused);
+ Assert.assertTrue("AnimatorSet was not paused", mPausedSet);
+ Assert.assertFalse("Non-infinite Animator was paused", mFinitePaused);
+ Assert.assertFalse("Non-infinite AnimatorSet was paused", mFinitePausedSet);
+ Assert.assertTrue("Animator was not resumed", mResumed);
+ Assert.assertTrue("AnimatorSet was not resumed", mResumed);
+ }
+
+ /**
+ * The approach of this test is to start animators in the main activity for the test.
+ * That activity is forced into the background and the test checks whether the animators
+ * are paused appropriately. The activity is then forced back into the foreground again
+ * and the test checks whether the animators previously paused are resumed. There are also
+ * checks to make sure that animators which should not have been paused are handled
+ * correctly.
+ */
+ @Test
+ public void testPauseDisablement() {
+ // Latches used to wait for each of the appropriate lifecycle events
+ final CountDownLatch animatorStartedLatch = new CountDownLatch(1);
+ // There are 2 animators which should be paused and resumed, thus a countdown of 2
+ final CountDownLatch animatorPausedLatch = new CountDownLatch(1);
+ final CountDownLatch animatorResumedLatch = new CountDownLatch(1);
+
+ // The first of these (infinite) should get paused, the second (finite) should not
+ ValueAnimator infiniteAnimator = ValueAnimator.ofFloat(0f, 1f).setDuration(1000);
+ infiniteAnimator.setRepeatCount(ValueAnimator.INFINITE);
+
+ // This listener tracks which animators get paused and resumed
+ AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ // Wait until animators start to trigger the lifecycle changes
+ animatorStartedLatch.countDown();
+ }
+
+ @Override
+ public void onAnimationPause(Animator animation) {
+ mPaused = true;
+ animatorPausedLatch.countDown();
+ }
+
+ @Override
+ public void onAnimationResume(Animator animation) {
+ mResumed = true;
+ animatorResumedLatch.countDown();
+ }
+ };
+ infiniteAnimator.addListener(listener);
+ infiniteAnimator.addPauseListener(listener);
+
+ getInstrumentation().runOnMainSync(new Runnable() {
+ public void run() {
+ Animator.setBackgroundPauseDelay(500);
+ Animator.setAnimatorPausingEnabled(false);
+ try {
+ infiniteAnimator.start();
+ } catch (Throwable throwable) {
+ }
+ }
+ });
+ try {
+ // Wait until the animators are running to start changing the activity lifecycle
+ animatorStartedLatch.await(5, TimeUnit.SECONDS);
+
+ // Send the activity to the background. This should cause the animators to be paused
+ // after Animator.getBackgroundPauseDelay()
+ UiDevice uiDevice = UiDevice.getInstance(getInstrumentation());
+ uiDevice.pressHome();
+
+ animatorPausedLatch.await(2, TimeUnit.SECONDS);
+
+ // It is not possible (or obvious) how to bring the activity back into the foreground.
+ // However, AnimationHandler pauses/resumes all animators for the process based on
+ // *any* visible activities in that process. So it is sufficient to launch a second
+ // activity, which should resume the animators paused when the first activity went
+ // into the background.
+ mActivityRule2.launchActivity(null);
+ animatorResumedLatch.await(2, TimeUnit.SECONDS);
+ } catch (Exception e) { }
+ Assert.assertFalse("Animator paused when pausing disabled", mPaused);
+ Assert.assertFalse("Animator resumed when pausing disabled", mResumed);
+ }
+
+}
diff --git a/tests/tests/graphics/src/android/graphics/cts/EmptyActivity.java b/tests/tests/graphics/src/android/graphics/cts/EmptyActivity.java
new file mode 100644
index 00000000000..5ae6cd30e89
--- /dev/null
+++ b/tests/tests/graphics/src/android/graphics/cts/EmptyActivity.java
@@ -0,0 +1,36 @@
+/*
+ * 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.graphics.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.ViewGroup;
+import android.widget.Button;
+
+/**
+ * Empty activity
+ */
+public final class EmptyActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Button b = new Button(this);
+ b.setLayoutParams(new ViewGroup.LayoutParams(100, 100));
+ b.setText("My Button 1111");
+ setContentView(b);
+ }
+}
diff --git a/tests/tests/graphics/src/android/graphics/cts/EmptyActivity2.java b/tests/tests/graphics/src/android/graphics/cts/EmptyActivity2.java
new file mode 100644
index 00000000000..da0b8a64b13
--- /dev/null
+++ b/tests/tests/graphics/src/android/graphics/cts/EmptyActivity2.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.ViewGroup;
+import android.widget.Button;
+
+/**
+ * Empty activity - this one exists in addition to EmptyActivity when an app
+ * needs two launch 2 separate activities.
+ */
+public final class EmptyActivity2 extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Button b = new Button(this);
+ b.setLayoutParams(new ViewGroup.LayoutParams(100, 100));
+ b.setText("My Button 22222");
+ setContentView(b);
+ }
+}
diff --git a/tests/tests/hardware/src/android/hardware/input/cts/tests/VirtualDeviceTestCase.java b/tests/tests/hardware/src/android/hardware/input/cts/tests/VirtualDeviceTestCase.java
index ba192c42bd8..8ad13dfdcb6 100644
--- a/tests/tests/hardware/src/android/hardware/input/cts/tests/VirtualDeviceTestCase.java
+++ b/tests/tests/hardware/src/android/hardware/input/cts/tests/VirtualDeviceTestCase.java
@@ -57,8 +57,8 @@ public abstract class VirtualDeviceTestCase extends InputTestCase {
private static final int ARBITRARY_SURFACE_TEX_ID = 1;
- static final int DISPLAY_WIDTH = 100;
- static final int DISPLAY_HEIGHT = 100;
+ protected static final int DISPLAY_WIDTH = 100;
+ protected static final int DISPLAY_HEIGHT = 100;
// Uses:
// Manifest.permission.CREATE_VIRTUAL_DEVICE,
@@ -140,10 +140,6 @@ public abstract class VirtualDeviceTestCase extends InputTestCase {
}
// Tap to gain window focus on the activity
tapActivityToFocus();
- // Wait for everything to settle. Like see in InputHidTestCase, registered input devices
- // don't always seem to produce events right away. Adding a bit of slack here decreases
- // the flake rate.
- SystemClock.sleep(1000L);
}
abstract void onSetUpVirtualInputDevice();
diff --git a/tests/tests/hardware/src/android/hardware/input/cts/tests/VirtualMouseTest.java b/tests/tests/hardware/src/android/hardware/input/cts/tests/VirtualMouseTest.java
index eb54097e2b0..6ca80e57de5 100644
--- a/tests/tests/hardware/src/android/hardware/input/cts/tests/VirtualMouseTest.java
+++ b/tests/tests/hardware/src/android/hardware/input/cts/tests/VirtualMouseTest.java
@@ -40,11 +40,7 @@ public class VirtualMouseTest extends VirtualDeviceTestCase {
private static final String DEVICE_NAME = "CtsVirtualMouseTestDevice";
- // TODO(b/216792538): while the start position is deterministic, it would be nice to test it at
- // runtime. The virtual display is 100x100px, running from [0,99]. Half of this is 49.5, and
- // we assume the pointer for a new display begins at the center.
- private static final PointF START_POSITION = new PointF((DISPLAY_WIDTH - 1) / 2f,
- (DISPLAY_HEIGHT - 1) / 2f);
+ private static final float EPSILON = 0.001f;
private VirtualMouse mVirtualMouse;
@@ -63,6 +59,7 @@ public class VirtualMouseTest extends VirtualDeviceTestCase {
@Test
public void sendButtonEvent() {
+ final PointF startPosition = mVirtualMouse.getCursorPosition();
mVirtualMouse.sendButtonEvent(new VirtualMouseButtonEvent.Builder()
.setAction(VirtualMouseButtonEvent.ACTION_BUTTON_PRESS)
.setButtonCode(VirtualMouseButtonEvent.BUTTON_PRIMARY)
@@ -72,59 +69,78 @@ public class VirtualMouseTest extends VirtualDeviceTestCase {
.setButtonCode(VirtualMouseButtonEvent.BUTTON_PRIMARY)
.build());
final MotionEvent buttonPressEvent = createMotionEvent(MotionEvent.ACTION_BUTTON_PRESS,
- START_POSITION.x, START_POSITION.y, /* relativeX= */ 0f, /* relativeY= */ 0f,
+ startPosition.x, startPosition.y, /* relativeX= */ 0f, /* relativeY= */ 0f,
/* vScroll= */ 0f, /* hScroll= */ 0f, MotionEvent.BUTTON_PRIMARY,
/* pressure= */ 1.0f);
buttonPressEvent.setActionButton(MotionEvent.BUTTON_PRIMARY);
final MotionEvent buttonReleaseEvent = createMotionEvent(MotionEvent.ACTION_BUTTON_RELEASE,
- START_POSITION.x, START_POSITION.y, /* relativeX= */ 0f, /* relativeY= */ 0f,
+ startPosition.x, startPosition.y, /* relativeX= */ 0f, /* relativeY= */ 0f,
/* vScroll= */ 0f, /* hScroll= */ 0f, /* buttonState= */ 0, /* pressure= */ 0.0f);
buttonReleaseEvent.setActionButton(MotionEvent.BUTTON_PRIMARY);
verifyEvents(Arrays.asList(
- createMotionEvent(MotionEvent.ACTION_DOWN, START_POSITION.x, START_POSITION.y,
+ createMotionEvent(MotionEvent.ACTION_DOWN, startPosition.x, startPosition.y,
/* relativeX= */ 0f, /* relativeY= */ 0f, /* vScroll= */ 0f,
/* hScroll= */ 0f, MotionEvent.BUTTON_PRIMARY, /* pressure= */ 1.0f),
buttonPressEvent,
buttonReleaseEvent,
- createMotionEvent(MotionEvent.ACTION_UP, START_POSITION.x, START_POSITION.y,
+ createMotionEvent(MotionEvent.ACTION_UP, startPosition.x, startPosition.y,
/* relativeX= */ 0f, /* relativeY= */ 0f, /* vScroll= */ 0f,
/* hScroll= */ 0f, /* buttonState= */ 0, /* pressure= */ 0.0f),
- createMotionEvent(MotionEvent.ACTION_HOVER_ENTER, START_POSITION.x,
- START_POSITION.y, /* relativeX= */ 0f, /* relativeY= */ 0f,
+ createMotionEvent(MotionEvent.ACTION_HOVER_ENTER, startPosition.x,
+ startPosition.y, /* relativeX= */ 0f, /* relativeY= */ 0f,
/* vScroll= */ 0f, /* hScroll= */ 0f, /* buttonState= */ 0,
/* pressure= */ 0.0f)));
}
@Test
public void sendRelativeEvent() {
+ final PointF startPosition = mVirtualMouse.getCursorPosition();
final float relativeChangeX = 25f;
final float relativeChangeY = 35f;
mVirtualMouse.sendRelativeEvent(new VirtualMouseRelativeEvent.Builder()
.setRelativeY(relativeChangeY)
.setRelativeX(relativeChangeX)
.build());
- mVirtualMouse.sendRelativeEvent(new VirtualMouseRelativeEvent.Builder()
- .setRelativeY(-relativeChangeY)
- .setRelativeX(-relativeChangeX)
- .build());
- final float firstStopPositionX = START_POSITION.x + relativeChangeX;
- final float firstStopPositionY = START_POSITION.y + relativeChangeY;
- final float secondStopPositionX = firstStopPositionX - relativeChangeX;
- final float secondStopPositionY = firstStopPositionY - relativeChangeY;
+ final float firstStopPositionX = startPosition.x + relativeChangeX;
+ final float firstStopPositionY = startPosition.y + relativeChangeY;
verifyEvents(Arrays.asList(
createMotionEvent(MotionEvent.ACTION_HOVER_ENTER, firstStopPositionX,
firstStopPositionY, relativeChangeX, relativeChangeY, /* vScroll= */ 0f,
/* hScroll= */ 0f, /* buttonState= */ 0, /* pressure= */ 0.0f),
createMotionEvent(MotionEvent.ACTION_HOVER_MOVE, firstStopPositionX,
firstStopPositionY, relativeChangeX, relativeChangeY, /* vScroll= */ 0f,
+ /* hScroll= */ 0f, /* buttonState= */ 0, /* pressure= */ 0.0f)));
+ final PointF cursorPosition1 = mVirtualMouse.getCursorPosition();
+ assertEquals("getCursorPosition() should return the updated x position",
+ firstStopPositionX, cursorPosition1.x, EPSILON);
+ assertEquals("getCursorPosition() should return the updated y position",
+ firstStopPositionY, cursorPosition1.y, EPSILON);
+
+ final float secondStopPositionX = firstStopPositionX - relativeChangeX;
+ final float secondStopPositionY = firstStopPositionY - relativeChangeY;
+ mVirtualMouse.sendRelativeEvent(new VirtualMouseRelativeEvent.Builder()
+ .setRelativeY(-relativeChangeY)
+ .setRelativeX(-relativeChangeX)
+ .build());
+ verifyEvents(Arrays.asList(
+ createMotionEvent(MotionEvent.ACTION_HOVER_ENTER, secondStopPositionX,
+ secondStopPositionY, -relativeChangeX,
+ -relativeChangeY, /* vScroll= */ 0f,
/* hScroll= */ 0f, /* buttonState= */ 0, /* pressure= */ 0.0f),
createMotionEvent(MotionEvent.ACTION_HOVER_MOVE, secondStopPositionX,
- secondStopPositionY, -relativeChangeX, -relativeChangeY, /* vScroll= */ 0f,
+ secondStopPositionY, -relativeChangeX,
+ -relativeChangeY, /* vScroll= */ 0f,
/* hScroll= */ 0f, /* buttonState= */ 0, /* pressure= */ 0.0f)));
+ final PointF cursorPosition2 = mVirtualMouse.getCursorPosition();
+ assertEquals("getCursorPosition() should return the updated x position",
+ secondStopPositionX, cursorPosition2.x, EPSILON);
+ assertEquals("getCursorPosition() should return the updated y position",
+ secondStopPositionY, cursorPosition2.y, EPSILON);
}
@Test
public void sendScrollEvent() {
+ final PointF startPosition = mVirtualMouse.getCursorPosition();
final float moveX = 0f;
final float moveY = 1f;
mVirtualMouse.sendScrollEvent(new VirtualMouseScrollEvent.Builder()
@@ -132,42 +148,46 @@ public class VirtualMouseTest extends VirtualDeviceTestCase {
.setXAxisMovement(moveX)
.build());
verifyEvents(Arrays.asList(
- createMotionEvent(MotionEvent.ACTION_HOVER_ENTER, START_POSITION.x,
- START_POSITION.y, /* relativeX= */ 0f, /* relativeY= */ 0f,
+ createMotionEvent(MotionEvent.ACTION_HOVER_ENTER, startPosition.x,
+ startPosition.y, /* relativeX= */ 0f, /* relativeY= */ 0f,
/* vScroll= */ 0f, /* hScroll= */ 0f, /* buttonState= */ 0,
/* pressure= */ 0f),
- createMotionEvent(MotionEvent.ACTION_HOVER_MOVE, START_POSITION.x,
- START_POSITION.y, /* relativeX= */ 0f, /* relativeY= */ 0f,
+ createMotionEvent(MotionEvent.ACTION_HOVER_MOVE, startPosition.x,
+ startPosition.y, /* relativeX= */ 0f, /* relativeY= */ 0f,
/* vScroll= */ 0f, /* hScroll= */ 0f, /* buttonState= */ 0,
/* pressure= */ 0f),
- createMotionEvent(MotionEvent.ACTION_SCROLL, START_POSITION.x,
- START_POSITION.y, /* relativeX= */ 0f, /* relativeY= */ 0f,
+ createMotionEvent(MotionEvent.ACTION_SCROLL, startPosition.x,
+ startPosition.y, /* relativeX= */ 0f, /* relativeY= */ 0f,
/* vScroll= */ 1f, /* hScroll= */ 0f, /* buttonState= */ 0,
/* pressure= */ 0f)));
}
@Test
- public void getCursorPosition() {
+ public void testStartingCursorPosition() {
+ // The virtual display is 100x100px, running from [0,99]. Half of this is 49.5, and
+ // we assume the pointer for a new display begins at the center.
+ final PointF startPosition = new PointF((DISPLAY_WIDTH - 1) / 2f,
+ (DISPLAY_HEIGHT - 1) / 2f);
// Trigger a position update without moving the cursor off the starting position.
mVirtualMouse.sendButtonEvent(new VirtualMouseButtonEvent.Builder()
.setAction(VirtualMouseButtonEvent.ACTION_BUTTON_PRESS)
.setButtonCode(VirtualMouseButtonEvent.BUTTON_PRIMARY)
.build());
final MotionEvent buttonPressEvent = createMotionEvent(MotionEvent.ACTION_BUTTON_PRESS,
- START_POSITION.x, START_POSITION.y, /* relativeX= */ 0f, /* relativeY= */ 0f,
+ startPosition.x, startPosition.y, /* relativeX= */ 0f, /* relativeY= */ 0f,
/* vScroll= */ 0f, /* hScroll= */ 0f, MotionEvent.BUTTON_PRIMARY,
/* pressure= */ 1.0f);
buttonPressEvent.setActionButton(MotionEvent.BUTTON_PRIMARY);
verifyEvents(Arrays.asList(
- createMotionEvent(MotionEvent.ACTION_DOWN, START_POSITION.x, START_POSITION.y,
+ createMotionEvent(MotionEvent.ACTION_DOWN, startPosition.x, startPosition.y,
/* relativeX= */ 0f, /* relativeY= */ 0f, /* vScroll= */ 0f,
/* hScroll= */ 0f, MotionEvent.BUTTON_PRIMARY, /* pressure= */ 1.0f),
buttonPressEvent));
final PointF position = mVirtualMouse.getCursorPosition();
- assertEquals("Cursor position x differs", START_POSITION.x, position.x, 0.0001f);
- assertEquals("Cursor position y differs", START_POSITION.y, position.y, 0.0001f);
+ assertEquals("Cursor position x differs", startPosition.x, position.x, EPSILON);
+ assertEquals("Cursor position y differs", startPosition.y, position.y, EPSILON);
}
private MotionEvent createMotionEvent(int action, float x, float y, float relativeX,
diff --git a/tests/tests/keystore/src/android/keystore/cts/BlockCipherTestBase.java b/tests/tests/keystore/src/android/keystore/cts/BlockCipherTestBase.java
index be2ecc5a5b2..6057e457fb8 100644
--- a/tests/tests/keystore/src/android/keystore/cts/BlockCipherTestBase.java
+++ b/tests/tests/keystore/src/android/keystore/cts/BlockCipherTestBase.java
@@ -842,19 +842,19 @@ abstract class BlockCipherTestBase {
int ciphertextIndex = 0;
for (int plaintextIndex = 0; plaintextIndex < plaintext.length; plaintextIndex++) {
byte[] output = update(new byte[] {plaintext[plaintextIndex]});
- if ((plaintextIndex % blockSize) == blockSize - 1) {
- String additionalInformation = "";
- boolean compareOutput = true;
- if (isStrongbox() && output == null) {
- // This is known to be broken on older vendor implementations.
- if (Build.VERSION_CODES.TIRAMISU
- > SystemProperties.getInt("ro.vendor.api_level", 0)) {
- compareOutput = false;
- } else {
- additionalInformation = " (b/194134359)";
- }
+ String additionalInformation = "";
+ boolean compareOutput = true;
+ if (isStrongbox()) {
+ // This is known to be broken on older vendor implementations.
+ if (Build.VERSION_CODES.TIRAMISU
+ > SystemProperties.getInt("ro.vendor.api_level", 0)) {
+ compareOutput = false;
+ } else {
+ additionalInformation = " (b/194134359)";
}
- if (compareOutput) {
+ }
+ if (compareOutput) {
+ if ((plaintextIndex % blockSize) == blockSize - 1) {
// Cipher.update is expected to have output a new block
assertArrayEquals(
"plaintext index: " + plaintextIndex + additionalInformation,
@@ -863,10 +863,12 @@ abstract class BlockCipherTestBase {
ciphertextIndex,
ciphertextIndex + blockSize),
output);
+ } else {
+ // Cipher.update is expected to have produced no output
+ assertArrayEquals(
+ "plaintext index: " + plaintextIndex + additionalInformation,
+ null, output);
}
- } else {
- // Cipher.update is expected to have produced no output
- assertArrayEquals("plaintext index: " + plaintextIndex, null, output);
}
if (output != null) {
ciphertextIndex += output.length;
@@ -943,27 +945,28 @@ abstract class BlockCipherTestBase {
&& (ciphertextIndex > 0) && ((ciphertextIndex % blockSize) == 0))
|| ((!paddingEnabled) && ((ciphertextIndex % blockSize) == blockSize - 1));
- if (outputExpected) {
- String additionalInformation = "";
- boolean compareOutput = true;
- if (isStrongbox()) {
- // This is known to be broken on older vendor implementations.
- if (Build.VERSION_CODES.TIRAMISU
- > SystemProperties.getInt("ro.vendor.api_level", 0)) {
- compareOutput = false;
- } else {
- additionalInformation = " (b/194134040)";
- }
+ String additionalInformation = "";
+ boolean compareOutput = true;
+ if (isStrongbox()) {
+ // This is known to be broken on older vendor implementations.
+ if (Build.VERSION_CODES.TIRAMISU
+ > SystemProperties.getInt("ro.vendor.api_level", 0)) {
+ compareOutput = false;
+ } else {
+ additionalInformation = " (b/194134040)";
}
- if (compareOutput) {
+ }
+ if (compareOutput) {
+ if (outputExpected) {
assertArrayEquals(
"ciphertext index: " + ciphertextIndex + additionalInformation,
subarray(expectedPlaintext, plaintextIndex,
plaintextIndex + blockSize),
output);
+ } else {
+ assertEquals("ciphertext index: " + ciphertextIndex + additionalInformation,
+ null, output);
}
- } else {
- assertEquals("ciphertext index: " + ciphertextIndex, null, output);
}
if (output != null) {
@@ -1322,7 +1325,6 @@ abstract class BlockCipherTestBase {
System.arraycopy(input, 0, buffer, inputOffsetInBuffer, input.length);
createCipher();
initKat(opmode);
- String additionalInformation = "";
int outputLength = update(buffer, inputOffsetInBuffer, input.length,
buffer, outputOffsetInBuffer);
if (isStrongbox()) {
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
index d899b04739c..56b5aaf24eb 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
@@ -815,6 +815,10 @@ public class KeyAttestationTest {
if (Build.VERSION.DEVICE_INITIAL_SDK_INT <= Build.VERSION_CODES.S) {
return;
}
+ // ID attestation is not implemented on the goldfish emulator.
+ if (Build.BOARD.startsWith("goldfish")) {
+ return;
+ }
// ID attestation is tested by other tests (outside of this class), including negative
// tests that ID attestation is failing if the platform does not declare support.
// Hence, it's safe to only test here that the feature is supported.
diff --git a/tests/tests/media/common/src/android/media/cts/MediaCodecTunneledPlayer.java b/tests/tests/media/common/src/android/media/cts/MediaCodecTunneledPlayer.java
index e0cae51fc93..3e90992f777 100644
--- a/tests/tests/media/common/src/android/media/cts/MediaCodecTunneledPlayer.java
+++ b/tests/tests/media/common/src/android/media/cts/MediaCodecTunneledPlayer.java
@@ -615,6 +615,9 @@ public class MediaCodecTunneledPlayer implements MediaTimeProvider {
* Note: This assumes there is exactly one video codec running in the player.
*/
public long getVideoTimeUs() {
+ if (mVideoCodecStates == null || mVideoCodecStates.get(0) == null) {
+ return CodecState.UNINITIALIZED_TIMESTAMP;
+ }
return mVideoCodecStates.get(0).getVideoTimeUs();
}
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 cde71e7a113..73ba7c309ff 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
@@ -16,6 +16,7 @@
package android.media.decoder.cts;
+import static android.media.MediaCodecInfo.CodecCapabilities.FEATURE_TunneledPlayback;
import static android.media.MediaCodecInfo.CodecProfileLevel.AVCLevel31;
import static android.media.MediaCodecInfo.CodecProfileLevel.AVCLevel32;
import static android.media.MediaCodecInfo.CodecProfileLevel.AVCLevel4;
@@ -40,7 +41,6 @@ import android.hardware.display.DisplayManager;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTimestamp;
-import android.media.AudioTrack;
import android.media.Image;
import android.media.MediaCodec;
import android.media.MediaCodec.BufferInfo;
@@ -3872,11 +3872,8 @@ public class DecoderTest extends MediaTestBase {
* TODO(b/182915887): Test all the codecs advertised by the DUT for the provided test content
*/
private void tunneledVideoPlayback(String mimeType, String videoName) throws Exception {
- if (!isVideoFeatureSupported(mimeType,
- CodecCapabilities.FEATURE_TunneledPlayback)) {
- MediaUtils.skipTest(
- TAG,
- "No tunneled video playback codec found for MIME " + mimeType);
+ if (!MediaUtils.check(isVideoFeatureSupported(mimeType, FEATURE_TunneledPlayback),
+ "No tunneled video playback codec found for MIME " + mimeType)) {
return;
}
@@ -3892,6 +3889,16 @@ public class DecoderTest extends MediaTestBase {
// starts video playback
mMediaCodecPlayer.startThread();
+ sleepUntil(() ->
+ mMediaCodecPlayer.getCurrentPosition() > CodecState.UNINITIALIZED_TIMESTAMP
+ && mMediaCodecPlayer.getTimestamp() != null
+ && mMediaCodecPlayer.getTimestamp().framePosition > 0,
+ Duration.ofSeconds(1));
+ assertNotEquals("onFrameRendered was not called",
+ mMediaCodecPlayer.getVideoTimeUs(), CodecState.UNINITIALIZED_TIMESTAMP);
+ assertNotEquals("Audio timestamp is null", mMediaCodecPlayer.getTimestamp(), null);
+ assertNotEquals("Audio timestamp has a zero frame position",
+ mMediaCodecPlayer.getTimestamp().framePosition, 0);
final long durationMs = mMediaCodecPlayer.getDuration();
final long timeOutMs = System.currentTimeMillis() + durationMs + 5 * 1000; // add 5 sec
@@ -3947,11 +3954,8 @@ public class DecoderTest extends MediaTestBase {
* TODO(b/182915887): Test all the codecs advertised by the DUT for the provided test content
*/
private void testTunneledVideoFlush(String mimeType, String videoName) throws Exception {
- if (!isVideoFeatureSupported(mimeType,
- CodecCapabilities.FEATURE_TunneledPlayback)) {
- MediaUtils.skipTest(
- TAG,
- "No tunneled video playback codec found for MIME " + mimeType);
+ if (!MediaUtils.check(isVideoFeatureSupported(mimeType, FEATURE_TunneledPlayback),
+ "No tunneled video playback codec found for MIME " + mimeType)) {
return;
}
@@ -3967,7 +3971,17 @@ public class DecoderTest extends MediaTestBase {
// starts video playback
mMediaCodecPlayer.startThread();
- Thread.sleep(SLEEP_TIME_MS);
+ sleepUntil(() ->
+ mMediaCodecPlayer.getCurrentPosition() > CodecState.UNINITIALIZED_TIMESTAMP
+ && mMediaCodecPlayer.getTimestamp() != null
+ && mMediaCodecPlayer.getTimestamp().framePosition > 0,
+ Duration.ofSeconds(1));
+ assertNotEquals("onFrameRendered was not called",
+ mMediaCodecPlayer.getVideoTimeUs(), CodecState.UNINITIALIZED_TIMESTAMP);
+ assertNotEquals("Audio timestamp is null", mMediaCodecPlayer.getTimestamp(), null);
+ assertNotEquals("Audio timestamp has a zero frame position",
+ mMediaCodecPlayer.getTimestamp().framePosition, 0);
+
mMediaCodecPlayer.pause();
mMediaCodecPlayer.flush();
// mMediaCodecPlayer.reset() handled in TearDown();
@@ -4013,9 +4027,8 @@ public class DecoderTest extends MediaTestBase {
return;
}
- if (!MediaUtils.check(isVideoFeatureSupported(mimeType,
- CodecCapabilities.FEATURE_TunneledPlayback),
- "No tunneled video playback codec found for MIME " + mimeType)){
+ if (!MediaUtils.check(isVideoFeatureSupported(mimeType, FEATURE_TunneledPlayback),
+ "No tunneled video playback codec found for MIME " + mimeType)) {
return;
}
@@ -4088,9 +4101,8 @@ public class DecoderTest extends MediaTestBase {
return;
}
- if (!MediaUtils.check(isVideoFeatureSupported(mimeType,
- CodecCapabilities.FEATURE_TunneledPlayback),
- "No tunneled video playback codec found for MIME " + mimeType)){
+ if (!MediaUtils.check(isVideoFeatureSupported(mimeType, FEATURE_TunneledPlayback),
+ "No tunneled video playback codec found for MIME " + mimeType)) {
return;
}
@@ -4199,9 +4211,8 @@ public class DecoderTest extends MediaTestBase {
}
private void testTunneledAudioPtsGaps(String mimeType, String fileName) throws Exception {
- if (!MediaUtils.check(isVideoFeatureSupported(mimeType,
- CodecCapabilities.FEATURE_TunneledPlayback),
- "No tunneled video playback codec found for MIME " + mimeType)) {
+ if (!MediaUtils.check(isVideoFeatureSupported(mimeType, FEATURE_TunneledPlayback),
+ "No tunneled video playback codec found for MIME " + mimeType)) {
return;
}
@@ -4212,52 +4223,71 @@ public class DecoderTest extends MediaTestBase {
final Uri mediaUri = Uri.fromFile(new File(mInpPrefix, fileName));
mMediaCodecPlayer.setAudioDataSource(mediaUri, null);
-
+ mMediaCodecPlayer.setVideoDataSource(mediaUri, null);
assertTrue("MediaCodecPlayer.start() failed!", mMediaCodecPlayer.start());
assertTrue("MediaCodecPlayer.prepare() failed!", mMediaCodecPlayer.prepare());
+ // starts video playback
mMediaCodecPlayer.startThread();
- sleepUntil(() -> mMediaCodecPlayer.getTimestamp() != null
- && mMediaCodecPlayer.getTimestamp().framePosition > 0, Duration.ofSeconds(1));
- // After 30 ms, Changing the presentation offset for audio track
- Thread.sleep(30);
+ sleepUntil(() ->
+ mMediaCodecPlayer.getCurrentPosition() > CodecState.UNINITIALIZED_TIMESTAMP
+ && mMediaCodecPlayer.getTimestamp() != null
+ && mMediaCodecPlayer.getTimestamp().framePosition > 0,
+ Duration.ofSeconds(1));
+ assertNotEquals("onFrameRendered was not called",
+ mMediaCodecPlayer.getVideoTimeUs(), CodecState.UNINITIALIZED_TIMESTAMP);
+ assertNotEquals("Audio timestamp is null", mMediaCodecPlayer.getTimestamp(), null);
+ assertNotEquals("Audio timestamp has a zero frame position",
+ mMediaCodecPlayer.getTimestamp().framePosition, 0);
// Requirement: If the audio presentation timestamp header sent by the app is greater than
// the current audio clock by less than 100ms, the framePosition returned by
// AudioTrack#getTimestamp (per get_presentation_position) must not advance for any silent
// frames rendered to fill the gap.
// TODO: add link to documentation when available
- mMediaCodecPlayer.setAudioTrackOffsetMs(100);
- // Wait for 20 ms so that whatever was buffered before offset is played
- Thread.sleep(20);
- long initialFramePosition = mMediaCodecPlayer.getTimestamp().framePosition;
- // Verify that the framePosition did not advance after 30 ms. This ensures framePosition
- // returned by AudioTrack#getTimestamp did not advance for any silent frames rendered to
- // fill PTS gaps.
+ // Simulate a PTS gap of 100ms after 30ms
Thread.sleep(30);
- assertEquals(
- "Initial frame position != Final frame position after introducing PTS gaps",
- initialFramePosition, mMediaCodecPlayer.getTimestamp().framePosition);
+ mMediaCodecPlayer.setAudioTrackOffsetMs(100);
+ // Verify that at some point in time in the future, the framePosition stopped advancing.
+ // This verifies that when silence was rendered to fill the PTS gap, that the silent frames
+ // do not cause framePosition to advance.
+ final long ptsGapTimeoutMs = 1000;
+ long startTimeMs = System.currentTimeMillis();
+ AudioTimestamp currentTimestamp = mMediaCodecPlayer.getTimestamp();
+ AudioTimestamp ptsGapTimestamp;
+ do {
+ assertTrue(String.format("No audio PTS gap after %d milliseconds", ptsGapTimeoutMs),
+ System.currentTimeMillis() - startTimeMs < ptsGapTimeoutMs);
+ ptsGapTimestamp = currentTimestamp;
+ Thread.sleep(50);
+ currentTimestamp = mMediaCodecPlayer.getTimestamp();
+ } while (currentTimestamp.framePosition != ptsGapTimestamp.framePosition);
+
+ // Allow the playback to advance past the PTS gap and back to normal operation
Thread.sleep(500);
+ // Simulate the end of playback
mMediaCodecPlayer.stopWritingToAudioTrack(true);
// Sleep till framePosition stabilizes, i.e. playback is complete or till max 3 seconds.
- long framePosCurrent = 0;
- int totalSleepMs = 0;
- while (totalSleepMs < 3000
- && framePosCurrent != mMediaCodecPlayer.getTimestamp().framePosition) {
- framePosCurrent = mMediaCodecPlayer.getTimestamp().framePosition;
- Thread.sleep(500);
- totalSleepMs += 500;
- }
+ final long endOfPlayackTimeoutMs = 3000;
+ startTimeMs = System.currentTimeMillis();
+ AudioTimestamp endOfPlaybackTimestamp;
+ do {
+ assertTrue(String.format("No end of playback after %d milliseconds",
+ endOfPlayackTimeoutMs),
+ System.currentTimeMillis() - startTimeMs < endOfPlayackTimeoutMs);
+ endOfPlaybackTimestamp = currentTimestamp;
+ Thread.sleep(50);
+ currentTimestamp = mMediaCodecPlayer.getTimestamp();
+ } while (currentTimestamp.framePosition != endOfPlaybackTimestamp.framePosition);
- // Verify if number of frames written and played are same even if PTS Gaps were present
+ // Verify if number of frames written and played are same even if PTS gaps were present
// in the playback.
assertEquals("Number of frames written != Number of frames played",
mMediaCodecPlayer.getAudioFramesWritten(),
- mMediaCodecPlayer.getTimestamp().framePosition);
+ endOfPlaybackTimestamp.framePosition);
}
/**
@@ -4292,8 +4322,7 @@ public class DecoderTest extends MediaTestBase {
private void testTunneledAudioTimestampProgressWithUnderrun(
String mimeType, String fileName) throws Exception {
- if (!MediaUtils.check(isVideoFeatureSupported(mimeType,
- CodecCapabilities.FEATURE_TunneledPlayback),
+ if (!MediaUtils.check(isVideoFeatureSupported(mimeType, FEATURE_TunneledPlayback),
"No tunneled video playback codec found for MIME " + mimeType)) {
return;
}
@@ -4305,11 +4334,22 @@ public class DecoderTest extends MediaTestBase {
final Uri mediaUri = Uri.fromFile(new File(mInpPrefix, fileName));
mMediaCodecPlayer.setAudioDataSource(mediaUri, null);
-
+ mMediaCodecPlayer.setVideoDataSource(mediaUri, null);
assertTrue("MediaCodecPlayer.start() failed!", mMediaCodecPlayer.start());
assertTrue("MediaCodecPlayer.prepare() failed!", mMediaCodecPlayer.prepare());
+ // starts video playback
mMediaCodecPlayer.startThread();
+ sleepUntil(() ->
+ mMediaCodecPlayer.getCurrentPosition() > CodecState.UNINITIALIZED_TIMESTAMP
+ && mMediaCodecPlayer.getTimestamp() != null
+ && mMediaCodecPlayer.getTimestamp().framePosition > 0,
+ Duration.ofSeconds(1));
+ assertNotEquals("onFrameRendered was not called",
+ mMediaCodecPlayer.getVideoTimeUs(), CodecState.UNINITIALIZED_TIMESTAMP);
+ assertNotEquals("Audio timestamp is null", mMediaCodecPlayer.getTimestamp(), null);
+ assertNotEquals("Audio timestamp has a zero frame position",
+ mMediaCodecPlayer.getTimestamp().framePosition, 0);
// Stop writing to the AudioTrack after 200 ms.
Thread.sleep(200);
@@ -4354,9 +4394,8 @@ public class DecoderTest extends MediaTestBase {
return;
}
- if (!MediaUtils.check(isVideoFeatureSupported(mimeType,
- CodecCapabilities.FEATURE_TunneledPlayback),
- "No tunneled video playback codec found for MIME " + mimeType)){
+ if (!MediaUtils.check(isVideoFeatureSupported(mimeType, FEATURE_TunneledPlayback),
+ "No tunneled video playback codec found for MIME " + mimeType)) {
return;
}
@@ -4382,12 +4421,19 @@ public class DecoderTest extends MediaTestBase {
// does.
mMediaCodecPlayer.setVideoPeek(false);
- // Start playback
+ // starts video playback
mMediaCodecPlayer.startThread();
- Thread.sleep(maxAllowedTimeToFirstFrameMs);
- assertNotEquals(String.format("No frame displayed after %d ms",
- maxAllowedTimeToFirstFrameMs), CodecState.UNINITIALIZED_TIMESTAMP,
- mMediaCodecPlayer.getCurrentPosition());
+ sleepUntil(() ->
+ mMediaCodecPlayer.getCurrentPosition() > CodecState.UNINITIALIZED_TIMESTAMP
+ && mMediaCodecPlayer.getTimestamp() != null
+ && mMediaCodecPlayer.getTimestamp().framePosition > 0,
+ Duration.ofSeconds(1));
+ assertNotEquals("onFrameRendered was not called",
+ mMediaCodecPlayer.getVideoTimeUs(), CodecState.UNINITIALIZED_TIMESTAMP);
+ assertNotEquals("Audio timestamp is null", mMediaCodecPlayer.getTimestamp(), null);
+ assertNotEquals("Audio timestamp has a zero frame position",
+ mMediaCodecPlayer.getTimestamp().framePosition, 0);
+
// Pause playback
mMediaCodecPlayer.pause();
// Ensure audio and video are in sync. We give some time to the codec to finish displaying
@@ -4492,9 +4538,8 @@ public class DecoderTest extends MediaTestBase {
private void
testTunneledAudioTimestampProgress(String mimeType, String videoName) throws Exception
{
- if (!isVideoFeatureSupported(mimeType,
- CodecCapabilities.FEATURE_TunneledPlayback)) {
- MediaUtils.skipTest(TAG,"No tunneled video playback codec found for MIME " + mimeType);
+ if (!MediaUtils.check(isVideoFeatureSupported(mimeType, FEATURE_TunneledPlayback),
+ "No tunneled video playback codec found for MIME " + mimeType)) {
return;
}
@@ -4510,15 +4555,18 @@ public class DecoderTest extends MediaTestBase {
// starts video playback
mMediaCodecPlayer.startThread();
-
sleepUntil(() ->
- mMediaCodecPlayer.getCurrentPosition() > CodecState.UNINITIALIZED_TIMESTAMP,
+ mMediaCodecPlayer.getCurrentPosition() > CodecState.UNINITIALIZED_TIMESTAMP
+ && mMediaCodecPlayer.getTimestamp() != null
+ && mMediaCodecPlayer.getTimestamp().framePosition > 0,
Duration.ofSeconds(1));
- final int firstPosition = mMediaCodecPlayer.getCurrentPosition();
- assertNotEquals("On frame rendered not called after playback start!",
- CodecState.UNINITIALIZED_TIMESTAMP, firstPosition);
- AudioTimestamp firstTimestamp = mMediaCodecPlayer.getTimestamp();
- assertTrue("Timestamp is null!", firstTimestamp != null);
+ long firstVideoPosition = mMediaCodecPlayer.getVideoTimeUs();
+ assertNotEquals("onFrameRendered was not called",
+ firstVideoPosition, CodecState.UNINITIALIZED_TIMESTAMP);
+ AudioTimestamp firstAudioTimestamp = mMediaCodecPlayer.getTimestamp();
+ assertNotEquals("Audio timestamp is null", firstAudioTimestamp, null);
+ assertNotEquals("Audio timestamp has a zero frame position",
+ firstAudioTimestamp.framePosition, 0);
// Expected stabilization wait is 60ms. We triple to 180ms to prevent flakiness
// and still test basic functionality.
@@ -4527,15 +4575,15 @@ public class DecoderTest extends MediaTestBase {
mMediaCodecPlayer.pause();
// pause might take some time to ramp volume down.
Thread.sleep(sleepTimeMs);
- AudioTimestamp timeStampAfterPause = mMediaCodecPlayer.getTimestamp();
+ AudioTimestamp audioTimestampAfterPause = mMediaCodecPlayer.getTimestamp();
// Verify the video has advanced beyond the first position.
- assertTrue(mMediaCodecPlayer.getCurrentPosition() > firstPosition);
+ assertTrue(mMediaCodecPlayer.getVideoTimeUs() > firstVideoPosition);
// Verify that the timestamp has advanced beyond the first timestamp.
- assertTrue(timeStampAfterPause.nanoTime > firstTimestamp.nanoTime);
+ assertTrue(audioTimestampAfterPause.nanoTime > firstAudioTimestamp.nanoTime);
Thread.sleep(sleepTimeMs);
// Verify that the timestamp does not advance after pause.
- assertEquals(timeStampAfterPause.nanoTime, mMediaCodecPlayer.getTimestamp().nanoTime);
+ assertEquals(audioTimestampAfterPause.nanoTime, mMediaCodecPlayer.getTimestamp().nanoTime);
}
/**
@@ -4547,11 +4595,8 @@ public class DecoderTest extends MediaTestBase {
*/
private void tunneledAudioUnderrun(String mimeType, String videoName, int frameRate)
throws Exception {
- if (!isVideoFeatureSupported(mimeType,
- CodecCapabilities.FEATURE_TunneledPlayback)) {
- MediaUtils.skipTest(
- TAG,
- "No tunneled video playback codec found for MIME " + mimeType);
+ if (!MediaUtils.check(isVideoFeatureSupported(mimeType, FEATURE_TunneledPlayback),
+ "No tunneled video playback codec found for MIME " + mimeType)) {
return;
}
@@ -4565,90 +4610,112 @@ public class DecoderTest extends MediaTestBase {
assertTrue("MediaCodecPlayer.start() failed!", mMediaCodecPlayer.start());
assertTrue("MediaCodecPlayer.prepare() failed!", mMediaCodecPlayer.prepare());
- // Start media playback
+ // Starts video playback
mMediaCodecPlayer.startThread();
- final int waitStartMs = 50;
- Thread.sleep(waitStartMs);
- assertTrue(String.format("Playback has not started after %d milliseconds", waitStartMs),
- mMediaCodecPlayer.getVideoTimeUs() != 0);
+ sleepUntil(() ->
+ mMediaCodecPlayer.getCurrentPosition() > CodecState.UNINITIALIZED_TIMESTAMP
+ && mMediaCodecPlayer.getTimestamp() != null
+ && mMediaCodecPlayer.getTimestamp().framePosition > 0,
+ Duration.ofSeconds(1));
+ assertNotEquals("onFrameRendered was not called",
+ mMediaCodecPlayer.getVideoTimeUs(), CodecState.UNINITIALIZED_TIMESTAMP);
+ assertNotEquals("Audio timestamp is null", mMediaCodecPlayer.getTimestamp(), null);
+ assertNotEquals("Audio timestamp has a zero frame position",
+ mMediaCodecPlayer.getTimestamp().framePosition, 0);
+
// Keep buffering video content but stop buffering audio content -> audio underrun
mMediaCodecPlayer.simulateAudioUnderrun(true);
- // Loop to wait for audio underrun
- // TODO(b/200280965): Find a more appropriate delay based on partner feedback
+
+ // Wait for audio underrun
final int audioUnderrunTimeoutMs = 1000; // Arbitrary upper time limit on loop time duration
long startTimeMs = System.currentTimeMillis();
- AudioTimestamp previousTimestamp;
- while ((previousTimestamp = mMediaCodecPlayer.getTimestamp()) == null) {
- assertTrue(String.format("No audio timestamp after %d milliseconds",
- System.currentTimeMillis() - startTimeMs),
- System.currentTimeMillis() - startTimeMs < audioUnderrunTimeoutMs);
- Thread.sleep(50);
- }
+ AudioTimestamp currentAudioTimestamp = mMediaCodecPlayer.getTimestamp();
AudioTimestamp underrunAudioTimestamp;
- while ((underrunAudioTimestamp = mMediaCodecPlayer.getTimestamp()) != previousTimestamp) {
+ do {
assertTrue(String.format("No audio underrun after %d milliseconds",
- audioUnderrunTimeoutMs),
+ System.currentTimeMillis() - startTimeMs),
System.currentTimeMillis() - startTimeMs < audioUnderrunTimeoutMs);
- previousTimestamp = underrunAudioTimestamp;
+ underrunAudioTimestamp = currentAudioTimestamp;
Thread.sleep(50);
- }
- // Loop to wait until video playback stalls
- long previousVideoTimeUs = mMediaCodecPlayer.getVideoTimeUs();
- long underrunVideoTimeUs;
- startTimeMs = System.currentTimeMillis();
- // TODO(b/200280965): Find a more appropriate delay based on partner feedback
+ currentAudioTimestamp = mMediaCodecPlayer.getTimestamp();
+ } while (currentAudioTimestamp.framePosition != underrunAudioTimestamp.framePosition);
+
+
+ // Wait until video playback stalls
final int videoUnderrunTimeoutMs = 1000;
- while ((underrunVideoTimeUs = mMediaCodecPlayer.getVideoTimeUs()) != previousVideoTimeUs) {
+ startTimeMs = System.currentTimeMillis();
+ long currentVideoTimeUs = mMediaCodecPlayer.getVideoTimeUs();
+ long underrunVideoTimeUs = -1;
+ do {
assertTrue(String.format("No video underrun after %d milliseconds",
videoUnderrunTimeoutMs),
System.currentTimeMillis() - startTimeMs < videoUnderrunTimeoutMs);
- previousVideoTimeUs = underrunVideoTimeUs;
+ underrunVideoTimeUs = currentVideoTimeUs;
Thread.sleep(50);
- }
+ currentVideoTimeUs = mMediaCodecPlayer.getVideoTimeUs();
+ } while (currentVideoTimeUs != underrunVideoTimeUs);
- final int underrunVideoRenderedTimestampIndex =
+ // Retrieve index for the video rendered frame at the time of underrun
+ int underrunVideoRenderedTimestampIndex =
mMediaCodecPlayer.getRenderedVideoFrameTimestampList().size() - 1;
+
// Resume audio buffering with a negative offset, in order to simulate a desynchronisation.
// TODO(b/202710709): Use timestamp relative to last played video frame before pause
mMediaCodecPlayer.setAudioTrackOffsetMs(-100);
mMediaCodecPlayer.simulateAudioUnderrun(false);
- // Loop to wait until audio playback resumes
+ // Wait until audio playback resumes
+ final int audioResumeTimeoutMs = 1000;
startTimeMs = System.currentTimeMillis();
- AudioTimestamp postResumeTimestamp;
- while ((postResumeTimestamp = mMediaCodecPlayer.getTimestamp()) == underrunAudioTimestamp) {
+ currentAudioTimestamp = mMediaCodecPlayer.getTimestamp();
+ AudioTimestamp postResumeAudioTimestamp;
+ do {
assertTrue(String.format("Audio has not resumed after %d milliseconds",
- audioUnderrunTimeoutMs),
- System.currentTimeMillis() - startTimeMs < audioUnderrunTimeoutMs);
+ audioResumeTimeoutMs),
+ System.currentTimeMillis() - startTimeMs < audioResumeTimeoutMs);
+ postResumeAudioTimestamp = currentAudioTimestamp;
Thread.sleep(50);
- }
-
- long resumeAudioSystemTime = interpolateSystemTimeAt(
- underrunAudioTimestamp.framePosition + 1, postResumeTimestamp,
- mMediaCodecPlayer.getAudioTrack());
+ currentAudioTimestamp = mMediaCodecPlayer.getTimestamp();
+ } while(currentAudioTimestamp.framePosition == postResumeAudioTimestamp.framePosition);
- // Now that audio playback has resumed, loop to wait until video playback resumes
+ // Now that audio playback has resumed, wait until video playback resumes
// We care about the timestamp of the first output frame, rather than the exact time the
// video resumed, which is why we only start polling after we are sure audio playback has
// resumed.
- long resumeVideoTimeUs = 0;
+ final int videoResumeTimeoutMs = 1000;
startTimeMs = System.currentTimeMillis();
- while ((resumeVideoTimeUs = mMediaCodecPlayer.getVideoTimeUs()) == underrunVideoTimeUs) {
+ currentVideoTimeUs = mMediaCodecPlayer.getVideoTimeUs();
+ long resumeVideoTimeUs = -1;
+ do {
assertTrue(String.format("Video has not resumed after %d milliseconds",
- videoUnderrunTimeoutMs),
- System.currentTimeMillis() - startTimeMs < videoUnderrunTimeoutMs);
+ videoResumeTimeoutMs),
+ System.currentTimeMillis() - startTimeMs < videoResumeTimeoutMs);
+ resumeVideoTimeUs = currentVideoTimeUs;
Thread.sleep(50);
- }
-
- final ImmutableList<Long> renderedSystemTimeList =
- mMediaCodecPlayer.getRenderedVideoFrameSystemTimeList();
- final long resumeVideoFrameSystemTime = mMediaCodecPlayer
- .getRenderedVideoFrameSystemTimeList().get(underrunVideoRenderedTimestampIndex + 1);
- final long vsync = (long) (1000 / frameRate);
- final long avSyncOffset = resumeAudioSystemTime + 100 - resumeVideoFrameSystemTime;
- assertTrue(String.format("Audio and video tracks are more than %d milliseconds out of sync",
- vsync),
- Math.abs(avSyncOffset) <= vsync);
+ currentVideoTimeUs = mMediaCodecPlayer.getVideoTimeUs();
+ } while (currentVideoTimeUs == resumeVideoTimeUs);
+
+ // The system time when rendering the first audio frame after the resume
+ long playbackRateFps = mMediaCodecPlayer.getAudioTrack().getPlaybackRate();
+ long playedFrames = postResumeAudioTimestamp.framePosition
+ - underrunAudioTimestamp.framePosition + 1;
+ double elapsedTimeNs = playedFrames * (1000.0 * 1000.0 * 1000.0 / playbackRateFps);
+ long resumeAudioSystemTimeNs = postResumeAudioTimestamp.nanoTime - (long) elapsedTimeNs;
+ long resumeAudioSystemTimeMs = resumeAudioSystemTimeNs / 1000 / 1000;
+
+ // The system time when rendering the first video frame after the resume
+ long resumeVideoSystemTimeMs = mMediaCodecPlayer.getRenderedVideoFrameSystemTimeList()
+ .get(underrunVideoRenderedTimestampIndex + 1) / 1000 / 1000;
+
+ // Verify that audio and video are in-sync after resume time
+ // Note: Because a -100ms PTS gap is introduced, the video should resume 100ms later
+ resumeAudioSystemTimeMs += 100;
+ long vsyncMs = 1000 / frameRate;
+ long avSyncOffsetMs = resumeAudioSystemTimeMs - resumeVideoSystemTimeMs;
+ assertTrue(String.format(
+ "Audio is %d milliseconds out of sync of video (audio:%d video:%d)",
+ avSyncOffsetMs, resumeAudioSystemTimeMs, resumeVideoSystemTimeMs),
+ Math.abs(avSyncOffsetMs) <= vsyncMs);
}
/**
@@ -4692,18 +4759,6 @@ public class DecoderTest extends MediaTestBase {
}
/**
- * Returns the system time of the frame {@code framePosition} from {@code timestamp}, for a
- * specific {@code AudioTrack}.
- */
- private static long interpolateSystemTimeAt(long framePosition, AudioTimestamp timestamp,
- AudioTrack audioTrack) {
- final long playbackRateFps = audioTrack.getPlaybackRate(); // Frames per second
- final long playedFrames = timestamp.framePosition - framePosition;
- final double elapsedTimeNs = playedFrames * (1000000000.0 / playbackRateFps);
- return timestamp.nanoTime - (long) elapsedTimeNs;
- }
-
- /**
* Returns list of CodecCapabilities advertising support for the given MIME type.
*/
private static List<CodecCapabilities> getCodecCapabilitiesForMimeType(String mimeType) {
diff --git a/tests/tests/media/misc/src/android/media/misc/cts/CamcorderProfileTest.java b/tests/tests/media/misc/src/android/media/misc/cts/CamcorderProfileTest.java
index a28095f0842..eab6aebf495 100644
--- a/tests/tests/media/misc/src/android/media/misc/cts/CamcorderProfileTest.java
+++ b/tests/tests/media/misc/src/android/media/misc/cts/CamcorderProfileTest.java
@@ -449,6 +449,8 @@ public class CamcorderProfileTest {
CamcorderProfile.getAll(String.valueOf(cameraId), quality);
checkAllProfiles(allProfiles, profile, videoSizesToCheck);
}
+ } else {
+ assertNull(CamcorderProfile.getAll(String.valueOf(cameraId), quality));
}
}
diff --git a/tests/tests/os/UffdGc/jni/android_os_cts_uffdgc_UserfaultfdTest.cc b/tests/tests/os/UffdGc/jni/android_os_cts_uffdgc_UserfaultfdTest.cc
index 8c17a72f38d..8533d7e47af 100644
--- a/tests/tests/os/UffdGc/jni/android_os_cts_uffdgc_UserfaultfdTest.cc
+++ b/tests/tests/os/UffdGc/jni/android_os_cts_uffdgc_UserfaultfdTest.cc
@@ -16,6 +16,7 @@
#include "jni.h"
#include <cstring>
+#include <cassert>
#include <errno.h>
#include <fcntl.h>
@@ -118,9 +119,9 @@ JNIEXPORT bool JNICALL Java_android_os_cts_uffdgc_UserfaultfdTest_confirmKernelV
int major, minor;
struct utsname uts;
- if (uname(&uts) != 0 ||
- strcmp(uts.sysname, "Linux") != 0 ||
- sscanf(uts.release, "%d.%d", &major, &minor) != 2 ||
+ uname(&uts);
+ assert(strcmp(uts.sysname, "Linux") == 0);
+ if (sscanf(uts.release, "%d.%d", &major, &minor) != 2 ||
(major < kRequiredMajor || (major == kRequiredMajor && minor < kRequiredMinor))) {
return false;
}
@@ -131,6 +132,22 @@ JNIEXPORT bool JNICALL Java_android_os_cts_uffdgc_UserfaultfdTest_confirmKernelV
}
extern "C"
+JNIEXPORT bool JNICALL Java_android_os_cts_uffdgc_UserfaultfdTest_confirmKernelArch64bit(JNIEnv*) {
+#if defined(__linux__)
+ struct utsname uts;
+ uname(&uts);
+ assert(strcmp(uts.sysname, "Linux") == 0);
+ if (strstr(uts.machine, "64") != nullptr ||
+ strstr(uts.machine, "armv8") == uts.machine) {
+ return true;
+ }
+ return false;
+#else
+ return false;
+#endif
+}
+
+extern "C"
JNIEXPORT jint JNICALL Java_android_os_cts_uffdgc_UserfaultfdTest_performKernelSpaceUffd(JNIEnv*) {
int ret = 0, write_fd = 0;
void* addr = nullptr;
diff --git a/tests/tests/os/UffdGc/src/android/os/cts/uffdgc/UserfaultfdTest.java b/tests/tests/os/UffdGc/src/android/os/cts/uffdgc/UserfaultfdTest.java
index fc4df1397b9..2f092a62b36 100644
--- a/tests/tests/os/UffdGc/src/android/os/cts/uffdgc/UserfaultfdTest.java
+++ b/tests/tests/os/UffdGc/src/android/os/cts/uffdgc/UserfaultfdTest.java
@@ -71,6 +71,8 @@ public final class UserfaultfdTest {
// Test if userfaultfd works for minor-faults on shmem.
@Test
public void minorUserfaultfd() {
+ // minor fault feature is not enabled on 32-bit kernel archs.
+ Assume.assumeTrue(confirmKernelArch64bit());
assertEquals(0, performMinorUffd());
}
@@ -82,6 +84,7 @@ public final class UserfaultfdTest {
assertEquals(13, checkGetattr());
}
+ private native boolean confirmKernelArch64bit();
private native boolean confirmKernelVersion();
private native int performKernelSpaceUffd();
private native int uffdWithoutUserModeOnly();
diff --git a/tests/tests/permission/Android.bp b/tests/tests/permission/Android.bp
index b78b6c07d5d..eae727629f3 100644
--- a/tests/tests/permission/Android.bp
+++ b/tests/tests/permission/Android.bp
@@ -63,4 +63,54 @@ android_test {
"android.test.runner",
"android.test.base",
],
+ data: [
+ ":AppThatDefinesUndefinedPermissionGroupElement",
+ ":AppThatDoesNotHaveBgLocationAccess",
+ ":CtsAdversarialPermissionDefinerApp",
+ ":CtsAdversarialPermissionUserApp",
+ ":CtsAppThatAccessesLocationOnCommand",
+ ":CtsAppThatAlsoDefinesPermissionA",
+ ":CtsAppThatAlsoDefinesPermissionADifferentCert",
+ ":CtsAppThatAlsoDefinesPermissionGroupADifferentCert",
+ ":CtsAppThatAlsoDefinesPermissionGroupADifferentCert30",
+ ":CtsAppThatDefinesPermissionA",
+ ":CtsAppThatDefinesPermissionInPlatformGroup",
+ ":CtsAppThatDefinesPermissionWithInvalidGroup",
+ ":CtsAppThatDefinesPermissionWithInvalidGroup30",
+ ":CtsAppThatRequestsBluetoothPermission30",
+ ":CtsAppThatRequestsCalendarContactsBodySensorCustomPermission",
+ ":CtsAppThatRequestsBluetoothPermission31",
+ ":CtsAppThatRequestsBluetoothPermissionNeverForLocation31",
+ ":CtsAppThatRequestsContactsAndCallLogPermission16",
+ ":CtsAppThatRequestsContactsPermission15",
+ ":CtsAppThatRequestsContactsPermission16",
+ ":CtsAppThatRequestsLocationAndBackgroundPermission28",
+ ":CtsAppThatRequestsLocationAndBackgroundPermission29",
+ ":CtsAppThatRequestsBluetoothPermissionNeverForLocationNoProvider",
+ ":CtsAppThatRequestsLocationPermission22",
+ ":CtsAppThatRequestsLocationPermission28",
+ ":CtsAppThatRequestsLocationPermission29",
+ ":CtsAppThatRequestsLocationPermission29v4",
+ ":CtsAppThatRequestsOneTimePermission",
+ ":CtsAppThatRequestsPermissionAandB",
+ ":CtsAppThatRequestsPermissionAandC",
+ ":CtsAppThatRequestsStoragePermission28",
+ ":CtsAppThatRequestsStoragePermission29",
+ ":CtsAppThatRunsRationaleTests",
+ ":CtsAppToTestRevokeSelfPermission",
+ ":CtsAppWithSharedUidThatRequestsLocationPermission28",
+ ":CtsAppWithSharedUidThatRequestsLocationPermission29",
+ ":CtsAppWithSharedUidThatRequestsNoPermissions",
+ ":CtsAppWithSharedUidThatRequestsPermissions",
+ ":CtsInstallPermissionDefinerApp",
+ ":CtsInstallPermissionEscalatorApp",
+ ":CtsInstallPermissionUserApp",
+ ":CtsRuntimePermissionDefinerApp",
+ ":CtsRuntimePermissionUserApp",
+ ":CtsStorageEscalationApp28",
+ ":CtsStorageEscalationApp29Full",
+ ":CtsStorageEscalationApp29Scoped",
+ ":CtsVictimPermissionDefinerApp",
+ ],
+ per_testcase_directory: true,
}
diff --git a/tests/tests/permission3/src/android/permission3/cts/PermissionAttributionTest.kt b/tests/tests/permission3/src/android/permission3/cts/PermissionAttributionTest.kt
index 57efe7410b7..31e544951b5 100644
--- a/tests/tests/permission3/src/android/permission3/cts/PermissionAttributionTest.kt
+++ b/tests/tests/permission3/src/android/permission3/cts/PermissionAttributionTest.kt
@@ -29,11 +29,9 @@ import com.android.compatibility.common.util.AppOpsUtils.setOpMode
import com.android.compatibility.common.util.CtsDownstreamingTest
import com.android.compatibility.common.util.SystemUtil.callWithShellPermissionIdentity
import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity
-import com.android.modules.utils.build.SdkLevel
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
-import org.junit.Assume.assumeFalse
import org.junit.Before
import org.junit.Test
import java.util.concurrent.TimeUnit
@@ -41,19 +39,16 @@ import java.util.concurrent.TimeUnit
/**
* Tests permission attribution for location providers.
*/
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
+// Tests converted to GTS since these are GMS requirements not CDD.
+// These will be moved to GTS in U.
+@CtsDownstreamingTest
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
class PermissionAttributionTest : BasePermissionHubTest() {
private val micLabel = packageManager.getPermissionGroupInfo(
android.Manifest.permission_group.MICROPHONE, 0).loadLabel(packageManager).toString()
val locationManager = context.getSystemService(LocationManager::class.java)!!
private var wasEnabled = false
- // Permission history is not available on Auto devices running S or below.
- @Before
- fun assumeNotAutoBelowT() {
- assumeFalse(isAutomotive && !SdkLevel.isAtLeastT())
- }
-
@Before
fun installAppLocationProviderAndAllowMockLocation() {
installPackage(APP_APK_PATH, grantRuntimePermissions = true)
@@ -79,7 +74,6 @@ class PermissionAttributionTest : BasePermissionHubTest() {
}
}
- @CtsDownstreamingTest
@Test
fun testLocationProviderAttributionForMicrophone() {
enableAppAsLocationProvider()
diff --git a/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt b/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt
index f23faae7468..fe9037a571e 100644
--- a/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt
+++ b/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt
@@ -295,7 +295,7 @@ class CameraMicIndicatorsPermissionTest {
// indicator
uiDevice.openQuickSettings()
assertPrivacyChipAndIndicatorsPresent(
- useMic || useHotword,
+ useMic,
useCamera,
chainUsage,
safetyCenterEnabled
@@ -390,11 +390,13 @@ class CameraMicIndicatorsPermissionTest {
chainUsage: Boolean,
safetyCenterEnabled: Boolean = false
) {
- // Ensure the privacy chip is present
- eventually {
- val privacyChip = uiDevice.findObject(UiSelector().resourceId(PRIVACY_CHIP_ID))
- assertTrue("view with id $PRIVACY_CHIP_ID not found", privacyChip.exists())
- privacyChip.click()
+ // Ensure the privacy chip is present (or not)
+ val chipFound = isChipPresent()
+ if (useMic || useCamera) {
+ assertTrue("Did not find chip", chipFound)
+ } else { // hotword
+ assertFalse("Found chip, but did not expect to", chipFound)
+ return
}
eventually {
@@ -455,6 +457,21 @@ class CameraMicIndicatorsPermissionTest {
assertEquals("Expected only one shell view", 1, shellView.size)
}
+ private fun isChipPresent(): Boolean {
+ var chipFound = false
+ try {
+ eventually {
+ val privacyChip = uiDevice.findObject(By.res(PRIVACY_CHIP_ID))
+ assertNotNull("view with id $PRIVACY_CHIP_ID not found", privacyChip)
+ privacyChip.click()
+ chipFound = true
+ }
+ } catch (e: Exception) {
+ // Handle more gracefully after
+ }
+ return chipFound
+ }
+
private fun pressBack() {
uiDevice.pressBack()
waitForIdle()
diff --git a/tests/tests/security/AndroidManifest.xml b/tests/tests/security/AndroidManifest.xml
index 5b53d0e4278..186c5e2ab7b 100644
--- a/tests/tests/security/AndroidManifest.xml
+++ b/tests/tests/security/AndroidManifest.xml
@@ -194,6 +194,13 @@
android:grantUriPermissions="true"
android:process=":badprovider" />
+ <activity android:name="android.security.cts.CVE_2022_20143.PocActivity"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.app.action.AUTOMATIC_ZEN_RULE"/>
+ </intent-filter>
+ </activity>
+
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/tests/tests/security/src/android/security/cts/CVE_2022_20143/CVE_2022_20143.java b/tests/tests/security/src/android/security/cts/CVE_2022_20143/CVE_2022_20143.java
new file mode 100644
index 00000000000..3c08cbb95b6
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2022_20143/CVE_2022_20143.java
@@ -0,0 +1,117 @@
+/*
+ * 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_20143;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.app.AutomaticZenRule;
+import android.app.Instrumentation;
+import android.app.NotificationManager;
+import android.app.UiAutomation;
+import android.content.ComponentName;
+import android.content.Context;
+import android.net.Uri;
+import android.platform.test.annotations.AsbSecurityTest;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+
+@RunWith(AndroidJUnit4.class)
+public class CVE_2022_20143 extends StsExtraBusinessLogicTestCase {
+
+ @AsbSecurityTest(cveBugId = 220735360)
+ @Test
+ public void testPocCVE_2022_20143() {
+ final int ruleLimitPerPackage = 200;
+ final int timeoutDuration = 5000;
+ final int waitDuration = 100;
+ Instrumentation instrumentation;
+ Context context;
+ NotificationManager notificationManager = null;
+ String packageName = null;
+ UiAutomation uiautomation = null;
+ boolean isVulnerable = true;
+ boolean notificationPolicyAccessGranted = false;
+ int automaticZenRules = 0;
+ ArrayList<String> ruleIds = new ArrayList<>();
+ try {
+ instrumentation = InstrumentationRegistry.getInstrumentation();
+ context = instrumentation.getContext();
+ notificationManager = context.getSystemService(NotificationManager.class);
+ packageName = context.getPackageName();
+ uiautomation = instrumentation.getUiAutomation();
+ uiautomation.executeShellCommand("cmd notification allow_dnd " + packageName);
+ long startTime = System.currentTimeMillis();
+ while (System.currentTimeMillis() - startTime < timeoutDuration) {
+ // busy wait until notification policy access is granted
+ if (notificationManager.isNotificationPolicyAccessGranted()) {
+ notificationPolicyAccessGranted = true;
+ break;
+ }
+ Thread.sleep(waitDuration);
+ }
+ // storing the number of automaticZenRules present before test run
+ automaticZenRules = notificationManager.getAutomaticZenRules().size();
+ ComponentName component =
+ new ComponentName(packageName, PocActivity.class.getCanonicalName());
+ for (int i = 0; i < ruleLimitPerPackage; ++i) {
+ Uri conditionId = Uri.parse("condition://android/" + i);
+ AutomaticZenRule rule = new AutomaticZenRule("ZenRuleName" + i, null, component,
+ conditionId, null, NotificationManager.INTERRUPTION_FILTER_ALL, true);
+ String id = notificationManager.addAutomaticZenRule(rule);
+ ruleIds.add(id);
+ }
+ } catch (Exception e) {
+ if (e instanceof IllegalArgumentException) {
+ isVulnerable = false; // expected with fix
+ } else {
+ assumeNoException(e);
+ }
+ } finally {
+ try {
+ if (notificationPolicyAccessGranted) {
+ /* retrieving the total number of automaticZenRules added by test so that the */
+ /* test fails only if all automaticZenRules were added successfully */
+ automaticZenRules =
+ notificationManager.getAutomaticZenRules().size() - automaticZenRules;
+ for (String id : ruleIds) {
+ notificationManager.removeAutomaticZenRule(id);
+ }
+ uiautomation
+ .executeShellCommand("cmd notification disallow_dnd " + packageName);
+ }
+ boolean allZenRulesAdded = ruleLimitPerPackage == automaticZenRules;
+ assumeTrue("Notification policy access not granted",
+ notificationPolicyAccessGranted);
+ assertFalse(
+ "Vulnerable to b/220735360!! System can be corrupted by adding many"
+ + " AutomaticZenRules via NotificationManager#addAutomaticZenRule",
+ isVulnerable && allZenRulesAdded);
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2022_20143/PocActivity.java b/tests/tests/security/src/android/security/cts/CVE_2022_20143/PocActivity.java
new file mode 100644
index 00000000000..4416990a804
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2022_20143/PocActivity.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.CVE_2022_20143;
+
+import android.app.Activity;
+
+public class PocActivity extends Activity {
+}
diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java
index af5fb29dcb5..a06192036c8 100644
--- a/tests/tests/security/src/android/security/cts/StagefrightTest.java
+++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java
@@ -95,6 +95,8 @@ import org.junit.runner.RunWith;
import static org.junit.Assume.*;
import static org.junit.Assert.*;
+import static org.hamcrest.Matchers.is;
+
/**
* Verify that the device is not vulnerable to any known Stagefright
* vulnerabilities.
@@ -2361,6 +2363,16 @@ public class StagefrightTest extends StsExtraBusinessLogicTestCase {
try {
MediaCodecInfo.CodecCapabilities caps = info.getCapabilitiesForType(mime);
if (caps != null) {
+ /* Add mainline skip to decoders in mainline module */
+ if (isCodecInMainlineModule(info.getName())) {
+ Log.i(TAG, "Skipping codec " + info.getName() +
+ " as it is part of mainline");
+ continue;
+ }
+ if (info.isAlias()) {
+ Log.i(TAG, "Skipping codec " + info.getName() + " as it is an alias");
+ continue;
+ }
matchingCodecs.add(info.getName());
Log.i(TAG, "Found matching codec " + info.getName() + " for track " + t);
}
@@ -2678,9 +2690,8 @@ public class StagefrightTest extends StsExtraBusinessLogicTestCase {
} catch (InterruptedException e) {
fail("operation was interrupted");
}
- if (t.isAlive()) {
- fail("operation not completed within timeout of " + timeout + "ms");
- }
+ assumeThat("operation not completed within timeout of " + timeout + "ms", t.isAlive(),
+ is(false));
}
private void releaseCodec(final MediaCodec codec) {
@@ -2692,6 +2703,20 @@ public class StagefrightTest extends StsExtraBusinessLogicTestCase {
}, 5000);
}
+ private boolean isCodecInMainlineModule(String codecName) {
+ boolean value = false;
+ if (codecName.startsWith("c2.android.")) {
+ try {
+ value = ModuleDetector.moduleIsPlayManaged(
+ getInstrumentation().getContext().getPackageManager(),
+ MainlineModule.MEDIA_SOFTWARE_CODEC);
+ } catch (Exception e) {
+ Log.e(TAG, "Exception caught " + e.toString());
+ }
+ }
+ return value;
+ }
+
private void doStagefrightTestRawBlob(
int rid, String mime, int initWidth, int initHeight) throws Exception {
doStagefrightTestRawBlob(rid, mime, initWidth, initHeight, new CrashUtils.Config());
@@ -2755,6 +2780,16 @@ public class StagefrightTest extends StsExtraBusinessLogicTestCase {
try {
MediaCodecInfo.CodecCapabilities caps = info.getCapabilitiesForType(mime);
if (caps != null) {
+ /* Add mainline skip to decoders in mainline module */
+ if (isCodecInMainlineModule(info.getName())) {
+ Log.i(TAG, "Skipping codec " + info.getName() +
+ " as it is part of mainline");
+ continue;
+ }
+ if (info.isAlias()) {
+ Log.i(TAG, "Skipping codec " + info.getName() + " as it is an alias");
+ continue;
+ }
matchingCodecs.add(info.getName());
}
} catch (IllegalArgumentException e) {
@@ -2886,6 +2921,16 @@ public class StagefrightTest extends StsExtraBusinessLogicTestCase {
try {
MediaCodecInfo.CodecCapabilities caps = info.getCapabilitiesForType(mime);
if (caps != null) {
+ /* Add mainline skip to decoders in mainline module */
+ if (isCodecInMainlineModule(info.getName())) {
+ Log.i(TAG, "Skipping codec " + info.getName() +
+ " as it is part of mainline");
+ continue;
+ }
+ if (info.isAlias()) {
+ Log.i(TAG, "Skipping codec " + info.getName() + " as it is an alias");
+ continue;
+ }
matchingCodecs.add(info.getName());
}
} catch (IllegalArgumentException e) {
@@ -3031,6 +3076,16 @@ public class StagefrightTest extends StsExtraBusinessLogicTestCase {
try {
MediaCodecInfo.CodecCapabilities caps = info.getCapabilitiesForType(mime);
if (caps != null) {
+ /* Add mainline skip to decoders in mainline module */
+ if (isCodecInMainlineModule(info.getName())) {
+ Log.i(TAG, "Skipping codec " + info.getName() +
+ " as it is part of mainline");
+ continue;
+ }
+ if (info.isAlias()) {
+ Log.i(TAG, "Skipping codec " + info.getName() + " as it is an alias");
+ continue;
+ }
matchingCodecs.add(info.getName());
}
} catch (IllegalArgumentException e) {
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
index e934b2aae5c..137a43b0ca2 100755
--- a/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
@@ -33,7 +33,6 @@ import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;
import android.annotation.Nullable;
-import android.app.AppOpsManager;
import android.app.UiAutomation;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -50,7 +49,6 @@ import android.net.Uri;
import android.os.Looper;
import android.os.ParcelUuid;
import android.os.PersistableBundle;
-import android.os.Process;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
@@ -680,20 +678,10 @@ public class SubscriptionManagerTest {
(sm) -> sm.createSubscriptionGroup(subGroup));
// Getting subscriptions in group.
- List<SubscriptionInfo> infoList;
- try {
- mSm.getSubscriptionsInGroup(uuid);
- fail("SecurityException should be thrown without USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER");
- } catch (SecurityException ex) {
- // Expected
- }
-
- // has the READ_PRIVILEGED_PHONE_STATE permission
- infoList = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm,
- (sm) -> sm.getSubscriptionsInGroup(uuid), READ_PRIVILEGED_PHONE_STATE);
+ List<SubscriptionInfo> infoList = mSm.getSubscriptionsInGroup(uuid);
assertNotNull(infoList);
assertEquals(1, infoList.size());
- assertEquals(uuid, infoList.get(0).getGroupUuid());
+ assertNull(infoList.get(0).getGroupUuid());
infoList = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm,
(sm) -> sm.getSubscriptionsInGroup(uuid));
@@ -710,36 +698,30 @@ public class SubscriptionManagerTest {
}
availableInfoList = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm,
(sm) -> sm.getAvailableSubscriptionInfoList());
- // has the USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER permission
- try {
- setIdentifierAccess(true);
- if (availableInfoList.size() > 1) {
- List<Integer> availableSubGroup = availableInfoList.stream()
- .map(info -> info.getSubscriptionId())
- .filter(subId -> subId != mSubId)
- .collect(Collectors.toList());
-
- ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm,
- (sm) -> sm.addSubscriptionsIntoGroup(availableSubGroup, uuid));
-
- infoList = mSm.getSubscriptionsInGroup(uuid);
- assertNotNull(infoList);
- assertEquals(availableInfoList.size(), infoList.size());
-
- ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm,
- (sm) -> sm.removeSubscriptionsFromGroup(availableSubGroup, uuid));
- }
+ if (availableInfoList.size() > 1) {
+ List<Integer> availableSubGroup = availableInfoList.stream()
+ .map(info -> info.getSubscriptionId())
+ .filter(subId -> subId != mSubId)
+ .collect(Collectors.toList());
- // Remove from subscription group with current sub Id.
ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm,
- (sm) -> sm.removeSubscriptionsFromGroup(subGroup, uuid));
+ (sm) -> sm.addSubscriptionsIntoGroup(availableSubGroup, uuid));
infoList = mSm.getSubscriptionsInGroup(uuid);
assertNotNull(infoList);
- assertTrue(infoList.isEmpty());
- } finally {
- setIdentifierAccess(false);
+ assertEquals(availableInfoList.size(), infoList.size());
+
+ ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm,
+ (sm) -> sm.removeSubscriptionsFromGroup(availableSubGroup, uuid));
}
+
+ // Remove from subscription group with current sub Id.
+ ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm,
+ (sm) -> sm.removeSubscriptionsFromGroup(subGroup, uuid));
+
+ infoList = mSm.getSubscriptionsInGroup(uuid);
+ assertNotNull(infoList);
+ assertTrue(infoList.isEmpty());
}
@Test
@@ -751,31 +733,23 @@ public class SubscriptionManagerTest {
ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm,
(sm) -> sm.addSubscriptionsIntoGroup(subGroup, uuid));
- List<SubscriptionInfo> infoList;
- try {
- mSm.getSubscriptionsInGroup(uuid);
- fail("SecurityException should be thrown without USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER");
- } catch (SecurityException ex) {
- // Expected
- }
-
// Getting subscriptions in group.
- try {
- setIdentifierAccess(true);
- infoList = mSm.getSubscriptionsInGroup(uuid);
- assertNotNull(infoList);
- assertEquals(1, infoList.size());
- assertEquals(uuid, infoList.get(0).getGroupUuid());
- } finally {
- setIdentifierAccess(false);
- }
+ List<SubscriptionInfo> infoList = mSm.getSubscriptionsInGroup(uuid);
+ assertNotNull(infoList);
+ assertEquals(1, infoList.size());
+ assertNull(infoList.get(0).getGroupUuid());
+
+ infoList = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm,
+ (sm) -> sm.getSubscriptionsInGroup(uuid));
+ assertNotNull(infoList);
+ assertEquals(1, infoList.size());
+ assertEquals(uuid, infoList.get(0).getGroupUuid());
// Remove from subscription group with current sub Id.
ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mSm,
(sm) -> sm.removeSubscriptionsFromGroup(subGroup, uuid));
- infoList = ShellIdentityUtils.invokeMethodWithShellPermissions(mSm,
- (sm) -> sm.getSubscriptionsInGroup(uuid));
+ infoList = mSm.getSubscriptionsInGroup(uuid);
assertNotNull(infoList);
assertTrue(infoList.isEmpty());
}
@@ -1485,13 +1459,4 @@ public class SubscriptionManagerTest {
return validCarrier && validNetworkType && validCapabilities;
}
-
- private void setIdentifierAccess(boolean allowed) {
- String op = AppOpsManager.OPSTR_USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER;
- AppOpsManager appOpsManager = InstrumentationRegistry.getContext().getSystemService(
- AppOpsManager.class);
- int mode = allowed ? AppOpsManager.MODE_ALLOWED : AppOpsManager.opToDefaultMode(op);
- ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
- appOpsManager, (appOps) -> appOps.setUidMode(op, Process.myUid(), mode));
- }
}
diff --git a/tools/cts-tradefed/res/config/cts-known-failures.xml b/tools/cts-tradefed/res/config/cts-known-failures.xml
index c8a450d1c49..22ec7d09a20 100644
--- a/tools/cts-tradefed/res/config/cts-known-failures.xml
+++ b/tools/cts-tradefed/res/config/cts-known-failures.xml
@@ -261,4 +261,10 @@
<!-- b/198021503 -->
<option name="compatibility:exclude-filter" value="CtsAppSecurityHostTestCases android.appsecurity.cts.StorageHostTest#testFullDisk" />
+ <!-- b/216546060 -->
+ <option name="compatibility:exclude-filter" value="CtsFragmentTestCases android.fragment.cts.FragmentAnimatorTest#saveWhileAnimatingAway" />
+
+ <!-- b/216553645 -->
+ <option name="compatibility:exclude-filter" value="CtsKeystoreTestCases android.keystore.cts.ECDSASignatureTest#testNONEwithECDSATruncatesInputToFieldSize" />
+
</configuration>
diff --git a/tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml b/tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml
index cbd7611c7c9..a6e59acd469 100644
--- a/tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml
+++ b/tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml
@@ -112,4 +112,6 @@
<option name="compatibility:exclude-filter" value="CtsHdmiCecHostTestCases android.hdmicec.cts.tv.HdmiCecRoutingControlTest" />
<option name="compatibility:exclude-filter" value="CtsHdmiCecHostTestCases android.hdmicec.cts.tv.HdmiCecTvOneTouchPlayTest" />
+ <!-- b/234409652 Stable API does not exist to enforce this requirement on variable geometry devices -->
+ <option name="compatibility:exclude-filter" value="CtsCameraTestCases android.hardware.camera2.cts.ExtendedCameraCharacteristicsTest#testCameraOrientationAlignedWithDevice"/>
</configuration>