diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-09-08 13:32:43 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-09-08 13:32:43 +0000 |
commit | 3ad1cdb7e1682ed317c463f6d8284b86d6ca25f3 (patch) | |
tree | 7d93dcf5eaff87540422a6949f5a2b803a5ed245 | |
parent | b331360090f07c5b549938446c40d54bb616b5f1 (diff) | |
parent | fba97b83fcee036b8bcbf533fa2ae9034bd47d0e (diff) | |
download | cts-android13-mainline-go-sdkext-release.tar.gz |
Snap for 8756029 from fba97b83fcee036b8bcbf533fa2ae9034bd47d0e to mainline-go-sdkext-releaseaml_go_sdk_330810000android13-mainline-go-sdkext-release
Change-Id: Id5931dc0fc12df589e8837c67927310948c26303
212 files changed, 3081 insertions, 4996 deletions
diff --git a/apps/CameraITS/config.yml b/apps/CameraITS/config.yml index 0ae754eb3be..7302e3cb1f0 100644 --- a/apps/CameraITS/config.yml +++ b/apps/CameraITS/config.yml @@ -45,7 +45,7 @@ TestBeds: test_length: 7 debug_mode: "False" # quotes are needed here chart_distance: 25 - rotator_cntl: "arduino" # Note: only sensor fusion supports manual + rotator_cntl: <controller-type> # arduino, canakit, or as-is for manual rotator_ch: <controller-channel> camera: <camera-id> diff --git a/apps/CameraITS/tests/scene2_a/test_auto_flash.py b/apps/CameraITS/tests/scene2_a/test_auto_flash.py index c00cd5c358c..f1b879bc1f6 100644 --- a/apps/CameraITS/tests/scene2_a/test_auto_flash.py +++ b/apps/CameraITS/tests/scene2_a/test_auto_flash.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Android Open Source Project +# Copyright 2013 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -11,30 +11,27 @@ # 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. -"""Verifies that flash is fired when lighting conditions are dark.""" +"""Verifies android.flash.mode parameters is applied when set.""" import logging import os.path +from mobly import test_runner +import its_base_test import camera_properties_utils import capture_request_utils +import lighting_control_utils import image_processing_utils -import its_base_test import its_session_utils -import lighting_control_utils -from mobly import test_runner AE_MODES = {0: 'OFF', 1: 'ON', 2: 'ON_AUTO_FLASH', 3: 'ON_ALWAYS_FLASH', 4: 'ON_AUTO_FLASH_REDEYE', 5: 'ON_EXTERNAL_FLASH'} AE_STATES = {0: 'INACTIVE', 1: 'SEARCHING', 2: 'CONVERGED', 3: 'LOCKED', 4: 'FLASH_REQUIRED', 5: 'PRECAPTURE'} -FLASH_STATES = {0: 'FLASH_STATE_UNAVAILABLE', 1: 'FLASH_STATE_CHARGING', - 2: 'FLASH_STATE_READY', 3: 'FLASH_STATE_FIRED', - 4: 'FLASH_STATE_PARTIAL'} -_GRAD_DELTA_ATOL = 15 # gradiant for tablets as screen aborbs energy -_MEAN_DELTA_ATOL = 15 # mean used for reflective charts - +_GRAD_DELTA_ATOL = 50 # gradiant for tablets as screen aborbs energy +_MEAN_DELTA_ATOL = 50 # mean used for reflective charts +_NUM_FRAMES = 8 _PATCH_H = 0.25 # center 25% _PATCH_W = 0.25 _PATCH_X = 0.5 - _PATCH_W/2 @@ -43,60 +40,27 @@ _TEST_NAME = os.path.splitext(os.path.basename(__file__))[0] VGA_W, VGA_H = 640, 480 _CAPTURE_INTENT_STILL_CAPTURE = 2 _AE_MODE_ON_AUTO_FLASH = 2 -_CAPTURE_INTENT_PREVIEW = 1 -_CAPTURE_INTENT_STILL_CAPTURE = 2 -_AE_PRECAPTURE_TRIGGER_START = 1 -_AE_PRECAPTURE_TRIGGER_IDLE = 0 - - -def turn_off_tablet(tablet_device): - output = tablet_device.adb.shell('dumpsys display | grep mScreenState') - output_list = str(output.decode('utf-8')).strip().split(' ') - for val in output_list: - if 'ON' in val: - tablet_device.adb.shell(['input', 'keyevent', 'KEYCODE_POWER']) - - -def take_captures_with_flash(cam, fmt): - # Run precapture sequence by setting the aePrecapture trigger to - # START and capture intent set to Preview. - preview_req_start = capture_request_utils.auto_capture_request() - preview_req_start[ - 'android.control.aeMode'] = _AE_MODE_ON_AUTO_FLASH - preview_req_start[ - 'android.control.captureIntent'] = _CAPTURE_INTENT_PREVIEW - preview_req_start[ - 'android.control.aePrecaptureTrigger'] = _AE_PRECAPTURE_TRIGGER_START - # Repeat preview requests with aePrecapture set to IDLE - # until AE is converged. - preview_req_idle = capture_request_utils.auto_capture_request() - preview_req_idle[ - 'android.control.aeMode'] = _AE_MODE_ON_AUTO_FLASH - preview_req_idle[ - 'android.control.captureIntent'] = _CAPTURE_INTENT_PREVIEW - preview_req_idle[ - 'android.control.aePrecaptureTrigger'] = _AE_PRECAPTURE_TRIGGER_IDLE - # Single still capture request. - still_capture_req = capture_request_utils.auto_capture_request() - still_capture_req[ - 'android.control.aeMode'] = _AE_MODE_ON_AUTO_FLASH - still_capture_req[ - 'android.control.captureIntent'] = _CAPTURE_INTENT_STILL_CAPTURE - still_capture_req[ - 'android.control.aePrecaptureTrigger'] = _AE_PRECAPTURE_TRIGGER_IDLE - cap = cam.do_capture_with_flash(preview_req_start, - preview_req_idle, - still_capture_req, fmt) - return cap + + +def take_captures(cam, auto_flash=False): + req = capture_request_utils.auto_capture_request() + req['android.control.captureIntent'] = _CAPTURE_INTENT_STILL_CAPTURE + if auto_flash: + req['android.control.aeMode'] = _AE_MODE_ON_AUTO_FLASH + fmt = {'format': 'yuv', 'width': VGA_W, 'height': VGA_H} + captures = [] + for _ in range(_NUM_FRAMES): + one_capture = cam.do_capture(req, fmt) + captures.append(one_capture) + return captures class AutoFlashTest(its_base_test.ItsBaseTest): - """Test that flash is fired when lighting conditions are dark.""" + """Test that the android.flash.mode parameter is applied.""" def test_auto_flash(self): logging.debug('AE_MODES: %s', str(AE_MODES)) logging.debug('AE_STATES: %s', str(AE_STATES)) - logging.debug('FLASH_STATES: %s', str(FLASH_STATES)) with its_session_utils.ItsSession( device_id=self.dut.serial, @@ -107,10 +71,10 @@ class AutoFlashTest(its_base_test.ItsBaseTest): test_name = os.path.join(self.log_path, _TEST_NAME) # check SKIP conditions - vendor_api_level = its_session_utils.get_vendor_api_level(self.dut.serial) + first_api_level = its_session_utils.get_first_api_level(self.dut.serial) camera_properties_utils.skip_unless( camera_properties_utils.flash(props) and - vendor_api_level >= its_session_utils.ANDROID13_API_LEVEL) + first_api_level >= its_session_utils.ANDROID13_API_LEVEL) # establish connection with lighting controller arduino_serial_port = lighting_control_utils.lighting_control( @@ -122,22 +86,23 @@ class AutoFlashTest(its_base_test.ItsBaseTest): # turn OFF tablet to darken scene if self.tablet: - turn_off_tablet(self.tablet) - fmt_name = 'jpeg' - fmt = {'format': fmt_name} - logging.debug('Testing %s format.', fmt_name) + output = self.tablet.adb.shell('dumpsys display | grep mScreenState') + output_list = str(output.decode('utf-8')).strip().split(' ') + for val in output_list: + if 'ON' in val: + self.tablet.adb.shell(['input', 'keyevent', 'KEYCODE_POWER']) + no_flash_exp_x_iso = 0 no_flash_mean = 0 no_flash_grad = 0 flash_exp_x_iso = [] + flash_means = [] + flash_grads = [] - # take capture with no flash as baseline - logging.debug('Taking reference frame with no flash.') + # take captures with no flash as baseline: use last frame + logging.debug('Taking reference frame(s) with no flash.') cam.do_3a(do_af=False) - no_flash_req = capture_request_utils.auto_capture_request() - no_flash_req[ - 'android.control.captureIntent'] = _CAPTURE_INTENT_STILL_CAPTURE - cap = cam.do_capture(no_flash_req, fmt) + cap = take_captures(cam)[_NUM_FRAMES-1] metadata = cap['metadata'] exp = int(metadata['android.sensor.exposureTime']) iso = int(metadata['android.sensor.sensitivity']) @@ -155,79 +120,65 @@ class AutoFlashTest(its_base_test.ItsBaseTest): patch)[0]*255 no_flash_grad = image_processing_utils.compute_image_max_gradients( patch)[0]*255 - image_processing_utils.write_image( - y, f'{test_name}_{fmt_name}_no_flash_Y.jpg') + image_processing_utils.write_image(y, f'{test_name}_no_flash_Y.jpg') # log results logging.debug('No flash exposure X ISO %d', no_flash_exp_x_iso) logging.debug('No flash Y grad: %.4f', no_flash_grad) logging.debug('No flash Y mean: %.4f', no_flash_mean) - # take capture with auto flash enabled - logging.debug('Taking capture with auto flash enabled.') - flash_fired = False - - cap = take_captures_with_flash(cam, fmt) - y, _, _ = image_processing_utils.convert_capture_to_planes( - cap, props) - # Save captured image - image_processing_utils.write_image(y, - f'{test_name}_{fmt_name}_flash_Y.jpg') - # evaluate captured image - metadata = cap['metadata'] - exp = int(metadata['android.sensor.exposureTime']) - iso = int(metadata['android.sensor.sensitivity']) - logging.debug('cap ISO: %d, exp: %d ns', iso, exp) - logging.debug('AE_MODE (cap): %s', - AE_MODES[metadata['android.control.aeMode']]) - ae_state = AE_STATES[metadata['android.control.aeState']] - logging.debug('AE_STATE (cap): %s', ae_state) - flash_state = FLASH_STATES[metadata['android.flash.state']] - logging.debug('FLASH_STATE: %s', flash_state) - # FLASH_REQUIRED and FLASH_FIRED - if ae_state == 'FLASH_REQUIRED' and flash_state == 'FLASH_STATE_FIRED': - logging.debug('Flash fired') - flash_fired = True - flash_exp_x_iso = exp*iso + # take captures with auto flash enabled + logging.debug('Taking frames with auto flash enabled.') + cam.do_3a(do_af=False, auto_flash=True) + caps = take_captures(cam, auto_flash=True) + + # evaluate captured images + for i in range(_NUM_FRAMES): + logging.debug('frame # %d', i) + metadata = caps[i]['metadata'] + exp = int(metadata['android.sensor.exposureTime']) + iso = int(metadata['android.sensor.sensitivity']) + logging.debug('ISO: %d, exp: %d ns', iso, exp) + logging.debug('AE_MODE (cap): %s', + AE_MODES[metadata['android.control.aeMode']]) + ae_state = AE_STATES[metadata['android.control.aeState']] + logging.debug('AE_STATE (cap): %s', ae_state) + flash_exp_x_iso.append(exp*iso) y, _, _ = image_processing_utils.convert_capture_to_planes( - cap, props) + caps[i], props) patch = image_processing_utils.get_image_patch( y, _PATCH_X, _PATCH_Y, _PATCH_W, _PATCH_H) - flash_mean = image_processing_utils.compute_image_means( - patch)[0]*255 - flash_grad = image_processing_utils.compute_image_max_gradients( - patch)[0]*255 + flash_means.append( + image_processing_utils.compute_image_means(patch)[0]*255) + flash_grads.append( + image_processing_utils.compute_image_max_gradients(patch)[0]*255) - if not flash_fired: - raise AssertionError('Flash was not fired.') + image_processing_utils.write_image( + y, f'{test_name}_auto_flash_Y_{i}.jpg') + + if i == 0: + if ae_state != AE_STATES[4]: # FLASH_REQUIRED + raise AssertionError('Scene not dark enough to trigger auto-flash. ' + 'Check scene.') # log results - logging.debug('Flash exposure X ISO %d', flash_exp_x_iso) - logging.debug('Flash frames Y grad: %.4f', flash_grad) - logging.debug('Flash frames Y mean: %.4f', flash_mean) + logging.debug('Flash exposure X ISOs %s', str(flash_exp_x_iso)) + logging.debug('Flash frames Y grads: %s', str(flash_grads)) + logging.debug('Flash frames Y means: %s', str(flash_means)) + + # turn lights back ON + lighting_control_utils.set_lighting_state( + arduino_serial_port, self.lighting_ch, 'ON') # assert correct behavior - grad_delta = flash_grad - no_flash_grad - mean_delta = flash_mean - no_flash_mean + grad_delta = max(flash_grads) - no_flash_grad + mean_delta = max(flash_means) - no_flash_mean if not (grad_delta > _GRAD_DELTA_ATOL or mean_delta > _MEAN_DELTA_ATOL): raise AssertionError( f'grad FLASH-OFF: {grad_delta:.3f}, ATOL: {_GRAD_DELTA_ATOL}, ' f'mean FLASH-OFF: {mean_delta:.3f}, ATOL: {_MEAN_DELTA_ATOL}') - # Ensure that the flash is turned OFF after flash was fired. - req = capture_request_utils.auto_capture_request() - req['android.control.captureIntent'] = _CAPTURE_INTENT_STILL_CAPTURE - cap = cam.do_capture(req, fmt) - flash_state_after = FLASH_STATES[cap['metadata']['android.flash.state']] - logging.debug('FLASH_STATE after flash fired: %s', flash_state_after) - if flash_state_after != 'FLASH_STATE_READY': - raise AssertionError('Flash should turn OFF after it was fired.') - - # turn lights back ON - lighting_control_utils.set_lighting_state( - arduino_serial_port, self.lighting_ch, 'ON') - if __name__ == '__main__': test_runner.main() diff --git a/apps/CameraITS/tests/scene2_a/test_num_faces.py b/apps/CameraITS/tests/scene2_a/test_num_faces.py index f7e111bfea9..304b67b342b 100644 --- a/apps/CameraITS/tests/scene2_a/test_num_faces.py +++ b/apps/CameraITS/tests/scene2_a/test_num_faces.py @@ -16,8 +16,6 @@ import logging import os.path - -import cv2 from mobly import test_runner import its_base_test @@ -25,6 +23,7 @@ import camera_properties_utils import capture_request_utils import image_processing_utils import its_session_utils +import cv2 FD_MODE_OFF = 0 FD_MODE_SIMPLE = 1 @@ -150,7 +149,8 @@ class NumFacesTest(its_base_test.ItsBaseTest): logging.debug('active array size: %s', str(a)) file_name_stem = os.path.join(self.log_path, NAME) - cam.do_3a(mono_camera=mono_camera) + if camera_properties_utils.read_3a(props): + _, _, _, _, _ = cam.do_3a(get_results=True, mono_camera=mono_camera) for fd_mode in fd_modes: logging.debug('face detection mode: %d', fd_mode) diff --git a/apps/CameraITS/tests/scene4/test_preview_stabilization_fov.py b/apps/CameraITS/tests/scene4/test_preview_stabilization_fov.py index 2781f18805e..3959b42ef27 100644 --- a/apps/CameraITS/tests/scene4/test_preview_stabilization_fov.py +++ b/apps/CameraITS/tests/scene4/test_preview_stabilization_fov.py @@ -35,9 +35,9 @@ _MAX_STABILIZED_RADIUS_RATIO = 1.2 # radius of circle in stabilized preview _ROUNDESS_DELTA_THRESHOLD = 0.05 _MAX_CENTER_THRESHOLD_PERCENT = 0.075 -_MAX_AREA = 1920 * 1440 # max mandatory preview stream resolution +_MAX_DIMENSION_SIZE = (1920, 1080) # max preview size in Android _MIN_CENTER_THRESHOLD_PERCENT = 0.02 -_MIN_AREA = 176 * 144 # assume QCIF to be min preview size +_MIN_DIMENSION_SIZE = (176, 144) # assume QCIF to be min preview size def _collect_data(cam, video_size, stabilize): @@ -90,26 +90,27 @@ def _calculate_center_offset_threshold(image_size): calculated. ex. (1920, 1080) Returns: - threshold value ratio between which the circle centers can differ + threshold value in pixels be which the circle centers can differ """ - img_area = image_size[0] * image_size[1] + max_diagonal = _point_distance(0, 0, + _MAX_DIMENSION_SIZE[0], _MAX_DIMENSION_SIZE[1]) + min_diagonal = _point_distance(0, 0, + _MIN_DIMENSION_SIZE[0], _MIN_DIMENSION_SIZE[1]) - normalized_area = ((img_area - _MIN_AREA) / - (_MAX_AREA - _MIN_AREA)) + img_diagonal = _point_distance(0, 0, image_size[0], image_size[1]) - if normalized_area > 1 or normalized_area < 0: - raise AssertionError(f'normalized area > 1 or < 0! ' - f'image_size[0]: {image_size[0]}, ' - f'image_size[1]: {image_size[1]}, ' - f'normalized_area: {normalized_area}') + normalized_diagonal = ((img_diagonal - min_diagonal) / + (max_diagonal - min_diagonal)) # Threshold should be larger for images with smaller resolution - normalized_threshold_percent = ((1 - normalized_area) * + normalized_threshold_percent = ((1 - normalized_diagonal) * (_MAX_CENTER_THRESHOLD_PERCENT - _MIN_CENTER_THRESHOLD_PERCENT)) - return (normalized_threshold_percent + _MIN_CENTER_THRESHOLD_PERCENT) + return ((normalized_threshold_percent + _MIN_CENTER_THRESHOLD_PERCENT) + * img_diagonal) + class PreviewStabilizationFoVTest(its_base_test.ItsBaseTest): """Tests if stabilized preview FoV is within spec. @@ -140,7 +141,7 @@ class PreviewStabilizationFoVTest(its_base_test.ItsBaseTest): # Load scene. its_session_utils.load_scene(cam, props, self.scene, - self.tablet, self.chart_distance) + self.tablet, chart_distance=0) # Check skip condition first_api_level = its_session_utils.get_first_api_level(self.dut.serial) @@ -249,8 +250,7 @@ class PreviewStabilizationFoVTest(its_base_test.ItsBaseTest): f'{_ROUNDESS_DELTA_THRESHOLD}, ' f'actual ratio difference: {roundness_diff}. ') - # Distance between centers, x_offset and y_offset are relative to the - # radius of the circle, so they're normalized. Not pixel values. + # Distance between centers unstab_center = (ustab_circle['x_offset'], ustab_circle['y_offset']) logging.debug('unstabilized center: %s', unstab_center) stab_center = (stab_circle['x_offset'], stab_circle['y_offset']) diff --git a/apps/CameraITS/tests/scene4/test_video_aspect_ratio_and_crop.py b/apps/CameraITS/tests/scene4/test_video_aspect_ratio_and_crop.py index bb713672e00..6eaca195c22 100644 --- a/apps/CameraITS/tests/scene4/test_video_aspect_ratio_and_crop.py +++ b/apps/CameraITS/tests/scene4/test_video_aspect_ratio_and_crop.py @@ -137,13 +137,13 @@ class VideoAspectRatioAndCropTest(its_base_test.ItsBaseTest): logging.debug('physical available focal lengths: %s', str(fls_physical)) # Check SKIP conditions. - vendor_api_level = its_session_utils.get_vendor_api_level(self.dut.serial) + first_api_level = its_session_utils.get_first_api_level(self.dut.serial) camera_properties_utils.skip_unless( - vendor_api_level >= its_session_utils.ANDROID13_API_LEVEL) + first_api_level >= its_session_utils.ANDROID13_API_LEVEL) # Load scene. its_session_utils.load_scene(cam, props, self.scene, - self.tablet, self.chart_distance) + self.tablet, chart_distance=0) # Determine camera capabilities. supported_video_qualities = cam.get_supported_video_qualities( diff --git a/apps/CameraITS/tests/sensor_fusion/test_video_stabilization.py b/apps/CameraITS/tests/sensor_fusion/test_video_stabilization.py index 195d5670eba..0be38b56d11 100644 --- a/apps/CameraITS/tests/sensor_fusion/test_video_stabilization.py +++ b/apps/CameraITS/tests/sensor_fusion/test_video_stabilization.py @@ -129,7 +129,7 @@ class VideoStabilizationTest(its_base_test.ItsBaseTest): in gyroscope movement. Test is a PASS if rotation is reduced in video. """ - def test_video_stabilization(self): + def test_video_stability(self): rot_rig = {} log_path = self.log_path @@ -139,12 +139,12 @@ class VideoStabilizationTest(its_base_test.ItsBaseTest): hidden_physical_id=self.hidden_physical_id) as cam: props = cam.get_camera_properties() props = cam.override_with_hidden_physical_camera_props(props) - vendor_api_level = its_session_utils.get_vendor_api_level(self.dut.serial) + first_api_level = its_session_utils.get_first_api_level(self.dut.serial) supported_stabilization_modes = props[ 'android.control.availableVideoStabilizationModes'] camera_properties_utils.skip_unless( - vendor_api_level >= its_session_utils.ANDROID13_API_LEVEL and + first_api_level >= its_session_utils.ANDROID13_API_LEVEL and _VIDEO_STABILIZATION_MODE in supported_stabilization_modes) # Raise error if not FRONT or REAR facing camera diff --git a/apps/CameraITS/tools/run_all_tests.py b/apps/CameraITS/tools/run_all_tests.py index dae63c3732e..3ecc8dfeef1 100755 --- a/apps/CameraITS/tools/run_all_tests.py +++ b/apps/CameraITS/tools/run_all_tests.py @@ -240,7 +240,7 @@ def check_manual_scenes(device_id, camera_id, scene, out_path): img_name = os.path.join(out_path, f'test_{scene}.jpg') logging.info('Please check scene setup in %s', img_name) image_processing_utils.write_image(img, img_name) - choice = input(f'Is the image okay for ITS {scene}? (Y/N)').lower() + choice = input('Is the image okay for ITS {scene}? (Y/N)').lower() if choice == 'y': break @@ -518,13 +518,13 @@ def main(): # Handle repeated test if 'tests/' in test: cmd = [ - 'python3', + 'python', os.path.join(os.environ['CAMERA_ITS_TOP'], test), '-c', '%s' % new_yml_file_name ] else: cmd = [ - 'python3', + 'python', os.path.join(os.environ['CAMERA_ITS_TOP'], 'tests', s, test), '-c', '%s' % new_yml_file_name diff --git a/apps/CameraITS/utils/its_session_utils.py b/apps/CameraITS/utils/its_session_utils.py index c2065ba6ac4..4a6cbf9af01 100644 --- a/apps/CameraITS/utils/its_session_utils.py +++ b/apps/CameraITS/utils/its_session_utils.py @@ -616,122 +616,6 @@ class ItsSession(object): raise error_util.CameraItsError('No supported preview sizes') return data['strValue'].split(';') - def do_capture_with_flash(self, - preview_request_start, - preview_request_idle, - still_capture_req, - out_surface): - """Issue capture request with flash and read back the image and metadata. - - Captures a single image with still_capture_req as capture request - with flash. It triggers the precapture sequence with preview request - preview_request_start with capture intent preview by setting aePrecapture - trigger to Start. This is followed by repeated preview requests - preview_request_idle with aePrecaptureTrigger set to IDLE. - Once the AE is converged, a single image is captured still_capture_req - during which the flash must be fired. - Note: The part where we read output data from socket is cloned from - do_capture and will be consolidated in U. - - Args: - preview_request_start: Preview request with aePrecaptureTrigger set to - Start - preview_request_idle: Preview request with aePrecaptureTrigger set to Idle - still_capture_req: Single still capture request. - out_surface: Specifications of the output image formats and - sizes to use for capture. - Returns: - An object which contains following fields: - * data: the image data as a numpy array of bytes. - * width: the width of the captured image. - * height: the height of the captured image. - * format: image format - * metadata: the capture result object - """ - cmd = {} - cmd['cmdName'] = 'doCaptureWithFlash' - cmd['previewRequestStart'] = [preview_request_start] - cmd['previewRequestIdle'] = [preview_request_idle] - cmd['stillCaptureRequest'] = [still_capture_req] - cmd['outputSurfaces'] = [out_surface] - - cam_ids = self._camera_id - self.sock.settimeout(self.SOCK_TIMEOUT + self.EXTRA_SOCK_TIMEOUT) - logging.debug('Capturing image with ON_AUTO_FLASH.') - self.sock.send(json.dumps(cmd).encode() + '\n'.encode()) - - bufs = {} - bufs[self._camera_id] = {'jpeg': []} - formats = ['jpeg'] - rets = [] - nbufs = 0 - mds = [] - physical_mds = [] - widths = None - heights = None - ncap = 1 - capture_results_returned = False - yuv_bufs = {} - while not capture_results_returned: - json_obj, buf = self.__read_response_from_socket() - if json_obj['tag'] in ItsSession.IMAGE_FORMAT_LIST_1 and buf is not None: - fmt = json_obj['tag'][:-5] - bufs[self._camera_id][fmt].append(buf) - nbufs += 1 - elif json_obj['tag'] == 'captureResults': - capture_results_returned = True - mds.append(json_obj['objValue']['captureResult']) - physical_mds.append(json_obj['objValue']['physicalResults']) - outputs = json_obj['objValue']['outputs'] - widths = [out['width'] for out in outputs] - heights = [out['height'] for out in outputs] - else: - tag_string = unicodedata.normalize('NFKD', json_obj['tag']).encode( - 'ascii', 'ignore') - for x in ItsSession.IMAGE_FORMAT_LIST_2: - x = bytes(x, encoding='utf-8') - if tag_string.startswith(x): - if x == b'yuvImage': - physical_id = json_obj['tag'][len(x):] - if physical_id in cam_ids: - buf_size = numpy.product(buf.shape) - yuv_bufs[physical_id][buf_size].append(buf) - nbufs += 1 - else: - physical_id = json_obj['tag'][len(x):] - if physical_id in cam_ids: - fmt = x[:-5].decode('UTF-8') - bufs[physical_id][fmt].append(buf) - nbufs += 1 - rets = [] - for j, fmt in enumerate(formats): - objs = [] - if 'physicalCamera' in cmd['outputSurfaces'][j]: - cam_id = cmd['outputSurfaces'][j]['physicalCamera'] - else: - cam_id = self._camera_id - for i in range(ncap): - obj = {} - obj['width'] = widths[j] - obj['height'] = heights[j] - obj['format'] = fmt - if cam_id == self._camera_id: - obj['metadata'] = mds[i] - else: - for physical_md in physical_mds[i]: - if cam_id in physical_md: - obj['metadata'] = physical_md[cam_id] - break - obj['data'] = bufs[cam_id][fmt][i] - objs.append(obj) - rets.append(objs if ncap > 1 else objs[0]) - self.sock.settimeout(self.SOCK_TIMEOUT) - if len(rets) > 1 or (isinstance(rets[0], dict) and - isinstance(still_capture_req, list)): - return rets - else: - return rets[0] - def do_capture(self, cap_request, out_surfaces=None, @@ -1612,18 +1496,6 @@ def get_first_api_level(device_id): return first_api_level -def get_vendor_api_level(device_id): - """Return the int value for the vendor API level of the device.""" - cmd = 'adb -s %s shell getprop ro.vendor.api_level' % device_id - try: - vendor_api_level = int(subprocess.check_output(cmd.split()).rstrip()) - logging.debug('First vendor API level: %d', vendor_api_level) - except (subprocess.CalledProcessError, ValueError): - logging.error('No vendor_api_level. Setting to build version.') - vendor_api_level = get_build_sdk_version(device_id) - return vendor_api_level - - class ItsSessionUtilsTests(unittest.TestCase): """Run a suite of unit tests on this module.""" diff --git a/apps/CameraITS/utils/opencv_processing_utils.py b/apps/CameraITS/utils/opencv_processing_utils.py index d108cacb0b2..29533146a41 100644 --- a/apps/CameraITS/utils/opencv_processing_utils.py +++ b/apps/CameraITS/utils/opencv_processing_utils.py @@ -18,9 +18,11 @@ import logging import math import os import unittest -import cv2 + import numpy + +import cv2 import capture_request_utils import image_processing_utils @@ -230,8 +232,6 @@ class Chart(object): scale_stop = self._scale_stop * s_factor scale_step = self._scale_step * s_factor self.scale = s_factor - logging.debug('scale start: %.3f, stop: %.3f, step: %.3f', - scale_start, scale_stop, scale_step) max_match = [] # check for normalized image if numpy.amax(scene) <= 1.0: @@ -250,7 +250,7 @@ class Chart(object): # determine if optimization results are valid opt_values = [x[0] for x in max_match] - if not opt_values or (2.0 * min(opt_values) > max(opt_values)): + if 2.0 * min(opt_values) > max(opt_values): estring = ('Warning: unable to find chart in scene!\n' 'Check camera distance and self-reported ' 'pixel pitch, focal length and hyperfocal distance.') @@ -538,7 +538,6 @@ class Cv2ImageProcessingUtilsTests(unittest.TestCase): """Unit tests for this module.""" def test_get_angle_identify_rotated_chessboard_angle(self): - """Unit test to check extracted angles from images.""" # Array of the image files and angles containing rotated chessboards. test_cases = [ ('', 0), diff --git a/apps/CtsVerifier/Android.bp b/apps/CtsVerifier/Android.bp index 024e0387c6f..b4485d19e99 100644 --- a/apps/CtsVerifier/Android.bp +++ b/apps/CtsVerifier/Android.bp @@ -91,7 +91,6 @@ android_library { "CtsForceStopHelper-constants", "ctsmediautil", "DpmWrapper", - "MediaPerformanceClassCommon", ], libs: ["telephony-common"] + ["android.test.runner.stubs"] + ["android.test.base.stubs"] + ["android.test.mock.stubs"] + ["android.car-test-stubs"] + ["voip-common"] + ["truth-prebuilt"], @@ -115,7 +114,7 @@ android_test { compile_multilib: "both", - additional_manifests: ["AndroidManifest-verifierConfig.xml"], + manifest: "AndroidManifest-verifierConfig.xml", jni_libs: [ "libctsverifier_jni", diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml index db1ca21c978..981f0fa4021 100644 --- a/apps/CtsVerifier/AndroidManifest.xml +++ b/apps/CtsVerifier/AndroidManifest.xml @@ -248,7 +248,6 @@ <action android:name="android.intent.action.MAIN" /> <category android:name="android.cts.intent.category.MANUAL_TEST" /> </intent-filter> - <meta-data android:name="CddTest" android:value="3.8.17/C-1-1,C-2-1" /> <meta-data android:name="test_category" android:value="@string/test_category_features" /> <meta-data android:name="test_excluded_features" android:value="android.hardware.type.watch:android.software.leanback:android.hardware.type.automotive" /> @@ -3213,6 +3212,22 @@ android:value="multi_display_mode" /> </activity> + <activity android:name=".notifications.MediaPlayerVerifierActivity" + android:label="@string/media_controls_title" + android:exported="true"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.cts.intent.category.MANUAL_TEST" /> + </intent-filter> + + <meta-data android:name="test_category" + android:value="@string/test_category_notifications" /> + <meta-data android:name="test_excluded_features" + android:value="android.hardware.type.watch:android.software.leanback:android.hardware.type.automotive" /> + <meta-data android:name="display_mode" + android:value="multi_display_mode" /> + </activity> + <service android:name=".notifications.MockListener" android:exported="true" android:label="@string/nls_service_name" @@ -3902,6 +3917,174 @@ android:value="single_display_mode" /> </activity> + <!-- CTS Verifier Presence Test Top Screen --> + <activity + android:name=".presence.PresenceTestActivity" + android:configChanges="keyboardHidden|orientation|screenSize" + android:exported="true" + android:label="@string/presence_test" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + + <category android:name="android.cts.intent.category.MANUAL_TEST" /> + </intent-filter> + + <meta-data + android:name="test_category" + android:value="@string/test_category_networking" /> + <meta-data android:name="display_mode" + android:value="single_display_mode" /> + </activity> + + <!-- + CTS Verifier Uwb Precision Test Screen + test category : uwb + test parent : PresenceTestActivity + --> + <activity + android:name=".presence.UwbPrecisionActivity" + android:configChanges="keyboardHidden|orientation|screenSize" + android:exported="true" + android:label="@string/uwb_precision" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + + <category android:name="android.cts.intent.category.MANUAL_TEST" /> + </intent-filter> + + <meta-data + android:name="test_category" + android:value="@string/uwb" /> + <meta-data + android:name="test_parent" + android:value="com.android.cts.verifier.presence.PresenceTestActivity" /> + <meta-data android:name="display_mode" + android:value="single_display_mode" /> + <meta-data android:name="CddTest" + android:value="7.4.9/C-1-1" /> + </activity> + + <!-- + CTS Verifier Uwb Short Range Test Screen + test category : uwb + test parent : PresenceTestActivity + --> + <activity + android:name=".presence.UwbShortRangeActivity" + android:configChanges="keyboardHidden|orientation|screenSize" + android:exported="true" + android:label="@string/uwb_short_range" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + + <category android:name="android.cts.intent.category.MANUAL_TEST" /> + </intent-filter> + + <meta-data + android:name="test_category" + android:value="@string/uwb" /> + <meta-data + android:name="test_parent" + android:value="com.android.cts.verifier.presence.PresenceTestActivity" /> + <meta-data + android:name="display_mode" + android:value="single_display_mode" /> + <meta-data + android:name="CddTest" + android:value="7.4.9/C-1-2" /> + </activity> + + <!-- + CTS Verifier BLE RSSI Precision Test Screen + test category : BLE + test parent : PresenceTestActivity + --> + <activity + android:name=".presence.BleRssiPrecisionActivity" + android:exported="true" + android:label="@string/ble_rssi_precision_name"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + + <category android:name="android.cts.intent.category.MANUAL_TEST" /> + </intent-filter> + + <meta-data + android:name="test_category" + android:value="@string/ble" /> + <meta-data + android:name="test_parent" + android:value="com.android.cts.verifier.presence.PresenceTestActivity" /> + <meta-data + android:name="test_required_features" + android:value="android.hardware.bluetooth_le" /> + <meta-data + android:name="display_mode" + android:value="single_display_mode" /> + <meta-data + android:name="CddText" + android:value="7.4.3/C-7-1" /> + </activity> + + <!-- + CTS Verifier BLE Rx/Tx Calibration Test Screen + test category : BLE + test parent : PresenceTestActivity + --> + <activity + android:name=".presence.BleRxTxCalibrationActivity" + android:exported="true" + android:label="@string/ble_rx_tx_calibration_name"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + + <category android:name="android.cts.intent.category.MANUAL_TEST" /> + </intent-filter> + + <meta-data + android:name="test_category" + android:value="@string/ble" /> + <meta-data + android:name="test_parent" + android:value="com.android.cts.verifier.presence.PresenceTestActivity" /> + <meta-data + android:name="test_required_features" + android:value="android.hardware.bluetooth_le" /> + <meta-data + android:name="display_mode" + android:value="single_display_mode" /> + <meta-data + android:name="CddText" + android:value="7.4.3/C-7-2" /> + </activity> + + <!-- CTS Verifier Nan Precision and Bias Test Screen + test category : wifi_nan + test parent : PresenceTestActivity + --> + <activity + android:name=".presence.NanPrecisionTestActivity" + android:configChanges="keyboardHidden|orientation|screenSize" + android:exported="true" + android:label="@string/nan_precision" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + + <category android:name="android.cts.intent.category.MANUAL_TEST" /> + </intent-filter> + + <meta-data + android:name="test_category" + android:value="@string/wifi_nan" /> + <meta-data + android:name="test_parent" + android:value="com.android.cts.verifier.presence.PresenceTestActivity" /> + <meta-data android:name="display_mode" + android:value="single_display_mode" /> + <meta-data android:name="CddTest" + android:value="7.4.2.5/H-1-1|7.4.2.5/H-1-2" /> + </activity> + <activity-alias android:name=".CtsVerifierActivity" android:label="@string/app_name" @@ -4871,7 +5054,6 @@ android:exported="true" android:launchMode="singleTask"> <intent-filter> - <action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.MAIN" /> <category android:name="android.cts.intent.category.MANUAL_TEST" /> </intent-filter> @@ -4880,8 +5062,6 @@ android:value="android.software.live_tv" /> <meta-data android:name="display_mode" android:value="multi_display_mode" /> - <meta-data android:name="CddTest" - android:value="3.12/C-1-2" /> </activity> <activity android:name=".tv.MicrophoneDeviceTestActivity" @@ -5992,7 +6172,6 @@ <category android:name="android.cts.intent.category.MANUAL_TEST" /> </intent-filter> <meta-data android:name="test_category" android:value="@string/test_category_logcat" /> - <meta-data android:name="test_excluded_features" android:value="android.hardware.type.automotive" /> </activity> <activity android:name=".displaycutout.DisplayCutoutTestActivity" diff --git a/apps/CtsVerifier/res/layout/ble_rssi_precision.xml b/apps/CtsVerifier/res/layout/ble_rssi_precision.xml new file mode 100644 index 00000000000..5f01e1fc442 --- /dev/null +++ b/apps/CtsVerifier/res/layout/ble_rssi_precision.xml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2022 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + style="@style/RootLayoutPadding" + tools:ignore="Autofill"> + + <ScrollView + android:layout_width="fill_parent" + android:layout_height="wrap_content"> + + <LinearLayout + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <TextView + android:text="@string/ble_rssi_precision_test_instructions" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:scrollbars="vertical" /> + + <EditText + android:id="@+id/report_rssi_range" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:hint="@string/report_ble_rssi_range" + android:inputType="number" /> + + <EditText + android:id="@+id/report_reference_device" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:hint="@string/report_reference_device" + android:inputType="text" /> + + <include + android:layout_width="match_parent" + android:layout_height="wrap_content" + layout="@layout/pass_fail_buttons" /> + </LinearLayout> + </ScrollView> +</RelativeLayout> diff --git a/apps/CtsVerifier/res/layout/ble_rx_tx_calibration.xml b/apps/CtsVerifier/res/layout/ble_rx_tx_calibration.xml new file mode 100644 index 00000000000..3ca955b7e30 --- /dev/null +++ b/apps/CtsVerifier/res/layout/ble_rx_tx_calibration.xml @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + ~ Copyright (C) 2022 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + style="@style/RootLayoutPadding" + tools:ignore="Autofill"> + + <ScrollView + android:layout_width="fill_parent" + android:layout_height="wrap_content"> + + <LinearLayout + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <TextView + android:text="@string/ble_rx_tx_calibration_test_instructions" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:scrollbars="vertical" /> + + <EditText + android:id="@+id/report_channels_rssi_range" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:hint="@string/report_channels_ble_rssi_range" + android:inputType="number" /> + + <EditText + android:id="@+id/report_cores_rssi_range" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:hint="@string/report_cores_ble_rssi_range" + android:inputType="number" /> + + <EditText + android:id="@+id/report_reference_device" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:hint="@string/report_reference_device" + android:inputType="text" /> + + <include + android:layout_width="match_parent" + android:layout_height="wrap_content" + layout="@layout/pass_fail_buttons" /> + </LinearLayout> + </ScrollView> +</RelativeLayout> diff --git a/apps/CtsVerifier/res/layout/clipboard_preview.xml b/apps/CtsVerifier/res/layout/clipboard_preview.xml index efec118cb4d..85f38c8eef7 100644 --- a/apps/CtsVerifier/res/layout/clipboard_preview.xml +++ b/apps/CtsVerifier/res/layout/clipboard_preview.xml @@ -31,6 +31,86 @@ android:layout_marginBottom="100dp" android:layout_marginTop="30dp" android:text="@string/clipboard_preview_test_copy_button"/> + + <TableLayout + android:layout_width="match_parent" + android:layout_height="wrap_content"> + <TableRow + android:layout_width="match_parent" + android:layout_height="50dp"> + <View android:layout_weight="3" + android:layout_height="50dp"/> + <Button android:layout_weight="1" + android:id="@+id/clipboard_preview_test_b1" + android:layout_width="50dp" + android:layout_height="50dp" + android:text="1"/> + <Button android:layout_weight="1" + android:id="@+id/clipboard_preview_test_b2" + android:layout_width="50dp" + android:layout_height="50dp" + android:text="2"/> + <Button android:layout_weight="1" + android:id="@+id/clipboard_preview_test_b3" + android:layout_width="50dp" + android:layout_height="50dp" + android:text="3"/> + <View android:layout_weight="3" + android:layout_height="50dp"/> + </TableRow> + <TableRow + android:layout_width="match_parent" + android:layout_height="50dp"> + <View android:layout_weight="3" + android:layout_height="50dp"/> + <Button android:layout_weight="1" + android:id="@+id/clipboard_preview_test_b4" + android:layout_width="50dp" + android:layout_height="50dp" + android:text="4"/> + <Button android:layout_weight="1" + android:id="@+id/clipboard_preview_test_b5" + android:layout_width="50dp" + android:layout_height="50dp" + android:text="5"/> + <Button android:layout_weight="1" + android:id="@+id/clipboard_preview_test_b6" + android:layout_width="50dp" + android:layout_height="50dp" + android:text="6"/> + <View android:layout_weight="3" + android:layout_height="50dp"/> + </TableRow> + <TableRow + android:layout_width="match_parent" + android:layout_height="50dp"> + <View android:layout_weight="3" + android:layout_height="match_parent"/> + <Button android:layout_weight="1" + android:id="@+id/clipboard_preview_test_b7" + android:layout_width="50dp" + android:layout_height="match_parent" + android:text="7"/> + <Button android:layout_weight="1" + android:id="@+id/clipboard_preview_test_b8" + android:layout_width="50dp" + android:layout_height="match_parent" + android:text="8"/> + <Button android:layout_weight="1" + android:id="@+id/clipboard_preview_test_b9" + android:layout_width="50dp" + android:layout_height="match_parent" + android:text="9"/> + <View android:layout_weight="3" + android:layout_height="50dp"/> + </TableRow> + </TableLayout> + <Button + android:id="@+id/clipboard_preview_test_b0" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:text="0"/> <include android:id="@+id/clipboard_preview_test_pass_fail" android:layout_width="match_parent" diff --git a/apps/CtsVerifier/res/layout/nan_precision.xml b/apps/CtsVerifier/res/layout/nan_precision.xml new file mode 100644 index 00000000000..c81a9c4f120 --- /dev/null +++ b/apps/CtsVerifier/res/layout/nan_precision.xml @@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2022 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + style="@style/RootLayoutPadding"> + <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="wrap_content"> + <LinearLayout android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + <TextView android:text="@string/nan_precision_instruction" + android:id="@+id/nan_precision_instruction" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:scrollbars="vertical"/> + <LinearLayout android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + <EditText android:id="@+id/nan_bandwidth" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:inputType="number" + android:hint="@string/report_nan_bandwidth_mhz"/> + <EditText android:id="@+id/distance_range_10cm_gt_68p" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:inputType="numberDecimal" + android:hint="@string/report_distance_range_10cm_gt_68p"/> + <EditText android:id="@+id/distance_range_1m_gt_68p" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:inputType="numberDecimal" + android:hint="@string/report_distance_range_1m_gt_68p"/> + <EditText android:id="@+id/distance_range_3m_gt_68p" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:inputType="numberDecimal" + android:hint="@string/report_distance_range_3m_gt_68p"/> + <EditText android:id="@+id/distance_range_5m_gt_68p" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:inputType="numberDecimal" + android:hint="@string/report_distance_range_5m_gt_68p"/> + <EditText android:id="@+id/distance_range_10cm_gt_90p" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:inputType="numberDecimal" + android:hint="@string/report_distance_range_10cm_gt_90p"/> + <EditText android:id="@+id/distance_range_1m_gt_90p" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:inputType="numberDecimal" + android:hint="@string/report_distance_range_1m_gt_90p"/> + <EditText android:id="@+id/distance_range_3m_gt_90p" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:inputType="numberDecimal" + android:hint="@string/report_distance_range_3m_gt_90p"/> + <EditText android:id="@+id/distance_range_5m_gt_90p" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:inputType="numberDecimal" + android:hint="@string/report_distance_range_5m_gt_90p"/> + <EditText android:id="@+id/reference_device" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:hint="@string/report_reference_device"/> + </LinearLayout> + + <include android:layout_width="match_parent" + android:layout_height="wrap_content" + layout="@layout/pass_fail_buttons"/> + </LinearLayout> + </ScrollView> +</RelativeLayout> diff --git a/apps/CtsVerifier/res/layout/uwb_precision.xml b/apps/CtsVerifier/res/layout/uwb_precision.xml new file mode 100644 index 00000000000..14e996d6f5f --- /dev/null +++ b/apps/CtsVerifier/res/layout/uwb_precision.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2022 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + style="@style/RootLayoutPadding"> + <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="wrap_content"> + <LinearLayout android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + <TextView android:text="@string/uwb_precision_instruction" + android:id="@+id/uwb_precision_instruction" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:scrollbars="vertical"/> + <LinearLayout android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + <EditText android:id="@+id/distance_range_cm" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:inputType="numberDecimal" + android:hint="@string/report_distance_range_cm"/> + <EditText android:id="@+id/reference_device" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:hint="@string/report_reference_device"/> + </LinearLayout> + + <include android:layout_width="match_parent" + android:layout_height="wrap_content" + layout="@layout/pass_fail_buttons"/> + </LinearLayout> + </ScrollView> +</RelativeLayout> diff --git a/apps/CtsVerifier/res/layout/uwb_short_range.xml b/apps/CtsVerifier/res/layout/uwb_short_range.xml new file mode 100644 index 00000000000..9afc6e5a6b4 --- /dev/null +++ b/apps/CtsVerifier/res/layout/uwb_short_range.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2022 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + style="@style/RootLayoutPadding"> + <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="wrap_content"> + <LinearLayout android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + <TextView android:text="@string/uwb_short_range_instruction" + android:id="@+id/uwb_short_range_instruction" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:scrollbars="vertical"/> + <LinearLayout android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + <EditText android:id="@+id/distance_median_meters" + android:layout_width="wrap_content" + android:inputType="numberDecimal" + android:layout_height="wrap_content" + android:hint="@string/report_distance_median_meters"/> + <EditText android:id="@+id/reference_device" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:hint="@string/report_reference_device"/> + </LinearLayout> + + <include android:layout_width="match_parent" + android:layout_height="wrap_content" + layout="@layout/pass_fail_buttons"/> + </LinearLayout> + </ScrollView> +</RelativeLayout> diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml index 0f32b34e78e..9f0aa964beb 100644 --- a/apps/CtsVerifier/res/values/strings.xml +++ b/apps/CtsVerifier/res/values/strings.xml @@ -32,16 +32,6 @@ <string name="finish_button_text">Finish</string> <string name="fail_and_next_button_text">Fail and Next</string> - <!-- Strings for CtsReportLog warning --> - <string name="reportlog_warning_title">CTS-Verifier Report Log</string> - <string name="reportlog_warning_body">Can\'t create folder for CTS-Verifier Report Logs. - \n\nPlease enable Report Log creation by exiting CTS Verifier and running the following commands: - \n\n<code>adb shell appops set com.android.cts.verifier android:read_device_identifiers allow</code> - \n\n<code>adb shell appops set com.android.cts.verifier MANAGE_EXTERNAL_STORAGE 0</code> - \n\nTest instructions are found in the \"Using CTS Verifier\" document found at - <a href="https://source.android.com/compatibility/cts/verifier">https://source.android.com/compatibility/cts/verifier</a> - </string> - <!-- Strings for TestListActivity --> <string name="test_category_audio">Audio</string> <string name="test_category_camera">Camera</string> @@ -311,11 +301,9 @@ </string> <string name="clipboard_preview_test_instructions"> Press the \'Copy\' button to copy the secret code to the clipboard. - \n\n If nothing happens, press Fail. - \n\n If you see the word "FAIL" appear on screen, press Fail. - \n\n If you see a confirmation that content has been copied to the clipboard, press Pass. + \n\nUse the clipboard preview UI, or the clipboard editor component to view the secret code. + \n\nEnter the secret code using the buttons below. </string> - <string name="clipboard_preview_test_secret">FAIL</string> <string name="clipboard_preview_test_copy_button">Copy</string> @@ -790,7 +778,7 @@ <!-- BLE Advertising Set test strings --> <string name="ble_advertising_set_test_name">Bluetooth LE Advertising Set Test</string> <string name="ble_advertising_set_test_info">Bluetooth LE Advertising Set tests AdvertisingSet and AdvertisingSetCallback APIs.</string> - <string name="ble_advertising_set_test_instruction">Press the \"Start Test\" button. UI thread may freeze for a few seconds while enabling/disabling bluetooth adapter.</string> + <string name="ble_advertising_set_test_instruction">Press the \"Set Up\" button first, then start the test by pressing the \"Start Test\" button. UI thread may freeze for a few seconds while enabling/disabling bluetooth adapter.</string> <string name="ble_advertising_set_start_test">Start Test</string> <string name="ble_advertising_set_running_test">Running Test...</string> <string name="ble_advertising_set_finished_test">Finished Test</string> @@ -2462,6 +2450,16 @@ icon, large icon, notification title, notification text, and two action buttons. If this device does not support heads-up notifications, press Pass.</string> <string name="action">Action %1$d</string> + <string name="media_controls_title">Media Controls Test</string> + <string name="media_controls_info">This test checks that media controls appear in the shade for + applications that post a media style notification.</string> + <string name="media_controls_visible">Pull down the notification shade and check that the media + controls from the CTS Verifier app are visible. + </string> + <string name="media_controls_output_switcher_chip">Pull down the notification shade and look at + the media controls for the CTS Verifier app. + Check that it contains an affordance to switch between available media routes. + </string> <string name="tile_service_name">Tile Service for CTS Verifier</string> <string name="tiles_test">Tile Service Test</string> <string name="tiles_info">This test checks that a Tile Service added by a third party @@ -3757,11 +3755,6 @@ You should be prompted to select credentials; choose the ones you just installed Device Owner. Then press the button below, and check that CTSVerifier is NOT Device Owner anymore. </string> - <string name="device_owner_remove_device_owner_test_info_on_tv"> - Please check in Settings > Privacy > Security & Restrictions > Device Administrators if CTSVerifier is - Device Owner. Then press the button below, and check that CTSVerifier is NOT Device - Owner anymore. - </string> <string name="remove_device_owner_button">Remove device owner</string> <string name="device_owner_check_device_owner_test">Check device owner</string> <string name="device_owner_check_profile_owner_test">Check profile owner</string> @@ -4066,13 +4059,12 @@ You should be prompted to select credentials; choose the ones you just installed <string name="device_owner_disallow_config_bt">Disallow configuring Bluetooth</string> <string name="device_owner_disallow_config_bt_info"> Please press the Set restriction button to set the user restriction. - Then press Go, you should either see (a) the Bluetooth settings page or (b) trigger a support message directly.\n - In the case of (a), confirm that:\n + Then press Go to open the Bluetooth page in Settings. + Confirm that:\n + \n - You cannot view Bluetooth devices in range.\n - Trying to edit, add or remove any already paired devices triggers a support message.\n \n - In the case of (b) this step is successful.\n - \n Use the Back button to return to this page. </string> <string name="device_owner_disallow_config_wifi">Disallow configuring WiFi</string> @@ -5492,7 +5484,6 @@ You should be prompted to select credentials; choose the ones you just installed <string name="audio_general_test_not_run">Test Not Run</string> <string name="audio_general_testnotcompleted">Test not completed.</string> - <string name="audio_general_reportlogtest">[Can\'t Write ReportLog]</string> <!-- Audio Loopback Latency Test --> <string name="audio_loopback_latency_test">Audio Loopback Latency Test</string> diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/CtsVerifierReportLog.java b/apps/CtsVerifier/src/com/android/cts/verifier/CtsVerifierReportLog.java index a93e3b58c33..b013bb7180e 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/CtsVerifierReportLog.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/CtsVerifierReportLog.java @@ -74,10 +74,6 @@ public class CtsVerifierReportLog extends ReportLog { } } - public boolean isOpen() { - return mStore != null; - } - /** * Closes report file. Static functions that do not have access to instrumentation can * use this to close report logs. Summary, if present, is not reported to instrumentation, hence diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java b/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java index 7b993eefc58..0294ff78e7c 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java @@ -32,6 +32,7 @@ import android.database.Cursor; import android.os.Bundle; import android.os.PowerManager; import android.os.PowerManager.WakeLock; +import android.util.Log; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; @@ -145,8 +146,6 @@ public class PassFailButtons { private final CtsVerifierReportLog mReportLog; private final TestResultHistoryCollection mHistoryCollection; - protected boolean mRequireReportLogToPass; - public Activity() { this.mReportLog = new CtsVerifierReportLog(getReportFileName(), getReportSectionName()); this.mHistoryCollection = new TestResultHistoryCollection(); @@ -160,10 +159,6 @@ public class PassFailButtons { .newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "PassFailButtons"); mWakeLock.acquire(); } - - if (!this.mReportLog.isOpen()) { - showReportLogWarningDialog(this); - } } @Override @@ -217,14 +212,6 @@ public class PassFailButtons { } /** - * A mechanism to block tests from passing if no ReportLog data has been collected. - * @return true if the ReportLog is open OR if the test does not require that. - */ - public boolean isReportLogOkToPass() { - return !mRequireReportLogToPass || mReportLog.isOpen(); - } - - /** * @return The name of the file to store the (suite of) ReportLog information. */ @Override @@ -540,12 +527,6 @@ public class PassFailButtons { activity.showDialog(INFO_DIALOG_ID, args); } - protected static void showReportLogWarningDialog(final android.app.Activity activity) { - showInfoDialog(activity, - R.string.reportlog_warning_title, R.string.reportlog_warning_body, -1); - } - - protected static Dialog createDialog(final android.app.Activity activity, int id, Bundle args) { switch (id) { case INFO_DIALOG_ID: diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AnalogHeadsetAudioActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AnalogHeadsetAudioActivity.java index 83b32def714..528d9149588 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AnalogHeadsetAudioActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AnalogHeadsetAudioActivity.java @@ -182,15 +182,12 @@ public class AnalogHeadsetAudioActivity mResultsTxt.setText(getResources().getString(R.string.analog_headset_pass_noheadset)); return true; } else { - boolean pass = isReportLogOkToPass() - && mPlugIntentReceived - && mHeadsetDeviceInfo != null - && mPlaybackSuccess - && (mHasHeadsetHook || mHasPlayPause) && mHasVolUp && mHasVolDown; + boolean pass = mPlugIntentReceived && + mHeadsetDeviceInfo != null && + mPlaybackSuccess && + (mHasHeadsetHook || mHasPlayPause) && mHasVolUp && mHasVolDown; if (pass) { mResultsTxt.setText(getResources().getString(R.string.analog_headset_pass)); - } else if (!isReportLogOkToPass()) { - mResultsTxt.setText(getResources().getString(R.string.audio_general_reportlogtest)); } return pass; } diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioAEC.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioAEC.java index 3c1b8a1151e..48795efc142 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioAEC.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioAEC.java @@ -542,10 +542,8 @@ public class AudioAEC extends AudioFrequencyActivity implements View.OnClickList Log.v(TAG, "Test EndedOk. " + testId + " str:"+str); showView(mProgress, false); mResultTest.setText("test completed. " + str); - if (!isReportLogOkToPass()) { - mResultTest.setText(getResources().getString(R.string.audio_general_reportlogtest)); - } else if (mTestAECPassed) { - getPassButton().setEnabled(true); + if (mTestAECPassed) { + getPassButton().setEnabled(true);; } } diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackLatencyActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackLatencyActivity.java index 79d3e3b2b0b..a6bd4add994 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackLatencyActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackLatencyActivity.java @@ -294,8 +294,6 @@ public class AudioLoopbackLatencyActivity extends PassFailButtons.Activity { getPassButton().setEnabled(false); setInfoResources(R.string.audio_loopback_latency_test, R.string.audio_loopback_info, -1); - mRequireReportLogToPass = true; - mClaimsOutput = AudioSystemFlags.claimsOutput(this); mClaimsInput = AudioSystemFlags.claimsInput(this); mClaimsProAudio = AudioSystemFlags.claimsProAudio(this); @@ -685,8 +683,7 @@ public class AudioLoopbackLatencyActivity extends PassFailButtons.Activity { mResultsText[mTestRoute].setText(testSpec.getResultString()); LoopbackLatencyRequirements requirements = new LoopbackLatencyRequirements(); - boolean pass = isReportLogOkToPass() - && requirements.evaluate(mClaimsProAudio, + boolean pass = requirements.evaluate(mClaimsProAudio, Build.VERSION.MEDIA_PERFORMANCE_CLASS, mTestSpecs[TESTROUTE_DEVICE].isMeasurementValid() ? mTestSpecs[TESTROUTE_DEVICE].mMeanLatencyMS : 0.0, @@ -697,12 +694,8 @@ public class AudioLoopbackLatencyActivity extends PassFailButtons.Activity { getPassButton().setEnabled(pass); - StringBuilder sb = new StringBuilder(); - if (!isReportLogOkToPass()) { - sb.append(getResources().getString(R.string.audio_general_reportlogtest) + "\n"); - } - sb.append(requirements.getResultsString()); - mTestStatusText.setText(sb.toString()); + String resultText = requirements.getResultsString(); + mTestStatusText.setText(resultText); showWait(false); enableStartButtons(true); diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioTap2ToneActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioTap2ToneActivity.java index 8ff23588889..215d26fd65b 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioTap2ToneActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioTap2ToneActivity.java @@ -154,8 +154,6 @@ public class AudioTap2ToneActivity String yesString = getResources().getString(R.string.audio_general_yes); String noString = getResources().getString(R.string.audio_general_no); - mRequireReportLogToPass = true; - boolean claimsProAudio = AudioSystemFlags.claimsProAudio(this); boolean claimsLowLatencyAudio = AudioSystemFlags.claimsLowLatencyAudio(this); @@ -313,14 +311,11 @@ public class AudioTap2ToneActivity } double averageLatency = mLatencyAve[mActiveTestAPI]; - boolean pass = isReportLogOkToPass() - && averageLatency != 0 && averageLatency <= mMaxRequiredLatency; + boolean pass = averageLatency != 0 && averageLatency <= mMaxRequiredLatency; if (pass) { mSpecView.setText("Average: " + averageLatency + " ms <= " + mMaxRequiredLatency + " ms -- PASS"); - } else if (!isReportLogOkToPass()) { - mSpecView.setText(getResources().getString(R.string.audio_general_reportlogtest)); } else { mSpecView.setText("Average: " + averageLatency + " ms > " + mMaxRequiredLatency + " ms -- FAIL"); diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundSpeakerTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundSpeakerTestActivity.java index cac4659bba0..3dccf1f1293 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundSpeakerTestActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundSpeakerTestActivity.java @@ -92,15 +92,6 @@ public class HifiUltrasoundSpeakerTestActivity extends PassFailButtons.Activity } } - boolean getBoolPropValue(final String value) { - if (value == null) { - return false; - } - - return !value.equalsIgnoreCase(getResources().getString( - R.string.hifi_ultrasound_test_default_false_string)); - } - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -115,17 +106,27 @@ public class HifiUltrasoundSpeakerTestActivity extends PassFailButtons.Activity info.setText(R.string.hifi_ultrasound_speaker_test_instruction1); AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); - micSupport = getBoolPropValue(audioManager.getProperty( - AudioManager.PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND)); - spkrSupport = getBoolPropValue(audioManager.getProperty( - AudioManager.PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND)); - Log.d(TAG, "PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND = " + micSupport); - Log.d(TAG, "PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND = " + spkrSupport); - - if (!micSupport) { + String micSupportString = audioManager.getProperty( + AudioManager.PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND); + String spkrSupportString = audioManager.getProperty( + AudioManager.PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND); + Log.d(TAG, "PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND = " + micSupportString); + Log.d(TAG, "PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND = " + spkrSupportString); + + if (micSupportString == null) { + micSupportString = "null"; + } + if (spkrSupportString == null) { + spkrSupportString = "null"; + } + if (micSupportString.equalsIgnoreCase(getResources().getString( + R.string.hifi_ultrasound_test_default_false_string))) { + micSupport = false; info.append(getResources().getString(R.string.hifi_ultrasound_speaker_test_mic_no_support)); } - if (!spkrSupport) { + if (spkrSupportString.equalsIgnoreCase(getResources().getString( + R.string.hifi_ultrasound_test_default_false_string))) { + spkrSupport = false; getPassButton().setEnabled(true); info.append(getResources().getString(R.string.hifi_ultrasound_speaker_test_spkr_no_support)); } diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundTestActivity.java index 5f1be3899e8..f5e4271e981 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundTestActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundTestActivity.java @@ -75,15 +75,6 @@ public class HifiUltrasoundTestActivity extends PassFailButtons.Activity { } } - boolean getBoolPropValue(final String value) { - if (value == null) { - return false; - } - - return !value.equalsIgnoreCase(getResources().getString( - R.string.hifi_ultrasound_test_default_false_string)); - } - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -97,19 +88,29 @@ public class HifiUltrasoundTestActivity extends PassFailButtons.Activity { info.setText(R.string.hifi_ultrasound_test_instruction1); AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); - micSupport = getBoolPropValue(audioManager.getProperty( - AudioManager.PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND)); - spkrSupport = getBoolPropValue(audioManager.getProperty( - AudioManager.PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND)); - Log.d(TAG, "PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND = " + micSupport); - Log.d(TAG, "PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND = " + spkrSupport); - - if (!micSupport) { + String micSupportString = audioManager.getProperty( + AudioManager.PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND); + String spkrSupportString = audioManager.getProperty( + AudioManager.PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND); + Log.d(TAG, "PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND = " + micSupportString); + Log.d(TAG, "PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND = " + spkrSupportString); + + if (micSupportString == null) { + micSupportString = "null"; + } + if (spkrSupportString == null) { + spkrSupportString = "null"; + } + if (micSupportString.equalsIgnoreCase(getResources().getString( + R.string.hifi_ultrasound_test_default_false_string))) { + micSupport = false; getPassButton().setEnabled(true); getPassButton().performClick(); info.append(getResources().getString(R.string.hifi_ultrasound_test_mic_no_support)); } - if (!spkrSupport) { + if (spkrSupportString.equalsIgnoreCase(getResources().getString( + R.string.hifi_ultrasound_test_default_false_string))) { + spkrSupport = false; info.append(getResources().getString(R.string.hifi_ultrasound_test_spkr_no_support)); } diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java index e93d2b319ff..126d15fdacb 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java @@ -158,9 +158,11 @@ public class ProAudioActivity boolean usbOK = mClaimsUSBHostMode && mClaimsUSBPeripheralMode; boolean hdmiOK = !mClaimsHDMI || isHDMIValid(); - boolean hasPassed = isReportLogOkToPass() - && !mClaimsProAudio - || (mClaimsLowLatencyAudio && mClaimsMIDI && usbOK && hdmiOK); + boolean hasPassed = !mClaimsProAudio || + (mClaimsLowLatencyAudio && + mClaimsMIDI && + usbOK && + hdmiOK); getPassButton().setEnabled(hasPassed); return hasPassed; @@ -170,9 +172,7 @@ public class ProAudioActivity boolean hasPassed = calculatePass(); Resources strings = getResources(); - if (!isReportLogOkToPass()) { - mTestStatusLbl.setText(getResources().getString(R.string.audio_general_reportlogtest)); - } else if (hasPassed) { + if (hasPassed) { mTestStatusLbl.setText(strings.getString(R.string.audio_proaudio_pass)); } else if (!mClaimsMIDI) { mTestStatusLbl.setText(strings.getString(R.string.audio_proaudio_midinotreported)); diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralNotificationsTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralNotificationsTest.java index 6270a5a8311..bc23048c28e 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralNotificationsTest.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/USBAudioPeripheralNotificationsTest.java @@ -20,17 +20,23 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; + import android.media.AudioDeviceCallback; import android.media.AudioDeviceInfo; import android.media.AudioManager; + import android.os.Bundle; import android.os.Handler; + import android.util.Log; + import android.widget.TextView; import com.android.compatibility.common.util.CddTest; +import com.android.compatibility.common.util.ReportLog; import com.android.compatibility.common.util.ResultType; import com.android.compatibility.common.util.ResultUnit; + import com.android.cts.verifier.PassFailButtons; import com.android.cts.verifier.R; // needed to access resource in CTSVerifier project namespace. @@ -167,10 +173,9 @@ public class USBAudioPeripheralNotificationsTest extends PassFailButtons.Activit // Test Status // private boolean calculatePass() { - return isReportLogOkToPass() - && mUsbHeadsetInReceived && mUsbHeadsetOutReceived - && mUsbDeviceInReceived && mUsbDeviceOutReceived - && mPlugIntentReceived; + return mUsbHeadsetInReceived && mUsbHeadsetOutReceived && + mUsbDeviceInReceived && mUsbDeviceOutReceived && + mPlugIntentReceived; } // diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertisingSetTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertisingSetTestActivity.java index 164992b94a9..803c385f33f 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertisingSetTestActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertisingSetTestActivity.java @@ -244,16 +244,6 @@ public class BleAdvertisingSetTestActivity extends PassFailButtons.Activity { // The following order of commands follows the diagram of Bluetooth Core Specification, // Version 5.3, Vol 6, Part D, Figure 3.7: Periodic advertising. private void testPeriodicAdvertising() throws InterruptedException { - if (!mBluetoothAdapter.isLePeriodicAdvertisingSupported()) { - mAllTestsPassed |= PASS_FLAG_SET_PERIODIC_ADVERTISING_PARAMS - | PASS_FLAG_SET_PERIODIC_ADVERTISING_DATA - | PASS_FLAG_SET_PERIODIC_ADVERTISING_ENABLED_DISABLED; - mTestAdapter.setTestPass(TEST_ADAPTER_INDEX_SET_PERIODIC_ADVERTISING_PARAMS); - mTestAdapter.setTestPass(TEST_ADAPTER_INDEX_SET_PERIODIC_ADVERTISING_DATA); - mTestAdapter.setTestPass(TEST_ADAPTER_INDEX_SET_PERIODIC_ADVERTISING_ENABLED_DISABLED); - return; - } - mCallback.reset(); mCallback.mAdvertisingSet.get().setAdvertisingParameters( diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientService.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientService.java index 21e2877e1e6..3c1c58baee7 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientService.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientService.java @@ -120,8 +120,6 @@ public class BleClientService extends Service { "com.android.cts.verifier.bluetooth.BLE_READ_REMOTE_RSSI"; public static final String BLE_PHY_READ = "com.android.cts.verifier.bluetooth.BLE_PHY_READ"; - public static final String BLE_PHY_READ_SKIPPED = - "com.android.cts.verifier.bluetooth.BLE_PHY_READ_SKIPPED"; public static final String BLE_ON_SERVICE_CHANGED = "com.android.cts.verifier.bluetooth.BLE_ON_SERVICE_CHANGED"; public static final String BLE_CHARACTERISTIC_READ_NOPERMISSION = @@ -909,12 +907,6 @@ public class BleClientService extends Service { sendBroadcast(intent); } - private void notifyPhyReadSkipped() { - showMessage("Phy read not supported. Skipping the test."); - Intent intent = new Intent(BLE_PHY_READ_SKIPPED); - sendBroadcast(intent); - } - private void notifyServiceChanged() { showMessage("Remote service changed"); Intent intent = new Intent(BLE_ON_SERVICE_CHANGED); @@ -1437,12 +1429,10 @@ public class BleClientService extends Service { public void onPhyRead(BluetoothGatt gatt, int txPhy, int rxPhy, int status) { super.onPhyRead(gatt, txPhy, rxPhy, status); if (DEBUG) { - Log.d(TAG, "onPhyRead status=" + status); + Log.d(TAG, "onPhyRead"); } if (status == BluetoothGatt.GATT_SUCCESS) { notifyPhyRead(txPhy, rxPhy); - } else if (status == BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED) { - notifyPhyReadSkipped(); } else { notifyError("Failed to read phy"); } diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientTestBaseActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientTestBaseActivity.java index 2a7c8b40b18..357bb142aa3 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientTestBaseActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientTestBaseActivity.java @@ -127,7 +127,6 @@ public class BleClientTestBaseActivity extends PassFailButtons.Activity { filter.addAction(BleClientService.BLE_RELIABLE_WRITE_BAD_RESP_COMPLETED); filter.addAction(BleClientService.BLE_READ_REMOTE_RSSI); filter.addAction(BleClientService.BLE_PHY_READ); - filter.addAction(BleClientService.BLE_PHY_READ_SKIPPED); filter.addAction(BleClientService.BLE_ON_SERVICE_CHANGED); filter.addAction(BleClientService.BLE_CHARACTERISTIC_READ_NOPERMISSION); filter.addAction(BleClientService.BLE_CHARACTERISTIC_WRITE_NOPERMISSION); @@ -376,7 +375,6 @@ public class BleClientTestBaseActivity extends PassFailButtons.Activity { newAction = BleClientService.BLE_CLIENT_ACTION_READ_PHY; break; case BleClientService.BLE_PHY_READ: - case BleClientService.BLE_PHY_READ_SKIPPED: actionName = getString(R.string.ble_read_phy_name); mTestAdapter.setTestPass(BLE_READ_PHY); mPassed |= PASS_FLAG_READ_PHY; diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleSecureClientTestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleSecureClientTestListActivity.java index cde35beb8f6..feba59c048b 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleSecureClientTestListActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleSecureClientTestListActivity.java @@ -40,13 +40,6 @@ public class BleSecureClientTestListActivity extends PassFailButtons.TestListAct BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
List<String> disabledTest = new ArrayList<String>();
-
- // Temporarily disable this test (b/235763737).
- disabledTest.add(
- "com.android.cts.verifier.bluetooth.BleSecureConnectionPriorityClientTestActivity");
- disabledTest.add(
- "com.android.cts.verifier.bluetooth.BleSecureEncryptedClientTestActivity");
-
if (adapter == null || !adapter.isOffloadedFilteringSupported()) {
disabledTest.add(
"com.android.cts.verifier.bluetooth.BleAdvertiserHardwareScanFilterActivity.");
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleSecureServerTestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleSecureServerTestListActivity.java index 6fc3b872754..06d6dabacd2 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleSecureServerTestListActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleSecureServerTestListActivity.java @@ -37,12 +37,6 @@ public class BleSecureServerTestListActivity extends PassFailButtons.TestListAct BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
List<String> disabledTest = new ArrayList<String>();
- // Temporarily disable this test (b/235763737).
- disabledTest.add(
- "com.android.cts.verifier.bluetooth.BleSecureConnectionPriorityServerTestActivity");
- disabledTest.add(
- "com.android.cts.verifier.bluetooth.BleSecureEncryptedServerTestActivity");
-
if (adapter == null || !adapter.isOffloadedFilteringSupported()) {
disabledTest.add(
"com.android.cts.verifier.bluetooth.BleAdvertiserHardwareScanFilterActivity.");
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java index 212f988d205..1349767889f 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java @@ -32,7 +32,6 @@ import android.content.Intent; import android.content.pm.ServiceInfo; import android.graphics.ImageFormat; import android.graphics.Rect; -import android.graphics.SurfaceTexture; import android.hardware.HardwareBuffer; import android.hardware.Sensor; import android.hardware.SensorEvent; @@ -242,8 +241,6 @@ public class ItsService extends Service implements SensorEventListener { final Object m3AStateLock = new Object(); private volatile boolean mConvergedAE = false; - private volatile boolean mPrecaptureTriggered = false; - private volatile boolean mConvergeAETriggered = false; private volatile boolean mConvergedAF = false; private volatile boolean mConvergedAWB = false; private volatile boolean mLockedAE = false; @@ -824,8 +821,6 @@ public class ItsService extends Service implements SensorEventListener { String cameraId = cmdObj.getString("cameraId"); int profileId = cmdObj.getInt("profileId"); doCheckHLG10Support(cameraId, profileId); - } else if ("doCaptureWithFlash".equals(cmdObj.getString("cmdName"))) { - doCaptureWithFlash(cmdObj); } else { throw new ItsException("Unknown command: " + cmd); } @@ -1847,8 +1842,6 @@ public class ItsService extends Service implements SensorEventListener { // s1440p which is the max supported stream size in a combination, when preview // stabilization is on. Size maxPreviewSize = new Size(1920, 1440); - // QCIF, we test only sizes >= this. - Size minPreviewSize = new Size(176, 144); Size[] outputSizes = configMap.getOutputSizes(ImageFormat.YUV_420_888); if (outputSizes == null) { mSocketRunnableObj.sendResponse("supportedPreviewSizes", ""); @@ -1859,8 +1852,6 @@ public class ItsService extends Service implements SensorEventListener { .distinct() .filter(s -> s.getWidth() * s.getHeight() <= maxPreviewSize.getWidth() * maxPreviewSize.getHeight()) - .filter(s -> s.getWidth() * s.getHeight() - >= minPreviewSize.getWidth() * minPreviewSize.getHeight()) .sorted(Comparator.comparingInt(s -> s.getWidth() * s.getHeight())) .map(Size::toString) .collect(Collectors.joining(";")); @@ -2346,104 +2337,6 @@ public class ItsService extends Service implements SensorEventListener { return mediaFile + fileExtension; } - private void doCaptureWithFlash(JSONObject params) throws ItsException { - // Parse the json to get the capture requests - List<CaptureRequest.Builder> previewStartRequests = ItsSerializer.deserializeRequestList( - mCamera, params, "previewRequestStart"); - List<CaptureRequest.Builder> previewIdleRequests = ItsSerializer.deserializeRequestList( - mCamera, params, "previewRequestIdle"); - List<CaptureRequest.Builder> stillCaptureRequests = ItsSerializer.deserializeRequestList( - mCamera, params, "stillCaptureRequest"); - - mCaptureResults = new CaptureResult[2]; - - ThreeAResultListener threeAListener = new ThreeAResultListener(); - List<OutputConfiguration> outputConfigs = new ArrayList<OutputConfiguration>(); - SurfaceTexture preview = new SurfaceTexture(/*random int*/ 1); - Surface previewSurface = new Surface(preview); - try { - BlockingSessionCallback sessionListener = new BlockingSessionCallback(); - try { - mCountCapRes.set(0); - mCountJpg.set(0); - JSONArray jsonOutputSpecs = ItsUtils.getOutputSpecs(params); - prepareImageReadersWithOutputSpecs(jsonOutputSpecs, /*inputSize*/null, - /*inputFormat*/0,/*maxInputBuffers*/0,false); - - outputConfigs.add(new OutputConfiguration(mOutputImageReaders[0].getSurface())); - outputConfigs.add(new OutputConfiguration(previewSurface)); - mCamera.createCaptureSessionByOutputConfigurations( - outputConfigs, sessionListener, mCameraHandler); - mSession = sessionListener.waitAndGetSession(TIMEOUT_IDLE_MS); - ImageReader.OnImageAvailableListener readerListener = - createAvailableListener(mCaptureCallback); - mOutputImageReaders[0].setOnImageAvailableListener(readerListener, - mSaveHandlers[0]); - } catch (Exception e) { - throw new ItsException("Error configuring outputs", e); - } - CaptureRequest.Builder previewIdleReq = previewIdleRequests.get(0); - previewIdleReq.addTarget(previewSurface); - mSession.setRepeatingRequest(previewIdleReq.build(), threeAListener, mResultHandler); - Logt.i(TAG, "Triggering precapture sequence"); - mPrecaptureTriggered = false; - CaptureRequest.Builder previewStartReq = previewStartRequests.get(0); - previewStartReq.addTarget(previewSurface); - mSession.capture(previewStartReq.build(), threeAListener ,mResultHandler); - mInterlock3A.open(); - synchronized(m3AStateLock) { - mPrecaptureTriggered = false; - mConvergeAETriggered = false; - } - long tstart = System.currentTimeMillis(); - boolean triggeredAE = false; - while (!mPrecaptureTriggered) { - if (!mInterlock3A.block(TIMEOUT_3A * 1000) || - System.currentTimeMillis() - tstart > TIMEOUT_3A * 1000) { - throw new ItsException ( - "AE state is " + CaptureResult.CONTROL_AE_STATE_PRECAPTURE + - "after " + TIMEOUT_3A + " seconds."); - } - } - mConvergeAETriggered = false; - - tstart = System.currentTimeMillis(); - while (!mConvergeAETriggered) { - if (!mInterlock3A.block(TIMEOUT_3A * 1000) || - System.currentTimeMillis() - tstart > TIMEOUT_3A * 1000) { - throw new ItsException ( - "3A failed to converge after " + TIMEOUT_3A + " seconds.\n" + - "AE converge state: " + mConvergedAE + "."); - } - } - mInterlock3A.close(); - Logt.i(TAG, "AE state after precapture sequence: " + mConvergeAETriggered); - threeAListener.stop(); - - // Send a still capture request - CaptureRequest.Builder stillCaptureRequest = stillCaptureRequests.get(0); - Logt.i(TAG, "Taking still capture with ON_AUTO_FLASH."); - stillCaptureRequest.addTarget(mOutputImageReaders[0].getSurface()); - mSession.capture(stillCaptureRequest.build(), mCaptureResultListener, mResultHandler); - mCountCallbacksRemaining.set(1); - long timeout = TIMEOUT_CALLBACK * 1000; - waitForCallbacks(timeout); - mSession.stopRepeating(); - } catch (android.hardware.camera2.CameraAccessException e) { - throw new ItsException("Access error: ", e); - } finally { - if (mSession != null) { - mSession.close(); - } - if (previewSurface != null) { - previewSurface.release(); - } - if (preview != null) { - preview.release(); - } - } - } - private void doCapture(JSONObject params) throws ItsException { try { // Parse the JSON to get the list of capture requests. @@ -2990,14 +2883,7 @@ public class ItsService extends Service implements SensorEventListener { result.get(CaptureResult.CONTROL_AE_STATE) == CaptureResult.CONTROL_AE_STATE_LOCKED; mLockedAE = result.get(CaptureResult.CONTROL_AE_STATE) == - CaptureResult.CONTROL_AE_STATE_LOCKED; - if (!mPrecaptureTriggered) { - mPrecaptureTriggered = result.get(CaptureResult.CONTROL_AE_STATE) == - CaptureResult.CONTROL_AE_STATE_PRECAPTURE; - } - if (!mConvergeAETriggered) { - mConvergeAETriggered = mConvergedAE; - } + CaptureResult.CONTROL_AE_STATE_LOCKED; } if (result.get(CaptureResult.CONTROL_AF_STATE) != null) { mConvergedAF = result.get(CaptureResult.CONTROL_AF_STATE) == diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java index 692538a81c3..d83464bd549 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsTestActivity.java @@ -21,8 +21,9 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.Configuration; +import android.hardware.camera2.CameraCharacteristics; import android.hardware.camera2.CameraManager; -import android.mediapc.cts.common.PerformanceClassEvaluator; +import android.os.Build; import android.os.Bundle; import android.text.method.ScrollingMovementMethod; import android.util.Log; @@ -30,11 +31,6 @@ import android.view.WindowManager; import android.widget.TextView; import android.widget.Toast; -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.FileNotFoundException; -import java.io.IOException; - import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; @@ -43,11 +39,17 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.Set; import java.util.TreeSet; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.FileNotFoundException; +import java.io.IOException; + import com.android.compatibility.common.util.ResultType; import com.android.compatibility.common.util.ResultUnit; import com.android.cts.verifier.ArrayTestListAdapter; @@ -57,7 +59,6 @@ import com.android.cts.verifier.TestResult; import org.json.JSONArray; import org.json.JSONObject; -import org.junit.rules.TestName; /** * Test for Camera features that require that the camera be aimed at a specific test scene. @@ -80,6 +81,12 @@ public class ItsTestActivity extends DialogTestListActivity { Arrays.asList(new String[] {RESULT_PASS, RESULT_FAIL, RESULT_NOT_EXECUTED})); private static final int MAX_SUMMARY_LEN = 200; + private static final int MPC12_CAMERA_LAUNCH_THRESHOLD = 600; // ms + private static final int MPC12_JPEG_CAPTURE_THRESHOLD = 1000; // ms + + private static final String MPC_TESTS_REPORT_LOG_NAME = "MediaPerformanceClassLogs"; + private static final String MPC_TESTS_REPORT_LOG_SECTION = "CameraIts"; + private static final Pattern MPC12_CAMERA_LAUNCH_PATTERN = Pattern.compile("camera_launch_time_ms:(\\d+(\\.\\d+)?)"); private static final Pattern MPC12_JPEG_CAPTURE_PATTERN = @@ -88,12 +95,8 @@ public class ItsTestActivity extends DialogTestListActivity { private final ResultReceiver mResultsReceiver = new ResultReceiver(); private boolean mReceiverRegistered = false; - public final TestName mTestName = new TestName(); - // Initialized in onCreate List<String> mToBeTestedCameraIds = null; - String mPrimaryRearCameraId = null; - String mPrimaryFrontCameraId = null; // Scenes private static final ArrayList<String> mSceneIds = new ArrayList<String> () {{ @@ -129,15 +132,8 @@ public class ItsTestActivity extends DialogTestListActivity { private final HashMap<ResultKey, String> mSummaryMap = new HashMap<>(); // All primary cameras for which MPC level test has run private Set<ResultKey> mExecutedMpcTests = null; - private static final String MPC_LAUNCH_REQ_NUM = "2.2.7.2/7.5/H-1-6"; - private static final String MPC_JPEG_CAPTURE_REQ_NUM = "2.2.7.2/7.5/H-1-5"; - // Performance class evaluator used for writing test result - PerformanceClassEvaluator mPce = new PerformanceClassEvaluator(mTestName); - PerformanceClassEvaluator.CameraLatencyRequirement mJpegLatencyReq = - mPce.addR7_5__H_1_5(); - PerformanceClassEvaluator.CameraLatencyRequirement mLaunchLatencyReq = - mPce.addR7_5__H_1_6(); - + // Map primary camera id to MPC level + private final HashMap<String, Integer> mMpcLevelMap = new HashMap<>(); final class ResultKey { public final String cameraId; @@ -270,7 +266,10 @@ public class ItsTestActivity extends DialogTestListActivity { JSONArray metrics = sceneResult.getJSONArray("mpc_metrics"); for (int i = 0; i < metrics.length(); i++) { String mpcResult = metrics.getString(i); - if (!matchMpcResult(cameraId, mpcResult)) { + if (!matchMpcResult(cameraId, mpcResult, MPC12_CAMERA_LAUNCH_PATTERN, + "2.2.7.2/7.5/H-1-6", MPC12_CAMERA_LAUNCH_THRESHOLD) && + !matchMpcResult(cameraId, mpcResult, MPC12_JPEG_CAPTURE_PATTERN, + "2.2.7.2/7.5/H-1-5", MPC12_JPEG_CAPTURE_THRESHOLD)) { Log.e(TAG, "Error parsing MPC result string:" + mpcResult); return; } @@ -295,6 +294,17 @@ public class ItsTestActivity extends DialogTestListActivity { summary.toString(), 1.0, ResultType.NEUTRAL, ResultUnit.NONE); } + // Save MPC info once both front primary and rear primary data are collected. + if (mExecutedMpcTests.size() == 4) { + ItsTestActivity.this.getReportLog().addValue( + "Version", "0.0.1", ResultType.NEUTRAL, ResultUnit.NONE); + for (Map.Entry<String, Integer> entry : mMpcLevelMap.entrySet()) { + ItsTestActivity.this.getReportLog().addValue(entry.getKey(), + entry.getValue(), ResultType.NEUTRAL, ResultUnit.NONE); + } + ItsTestActivity.this.getReportLog().submit(); + } + // Display current progress StringBuilder progress = new StringBuilder(); for (ResultKey k : mAllScenes) { @@ -357,44 +367,28 @@ public class ItsTestActivity extends DialogTestListActivity { } } - private boolean matchMpcResult(String cameraId, String mpcResult) { - Matcher launchMatcher = MPC12_CAMERA_LAUNCH_PATTERN.matcher(mpcResult); - boolean launchMatches = launchMatcher.matches(); + private boolean matchMpcResult(String cameraId, String mpcResult, Pattern pattern, + String reqNum, float threshold) { + Matcher matcher = pattern.matcher(mpcResult); + boolean match = matcher.matches(); + final int LATEST_MPC_LEVEL = Build.VERSION_CODES.TIRAMISU; - Matcher jpegMatcher = MPC12_JPEG_CAPTURE_PATTERN.matcher(mpcResult); - boolean jpegMatches = jpegMatcher.matches(); + if (match) { + // Store test result + ItsTestActivity.this.getReportLog().addValue("Cam" + cameraId, + mpcResult, ResultType.NEUTRAL, ResultUnit.NONE); - if (!launchMatches && !jpegMatches) { - return false; - } - if (!cameraId.equals(mPrimaryRearCameraId) && - !cameraId.equals(mPrimaryFrontCameraId)) { - return false; - } + float latency = Float.parseFloat(matcher.group(1)); + int mpcLevel = latency < threshold ? LATEST_MPC_LEVEL : 0; + mExecutedMpcTests.add(new ResultKey(cameraId, reqNum)); - if (launchMatches) { - float latency = Float.parseFloat(launchMatcher.group(1)); - if (cameraId.equals(mPrimaryRearCameraId)) { - mLaunchLatencyReq.setRearCameraLatency(latency); - } else { - mLaunchLatencyReq.setFrontCameraLatency(latency); - } - mExecutedMpcTests.add(new ResultKey(cameraId, MPC_LAUNCH_REQ_NUM)); - } else { - float latency = Float.parseFloat(jpegMatcher.group(1)); - if (cameraId.equals(mPrimaryRearCameraId)) { - mJpegLatencyReq.setRearCameraLatency(latency); - } else { - mJpegLatencyReq.setFrontCameraLatency(latency); + if (mMpcLevelMap.containsKey(reqNum)) { + mpcLevel = Math.min(mpcLevel, mMpcLevelMap.get(reqNum)); } - mExecutedMpcTests.add(new ResultKey(cameraId, MPC_JPEG_CAPTURE_REQ_NUM)); + mMpcLevelMap.put(reqNum, mpcLevel); } - // Save MPC info once both front primary and rear primary data are collected. - if (mExecutedMpcTests.size() == 4) { - mPce.submit(); - } - return true; + return match; } } @@ -403,11 +397,8 @@ public class ItsTestActivity extends DialogTestListActivity { // Hide the test if all camera devices are legacy CameraManager manager = (CameraManager) this.getSystemService(Context.CAMERA_SERVICE); try { - ItsUtils.ItsCameraIdList cameraIdList = - ItsUtils.getItsCompatibleCameraIds(manager); + ItsUtils.ItsCameraIdList cameraIdList = ItsUtils.getItsCompatibleCameraIds(manager); mToBeTestedCameraIds = cameraIdList.mCameraIdCombos; - mPrimaryRearCameraId = cameraIdList.mPrimaryRearCameraId; - mPrimaryFrontCameraId = cameraIdList.mPrimaryFrontCameraId; } catch (ItsException e) { Toast.makeText(ItsTestActivity.this, "Received error from camera service while checking device capabilities: " @@ -508,4 +499,14 @@ public class ItsTestActivity extends DialogTestListActivity { setInfoResources(R.string.camera_its_test, R.string.camera_its_test_info, -1); setPassFailButtonClickListeners(); } + + @Override + public String getReportFileName() { + return MPC_TESTS_REPORT_LOG_NAME; + } + + @Override + public String getReportSectionName() { + return MPC_TESTS_REPORT_LOG_SECTION; + } } diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java index 734b4a2a780..c648e8e18d9 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java @@ -16,24 +16,28 @@ package com.android.cts.verifier.camera.its; +import android.content.Context; import android.graphics.ImageFormat; import android.graphics.Rect; import android.hardware.camera2.CameraAccessException; import android.hardware.camera2.CameraDevice; import android.hardware.camera2.CameraCharacteristics; import android.hardware.camera2.CameraManager; -import android.hardware.camera2.CameraMetadata; import android.hardware.camera2.CaptureRequest; +import android.hardware.camera2.CaptureResult; import android.hardware.camera2.params.MeteringRectangle; import android.hardware.camera2.params.StreamConfigurationMap; import android.media.Image; import android.media.Image.Plane; +import android.net.Uri; +import android.os.Environment; import android.os.Handler; import android.os.HandlerThread; import android.util.Log; import android.util.Size; import com.android.ex.camera2.blocking.BlockingCameraManager; +import com.android.ex.camera2.blocking.BlockingCameraManager.BlockingOpenException; import com.android.ex.camera2.blocking.BlockingStateCallback; import org.json.JSONArray; @@ -318,9 +322,6 @@ public class ItsUtils { // Camera Id combos (ids from CameraIdList, and hidden physical camera Ids // in the form of [logical camera id]:[hidden physical camera id] public List<String> mCameraIdCombos; - // Primary rear and front camera Ids (as defined in MPC) - public String mPrimaryRearCameraId; - public String mPrimaryFrontCameraId; } public static ItsCameraIdList getItsCompatibleCameraIds(CameraManager manager) @@ -344,18 +345,6 @@ public class ItsUtils { CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE; final int LOGICAL_MULTI_CAMERA = CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA; - - final Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING); - if (facing != null) { - if (facing == CameraMetadata.LENS_FACING_BACK - && outList.mPrimaryRearCameraId == null) { - outList.mPrimaryRearCameraId = id; - } else if (facing == CameraMetadata.LENS_FACING_FRONT - && outList.mPrimaryFrontCameraId == null) { - outList.mPrimaryFrontCameraId = id; - } - } - for (int capability : actualCapabilities) { if (capability == BACKWARD_COMPAT) { haveBC = true; diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/clipboard/ClipboardPreviewTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/clipboard/ClipboardPreviewTestActivity.java index 63b8904fa03..3587e6f9b8c 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/clipboard/ClipboardPreviewTestActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/clipboard/ClipboardPreviewTestActivity.java @@ -18,22 +18,49 @@ package com.android.cts.verifier.clipboard; import android.content.ClipData; -import android.content.ClipDescription; import android.content.ClipboardManager; +import android.graphics.Color; import android.os.Bundle; -import android.os.PersistableBundle; import android.view.View; import android.widget.Button; import com.android.cts.verifier.PassFailButtons; import com.android.cts.verifier.R; +import java.util.concurrent.ThreadLocalRandom; + /** - * A CTS Verifier test case for validating the user-visible clipboard confirmation. + * A CTS Verifier test case for validating the user-visible clipboard preview. + * + * This test assumes bluetooth is turned on and the device is already paired with a second device. + * Note: the second device need not be an Android device; it could be a laptop or desktop. */ public class ClipboardPreviewTestActivity extends PassFailButtons.Activity { + /** + * The content of the test file being transferred. + */ + private static final String TEST_STRING = "Sample Test String"; + /** + * The name of the test file being transferred. + */ + private final int[] mSecretCode = new int[4]; + private final int[] mSecretGuess = new int[4]; + private final int[] mButtons = { + R.id.clipboard_preview_test_b0, + R.id.clipboard_preview_test_b1, + R.id.clipboard_preview_test_b2, + R.id.clipboard_preview_test_b3, + R.id.clipboard_preview_test_b4, + R.id.clipboard_preview_test_b5, + R.id.clipboard_preview_test_b6, + R.id.clipboard_preview_test_b7, + R.id.clipboard_preview_test_b8, + R.id.clipboard_preview_test_b9 + }; + private int mGuessIndex = 0; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -47,29 +74,87 @@ public class ClipboardPreviewTestActivity extends PassFailButtons.Activity { copyButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - setClipboardData(); + generateAndCopySecret(); } }); - disablePassFail(); + disableKeypad(); } - private void setClipboardData() { + private void generateAndCopySecret() { + String s = ""; + resetState(); + for (int i = 0; i < mSecretCode.length; ++i) { + mSecretCode[i] = ThreadLocalRandom.current().nextInt(0, 10); + s += mSecretCode[i]; + } ClipboardManager cm = this.getSystemService(ClipboardManager.class); + cm.setPrimaryClip(ClipData.newPlainText("Secret", s)); + enableKeypad(); + } - ClipData cd = ClipData.newPlainText("", - getString(R.string.clipboard_preview_test_secret)); - PersistableBundle pb = new PersistableBundle(1); - pb.putBoolean(ClipDescription.EXTRA_IS_SENSITIVE, true); - cd.getDescription().setExtras(pb); - cm.setPrimaryClip(cd); - enablePassFail(); + private void enableKeypad() { + for (int i = 0; i < mButtons.length; ++i) { + Button numButton = findViewById(mButtons[i]); + numButton.setBackgroundColor(Color.GREEN); + int finalI = i; + numButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + buttonClicked(finalI); + } + }); + } } - private void disablePassFail() { + private void disableKeypad() { + for (int i = 0; i < mButtons.length; ++i) { + Button numButton = findViewById(mButtons[i]); + numButton.setOnClickListener(null); + numButton.setBackgroundColor(Color.LTGRAY); + } + } + + private void resetState() { + for (int i = 0; i < mSecretGuess.length; ++i) { + mSecretGuess[i] = -1; + } + mGuessIndex = 0; + View v = findViewById(R.id.clipboard_preview_test_pass_fail); findViewById(R.id.clipboard_preview_test_pass_fail).setVisibility(View.INVISIBLE); + findViewById(R.id.fail_button).setVisibility(View.VISIBLE); + findViewById(R.id.pass_button).setVisibility(View.VISIBLE); + } + + private void buttonClicked(int i) { + if (mGuessIndex < mSecretGuess.length) { + mSecretGuess[mGuessIndex] = i; + ++mGuessIndex; + } + checkSolution(); + } + + private void checkSolution() { + boolean testPassed = true; + if (mGuessIndex == mSecretGuess.length) { + for (int i = 0; i < mSecretGuess.length && i < mSecretCode.length; ++i) { + if (mSecretGuess[i] != mSecretCode[i]) { + testPassed = false; + } + } + markPassed(testPassed); + disableKeypad(); + } } - private void enablePassFail() { + private void markPassed(boolean passed) { findViewById(R.id.clipboard_preview_test_pass_fail).setVisibility(View.VISIBLE); + if (passed) { + findViewById(R.id.fail_button).setVisibility(View.INVISIBLE); + } else { + findViewById(R.id.pass_button).setVisibility(View.INVISIBLE); + } + } + + } diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/companion/CompanionDeviceServiceTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/companion/CompanionDeviceServiceTestActivity.java index 97ec07acf78..b8b96023cb7 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/companion/CompanionDeviceServiceTestActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/companion/CompanionDeviceServiceTestActivity.java @@ -118,7 +118,7 @@ public class CompanionDeviceServiceTestActivity extends PassFailButtons.Activity /** Stop observing to associated device and then disassociate. */ private void disassociate(AssociationInfo association) { - String deviceAddress = association.getDeviceMacAddress().toString(); + String deviceAddress = association.getDeviceMacAddressAsString(); mCompanionDeviceManager.stopObservingDevicePresence(deviceAddress); mCompanionDeviceManager.disassociate(association.getId()); Log.d(LOG_TAG, "Disassociated with device: " + deviceAddress); @@ -142,14 +142,11 @@ public class CompanionDeviceServiceTestActivity extends PassFailButtons.Activity AssociationInfo association = data.getParcelableExtra(CompanionDeviceManager.EXTRA_ASSOCIATION, AssociationInfo.class); + String deviceAddress = association.getDeviceMacAddressAsString(); // This test is for bluetooth devices, which should all have a MAC address. - if (association == null || association.getDeviceMacAddress() == null) { - fail("The device was present but its address was null."); - return; - } + if (deviceAddress == null) fail("The device was present but its address was null."); - String deviceAddress = association.getDeviceMacAddress().toString(); mCompanionDeviceManager.startObservingDevicePresence(deviceAddress); mCurrentAssociation = getAssociation(association.getId()); Log.d(LOG_TAG, "Associated with device: " + deviceAddress); @@ -288,9 +285,7 @@ public class CompanionDeviceServiceTestActivity extends PassFailButtons.Activity @Override boolean verify() { // Check that it is associated and being observed. - // Bypass inaccessible AssociationInfo#isNotifyOnDeviceNearby() with toString() - return mCurrentAssociation != null - && mCurrentAssociation.toString().contains("mNotifyOnDeviceNearby=true"); + return mCurrentAssociation != null && mCurrentAssociation.isNotifyOnDeviceNearby(); } } diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/companion/DevicePresenceListener.java b/apps/CtsVerifier/src/com/android/cts/verifier/companion/DevicePresenceListener.java index 11829c3d4b7..37760d54440 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/companion/DevicePresenceListener.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/companion/DevicePresenceListener.java @@ -45,7 +45,7 @@ public class DevicePresenceListener extends CompanionDeviceService { @Override public void onDeviceAppeared(AssociationInfo association) { NEARBY_DEVICES.add(association.getId()); - String message = "Device appeared: " + association.getDeviceMacAddress(); + String message = "Device appeared: " + association.getDeviceMacAddressAsString(); Log.d(LOG_TAG, message); Toast.makeText(this, message, Toast.LENGTH_LONG).show(); } @@ -53,7 +53,7 @@ public class DevicePresenceListener extends CompanionDeviceService { @Override public void onDeviceDisappeared(AssociationInfo association) { NEARBY_DEVICES.remove(association.getId()); - String message = "Device disappeared: " + association.getDeviceMacAddress(); + String message = "Device disappeared: " + association.getDeviceMacAddressAsString(); Log.d(LOG_TAG, message); Toast.makeText(this, message, Toast.LENGTH_LONG).show(); } diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureUtil.java b/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureUtil.java index eddd930ac30..f6b179c5dd1 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureUtil.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureUtil.java @@ -130,6 +130,6 @@ public final class FeatureUtil { * Checks whether the device shows keyguard when the user doesn't have credentials. */ public static boolean isKeyguardShownWhenUserDoesntHaveCredentials(Context context) { - return !isAutomotive(context) && !isWatch(context); + return !isAutomotive(context); } } diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java index 1110b0f33e0..cdca014691d 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java @@ -96,8 +96,6 @@ public class DeviceOwnerPositiveTestActivity extends PassFailButtons.TestListAct private static final String DISALLOW_ADD_WIFI_CONFIG_ID = "DISALLOW_ADD_WIFI_CONFIG"; private static final String WIFI_SECURITY_LEVEL_RESTRICTION_ID = "WIFI_SECURITY_LEVEL_RESTRICTION"; - private static final String ACTION_CONNECT_INPUT = - "com.google.android.intent.action.CONNECT_INPUT"; @Override protected void onCreate(Bundle savedInstanceState) { @@ -403,8 +401,7 @@ public class DeviceOwnerPositiveTestActivity extends PassFailButtons.TestListAct UserManager.DISALLOW_CONFIG_BLUETOOTH, true)), new ButtonInfo( R.string.device_owner_settings_go, - new Intent(Utils.isTV(this) ? ACTION_CONNECT_INPUT - : Settings.ACTION_BLUETOOTH_SETTINGS)), + new Intent(Settings.ACTION_BLUETOOTH_SETTINGS)), new ButtonInfo( R.string.device_owner_user_restriction_unset, CommandReceiverActivity.createSetCurrentUserRestrictionIntent( @@ -413,7 +410,7 @@ public class DeviceOwnerPositiveTestActivity extends PassFailButtons.TestListAct } // DISALLOW_USB_FILE_TRANSFER - if (FeatureUtil.isUsbFileTransferSupported(this) && !Utils.isTV(this)) { + if (FeatureUtil.isUsbFileTransferSupported(this)) { adapter.add(createInteractiveTestItem(this, DISALLOW_USB_FILE_TRANSFER_ID, R.string.device_owner_disallow_usb_file_transfer_test, R.string.device_owner_disallow_usb_file_transfer_test_info, @@ -470,7 +467,7 @@ public class DeviceOwnerPositiveTestActivity extends PassFailButtons.TestListAct // setLockTaskFeatures // TODO(b/189282625): replace FEATURE_WATCH with a more specific feature - if (!packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH) && !Utils.isTV(this)) { + if (!packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)) { final Intent lockTaskUiTestIntent = new Intent(this, LockTaskUiTestActivity.class); lockTaskUiTestIntent.putExtra(LockTaskUiTestActivity.EXTRA_TEST_ID, LOCK_TASK_UI_TEST_ID); @@ -679,8 +676,7 @@ public class DeviceOwnerPositiveTestActivity extends PassFailButtons.TestListAct // removeDeviceOwner adapter.add(createInteractiveTestItem(this, REMOVE_DEVICE_OWNER_TEST_ID, R.string.device_owner_remove_device_owner_test, - Utils.isTV(this) ? R.string.device_owner_remove_device_owner_test_info_on_tv - : R.string.device_owner_remove_device_owner_test_info, + R.string.device_owner_remove_device_owner_test_info, new ButtonInfo( R.string.remove_device_owner_button, createTearDownIntent()))); diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerRequestingBugreportTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerRequestingBugreportTestActivity.java index 40eefea2d7b..4a4eae4f76f 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerRequestingBugreportTestActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerRequestingBugreportTestActivity.java @@ -240,8 +240,7 @@ public class DeviceOwnerRequestingBugreportTestActivity extends PassFailButtons. // removeDeviceOwner adapter.add(createInteractiveTestItem(this, REMOVE_DEVICE_OWNER_TEST_ID, R.string.device_owner_remove_device_owner_test, - Utils.isTV(this) ? R.string.device_owner_remove_device_owner_test_info_on_tv - : R.string.device_owner_remove_device_owner_test_info, + R.string.device_owner_remove_device_owner_test_info, new ButtonInfo( R.string.remove_device_owner_button, createTearDownIntent()))); diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/Utils.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/Utils.java index d8b659ef20e..5fad20c2a7d 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/Utils.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/Utils.java @@ -158,9 +158,4 @@ public class Utils { return context.getPackageManager().hasSystemFeature( PackageManager.FEATURE_SECURE_LOCK_SCREEN); } - - static boolean isTV(Context context) { - return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK) - || context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEVISION); - } } diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/BubblesVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/BubblesVerifierActivity.java index d22f0265abb..55a4cce906b 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/BubblesVerifierActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/BubblesVerifierActivity.java @@ -20,8 +20,6 @@ import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE; import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED; import static android.app.NotificationManager.IMPORTANCE_DEFAULT; import static android.content.Intent.ACTION_VIEW; -import static android.content.pm.PackageManager.FEATURE_INPUT_METHODS; -import static android.content.pm.PackageManager.FEATURE_PC; import static android.view.View.GONE; import static android.view.View.INVISIBLE; import static android.view.View.VISIBLE; @@ -190,14 +188,9 @@ public class BubblesVerifierActivity extends PassFailButtons.Activity { // // Expanded view appearance // - // At the moment, PC devices do not support rotation - if (!getPackageManager().hasSystemFeature(FEATURE_PC)) { - mTests.add(new PortraitAndLandscape()); - } + mTests.add(new PortraitAndLandscape()); mTests.add(new ScrimBehindExpandedView()); - if (getPackageManager().hasSystemFeature(FEATURE_INPUT_METHODS)) { - mTests.add(new ImeInsetsExpandedView()); - } + mTests.add(new ImeInsetsExpandedView()); mTests.add(new MinHeightExpandedView()); mTests.add(new MaxHeightExpandedView()); } diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MediaPlayerVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MediaPlayerVerifierActivity.java new file mode 100644 index 00000000000..c2208d4bdce --- /dev/null +++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MediaPlayerVerifierActivity.java @@ -0,0 +1,163 @@ +/* + * 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.notifications; + +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.media.MediaMetadata; +import android.media.session.MediaSession; +import android.media.session.PlaybackState; +import android.view.View; +import android.view.ViewGroup; + +import com.android.cts.verifier.R; + +import java.util.ArrayList; +import java.util.List; + +/** + * Tests for media player shown in shade when media style notification is posted. + */ +public class MediaPlayerVerifierActivity extends InteractiveVerifierActivity { + + // Media session info + private static final String SESSION_KEY = "Session"; + private static final String SESSION_TITLE = "Song"; + private static final String SESSION_ARTIST = "Artist"; + private static final long SESSION_DURATION = 60000L; + + // MediaStyle notification info + private static final String TITLE = "Media-style Notification"; + private static final String TEXT = "Notification for a test media session"; + private static final String CHANNEL_ID = "MediaPlayerVerifierActivity"; + + private MediaSession mSession; + private NotificationManager mManager; + private Notification.Builder mBuilder; + + @Override + public List<InteractiveTestCase> createTestItems() { + List<InteractiveTestCase> cases = new ArrayList<>(); + cases.add(new MediaPlayerTestCase(R.string.media_controls_visible)); + cases.add(new MediaPlayerTestCase(R.string.media_controls_output_switcher_chip)); + return cases; + } + + @Override + public int getInstructionsResource() { + return R.string.media_controls_info; + } + + @Override + public int getTitleResource() { + return R.string.media_controls_title; + } + + private class MediaPlayerTestCase extends InteractiveTestCase { + private final int mDescriptionResId; + + MediaPlayerTestCase(int resId) { + mDescriptionResId = resId; + } + + @Override + protected void setUp() { + postMediaStyleNotification(); + status = READY; + } + + @Override + protected void tearDown() { + cancelMediaStyleNotification(); + } + + @Override + protected View inflate(ViewGroup parent) { + return createPassFailItem(parent, mDescriptionResId); + } + + @Override + protected void test() { + status = WAIT_FOR_USER; + next(); + } + } + + private void postMediaStyleNotification() { + mManager = this.getSystemService(NotificationManager.class); + mSession = new MediaSession(this, SESSION_KEY); + + // Create a solid color bitmap to use as album art in media metadata + Bitmap bitmap = Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888); + new Canvas(bitmap).drawColor(Color.GREEN); + + // Set up media session with metadata and playback state + mSession.setMetadata(new MediaMetadata.Builder() + .putString(MediaMetadata.METADATA_KEY_ARTIST, SESSION_ARTIST) + .putString(MediaMetadata.METADATA_KEY_TITLE, SESSION_TITLE) + .putLong(MediaMetadata.METADATA_KEY_DURATION, SESSION_DURATION) + .putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, bitmap) + .build()); + mSession.setPlaybackState(new PlaybackState.Builder() + .setState(PlaybackState.STATE_PAUSED, 6000L, 1f) + .setActions(PlaybackState.ACTION_SEEK_TO + | PlaybackState.ACTION_PLAY + | PlaybackState.ACTION_PAUSE + | PlaybackState.ACTION_SKIP_TO_PREVIOUS + | PlaybackState.ACTION_SKIP_TO_NEXT) + .addCustomAction("rewind", "rewind", android.R.drawable.ic_media_rew) + .addCustomAction("fast forward", "fast forward", android.R.drawable.ic_media_ff) + .build()); + + // Set up notification builder + NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_ID, + NotificationManager.IMPORTANCE_LOW); + mManager.createNotificationChannel(channel); + mBuilder = new Notification.Builder(this, CHANNEL_ID) + .setContentTitle(TITLE).setContentText(TEXT) + .setSmallIcon(R.drawable.ic_android) + .setStyle(new Notification.MediaStyle() + .setShowActionsInCompactView(1, 2, 3) + .setMediaSession(mSession.getSessionToken())) + .setColor(Color.BLUE) + .setColorized(true) + .addAction(android.R.drawable.ic_media_rew, "rewind", null) + .addAction(android.R.drawable.ic_media_previous, "previous track", null) + .addAction(android.R.drawable.ic_media_play, "play", null) + .addAction(android.R.drawable.ic_media_next, "next track", null) + .addAction(android.R.drawable.ic_media_ff, "fast forward", null); + + mSession.setActive(true); + mManager.notify(1, mBuilder.build()); + } + + private void cancelMediaStyleNotification() { + if (mSession != null) { + mSession.release(); + mSession = null; + } + if (mManager != null) { + mManager.cancelAll(); + mManager.deleteNotificationChannel(CHANNEL_ID); + mManager = null; + } + } +} diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/BleRssiPrecisionActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/presence/BleRssiPrecisionActivity.java new file mode 100644 index 00000000000..1548910093a --- /dev/null +++ b/apps/CtsVerifier/src/com/android/cts/verifier/presence/BleRssiPrecisionActivity.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.cts.verifier.presence; + +import android.app.AlertDialog; +import android.bluetooth.BluetoothAdapter; +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.text.Editable; +import android.util.Log; +import android.widget.EditText; + +import com.android.compatibility.common.util.ResultType; +import com.android.compatibility.common.util.ResultUnit; +import com.android.cts.verifier.PassFailButtons; +import com.android.cts.verifier.R; + +/** Tests the precision of the device's RSSI measurement wtfdelet */ +public class BleRssiPrecisionActivity extends PassFailButtons.Activity { + private static final String TAG = BleRssiPrecisionActivity.class.getName(); + + // Report log schema + private static final String KEY_RSSI_RANGE_DBM = "rssi_range_dbm"; + private static final String KEY_REFERENCE_DEVICE = "reference_device"; + + // Thresholds + private static final int MAX_RSSI_RANGE_DBM = 18; + + private EditText reportRssiRangeEditText; + private EditText reportReferenceDeviceEditText; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.ble_rssi_precision); + setPassFailButtonClickListeners(); + getPassButton().setEnabled(false); + + reportRssiRangeEditText = findViewById(R.id.report_rssi_range); + reportReferenceDeviceEditText = findViewById(R.id.report_reference_device); + + DeviceFeatureChecker.checkFeatureSupported(this, getPassButton(), + PackageManager.FEATURE_BLUETOOTH_LE); + + BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); + + if (!adapter.isEnabled()) { + new AlertDialog.Builder(this) + .setTitle(R.string.ble_bluetooth_disable_title) + .setMessage(R.string.ble_bluetooth_disable_message) + .setOnCancelListener(dialog -> finish()) + .create().show(); + } + + reportRssiRangeEditText.addTextChangedListener( + InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs())); + reportReferenceDeviceEditText.addTextChangedListener( + InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs())); + } + + private void checkTestInputs() { + getPassButton().setEnabled(checkDistanceRangeInput() && checkReferenceDeviceInput()); + } + + private boolean checkDistanceRangeInput() { + String rssiRangeInput = reportRssiRangeEditText.getText().toString(); + + if (!rssiRangeInput.isEmpty()) { + int rssiRange = Integer.parseInt(rssiRangeInput); + // RSSI range must be inputted and within acceptable range before test can be passed + return rssiRange <= MAX_RSSI_RANGE_DBM; + } + return false; + } + + private boolean checkReferenceDeviceInput() { + // Reference device must be inputted before test can be passed + return !reportReferenceDeviceEditText.getText().toString().isEmpty(); + } + + @Override + public void recordTestResults() { + String rssiRange = reportRssiRangeEditText.getText().toString(); + String referenceDevice = reportReferenceDeviceEditText.getText().toString(); + + if (!rssiRange.isEmpty()) { + Log.i(TAG, "BLE RSSI Range (dBm): " + rssiRange); + getReportLog().addValue(KEY_RSSI_RANGE_DBM, Integer.parseInt(rssiRange), + ResultType.NEUTRAL, ResultUnit.NONE); + } + + if (!referenceDevice.isEmpty()) { + Log.i(TAG, "BLE Reference Device: " + referenceDevice); + getReportLog().addValue(KEY_REFERENCE_DEVICE, referenceDevice, + ResultType.NEUTRAL, ResultUnit.NONE); + } + getReportLog().submit(); + } +} diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/BleRxTxCalibrationActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/presence/BleRxTxCalibrationActivity.java new file mode 100644 index 00000000000..2de7edffe7c --- /dev/null +++ b/apps/CtsVerifier/src/com/android/cts/verifier/presence/BleRxTxCalibrationActivity.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.cts.verifier.presence; + +import android.app.AlertDialog; +import android.bluetooth.BluetoothAdapter; +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.text.Editable; +import android.util.Log; +import android.widget.EditText; + +import com.android.compatibility.common.util.ResultType; +import com.android.compatibility.common.util.ResultUnit; +import com.android.cts.verifier.PassFailButtons; +import com.android.cts.verifier.R; + +/** + * Tests that the device's Rx/Tx calibration results in a median range (cm) within the specified + * bounds + */ +public class BleRxTxCalibrationActivity extends PassFailButtons.Activity { + private static final String TAG = BleRxTxCalibrationActivity.class.getName(); + + // Report log schema + private static final String KEY_CHANNEL_RSSI_RANGE = "channel_rssi_range"; + private static final String KEY_CORE_RSSI_RANGE = "core_rssi_range"; + private static final String KEY_REFERENCE_DEVICE = "reference_device"; + + // Thresholds + private static final int MAX_RSSI_RANGE = 6; + + private EditText reportChannelsRssiRangeEditText; + private EditText reportCoresRssiRangeEditText; + private EditText reportReferenceDeviceEditText; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.ble_rx_tx_calibration); + setPassFailButtonClickListeners(); + getPassButton().setEnabled(false); + + reportChannelsRssiRangeEditText = findViewById(R.id.report_channels_rssi_range); + reportCoresRssiRangeEditText = findViewById(R.id.report_cores_rssi_range); + reportReferenceDeviceEditText = findViewById(R.id.report_reference_device); + + DeviceFeatureChecker.checkFeatureSupported(this, getPassButton(), + PackageManager.FEATURE_BLUETOOTH_LE); + + BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); + + if (!adapter.isEnabled()) { + new AlertDialog.Builder(this) + .setTitle(R.string.ble_bluetooth_disable_title) + .setMessage(R.string.ble_bluetooth_disable_message) + .setOnCancelListener(dialog -> finish()) + .create().show(); + } + + reportChannelsRssiRangeEditText.addTextChangedListener( + InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs())); + reportCoresRssiRangeEditText.addTextChangedListener( + InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs())); + reportReferenceDeviceEditText.addTextChangedListener( + InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs())); + } + + private void checkTestInputs() { + getPassButton().setEnabled( + checkChannelRssiInput() && checkCoreRssiInput() && checkReferenceDeviceInput()); + } + + private boolean checkChannelRssiInput() { + String channelsRssiRangeInput = reportChannelsRssiRangeEditText.getText().toString(); + if (!channelsRssiRangeInput.isEmpty()) { + int channelsRssiRange = Integer.parseInt(channelsRssiRangeInput); + // RSSI range must be inputted and within acceptable range before test can be passed + return channelsRssiRange <= MAX_RSSI_RANGE; + } + return false; + } + + private boolean checkCoreRssiInput() { + String coresRssiRangeInput = reportCoresRssiRangeEditText.getText().toString(); + if (!coresRssiRangeInput.isEmpty()) { + int coresRssiRange = Integer.parseInt(coresRssiRangeInput); + // RSSI range must be inputted and within acceptable range before test can be passed + return coresRssiRange <= MAX_RSSI_RANGE; + } + // This field is optional, so return true even if the user has not inputted anything + return true; + } + + private boolean checkReferenceDeviceInput() { + // Reference device must be inputted before test can be passed + return !reportReferenceDeviceEditText.getText().toString().isEmpty(); + } + + @Override + public void recordTestResults() { + String channelRssiRange = reportChannelsRssiRangeEditText.getText().toString(); + String coreRssiRange = reportCoresRssiRangeEditText.getText().toString(); + String referenceDevice = reportReferenceDeviceEditText.getText().toString(); + + if (!channelRssiRange.isEmpty()) { + Log.i(TAG, "BLE RSSI Range Across Channels (dBm): " + channelRssiRange); + getReportLog().addValue(KEY_CHANNEL_RSSI_RANGE, Integer.parseInt(channelRssiRange), + ResultType.NEUTRAL, ResultUnit.NONE); + } + + if (!coreRssiRange.isEmpty()) { + Log.i(TAG, "BLE RSSI Range Across Cores (dBm): " + coreRssiRange); + getReportLog().addValue(KEY_CORE_RSSI_RANGE, Integer.parseInt(coreRssiRange), + ResultType.NEUTRAL, ResultUnit.NONE); + } + + if (!referenceDevice.isEmpty()) { + Log.i(TAG, "BLE Reference Device: " + referenceDevice); + getReportLog().addValue(KEY_REFERENCE_DEVICE, referenceDevice, + ResultType.NEUTRAL, ResultUnit.NONE); + } + + getReportLog().submit(); + } +} diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/DeviceFeatureChecker.java b/apps/CtsVerifier/src/com/android/cts/verifier/presence/DeviceFeatureChecker.java new file mode 100644 index 00000000000..256fe3a078d --- /dev/null +++ b/apps/CtsVerifier/src/com/android/cts/verifier/presence/DeviceFeatureChecker.java @@ -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 com.android.cts.verifier.presence; +import android.app.Activity; +import android.content.Context; +import android.util.Log; +import android.view.View; +import android.widget.Toast; + +/** + * Checks if a device supports a hardware feature needed for a test, and passes the test + * automatically otherwise. + */ +public class DeviceFeatureChecker { + + /** Checks if a feature is supported. + * + * @param feature must be a string defined in PackageManager + */ + public static void checkFeatureSupported(Context context, View passButton, String feature) { + if (!context.getPackageManager().hasSystemFeature(feature)) { + String message = String.format("Device does not support %s, automatically passing test", + feature); + Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); + Log.e(context.getClass().getName(), message); + passButton.performClick(); + Activity activity = (Activity) (context); + activity.finish(); + } + } +} diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/InputTextHandler.java b/apps/CtsVerifier/src/com/android/cts/verifier/presence/InputTextHandler.java new file mode 100644 index 00000000000..2de68a5a78e --- /dev/null +++ b/apps/CtsVerifier/src/com/android/cts/verifier/presence/InputTextHandler.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package com.android.cts.verifier.presence; + +import android.text.Editable; +import android.text.TextWatcher; + +/** + * Handles editable text inputted into test activities. + */ +public class InputTextHandler { + + /** Callback that is executed when text is changed. Takes modified text as input. */ + public interface OnTextChanged { + void run(Editable s); + } + + /** + * Generic text changed handler that will execute the provided callback when text is modified. + * + * @param callback called when text is changed, and passed the modified text + */ + public static TextWatcher getOnTextChangedHandler(OnTextChanged callback) { + return new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} + + @Override + public void afterTextChanged(Editable s) { + callback.run(s); + } + }; + } +} diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/NanPrecisionTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/presence/NanPrecisionTestActivity.java new file mode 100644 index 00000000000..458d1920eca --- /dev/null +++ b/apps/CtsVerifier/src/com/android/cts/verifier/presence/NanPrecisionTestActivity.java @@ -0,0 +1,271 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.cts.verifier.presence; + +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.text.Editable; +import android.util.Log; +import android.widget.EditText; + +import com.android.compatibility.common.util.ResultType; +import com.android.compatibility.common.util.ResultUnit; +import com.android.cts.verifier.PassFailButtons; +import com.android.cts.verifier.R; + +import com.google.common.collect.ImmutableMap; + +import java.util.Arrays; +import java.util.List; + +/** + * Activity for testing that NAN measurements are within the acceptable ranges + */ +public class NanPrecisionTestActivity extends PassFailButtons.Activity { + private static final String TAG = NanPrecisionTestActivity.class.getName(); + + // Report log schema + private static final String KEY_BANDWIDTH = "nan_bandwidth"; + private static final String KEY_MEASUREMENT_RANGE_10CM_AT_68P = "measurement_range_10cm_68p"; + private static final String KEY_MEASUREMENT_RANGE_1M_AT_68P = "measurement_range_1m_68p"; + private static final String KEY_MEASUREMENT_RANGE_3M_AT_68p = "measurement_range_3m_68p"; + private static final String KEY_MEASUREMENT_RANGE_5M_AT_68p = "measurement_range_5m_68p"; + private static final String KEY_MEASUREMENT_RANGE_10CM_AT_90P = "measurement_range_10cm_90p"; + private static final String KEY_MEASUREMENT_RANGE_1M_AT_90P = "measurement_range_1m_90p"; + private static final String KEY_MEASUREMENT_RANGE_3M_AT_90p = "measurement_range_3m_90p"; + private static final String KEY_MEASUREMENT_RANGE_5M_AT_90p = "measurement_range_5m_90p"; + private static final String KEY_REFERENCE_DEVICE = "reference_device"; + + // Thresholds + private static final int MAX_DISTANCE_RANGE_METERS_160MHZ = 2; + private static final int MAX_DISTANCE_RANGE_METERS_80MHZ = 4; + private static final int MAX_DISTANCE_RANGE_METERS_40MHZ = 8; + private static final int MAX_DISTANCE_RANGE_METERS_20MHZ = 16; + + // Maps NAN bandwidths to acceptable range thresholds + private static final ImmutableMap<Integer, Integer> BANDWIDTH_TO_THRESHOLD_MAP = + ImmutableMap.of(160, MAX_DISTANCE_RANGE_METERS_160MHZ, 80, + MAX_DISTANCE_RANGE_METERS_80MHZ, 40, MAX_DISTANCE_RANGE_METERS_40MHZ, 20, + MAX_DISTANCE_RANGE_METERS_20MHZ); + + private EditText mBandwidthMhz; + private EditText mMeasurementRange10cmGt68p; + private EditText mMeasurementRange1mGt68p; + private EditText mMeasurementRange3mGt68p; + private EditText mMeasurementRange5mGt68p; + private EditText mMeasurementRange10cmGt90p; + private EditText mMeasurementRange1mGt90p; + private EditText mMeasurementRange3mGt90p; + private EditText mMeasurementRange5mGt90p; + private EditText mReferenceDeviceInput; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.nan_precision); + setPassFailButtonClickListeners(); + getPassButton().setEnabled(false); + + mBandwidthMhz = (EditText) findViewById(R.id.nan_bandwidth); + mMeasurementRange10cmGt68p = (EditText) findViewById(R.id.distance_range_10cm_gt_68p); + mMeasurementRange1mGt68p = (EditText) findViewById(R.id.distance_range_1m_gt_68p); + mMeasurementRange3mGt68p = (EditText) findViewById(R.id.distance_range_3m_gt_68p); + mMeasurementRange5mGt68p = (EditText) findViewById(R.id.distance_range_5m_gt_68p); + mMeasurementRange10cmGt90p = (EditText) findViewById(R.id.distance_range_10cm_gt_90p); + mMeasurementRange1mGt90p = (EditText) findViewById(R.id.distance_range_1m_gt_90p); + mMeasurementRange3mGt90p = (EditText) findViewById(R.id.distance_range_3m_gt_90p); + mMeasurementRange5mGt90p = (EditText) findViewById(R.id.distance_range_5m_gt_90p); + mReferenceDeviceInput = (EditText) findViewById(R.id.reference_device); + + DeviceFeatureChecker.checkFeatureSupported(this, getPassButton(), + PackageManager.FEATURE_WIFI_AWARE); + + mBandwidthMhz.addTextChangedListener( + InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs())); + mMeasurementRange10cmGt68p.addTextChangedListener( + InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs())); + mMeasurementRange1mGt68p.addTextChangedListener( + InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs())); + mMeasurementRange3mGt68p.addTextChangedListener( + InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs())); + mMeasurementRange5mGt68p.addTextChangedListener( + InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs())); + mMeasurementRange10cmGt90p.addTextChangedListener( + InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs())); + mMeasurementRange1mGt90p.addTextChangedListener( + InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs())); + mMeasurementRange3mGt90p.addTextChangedListener( + InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs())); + mMeasurementRange5mGt90p.addTextChangedListener( + InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs())); + mReferenceDeviceInput.addTextChangedListener( + InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs())); + } + + private void checkTestInputs() { + getPassButton().setEnabled(checkMeasurementRange68thPercentileInput() + && checkMeasurementRange90thPercentileInput() + && checkReferenceDeviceInput()); + } + + private boolean checkMeasurementRange68thPercentileInput() { + return checkRequiredMeasurementRangeInput(mMeasurementRange10cmGt68p, + mMeasurementRange1mGt68p, mMeasurementRange3mGt68p, mMeasurementRange5mGt68p); + } + + private boolean checkMeasurementRange90thPercentileInput() { + String measurementRangeInput10cmGt90p = mMeasurementRange10cmGt90p.getText().toString(); + String measurementRangeInput1mGt90p = mMeasurementRange1mGt90p.getText().toString(); + String measurementRangeInput3mGt90p = mMeasurementRange3mGt90p.getText().toString(); + String measurementRangeInput5mGt90p = mMeasurementRange5mGt90p.getText().toString(); + List<String> optionalMeasurementRangeList = Arrays.asList(measurementRangeInput10cmGt90p, + measurementRangeInput1mGt90p, + measurementRangeInput3mGt90p, measurementRangeInput5mGt90p); + + boolean inputted = false; + for (String input : optionalMeasurementRangeList) { + if (!input.isEmpty()) { + inputted = true; + break; + } + } + // If one of the ranges is inputted for one of the distances, then it becomes required + // that the ranges are inputted for all the distances and for tests to pass, must be + // acceptable values + return !inputted || checkRequiredMeasurementRangeInput(mMeasurementRange10cmGt90p, + mMeasurementRange1mGt90p, mMeasurementRange3mGt90p, mMeasurementRange5mGt90p); + } + + private boolean checkRequiredMeasurementRangeInput(EditText rangeInput10cm, + EditText rangeInput1m, EditText rangeInput3m, EditText rangeInput5m) { + String bandwidthInputMhz = mBandwidthMhz.getText().toString(); + String measurementRangeInput10cmGt = rangeInput10cm.getText().toString(); + String measurementRangeInput1mGt = rangeInput1m.getText().toString(); + String measurementRangeInput3mGt = rangeInput3m.getText().toString(); + String measurementRangeInput5mGt = rangeInput5m.getText().toString(); + List<String> requiredMeasurementRangeList = Arrays.asList(measurementRangeInput10cmGt, + measurementRangeInput1mGt, + measurementRangeInput3mGt, measurementRangeInput5mGt); + + for (String input : requiredMeasurementRangeList) { + if (bandwidthInputMhz.isEmpty() || input.isEmpty()) { + // Distance range must be inputted for all fields so fail early otherwise + return false; + } + if (!BANDWIDTH_TO_THRESHOLD_MAP.containsKey(Integer.parseInt(bandwidthInputMhz))) { + // bandwidth must be one of the expected thresholds + return false; + } + double distanceRange = Double.parseDouble(input); + int bandwidth = Integer.parseInt(bandwidthInputMhz); + if (distanceRange > BANDWIDTH_TO_THRESHOLD_MAP.get(bandwidth)) { + // All inputs must be in acceptable range so fail early otherwise + return false; + } + } + return true; + } + + private boolean checkReferenceDeviceInput() { + // Reference device used must be inputted before test can be passed. + return !mReferenceDeviceInput.getText().toString().isEmpty(); + } + + @Override + public void recordTestResults() { + String nanBandwidthMhz = mBandwidthMhz.getText().toString(); + String measurementRange10cmGt68p = mMeasurementRange10cmGt68p.getText().toString(); + String measurementRange1mGt68p = mMeasurementRange1mGt68p.getText().toString(); + String measurementRange3mGt68p = mMeasurementRange3mGt68p.getText().toString(); + String measurementRange5mGt68p = mMeasurementRange5mGt68p.getText().toString(); + String measurementRange10cmGt90p = mMeasurementRange10cmGt90p.getText().toString(); + String measurementRange1mGt90p = mMeasurementRange1mGt90p.getText().toString(); + String measurementRange3mGt90p = mMeasurementRange3mGt90p.getText().toString(); + String measurementRange5mGt90p = mMeasurementRange5mGt90p.getText().toString(); + String referenceDevice = mReferenceDeviceInput.getText().toString(); + + if (!nanBandwidthMhz.isEmpty()) { + Log.i(TAG, "NAN Bandwidth at which data was collected: " + nanBandwidthMhz); + getReportLog().addValue(KEY_BANDWIDTH, + Integer.parseInt(nanBandwidthMhz), + ResultType.NEUTRAL, ResultUnit.NONE); + } + + if (!measurementRange10cmGt68p.isEmpty()) { + Log.i(TAG, "NAN Measurement Range at 10cm: " + measurementRange10cmGt68p); + getReportLog().addValue(KEY_MEASUREMENT_RANGE_10CM_AT_68P, + Double.parseDouble(measurementRange10cmGt68p), + ResultType.NEUTRAL, ResultUnit.NONE); + } + + if (!measurementRange1mGt68p.isEmpty()) { + Log.i(TAG, "NAN Measurement Range at 1m: " + measurementRange1mGt68p); + getReportLog().addValue(KEY_MEASUREMENT_RANGE_1M_AT_68P, + Double.parseDouble(measurementRange1mGt68p), + ResultType.NEUTRAL, ResultUnit.NONE); + } + + if (!measurementRange3mGt68p.isEmpty()) { + Log.i(TAG, "NAN Measurement Range at 3m: " + measurementRange3mGt68p); + getReportLog().addValue(KEY_MEASUREMENT_RANGE_3M_AT_68p, + Double.parseDouble(measurementRange3mGt68p), + ResultType.NEUTRAL, ResultUnit.NONE); + } + + if (!measurementRange5mGt68p.isEmpty()) { + Log.i(TAG, "NAN Measurement Range at 5m: " + measurementRange5mGt68p); + getReportLog().addValue(KEY_MEASUREMENT_RANGE_5M_AT_68p, + Double.parseDouble(measurementRange5mGt68p), + ResultType.NEUTRAL, ResultUnit.NONE); + } + + if (!measurementRange10cmGt90p.isEmpty()) { + Log.i(TAG, "NAN Measurement Range at 10cm: " + measurementRange10cmGt68p); + getReportLog().addValue(KEY_MEASUREMENT_RANGE_10CM_AT_90P, + Double.parseDouble(measurementRange10cmGt90p), + ResultType.NEUTRAL, ResultUnit.NONE); + } + + if (!measurementRange1mGt90p.isEmpty()) { + Log.i(TAG, "NAN Measurement Range at 1m: " + measurementRange1mGt90p); + getReportLog().addValue(KEY_MEASUREMENT_RANGE_1M_AT_90P, + Double.parseDouble(measurementRange1mGt90p), + ResultType.NEUTRAL, ResultUnit.NONE); + } + + if (!measurementRange3mGt90p.isEmpty()) { + Log.i(TAG, "NAN Measurement Range at 3m: " + measurementRange3mGt90p); + getReportLog().addValue(KEY_MEASUREMENT_RANGE_3M_AT_90p, + Double.parseDouble(measurementRange3mGt90p), + ResultType.NEUTRAL, ResultUnit.NONE); + } + + if (!measurementRange5mGt90p.isEmpty()) { + Log.i(TAG, "NAN Measurement Range at 5m: " + measurementRange5mGt90p); + getReportLog().addValue(KEY_MEASUREMENT_RANGE_5M_AT_90p, + Double.parseDouble(measurementRange5mGt90p), + ResultType.NEUTRAL, ResultUnit.NONE); + } + + if (!referenceDevice.isEmpty()) { + Log.i(TAG, "NAN Reference Device: " + referenceDevice); + getReportLog().addValue(KEY_REFERENCE_DEVICE, referenceDevice, + ResultType.NEUTRAL, ResultUnit.NONE); + } + getReportLog().submit(); + } +} diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/presence/OWNERS new file mode 100644 index 00000000000..e8744995b6c --- /dev/null +++ b/apps/CtsVerifier/src/com/android/cts/verifier/presence/OWNERS @@ -0,0 +1,4 @@ +# Bug component: 1106357 +asalo@google.com +jbabs@google.com +christinatao@google.com
\ No newline at end of file diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/PresenceTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/presence/PresenceTestActivity.java new file mode 100644 index 00000000000..67766931591 --- /dev/null +++ b/apps/CtsVerifier/src/com/android/cts/verifier/presence/PresenceTestActivity.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.cts.verifier.presence; + +import android.content.pm.PackageManager; +import android.os.Build; +import android.os.Bundle; +import android.os.SystemProperties; + +import com.android.cts.verifier.ManifestTestListAdapter; +import com.android.cts.verifier.PassFailButtons; +import com.android.cts.verifier.R; + +import java.util.ArrayList; +import java.util.List; + +public class PresenceTestActivity extends PassFailButtons.TestListActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.pass_fail_list); + setPassFailButtonClickListeners(); + + List<String> disabledTest = new ArrayList<String>(); + boolean isTv = getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK); + if (isTv) { + setInfoResources(R.string.presence_test, R.string.presence_test_tv_info, -1); + int firstSdk = SystemProperties.getInt("ro.product.first_api_level", 0); + if (firstSdk < Build.VERSION_CODES.TIRAMISU) { + disabledTest.add("com.android.cts.verifier.presence.UwbPrecisionActivity"); + disabledTest.add("com.android.cts.verifier.presence.UwbShortRangeActivity"); + disabledTest.add("com.android.cts.verifier.presence.BleRssiPrecisionActivity"); + disabledTest.add("com.android.cts.verifier.presence.BleRxTxCalibrationActivity"); + disabledTest.add("com.android.cts.verifier.presence.BleRxOffsetActivity"); + disabledTest.add("com.android.cts.verifier.presence.BleTxOffsetActivity"); + disabledTest.add("com.android.cts.verifier.presence.NanPrecisionTestActivity"); + } + } else { + setInfoResources(R.string.presence_test, R.string.presence_test_info, -1); + } + + setTestListAdapter(new ManifestTestListAdapter(this, PresenceTestActivity.class.getName(), + disabledTest.toArray(new String[disabledTest.size()]))); + } +} diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/UwbPrecisionActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/presence/UwbPrecisionActivity.java new file mode 100644 index 00000000000..5d1ff8628dd --- /dev/null +++ b/apps/CtsVerifier/src/com/android/cts/verifier/presence/UwbPrecisionActivity.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.cts.verifier.presence; + +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.text.Editable; +import android.util.Log; +import android.widget.EditText; + +import com.android.compatibility.common.util.ResultType; +import com.android.compatibility.common.util.ResultUnit; +import com.android.cts.verifier.PassFailButtons; +import com.android.cts.verifier.R; + +/** + * Activity for testing that UWB distance and angle of arrival measurements are within the right + * range. + */ +public class UwbPrecisionActivity extends PassFailButtons.Activity { + private static final String TAG = UwbPrecisionActivity.class.getName(); + // Report log schema + private static final String KEY_DISTANCE_RANGE_CM = "distance_range_cm"; + private static final String KEY_REFERENCE_DEVICE = "reference_device"; + // Thresholds + private static final int MAX_DISTANCE_RANGE_CM = 30; + + private EditText mDistanceRangeInput; + private EditText mReferenceDeviceInput; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.uwb_precision); + setPassFailButtonClickListeners(); + getPassButton().setEnabled(false); + + mDistanceRangeInput = (EditText) findViewById(R.id.distance_range_cm); + mReferenceDeviceInput = (EditText) findViewById(R.id.reference_device); + + DeviceFeatureChecker.checkFeatureSupported(this, getPassButton(), + PackageManager.FEATURE_UWB); + + mDistanceRangeInput.addTextChangedListener( + InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs())); + mReferenceDeviceInput.addTextChangedListener( + InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs())); + } + + private void checkTestInputs() { + getPassButton().setEnabled( + checkDistanceRangeInput() && checkReferenceDeviceInput()); + } + + private boolean checkDistanceRangeInput() { + String distanceRangeInput = mDistanceRangeInput.getText().toString(); + if (!distanceRangeInput.isEmpty()) { + double distanceRange = Double.parseDouble(distanceRangeInput); + // Distance range must be inputted and within acceptable range before test can be + // passed. + return distanceRange <= MAX_DISTANCE_RANGE_CM; + } + return false; + } + + private boolean checkReferenceDeviceInput() { + // Reference device must be inputted before test can be passed. + return !mReferenceDeviceInput.getText().toString().isEmpty(); + } + + @Override + public void recordTestResults() { + String distanceRange = mDistanceRangeInput.getText().toString(); + String referenceDevice = mReferenceDeviceInput.getText().toString(); + if (!distanceRange.isEmpty()) { + Log.i(TAG, "UWB Distance Range: " + distanceRange); + getReportLog().addValue(KEY_DISTANCE_RANGE_CM, Double.parseDouble(distanceRange), + ResultType.NEUTRAL, ResultUnit.NONE); + } + if (!referenceDevice.isEmpty()) { + Log.i(TAG, "UWB Reference Device: " + referenceDevice); + getReportLog().addValue(KEY_REFERENCE_DEVICE, referenceDevice, + ResultType.NEUTRAL, ResultUnit.NONE); + } + getReportLog().submit(); + } +} diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/presence/UwbShortRangeActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/presence/UwbShortRangeActivity.java new file mode 100644 index 00000000000..7f14800b68c --- /dev/null +++ b/apps/CtsVerifier/src/com/android/cts/verifier/presence/UwbShortRangeActivity.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.cts.verifier.presence; + +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.text.Editable; +import android.util.Log; +import android.widget.EditText; + +import com.android.compatibility.common.util.ResultType; +import com.android.compatibility.common.util.ResultUnit; +import com.android.cts.verifier.PassFailButtons; +import com.android.cts.verifier.R; + +/** + * Activity for testing that UWB distance measurements are within the acceptable median. + */ +public class UwbShortRangeActivity extends PassFailButtons.Activity { + private static final String TAG = UwbShortRangeActivity.class.getName(); + // Report log schema + private static final String KEY_DISTANCE_MEDIAN_CM = "distance_median_cm"; + private static final String KEY_REFERENCE_DEVICE = "reference_device"; + // Median Thresholds + private static final double MIN_MEDIAN = 0.75; + private static final double MAX_MEDIAN = 1.25; + private EditText mMedianInput; + private EditText mReferenceDeviceInput; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.uwb_short_range); + setPassFailButtonClickListeners(); + getPassButton().setEnabled(false); + + mMedianInput = (EditText) findViewById(R.id.distance_median_meters); + mReferenceDeviceInput = (EditText) findViewById(R.id.reference_device); + + DeviceFeatureChecker.checkFeatureSupported(this, getPassButton(), + PackageManager.FEATURE_UWB); + + mMedianInput.addTextChangedListener( + InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs())); + mReferenceDeviceInput.addTextChangedListener( + InputTextHandler.getOnTextChangedHandler((Editable s) -> checkTestInputs())); + } + + private void checkTestInputs() { + getPassButton().setEnabled(checkMedianInput() && checkReferenceDeviceInput()); + } + + private boolean checkMedianInput() { + String medianInput = mMedianInput.getText().toString(); + if (!medianInput.isEmpty()) { + double median = Double.parseDouble(medianInput); + return median >= MIN_MEDIAN && median <= MAX_MEDIAN; + } + return false; + } + + private boolean checkReferenceDeviceInput() { + return !mReferenceDeviceInput.getText().toString().isEmpty(); + } + + @Override + public void recordTestResults() { + String medianInput = mMedianInput.getText().toString(); + String referenceDeviceInput = mReferenceDeviceInput.getText().toString(); + if (!medianInput.isEmpty()) { + Log.i(TAG, "UWB Distance Median: " + medianInput); + getReportLog().addValue(KEY_DISTANCE_MEDIAN_CM, Double.parseDouble(medianInput), + ResultType.NEUTRAL, ResultUnit.NONE); + } + if (!referenceDeviceInput.isEmpty()) { + Log.i(TAG, "UWB Reference Device: " + referenceDeviceInput); + getReportLog().addValue(KEY_REFERENCE_DEVICE, referenceDeviceInput, ResultType.NEUTRAL, + ResultUnit.NONE); + } + getReportLog().submit(); + } +} diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/GestureNavRule.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/GestureNavRule.java index ff389a118f5..9c363d23b39 100644 --- a/common/device-side/util-axt/src/com/android/compatibility/common/util/GestureNavRule.java +++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/GestureNavRule.java @@ -33,21 +33,17 @@ import android.util.ArrayMap; import androidx.test.InstrumentationRegistry; -import org.junit.ClassRule; import org.junit.rules.ExternalResource; -import java.io.IOException; import java.util.Map; /** - * Test rule to enable gesture navigation on the device. Designed to be a {@link ClassRule}. + * Test rule to enable gesture navigation on the device. */ public class GestureNavRule extends ExternalResource { private static final String SETTINGS_PACKAGE_NAME = "com.android.settings"; private static final String NAV_BAR_INTERACTION_MODE_RES_NAME = "config_navBarInteractionMode"; private static final int NAV_BAR_INTERACTION_MODE_GESTURAL = 2; - private static final String GESTURAL_OVERLAY_NAME = - "com.android.internal.systemui.navbar.gestural"; /** Most application's res id must be larger than 0x7f000000 */ public static final int MIN_APPLICATION_RES_ID = 0x7f000000; @@ -63,13 +59,13 @@ public class GestureNavRule extends ExternalResource { private String mSystemNavigationTitle; private String mGesturePreferenceTitle; private boolean mConfiguredInSettings; - private boolean mRevertOverlay; @Override protected void before() throws Throwable { if (!isGestureMode()) { enableGestureNav(); } + assumeGestureNavigationMode(); } @Override @@ -187,19 +183,6 @@ public class GestureNavRule extends ExternalResource { if (!hasSystemGestureFeature()) { return; } - try { - if (mDevice.executeShellCommand("cmd overlay list").contains(GESTURAL_OVERLAY_NAME)) { - mDevice.executeShellCommand("cmd overlay enable " + GESTURAL_OVERLAY_NAME); - mDevice.waitForIdle(); - } - } catch (IOException e) { - // Do nothing - } - - if (isGestureMode()) { - mRevertOverlay = true; - return; - } // Set up the gesture navigation by enabling it via the Settings app boolean isOperatedSettingsToExpectedOption = launchToSettingsSystemGesture(); @@ -231,17 +214,6 @@ public class GestureNavRule extends ExternalResource { return; } - if (mRevertOverlay) { - try { - mDevice.executeShellCommand("cmd overlay disable " + GESTURAL_OVERLAY_NAME); - } catch (IOException e) { - // Do nothing - } - if (!isGestureMode()) { - return; - } - } - if (mConfiguredInSettings) { launchToSettingsSystemGesture(); for (Map.Entry<String, Boolean> entry : mSystemGestureOptionsMap.entrySet()) { @@ -256,12 +228,7 @@ public class GestureNavRule extends ExternalResource { } } - /** - * Assumes the device is in gesture navigation mode. Due to constraints of AndroidJUnitRunner we - * can't make assumptions in static contexts like in a {@link ClassRule} so tests need to call - * this method explicitly. - */ - public void assumeGestureNavigationMode() { + private void assumeGestureNavigationMode() { boolean isGestureMode = isGestureMode(); assumeTrue("Gesture navigation required", isGestureMode); } diff --git a/hostsidetests/appcompat/strictjavapackages/src/android/compat/sjp/cts/StrictJavaPackagesTest.java b/hostsidetests/appcompat/strictjavapackages/src/android/compat/sjp/cts/StrictJavaPackagesTest.java index 24d1249d9cc..a1764996f11 100644 --- a/hostsidetests/appcompat/strictjavapackages/src/android/compat/sjp/cts/StrictJavaPackagesTest.java +++ b/hostsidetests/appcompat/strictjavapackages/src/android/compat/sjp/cts/StrictJavaPackagesTest.java @@ -83,7 +83,6 @@ public class StrictJavaPackagesTest extends BaseHostJUnit4Test { private static ImmutableList<String> sSystemserverclasspathJars; private static ImmutableList<String> sSharedLibJars; private static ImmutableList<SharedLibraryInfo> sSharedLibs; - private static ImmutableMultimap<String, String> sSharedLibsPathsToName; private static ImmutableMultimap<String, String> sJarsToClasses; private static ImmutableMultimap<String, String> sJarsToFiles; @@ -224,13 +223,7 @@ public class StrictJavaPackagesTest extends BaseHostJUnit4Test { "Landroid/os/CreateAppDataArgs;", "Landroid/os/CreateAppDataResult;", "Landroid/os/ReconcileSdkDataArgs;", - "Lcom/android/internal/util/FrameworkStatsLog;", - // Extra Pixel specific S oversights - "Landroid/os/BlockUntrustedTouchesMode;", - "Landroid/os/IInputConstants;", - "Landroid/os/InputEventInjectionResult;", - "Landroid/os/InputEventInjectionSync;" - + "Lcom/android/internal/util/FrameworkStatsLog;" ); private static final String FEATURE_WEARABLE = "android.hardware.type.watch"; @@ -342,7 +335,7 @@ public class StrictJavaPackagesTest extends BaseHostJUnit4Test { // Already duplicate in BCP. "Landroid/hidl/base/V1_0/DebugInfo;", "Landroid/hidl/base/V1_0/IBase;", - // /apex/com.android.btservices/javalib/framework-bluetooth.jar + // /apex/com.android.bluetooth/javalib/framework-bluetooth.jar "Lcom/android/bluetooth/x/android/sysprop/AdbProperties;", "Lcom/android/bluetooth/x/android/sysprop/ApkVerityProperties;", "Lcom/android/bluetooth/x/android/sysprop/BluetoothProperties;", @@ -731,9 +724,7 @@ public class StrictJavaPackagesTest extends BaseHostJUnit4Test { private static final ImmutableMap<String, ImmutableSet<String>> FULL_APK_IN_APEX_BURNDOWN = new ImmutableMap.Builder<String, ImmutableSet<String>>() - .put("/apex/com.android.btservices/app/Bluetooth/Bluetooth.apk", - BLUETOOTH_APK_IN_APEX_BURNDOWN_LIST) - .put("/apex/com.android.btservices/app/BluetoothGoogle/BluetoothGoogle.apk", + .put("/apex/com.android.bluetooth/app/Bluetooth/Bluetooth.apk", BLUETOOTH_APK_IN_APEX_BURNDOWN_LIST) .put("/apex/com.android.bluetooth/app/BluetoothGoogle/BluetoothGoogle.apk", BLUETOOTH_APK_IN_APEX_BURNDOWN_LIST) @@ -741,8 +732,6 @@ public class StrictJavaPackagesTest extends BaseHostJUnit4Test { PERMISSION_CONTROLLER_APK_IN_APEX_BURNDOWN_LIST) .put("/apex/com.android.permission/priv-app/GooglePermissionController/GooglePermissionController.apk", PERMISSION_CONTROLLER_APK_IN_APEX_BURNDOWN_LIST) - .put("/apex/com.android.tethering/priv-app/InProcessTethering/InProcessTethering.apk", - TETHERING_APK_IN_APEX_BURNDOWN_LIST) .put("/apex/com.android.tethering/priv-app/TetheringNextGoogle/TetheringNextGoogle.apk", TETHERING_APK_IN_APEX_BURNDOWN_LIST) .put("/apex/com.android.tethering/priv-app/TetheringGoogle/TetheringGoogle.apk", @@ -796,13 +785,6 @@ public class StrictJavaPackagesTest extends BaseHostJUnit4Test { .filter(file -> !file.contains("GmsCore")) .filter(file -> !file.contains("com.google.android.gms")) .collect(ImmutableList.toImmutableList()); - final ImmutableSetMultimap.Builder<String, String> sharedLibsPathsToName = - ImmutableSetMultimap.builder(); - sSharedLibs.forEach(sharedLibraryInfo -> { - sharedLibraryInfo.paths.forEach(path -> - sharedLibsPathsToName.putAll(path, sharedLibraryInfo.name)); - }); - sSharedLibsPathsToName = sharedLibsPathsToName.build(); final ImmutableSetMultimap.Builder<String, String> jarsToFiles = ImmutableSetMultimap.builder(); @@ -1011,8 +993,8 @@ public class StrictJavaPackagesTest extends BaseHostJUnit4Test { .collect(ImmutableSet.toImmutableSet()); // b/226559955: The directory paths containing APKs contain the build ID, // so strip out the @BUILD_ID portion. - // e.g. /apex/com.android.btservices/app/Bluetooth@SC-DEV/Bluetooth.apk -> - // /apex/com.android.btservices/app/Bluetooth/Bluetooth.apk + // e.g. /apex/com.android.bluetooth/app/Bluetooth@SC-DEV/Bluetooth.apk -> + // /apex/com.android.bluetooth/app/Bluetooth/Bluetooth.apk apk = apk.replaceFirst("@[^/]*", ""); final ImmutableSet<String> burndownClasses = FULL_APK_IN_APEX_BURNDOWN.getOrDefault(apk, ImmutableSet.of()); @@ -1046,18 +1028,16 @@ public class StrictJavaPackagesTest extends BaseHostJUnit4Test { // WARNING: Do not add more exceptions here, no androidx should be in bootclasspath. // See go/androidx-api-guidelines#module-naming for more details. final ImmutableMap<String, ImmutableSet<String>> - LegacyExemptAndroidxSharedLibsNamesToClasses = + LegacyExemptAndroidxSharedLibsJarToClasses = new ImmutableMap.Builder<String, ImmutableSet<String>>() - .put("androidx.camera.extensions.impl", + .put("/vendor/framework/androidx.camera.extensions.impl.jar", ImmutableSet.of("Landroidx/camera/extensions/impl/")) - .put("androidx.window.extensions", + .put("/system_ext/framework/androidx.window.extensions.jar", ImmutableSet.of("Landroidx/window/common/", "Landroidx/window/extensions/", "Landroidx/window/util/")) - .put("androidx.window.sidecar", + .put("/system_ext/framework/androidx.window.sidecar.jar", ImmutableSet.of("Landroidx/window/common/", "Landroidx/window/sidecar", "Landroidx/window/util")) - .put("com.google.android.camera.experimental2020_midyear", - ImmutableSet.of("Landroidx/annotation")) .build(); assertWithMessage("There must not be any androidx classes on the " + "bootclasspath. Please use alternatives provided by the platform instead. " @@ -1065,7 +1045,7 @@ public class StrictJavaPackagesTest extends BaseHostJUnit4Test { .that(sJarsToClasses.entries().stream() .filter(e -> e.getValue().startsWith("Landroidx/")) .filter(e -> !isLegacyAndroidxDependency( - LegacyExemptAndroidxSharedLibsNamesToClasses, e.getKey(), e.getValue())) + LegacyExemptAndroidxSharedLibsJarToClasses, e.getKey(), e.getValue())) .collect(Collectors.toList()) ).isEmpty(); } @@ -1111,12 +1091,11 @@ public class StrictJavaPackagesTest extends BaseHostJUnit4Test { } private boolean isLegacyAndroidxDependency( - ImmutableMap<String, ImmutableSet<String>> legacyExemptAndroidxSharedLibsNamesToClasses, - String path, String className) { - return sSharedLibsPathsToName.get(path).stream() - .filter(legacyExemptAndroidxSharedLibsNamesToClasses::containsKey) - .flatMap(name -> legacyExemptAndroidxSharedLibsNamesToClasses.get(name).stream()) - .anyMatch(className::startsWith); + ImmutableMap<String, ImmutableSet<String>> legacyExemptAndroidxSharedLibsJarToClasses, + String jar, String className) { + return legacyExemptAndroidxSharedLibsJarToClasses.containsKey(jar) + && legacyExemptAndroidxSharedLibsJarToClasses.get(jar).stream().anyMatch( + v -> className.startsWith(v)); } private String[] collectApkInApexPaths() { diff --git a/hostsidetests/appsecurity/res/apexsigverify/README.md b/hostsidetests/appsecurity/res/apexsigverify/README.md index 4b5dcd28ddb..9012a858ac4 100644 --- a/hostsidetests/appsecurity/res/apexsigverify/README.md +++ b/hostsidetests/appsecurity/res/apexsigverify/README.md @@ -15,7 +15,6 @@ frameworks/av/apex/com.android.media.avbpubkey frameworks/base/packages/Tethering/apex/com.android.tethering.avbpubkey frameworks/ml/nn/apex/com.android.neuralnetworks.avbpubkey frameworks/opt/net/ike/apex/com.android.ipsec.avbpubkey -packages/modules/Bluetooth/apex/com.android.btservices.avbpubkey packages/modules/SdkExtensions/com.android.sdkext.avbpubkey system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.avbpubkey system/apex/apexd/apexd_testdata/com.android.apex.test_package.no_inst_key.avbpubkey @@ -28,6 +27,7 @@ system/apex/apexer/testdata/com.android.example.apex.avbpubkey system/apex/apexer/etc/com.android.support.apexer.avbpubkey system/netd/apex/com.android.resolv.avbpubkey system/timezone/apex/com.android.tzdata.avbpubkey +system/bt/apex/com.android.bluetooth.updatable.avbpubkey system/core/adb/apex/com.android.adbd.avbpubkey system/core/rootdir/avb/s-gsi.avbpubkey system/core/rootdir/avb/q-developer-gsi.avbpubkey diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/AdoptableHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/AdoptableHostTest.java index cee6a39c46a..cb76f326f66 100644 --- a/hostsidetests/appsecurity/src/android/appsecurity/cts/AdoptableHostTest.java +++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/AdoptableHostTest.java @@ -76,7 +76,7 @@ public class AdoptableHostTest extends BaseHostJUnit4Test { int attempt = 0; boolean hasVirtualDisk = false; String result = ""; - while (!hasVirtualDisk && attempt++ < 50) { + while (!hasVirtualDisk && attempt++ < 20) { Thread.sleep(1000); result = getDevice().executeShellCommand("sm list-disks adoptable").trim(); hasVirtualDisk = result.startsWith("disk:"); diff --git a/hostsidetests/compilation/src/android/compilation/cts/AdbRootDependentCompilationTest.java b/hostsidetests/compilation/src/android/compilation/cts/AdbRootDependentCompilationTest.java index c2e95a3ae63..1bb14bdf7fe 100644 --- a/hostsidetests/compilation/src/android/compilation/cts/AdbRootDependentCompilationTest.java +++ b/hostsidetests/compilation/src/android/compilation/cts/AdbRootDependentCompilationTest.java @@ -266,11 +266,6 @@ public class AdbRootDependentCompilationTest extends BaseHostJUnit4Test { "android.compilation.cts.appusedbyotherapp.MyActivity.method1()", "android.compilation.cts.appusedbyotherapp.MyActivity.method2()"); - executeCompile(APP_USED_BY_OTHER_APP_PACKAGE, "-m", "verify"); - // The app should not be re-compiled with a worse compiler filter even if the odex file can - // be public after then. - assertThat(getCompilerFilter(odexFilePath)).isEqualTo("speed-profile"); - DeviceTestRunOptions options = new DeviceTestRunOptions(APP_USING_OTHER_APP_PACKAGE); options.setTestClassName(APP_USING_OTHER_APP_PACKAGE + ".UsingOtherAppTest"); options.setTestMethodName("useOtherApp"); diff --git a/hostsidetests/dumpsys/src/android/dumpsys/cts/BatteryStatsDumpsysTest.java b/hostsidetests/dumpsys/src/android/dumpsys/cts/BatteryStatsDumpsysTest.java index d6ac4851002..11f24fad5d5 100755 --- a/hostsidetests/dumpsys/src/android/dumpsys/cts/BatteryStatsDumpsysTest.java +++ b/hostsidetests/dumpsys/src/android/dumpsys/cts/BatteryStatsDumpsysTest.java @@ -25,7 +25,6 @@ import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.StringReader; -import java.util.ArrayList; import java.util.HashSet; import java.util.Set; @@ -37,41 +36,6 @@ public class BatteryStatsDumpsysTest extends BaseDumpsysTest { private static final String TEST_PKG = "com.android.cts.framestatstestapp"; /** - * Parse each line from output of dumpsys to handle special fields such as - * 'aaa,"bbb,ccc",ddd', to capture properly. - */ - private static String[] parseCsv(String line) { - ArrayList<String> parts = new ArrayList<>(); - String[] splitStrings = line.split(",", -1); - String s = ""; - boolean escaping = false; - for (String splitString : splitStrings) { - if (escaping) { - s += "," + splitString; - } else { - if (splitString.startsWith("\"")) { - // Field start with ". Start escaping. - s = splitString; - escaping = true; - } else { - parts.add(splitString); - } - } - if (escaping && s.length() > 1 && s.endsWith("\"")) { - // Field end with ". Stop escaping. - parts.add(s.substring(1, s.length() - 1)); - escaping = false; - } - } - if (escaping) { - // Unclosed escaping string. Add it anyway. - parts.add(s.substring(1)); - } - - return parts.toArray(new String[parts.size()]); - } - - /** * Tests the output of "dumpsys batterystats --checkin". * * @throws Exception @@ -94,7 +58,11 @@ public class BatteryStatsDumpsysTest extends BaseDumpsysTest { try { - String[] parts = parseCsv(line); + // With a default limit of 0, empty strings at the end are discarded. + // We still consider the empty string as a valid value in some cases. + // Using any negative number for the limit will preserve a trailing empty string. + // @see String#split(String, int) + String[] parts = line.split(",", -1); assertInteger(parts[0]); // old version assertInteger(parts[1]); // UID switch (parts[2]) { // aggregation type diff --git a/hostsidetests/media/bitstreams/AndroidTest.xml b/hostsidetests/media/bitstreams/AndroidTest.xml index c07fa07eb9e..070b44ddcf3 100644 --- a/hostsidetests/media/bitstreams/AndroidTest.xml +++ b/hostsidetests/media/bitstreams/AndroidTest.xml @@ -25,11 +25,6 @@ <option name="dynamic-config-name" value="cts-dynamic-config" /> <option name="version" value="9.0_r1"/> </target_preparer> - <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher"> - <option name="target" value="device" /> - <option name="config-filename" value="CtsMediaBitstreamsTestCases" /> - <option name="version" value="9.0_r1"/> - </target_preparer> <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer"> <option name="media-download-only" value="true" /> </target_preparer> @@ -37,6 +32,11 @@ <option name="cleanup-apks" value="true" /> <option name="test-file-name" value="CtsMediaBitstreamsDeviceSideTestApp.apk" /> </target_preparer> + <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher"> + <option name="target" value="device" /> + <option name="config-filename" value="CtsMediaBitstreamsTestCases" /> + <option name="version" value="9.0_r1"/> + </target_preparer> <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ReportLogCollector"> <option name="src-dir" value="/sdcard/report-log-files/"/> <option name="dest-dir" value="report-log-files/"/> diff --git a/hostsidetests/scopedstorage/Android.bp b/hostsidetests/scopedstorage/Android.bp index 527e8ef842b..da0df31dcf1 100644 --- a/hostsidetests/scopedstorage/Android.bp +++ b/hostsidetests/scopedstorage/Android.bp @@ -210,7 +210,7 @@ android_test_helper_app { min_sdk_version: "29", } -android_test_helper_app { +android_test { name: "ScopedStorageTest", manifest: "AndroidManifest.xml", srcs: ["src/**/*.java"], @@ -237,7 +237,7 @@ android_test_helper_app { ], } -android_test_helper_app { +android_test { name: "LegacyStorageTest", manifest: "legacy/AndroidManifest.xml", srcs: ["legacy/src/**/*.java"], diff --git a/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/ScopedStorageDeviceTest.java b/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/ScopedStorageDeviceTest.java index 35cb549c529..099a0ab7276 100644 --- a/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/ScopedStorageDeviceTest.java +++ b/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/ScopedStorageDeviceTest.java @@ -1772,37 +1772,6 @@ public class ScopedStorageDeviceTest extends ScopedStorageBaseDeviceTest { } /** - * Test that renaming file paths to an external directory such as Android/* and Android/* /* - * except Android/media/* /* is not allowed. - */ - @Test - public void testRenameFileToAppSpecificDir() throws Exception { - final File testFile = new File(getExternalMediaDir(), IMAGE_FILE_NAME); - final File testFileNew = new File(getExternalMediaDir(), NONMEDIA_FILE_NAME); - - try { - // Create a file in app's external media directory - if (!testFile.exists()) { - assertThat(testFile.createNewFile()).isTrue(); - } - - final String androidDirPath = getExternalStorageDir().getPath() + "/Android"; - - // Verify that we can't rename a file to Android/ or Android/data or - // Android/media directory - assertCantRenameFile(testFile, new File(androidDirPath, IMAGE_FILE_NAME)); - assertCantRenameFile(testFile, new File(androidDirPath + "/data", IMAGE_FILE_NAME)); - assertCantRenameFile(testFile, new File(androidDirPath + "/media", IMAGE_FILE_NAME)); - - // Verify that we can rename a file to app specific media directory. - assertCanRenameFile(testFile, testFileNew); - } finally { - testFile.delete(); - testFileNew.delete(); - } - } - - /** * Test that renaming directories is allowed and aligns to default directory restrictions. */ @Test diff --git a/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/StableUrisTest.java b/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/StableUrisTest.java index 4bff21bbd54..41a47b95a6d 100644 --- a/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/StableUrisTest.java +++ b/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/StableUrisTest.java @@ -33,8 +33,6 @@ import android.Manifest; import android.app.Instrumentation; import android.content.ContentResolver; import android.content.Context; -import android.content.pm.PackageManager; -import android.content.pm.ProviderInfo; import android.provider.MediaStore; import android.scopedstorage.cts.lib.TestUtils; import android.util.Log; @@ -123,7 +121,7 @@ public final class StableUrisTest extends ScopedStorageBaseDeviceTest { Log.d(TAG, "maxRowIdOfExternalDbBeforeReset:" + maxRowIdOfExternalDbBeforeReset); // Clear MediaProvider package data to trigger DB recreation. - mDevice.executeShellCommand("pm clear " + getMediaProviderPackageName()); + mDevice.executeShellCommand("pm clear com.google.android.providers.media.module"); waitForMountedAndIdleState(mContentResolver); MediaStore.scanVolume(mContentResolver, mVolumeName); @@ -174,11 +172,4 @@ public final class StableUrisTest extends ScopedStorageBaseDeviceTest { return files; } - private static String getMediaProviderPackageName() { - final Instrumentation inst = androidx.test.InstrumentationRegistry.getInstrumentation(); - final PackageManager packageManager = inst.getContext().getPackageManager(); - final ProviderInfo providerInfo = packageManager.resolveContentProvider( - MediaStore.AUTHORITY, PackageManager.MATCH_ALL); - return providerInfo.packageName; - } } diff --git a/hostsidetests/security/src/android/security/cts/KernelConfigTest.java b/hostsidetests/security/src/android/security/cts/KernelConfigTest.java index 44e616dfccc..ad99a5ae35c 100644 --- a/hostsidetests/security/src/android/security/cts/KernelConfigTest.java +++ b/hostsidetests/security/src/android/security/cts/KernelConfigTest.java @@ -187,8 +187,7 @@ public class KernelConfigTest extends BaseHostJUnit4Test { if (mitigationInfoMeltdown != null && mitigationInfoSpectreV2 != null && !mitigationInfoMeltdown.contains("Vulnerable") && - (!mitigationInfoSpectreV2.contains("Vulnerable") || - mitigationInfoSpectreV2.equals("Vulnerable: Unprivileged eBPF enabled\n"))) + !mitigationInfoSpectreV2.contains("Vulnerable")) return "VULN_SAFE"; for (String nodeInfo : pathList) { diff --git a/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java b/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java index 13ade8b0585..039867bbc85 100644 --- a/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java +++ b/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java @@ -983,17 +983,6 @@ public class SELinuxHostTest extends BaseHostJUnit4Test { } /** - * Tests that all types in /sys/fs/bpf have the bpffs_type attribute. - * - * @throws Exception - */ - @Test - public void testBpffsTypeViolators() throws Exception { - assertSepolicyTests("TestBpffsTypeViolations", "/sepolicy_tests", - PropertyUtil.isVendorApiLevelNewerThan(mDevice, 33) /* includeVendorSepolicy */); - } - - /** * Tests that all types in /proc have the proc_type attribute. * * @throws Exception @@ -1367,7 +1356,7 @@ public class SELinuxHostTest extends BaseHostJUnit4Test { @CddTest(requirement="9.7") @Test public void testDrmServerDomain() throws DeviceNotAvailableException { - assertDomainHasExecutable("u:r:drmserver:s0", "/system/bin/drmserver", "/system/bin/drmserver64"); + assertDomainN("u:r:drmserver:s0", "/system/bin/drmserver", "/system/bin/drmserver64"); } /* Installd is always running */ diff --git a/hostsidetests/securitybulletin/Android.bp b/hostsidetests/securitybulletin/Android.bp index 25242273f6b..323d5b7f573 100644 --- a/hostsidetests/securitybulletin/Android.bp +++ b/hostsidetests/securitybulletin/Android.bp @@ -23,6 +23,7 @@ java_test_host { java_resource_dirs: ["res"], // tag this module as a cts test artifact test_suites: [ + "cts", "general-tests", "sts", ], @@ -43,7 +44,6 @@ java_test_host { cc_defaults { name: "cts_hostsidetests_securitybulletin_defaults", - auto_gen_config: false, compile_multilib: "both", multilib: { lib32: { @@ -60,6 +60,7 @@ cc_defaults { }, }, test_suites: [ + "cts", "sts", "general-tests", ], diff --git a/hostsidetests/securitybulletin/res/cve_2021_39623.ogg b/hostsidetests/securitybulletin/res/cve_2021_39623.ogg Binary files differdeleted file mode 100644 index 1992a17f915..00000000000 --- a/hostsidetests/securitybulletin/res/cve_2021_39623.ogg +++ /dev/null diff --git a/hostsidetests/securitybulletin/res/cve_2022_22082.dsf b/hostsidetests/securitybulletin/res/cve_2022_22082.dsf Binary files differdeleted file mode 100644 index 60d1a5afbbc..00000000000 --- a/hostsidetests/securitybulletin/res/cve_2022_22082.dsf +++ /dev/null diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-39623/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39623/Android.bp deleted file mode 100644 index 50662fdeae6..00000000000 --- a/hostsidetests/securitybulletin/securityPatch/CVE-2021-39623/Android.bp +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package { - default_applicable_licenses: ["Android-Apache-2.0"], -} - -cc_test { - name: "CVE-2021-39623", - defaults: ["cts_hostsidetests_securitybulletin_defaults"], - srcs: [ - "poc.cpp", - ], - header_libs: [ - "libmediametrics_headers", - ], - shared_libs: [ - "libstagefright", - "libdatasource", - "libutils", - ], -} diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-39623/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39623/poc.cpp deleted file mode 100644 index d9e38baa633..00000000000 --- a/hostsidetests/securitybulletin/securityPatch/CVE-2021-39623/poc.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "../includes/common.h" -#include <datasource/DataSourceFactory.h> -#include <dlfcn.h> -#include <gui/SurfaceComposerClient.h> -#include <media/IMediaHTTPService.h> -#include <media/stagefright/InterfaceUtils.h> -#include <media/stagefright/MediaCodecList.h> -#include <media/stagefright/MediaExtractorFactory.h> -#include <media/stagefright/SimpleDecodingSource.h> -#include <sys/mman.h> - -typedef void *(*mmap_t)(void *, size_t, int, int, int, off_t); -mmap_t real_mmap = nullptr; - -using namespace android; - -bool testInProgress = false; -constexpr size_t kTargetBufferSize = 32768; -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 *mmap(void *addr, size_t length, int prot, int flags, int fd, - off_t offset) { - real_mmap = (mmap_t)dlsym(RTLD_NEXT, "mmap"); - if (!real_mmap) { - exit(EXIT_FAILURE); - } - if (length == kTargetBufferSize) { - char *tmp_ptr = (char *)real_mmap(addr, length + PAGE_SIZE, prot, - flags | MAP_ANONYMOUS, -1, offset); - mprotect(tmp_ptr + length, PAGE_SIZE, PROT_NONE); - return tmp_ptr; - } - return real_mmap(addr, length, prot, flags, fd, offset); -} - -int main(int argc, char **argv) { - FAIL_CHECK(argc > 1); - sigemptyset(&new_action.sa_mask); - new_action.sa_flags = SA_SIGINFO; - new_action.sa_sigaction = sigsegv_handler; - sigaction(SIGSEGV, &new_action, &old_action); - - sp<DataSource> dataSource = DataSourceFactory::getInstance()->CreateFromURI( - nullptr /* httpService */, argv[1]); - FAIL_CHECK(dataSource); - - sp<IMediaExtractor> extractor = MediaExtractorFactory::Create(dataSource); - FAIL_CHECK(extractor); - - sp<MediaSource> mediaSource = - CreateMediaSourceFromIMediaSource(extractor->getTrack(0)); - FAIL_CHECK(mediaSource); - - sp<MediaSource> rawSource = SimpleDecodingSource::Create( - mediaSource, MediaCodecList::kPreferSoftwareCodecs, nullptr, nullptr, - false); - FAIL_CHECK(rawSource); - - status_t err = rawSource->start(); - FAIL_CHECK(err == OK); - - MediaSource::ReadOptions options = {}; - MediaBufferBase *buffer = nullptr; - - testInProgress = true; - rawSource->read(&buffer, &options); - testInProgress = false; - if (buffer) { - buffer->release(); - buffer = nullptr; - } - options.clearSeekTo(); - options.setSeekTo(0); - rawSource->stop(); - 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 95c90d4ec4b..5532e4602a4 100644 --- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0954.java +++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0954.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 The Android Open Source Project + * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,39 +16,43 @@ package android.security.cts; -import static org.junit.Assume.assumeNoException; - +import android.platform.test.annotations.AppModeFull; import android.platform.test.annotations.AsbSecurityTest; -import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase; import com.android.tradefed.device.ITestDevice; import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; +import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; +import org.junit.Assert; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(DeviceJUnit4ClassRunner.class) -public class CVE_2021_0954 extends StsExtraBusinessLogicHostTestBase { - private static final String TEST_PKG = "android.security.cts.CVE_2021_0954"; +public class CVE_2021_0954 extends BaseHostJUnit4Test { + private static final String TEST_PKG = "android.security.cts.cve_2021_0954"; + private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest"; + private static final String TEST_APP = "CVE-2021-0954.apk"; + private ITestDevice device; + + @Before + public void setUp() throws Exception { + device = getDevice(); + uninstallPackage(device, TEST_PKG); + + /* Wake up the screen */ + AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device); + AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device); + AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device); + } + @AppModeFull @AsbSecurityTest(cveBugId = 143559931) @Test public void testPocCVE_2021_0954() throws Exception { - try { - ITestDevice device = getDevice(); - uninstallPackage(device, TEST_PKG); - - /* Wake up the screen */ - AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device); - AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device); - AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device); - - installPackage("CVE-2021-0954.apk"); - AdbUtils.runCommandLine( - "pm grant " + TEST_PKG + " android.permission.SYSTEM_ALERT_WINDOW", device); - runDeviceTests(TEST_PKG, TEST_PKG + "." + "DeviceTest", "testOverlayButtonPresence"); - } catch (Exception e) { - assumeNoException(e); - } + installPackage(TEST_APP); + AdbUtils.runCommandLine("pm grant " + TEST_PKG + " android.permission.SYSTEM_ALERT_WINDOW", + device); + runDeviceTests(TEST_PKG, TEST_CLASS, "testVulnerableActivityPresence"); } } diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39623.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39623.java deleted file mode 100644 index 9ab3f08f1e9..00000000000 --- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39623.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.security.cts; - -import android.platform.test.annotations.AsbSecurityTest; - -import com.android.compatibility.common.util.CrashUtils; -import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern; -import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.Arrays; - -@RunWith(DeviceJUnit4ClassRunner.class) -public class CVE_2021_39623 extends SecurityTestCase { - - /** - * b/194105348 - * Vulnerability Behaviour: SIGSEGV in self - * Vulnerable Library: libstagefright (As per AOSP code) - * Vulnerable Function: doRead (As per AOSP code) - */ - @AsbSecurityTest(cveBugId = 194105348) - @Test - public void testPocCVE_2021_39623() throws Exception { - String binaryName = "CVE-2021-39623"; - AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice()); - testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName) - .setBacktraceIncludes(new BacktraceFilterPattern("libstagefright", - "android::SimpleDecodingSource::doRead")); - String signals[] = {CrashUtils.SIGSEGV}; - testConfig.config.setSignals(signals); - testConfig.inputFilesDestination = AdbUtils.TMP_PATH; - String inputFiles[] = {"cve_2021_39623.ogg"}; - testConfig.inputFiles = Arrays.asList(inputFiles); - testConfig.arguments = AdbUtils.TMP_PATH + inputFiles[0]; - AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig); - } -} diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20348.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20348.java deleted file mode 100644 index 0f66dfdd87c..00000000000 --- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20348.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.security.cts; - -import static org.junit.Assume.assumeNoException; - -import android.platform.test.annotations.AsbSecurityTest; - -import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase; -import com.android.tradefed.device.ITestDevice; -import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; - -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(DeviceJUnit4ClassRunner.class) -public class CVE_2022_20348 extends StsExtraBusinessLogicHostTestBase { - static final String TEST_PKG = "android.security.cts.CVE_2022_20348"; - public static final String TEST_DEVICE_ADMIN_RECEIVER = ".PocDeviceAdminReceiver"; - - @AsbSecurityTest(cveBugId = 228315529) - @Test - public void testPocCVE_2022_20348() throws Exception { - try { - ITestDevice device = getDevice(); - - /* Wake up the screen */ - AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device); - AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device); - AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device); - - /* Install the test application */ - installPackage("CVE-2022-20348.apk"); - - /* Set Device Admin Component */ - AdbUtils.runCommandLine( - "dpm set-device-owner '" + TEST_PKG + "/" + TEST_DEVICE_ADMIN_RECEIVER + "'", - device); - - /* Run the test "testWifiScanningDisallowed" */ - runDeviceTests(TEST_PKG, TEST_PKG + ".DeviceTest", "testWifiScanningDisallowed"); - } catch (Exception e) { - assumeNoException(e); - } - } -} diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20353.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20353.java deleted file mode 100644 index e661b4ff4a1..00000000000 --- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20353.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.security.cts; - -import static org.junit.Assume.assumeNoException; - -import android.platform.test.annotations.AsbSecurityTest; - -import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase; -import com.android.tradefed.device.ITestDevice; -import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; - -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(DeviceJUnit4ClassRunner.class) -public class CVE_2022_20353 extends StsExtraBusinessLogicHostTestBase { - - @AsbSecurityTest(cveBugId = 221041256) - @Test - public void testPocCVE_2022_20353() { - try { - final String testPkg = "android.security.cts.CVE_2022_20353"; - ITestDevice device = getDevice(); - - AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device); - AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device); - AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device); - - // to generate NOTICE.html if not already present - AdbUtils.runCommandLine("am start -a android.settings.LICENSE", device); - - installPackage("CVE-2022-20353.apk"); - - runDeviceTests(testPkg, testPkg + ".DeviceTest", "testDefaultRingtonePreference"); - } catch (Exception e) { - assumeNoException(e); - } - } -} diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_22082.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_22082.java deleted file mode 100644 index e71a1f33eaf..00000000000 --- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_22082.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.security.cts; - -import static org.junit.Assume.*; - -import android.platform.test.annotations.AsbSecurityTest; -import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(DeviceJUnit4ClassRunner.class) -public class CVE_2022_22082 extends SecurityTestCase { - - /** - * CVE-2022-22082 - */ - @AsbSecurityTest(cveBugId = 223211217) - @Test - public void testPocCVE_2022_22082() throws Exception { - /* - * Non StageFright test. - */ - safeReboot(); - AdbUtils.pushResource("/cve_2022_22082.dsf", "/sdcard/cve_2022_22082.dsf", getDevice()); - AdbUtils.runCommandLine("logcat -c", getDevice()); - AdbUtils.runCommandLine( - "am start -a android.intent.action.VIEW -t audio/dsf -d file:///sdcard/cve_2022_22082.dsf", - getDevice()); - Thread.sleep(10000); - AdbUtils.assertNoCrashes(getDevice(), "media.extractor"); - } -} diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/Android.bp index 59350cf546f..aa9f71f574b 100644 --- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/Android.bp +++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/Android.bp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 The Android Open Source Project + * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,10 +18,10 @@ android_test_helper_app { name: "CVE-2021-0954", defaults: ["cts_support_defaults"], - srcs: [ - "src/**/*.java" - ], + srcs: ["src/**/*.java"], test_suites: [ + "cts", + "vts10", "sts", ], static_libs: [ diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/AndroidManifest.xml index 75299c4ddfe..a7e0218c422 100644 --- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/AndroidManifest.xml +++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/AndroidManifest.xml @@ -1,5 +1,5 @@ <!-- - Copyright 2022 The Android Open Source Project + Copyright 2021 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -13,19 +13,25 @@ See the License for the specific language governing permissions and limitations under the License. --> - <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" - package="android.security.cts.CVE_2021_0954" + package="android.security.cts.cve_2021_0954" android:versionCode="1" android:versionName="1.0"> + <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> - <application> + + <application + android:allowBackup="true" + android:label="CVE_2021_0954" + android:supportsRtl="true"> + <uses-library android:name="android.test.runner" /> <service android:name=".PocService" android:enabled="true" - android:exported="true" /> + android:exported="false" /> </application> + <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" - android:targetPackage="android.security.cts.CVE_2021_0954" /> + android:targetPackage="android.security.cts.cve_2021_0954" /> </manifest> diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/integers.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/integers.xml deleted file mode 100644 index 363df0001d7..00000000000 --- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/integers.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright 2022 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - --> - -<resources> - <integer name="assumptionFailure">-1</integer> - <integer name="noAssumptionFailure">0</integer> -</resources> diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/strings.xml deleted file mode 100644 index 7c4d959b70f..00000000000 --- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/strings.xml +++ /dev/null @@ -1,38 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2022 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<resources> - <string name="canNotDrawOverlaysMsg">The application cannot draw overlays</string> - <string name="defaultSemaphoreMsg">Could not get message key in shared preferences</string> - <string name="cmdDumpsysActivity">dumpsys activity %1$s</string> - <string name="empty"></string> - <string name="overlayErrorMessage">Device is vulnerable to b/143559931 hence any app with - "SYSTEM_ALERT_WINDOW can overlay the %1$s screen</string> - <string name="mResumedTrue">mResumed=true</string> - <string name="messageKey">message</string> - <string name="overlayButtonText">OverlayButton</string> - <string name="overlayUiScreenError">Overlay UI did not appear on the screen</string> - <string name="resultKey">result</string> - <string name="sharedPreferences">CVE_2021_0954_prefs</string> - <string name="timedOutPocActivity">Timed out waiting on a result from PocActivity</string> - <string name="vulClass">com.android.internal.app.ResolverActivity</string> - <string name="vulClassAuto">com.android.car.activityresolver.CarResolverActivity</string> - <string name="vulPkg">android</string> - <string name="vulPkgAuto">com.android.car.activityresolver</string> - <string name="vulActivityNotRunningError">The %1$s is not currently running on the device - </string> -</resources> diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/DeviceTest.java index 9a94ef953c1..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 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 The Android Open Source Project + * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,20 +14,17 @@ * limitations under the License. */ -package android.security.cts.CVE_2021_0954; +package android.security.cts.cve_2021_0954; import static androidx.test.core.app.ApplicationProvider.getApplicationContext; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; - -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assume.assumeNoException; -import static org.junit.Assume.assumeTrue; +import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; -import android.content.SharedPreferences.OnSharedPreferenceChangeListener; -import android.content.pm.PackageManager; import android.provider.Settings; import androidx.test.runner.AndroidJUnit4; @@ -35,107 +32,90 @@ import androidx.test.uiautomator.By; import androidx.test.uiautomator.UiDevice; import androidx.test.uiautomator.Until; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; +import java.io.IOException; import java.util.regex.Pattern; @RunWith(AndroidJUnit4.class) public class DeviceTest { - private Context mContext = getApplicationContext(); - private static final int TIMEOUT_MS = 10000; - - private boolean hasFeature(String feature) { - return mContext.getPackageManager().hasSystemFeature(feature); + private static final String TEST_PKG = "android.security.cts.cve_2021_0954"; + private static final String TEST_VULNERABLE_PKG = "android"; + private static final String TEST_VULNERABLE_ACTIVITY = + "com.android.internal.app.ResolverActivity"; + private static final int LAUNCH_TIMEOUT_MS = 20000; + private static final String vulnerableActivityName = "ResolverActivity"; + private UiDevice mDevice; + String activityDump = ""; + + private void startOverlayService() { + Context context = getApplicationContext(); + assertNotNull(context); + Intent intent = new Intent(context, PocService.class); + assertNotNull(intent); + + if (Settings.canDrawOverlays(getApplicationContext())) { + context.startService(intent); + } else { + try { + context.startService(intent); + } catch (Exception e) { + throw new RuntimeException("Unable to start the overlay service", e); + } + } } - private boolean isAuto() { - return hasFeature(PackageManager.FEATURE_AUTOMOTIVE); + public void startVulnerableActivity() { + Context context = getApplicationContext(); + Intent intent = new Intent(); + intent.setClassName(TEST_VULNERABLE_PKG, TEST_VULNERABLE_ACTIVITY); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + try { + context.startActivity(intent); + } catch (ActivityNotFoundException e) { + assumeNoException("Activity not found on device", e); + } } - String getStringRes(int key) { - return mContext.getResources().getString(key); - } + @Before + public void setUp() throws Exception { + mDevice = UiDevice.getInstance(getInstrumentation()); - String getStringResWithArg(int key, String arg) { - return mContext.getResources().getString(key, arg); - } + /* Start the vulnerable activity */ + startVulnerableActivity(); + if (!mDevice.wait(Until.hasObject(By.res("android:id/contentPanel") + .clazz("android.widget.ScrollView").pkg("android")), LAUNCH_TIMEOUT_MS)) { + return; + } - int getIntegerRes(int key) { - return mContext.getResources().getInteger(key); + /* Start the overlay service */ + startOverlayService(); } @Test - public void testOverlayButtonPresence() { - try { - UiDevice device = UiDevice.getInstance(getInstrumentation()); - - /* Start the overlay service */ - assumeTrue(getStringRes(R.string.canNotDrawOverlaysMsg), - Settings.canDrawOverlays(mContext)); - Intent intent = new Intent(mContext, PocService.class); - mContext.startService(intent); - - /* Wait for a result from overlay service */ - SharedPreferences sharedPrefs = mContext.getSharedPreferences( - getStringRes(R.string.sharedPreferences), Context.MODE_PRIVATE); - final Semaphore preferenceChanged = new Semaphore(0); - OnSharedPreferenceChangeListener listener = new OnSharedPreferenceChangeListener() { - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, - String key) { - if (key.equals(getStringRes(R.string.resultKey))) { - preferenceChanged.release(); - } - } - }; - sharedPrefs.registerOnSharedPreferenceChangeListener(listener); - assumeTrue(preferenceChanged.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS)); - int result = sharedPrefs.getInt(getStringRes(R.string.resultKey), - getIntegerRes(R.integer.assumptionFailure)); - String message = sharedPrefs.getString(getStringRes(R.string.messageKey), - getStringRes(R.string.defaultSemaphoreMsg)); - assumeTrue(message, result != getIntegerRes(R.integer.assumptionFailure)); - - /* Wait for the UI of overlay window to appear */ - Pattern overlayTextPattern = Pattern.compile( - mContext.getString(R.string.overlayButtonText), Pattern.CASE_INSENSITIVE); - assumeTrue(mContext.getString(R.string.overlayUiScreenError), - device.wait(Until.hasObject(By.text(overlayTextPattern)), TIMEOUT_MS)); - - /* Start the vulnerable activity */ - intent = new Intent(); - String vulActivity = getStringRes(R.string.vulClass); - String vulPkg = getStringRes(R.string.vulPkg); - if (isAuto()) { - vulActivity = getStringRes(R.string.vulClassAuto); - vulPkg = getStringRes(R.string.vulPkgAuto); - } - intent.setClassName(vulPkg, vulActivity); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - mContext.startActivity(intent); - - /* Wait until the object of overlay window is gone */ - boolean overlayDisallowed = - device.wait(Until.gone(By.pkg(mContext.getPackageName())), TIMEOUT_MS); - - /* - * Check if the currently running activity is the vulnerable activity, if not abort the - * test - */ - String activityDump = device.executeShellCommand( - getStringResWithArg(R.string.cmdDumpsysActivity, vulActivity)); - Pattern activityPattern = Pattern.compile(getStringRes(R.string.mResumedTrue)); - assumeTrue(getStringRes(R.string.vulActivityNotRunningError), - activityPattern.matcher(activityDump).find()); + public void testVulnerableActivityPresence() { + Pattern overlayTextPattern = Pattern.compile("OverlayButton", Pattern.CASE_INSENSITIVE); + if (!mDevice.wait(Until.hasObject(By.text(overlayTextPattern)), LAUNCH_TIMEOUT_MS)) { + return; + } - /* Failing the test as fix is not present */ - assertTrue(getStringResWithArg(R.string.overlayErrorMessage, vulActivity), - overlayDisallowed); - } catch (Exception e) { - assumeNoException(e); + /* + * Check if the currently running activity is the vulnerable activity, if not abort the test + */ + try { + activityDump = mDevice.executeShellCommand("dumpsys activity"); + } catch (IOException e) { + throw new RuntimeException("Could not execute dumpsys activity command"); + } + Pattern activityPattern = + Pattern.compile("mResumedActivity.*" + vulnerableActivityName + ".*\n"); + if (!activityPattern.matcher(activityDump).find()) { + return; } + String message = "Device is vulnerable to b/143559931 hence any app with " + + "SYSTEM_ALERT_WINDOW can overlay the ResolverActivity screen"; + assertNull(message, mDevice.findObject(By.text(overlayTextPattern))); } } diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/PocService.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/PocService.java index 79270baa65e..82b78a2beba 100644 --- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/PocService.java +++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/PocService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 The Android Open Source Project + * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,65 +14,47 @@ * limitations under the License. */ -package android.security.cts.CVE_2021_0954; +package android.security.cts.cve_2021_0954; import android.app.Service; -import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; import android.content.res.Resources; import android.graphics.PixelFormat; +import android.os.Handler; import android.os.IBinder; +import android.provider.Settings; import android.view.Gravity; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import android.widget.Button; public class PocService extends Service { - Button mButton; - WindowManager mWindowManager; + public static Button mButton; + private WindowManager mWindowManager; + private WindowManager.LayoutParams mLayoutParams; - private int getScreenWidth() { + private static int getScreenWidth() { return Resources.getSystem().getDisplayMetrics().widthPixels; } - private int getScreenHeight() { + private static int getScreenHeight() { return Resources.getSystem().getDisplayMetrics().heightPixels; } - String getStringRes(int key) { - return getResources().getString(key); - } - - int getIntegerRes(int key) { - return getResources().getInteger(key); - } - @Override public void onCreate() { - try { - super.onCreate(); - mWindowManager = getSystemService(WindowManager.class); - LayoutParams layoutParams = new LayoutParams(); - layoutParams.type = LayoutParams.TYPE_APPLICATION_OVERLAY; - layoutParams.flags = - LayoutParams.FLAG_NOT_TOUCH_MODAL | LayoutParams.FLAG_NOT_FOCUSABLE; - layoutParams.format = PixelFormat.OPAQUE; - layoutParams.gravity = Gravity.LEFT | Gravity.TOP; - layoutParams.width = getScreenWidth(); - layoutParams.height = getScreenHeight(); - layoutParams.x = getScreenWidth() / 2; - layoutParams.y = getScreenHeight() / 2; - - /* Show the floating window */ - mButton = new Button(this); - mButton.setText(getString(R.string.overlayButtonText)); - mWindowManager.addView(mButton, layoutParams); - } catch (Exception e) { - sendTestResult(getIntegerRes(R.integer.assumptionFailure), e.getMessage()); - return; - } - sendTestResult(getIntegerRes(R.integer.noAssumptionFailure), getStringRes(R.string.empty)); + super.onCreate(); + mWindowManager = getSystemService(WindowManager.class); + mLayoutParams = new WindowManager.LayoutParams(); + mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; + mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL + | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; + mLayoutParams.format = PixelFormat.OPAQUE; + mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP; + mLayoutParams.width = getScreenWidth(); + mLayoutParams.height = getScreenHeight(); + mLayoutParams.x = getScreenWidth() / 2; + mLayoutParams.y = getScreenHeight() / 2; } @Override @@ -81,27 +63,31 @@ public class PocService extends Service { } @Override + public int onStartCommand(Intent intent, int flags, int startId) { + showFloatingWindow(); + return super.onStartCommand(intent, flags, startId); + } + + @Override public void onDestroy() { - try { - if (mWindowManager != null && mButton != null) { - mWindowManager.removeView(mButton); - } - super.onDestroy(); - } catch (Exception e) { - sendTestResult(getIntegerRes(R.integer.assumptionFailure), e.getMessage()); + if (mWindowManager != null && mButton != null) { + mWindowManager.removeView(mButton); } + super.onDestroy(); } - private void sendTestResult(int result, String message) { - try { - SharedPreferences sh = getSharedPreferences(getStringRes(R.string.sharedPreferences), - Context.MODE_PRIVATE); - SharedPreferences.Editor edit = sh.edit(); - edit.putInt(getStringRes(R.string.resultKey), result); - edit.putString(getStringRes(R.string.messageKey), message); - edit.commit(); - } catch (Exception e) { - // ignore the exception + private void showFloatingWindow() { + if (Settings.canDrawOverlays(this)) { + mButton = new Button(getApplicationContext()); + mButton.setText("OverlayButton"); + mWindowManager.addView(mButton, mLayoutParams); + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + onDestroy(); + } + }, 60000); // one minute + mButton.setTag(mButton.getVisibility()); } } } diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/Android.bp index 2f87b9cdf31..d3e2302d280 100644 --- a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/Android.bp +++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/Android.bp @@ -30,10 +30,10 @@ android_test_helper_app { test_suites: [ "sts", ], + sdk_version: "current", static_libs: [ "androidx.test.core", "androidx.test.rules", "androidx.test.uiautomator_uiautomator", ], - platform_apis: true, } diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/AndroidManifest.xml index 74e263c53d4..f0978251006 100644 --- a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/AndroidManifest.xml +++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/AndroidManifest.xml @@ -22,8 +22,12 @@ <uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/> <uses-permission android:name="android.permission.BLUETOOTH_SCAN"/> - <application> - <activity android:name=".PocActivity" + <application + android:testOnly="true" + android:label="CVE-2021-39626" + android:supportsRtl="true"> + <activity + android:name=".PocActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> @@ -31,6 +35,7 @@ </intent-filter> </activity> </application> + <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" android:targetPackage="android.security.cts.CVE_2021_39626" /> diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/res/values/integers.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/res/values/integers.xml deleted file mode 100644 index d5ae7443184..00000000000 --- a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/res/values/integers.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright 2022 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - --> - -<resources> - <integer name="assumptionFailure">-1</integer> - <integer name="pass">0</integer> - <integer name="enabled">1</integer> - <integer name="disabled">2</integer> -</resources> diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/res/values/strings.xml deleted file mode 100644 index e6f53e7ccc7..00000000000 --- a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/res/values/strings.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright 2022 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - --> - -<resources> - <string name="allowButtonResName">android:id/button1</string> - <string name="btAction">btAction</string> - <string name="className">.Settings$ConnectedDeviceDashboardActivity</string> - <string name="defaultSemaphoreMsg">Could not get message key in shared preferences</string> - <string name="defaultSettingsPkg">com.android.settings</string> - <string name="failMessage">Vulnerable to b/194695497 !!</string> - <string name="messageKey">message</string> - <string name="resultKey">result</string> - <string name="sharedPreferences">CVE_2021_39626_prefs</string> -</resources> diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/DeviceTest.java index 6bb8d166080..cd245400fc9 100644 --- a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/DeviceTest.java +++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/DeviceTest.java @@ -18,15 +18,14 @@ package android.security.cts.CVE_2021_39626; import static org.junit.Assert.assertFalse; import static org.junit.Assume.assumeNoException; +import static org.junit.Assume.assumeNotNull; import static org.junit.Assume.assumeTrue; import android.bluetooth.BluetoothAdapter; import android.content.ComponentName; import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; -import android.content.SharedPreferences.OnSharedPreferenceChangeListener; -import android.content.res.Resources; +import android.content.pm.PackageManager; import android.provider.Settings; import androidx.test.InstrumentationRegistry; @@ -35,121 +34,69 @@ import androidx.test.uiautomator.By; import androidx.test.uiautomator.UiDevice; import androidx.test.uiautomator.Until; -import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; - @RunWith(AndroidJUnit4.class) public class DeviceTest { - static final int TIMEOUT = 10000; - boolean mBtState = false; - BluetoothAdapter mBtAdapter; - Context mContext; - OnSharedPreferenceChangeListener mListener; - Resources mResources; - SharedPreferences mSharedPrefs; - Semaphore mPreferenceChanged; - UiDevice mDevice; + private static final int TIMEOUT = 5000; + private static Context context; - private String getSettingsPkgName() { + private static String getSettingsPkgName() { Intent settingsIntent = new Intent(Settings.ACTION_SETTINGS); ComponentName settingsComponent = - settingsIntent.resolveActivity(mContext.getPackageManager()); + settingsIntent.resolveActivity(context.getPackageManager()); String pkgName = settingsComponent != null ? settingsComponent.getPackageName() - : mContext.getString(R.string.defaultSettingsPkg); + : "com.android.settings"; + assumeNotNull(pkgName); return pkgName; } - @After - public void tearDown() { + private void openApplication(String applicationName) { + Intent intent = context.getPackageManager().getLaunchIntentForPackage(applicationName); + assumeNotNull(intent); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); try { - // Disable bluetooth if it was OFF before the test - if (!mBtState) { - Intent intent = new Intent(mContext, PocActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.putExtra(mContext.getString(R.string.btAction), - BluetoothAdapter.ACTION_REQUEST_DISABLE); - mContext.startActivity(intent); - } - mPreferenceChanged = new Semaphore(0); - mPreferenceChanged.tryAcquire(TIMEOUT, TimeUnit.MILLISECONDS); - int result = mSharedPrefs.getInt(mResources.getString(R.string.resultKey), - mResources.getInteger(R.integer.assumptionFailure)); - String message = mSharedPrefs.getString(mResources.getString(R.string.messageKey), - mResources.getString(R.string.defaultSemaphoreMsg)); - - // Go to home screen - mDevice.pressHome(); + context.startActivity(intent); } catch (Exception e) { - // ignore the exception + assumeNoException(e); } } @Test public void testBtDiscoverable() { - try { - // Initialize UiDevice instance - mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); - mContext = InstrumentationRegistry.getInstrumentation().getContext(); - mBtAdapter = BluetoothAdapter.getDefaultAdapter(); - - // Save the state of bluetooth adapter to reset after the test - mBtState = mBtAdapter.isEnabled(); - - // If bluetooth is disabled, enable it and wait for start activity to complete - Intent intent = new Intent(mContext, PocActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.putExtra(mContext.getString(R.string.btAction), - BluetoothAdapter.ACTION_REQUEST_ENABLE); - mContext.startActivity(intent); - mResources = mContext.getResources(); - - mSharedPrefs = mContext.getSharedPreferences( - mResources.getString(R.string.sharedPreferences), Context.MODE_APPEND); - mPreferenceChanged = new Semaphore(0); - mListener = new OnSharedPreferenceChangeListener() { - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, - String key) { - if (key.equals(mResources.getString(R.string.resultKey))) { - mPreferenceChanged.release(); - } - } - }; - mSharedPrefs.registerOnSharedPreferenceChangeListener(mListener); - mPreferenceChanged.tryAcquire(TIMEOUT, TimeUnit.MILLISECONDS); - - int result = mSharedPrefs.getInt(mResources.getString(R.string.resultKey), - mResources.getInteger(R.integer.assumptionFailure)); - String message = mSharedPrefs.getString(mResources.getString(R.string.messageKey), - mResources.getString(R.string.defaultSemaphoreMsg)); - assumeTrue(message, result != mResources.getInteger(R.integer.assumptionFailure)); - - // Checking if bluetooth is enabled. The test requires bluetooth to be enabled, - // assumption failing the test if it's not enabled - assumeTrue(mBtAdapter.isEnabled()); - - // Launch bluetooth settings which is supposed to set scan mode to - // SCAN_MODE_CONNECTABLE_DISCOVERABLE if vulnerability is active - intent = new Intent(); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - String settingsPkg = getSettingsPkgName(); - intent.setClassName(settingsPkg, settingsPkg + mContext.getString(R.string.className)); - mContext.startActivity(intent); + // Initialize UiDevice instance + UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); + context = InstrumentationRegistry.getInstrumentation().getContext(); + BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter(); + assumeNotNull(btAdapter); + + // Save the state of bluetooth adapter to reset after the test + boolean btState = btAdapter.isEnabled(); + if (!btState) { + // If bluetooth is disabled, enable it and wait for adapter startup to complete + assumeTrue(btAdapter.enable()); + try { + Thread.sleep(TIMEOUT); + } catch (Exception e) { + assumeNoException(e); + } + } + assumeTrue(btAdapter.isEnabled()); - assumeTrue(mDevice.wait(Until.hasObject(By.pkg(settingsPkg)), TIMEOUT)); + // Launch the PoC application and ensure that it launches bluetooth settings + openApplication(context.getPackageName()); + assumeTrue(device.wait(Until.hasObject(By.pkg(getSettingsPkgName())), TIMEOUT)); - boolean isBtDiscoverable = false; - isBtDiscoverable = - (mBtAdapter.getScanMode() == mBtAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE); + boolean isBtDiscoverable = + (btAdapter.getScanMode() == btAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE); - // The test fails if bluetooth is made discoverable through PoC - assertFalse(mContext.getString(R.string.failMessage), isBtDiscoverable); - } catch (Exception e) { - assumeNoException(e); + // Disable bluetooth if it was OFF before the test + if (!btState) { + btAdapter.disable(); } + + // The test fails if bluetooth is made discoverable through PoC + assertFalse("Vulnerable to b/194695497 !!", isBtDiscoverable); } } diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/PocActivity.java index 9a43cd19f31..d4425ff0eb3 100644 --- a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/PocActivity.java +++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/PocActivity.java @@ -16,88 +16,24 @@ package android.security.cts.CVE_2021_39626; +import static org.junit.Assume.assumeNoException; + import android.app.Activity; -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothManager; -import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; import android.os.Bundle; - -import androidx.annotation.IntegerRes; -import androidx.test.InstrumentationRegistry; -import androidx.test.uiautomator.By; -import androidx.test.uiautomator.UiDevice; -import androidx.test.uiautomator.UiObject2; -import androidx.test.uiautomator.Until; +import android.provider.Settings; public class PocActivity extends Activity { - private static final int TIMEOUT = 5000; - private static final int REQUEST_ENABLE_BT = 1; - private static final int REQUEST_DISABLE_BT = 2; - - int getInteger(@IntegerRes int resId) { - return getResources().getInteger(resId); - } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + Intent intent = new Intent(); + intent.setAction(Settings.ACTION_BLUETOOTH_SETTINGS); try { - String action = getIntent().getStringExtra(getString(R.string.btAction)); - UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); - BluetoothManager bluetoothManager = getSystemService(BluetoothManager.class); - BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter(); - int code = REQUEST_ENABLE_BT; - if (action.equals(BluetoothAdapter.ACTION_REQUEST_DISABLE)) { - code = REQUEST_DISABLE_BT; - } - - if ((action.equals(BluetoothAdapter.ACTION_REQUEST_ENABLE) - && !bluetoothAdapter.isEnabled()) - || (action.equals(BluetoothAdapter.ACTION_REQUEST_DISABLE) - && bluetoothAdapter.isEnabled())) { - Intent enableBtIntent = new Intent(action); - startActivityForResult(enableBtIntent, code); - - // Wait for the activity to appear and the allow button - device.wait(Until.hasObject(By.res(getString(R.string.allowButtonResName))), - TIMEOUT); - - // Click on the allow button - UiObject2 object = - device.findObject(By.res(getString(R.string.allowButtonResName))); - object.click(); - } else { - sendTestResult(getInteger(R.integer.pass), ""); - finish(); - return; - } + startActivity(intent); } catch (Exception e) { - sendTestResult(getInteger(R.integer.assumptionFailure), e.getMessage()); - return; - } - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == REQUEST_ENABLE_BT && resultCode == Activity.RESULT_OK) { - finish(); - sendTestResult(getInteger(R.integer.enabled), ""); - } else if (requestCode == REQUEST_DISABLE_BT && resultCode == Activity.RESULT_OK) { - finish(); - sendTestResult(getInteger(R.integer.disabled), ""); - } - } - - private void sendTestResult(int result, String message) { - SharedPreferences sh = - getSharedPreferences(getString(R.string.sharedPreferences), Context.MODE_PRIVATE); - if (sh != null) { - SharedPreferences.Editor edit = sh.edit(); - edit.putInt(getString(R.string.resultKey), result); - edit.putString(getString(R.string.messageKey), message); - edit.commit(); + assumeNoException(e); } } } diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/Android.bp deleted file mode 100644 index b07e9f27603..00000000000 --- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/Android.bp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package { - default_applicable_licenses: ["Android-Apache-2.0"], -} - -android_test_helper_app { - name: "CVE-2022-20348", - defaults: [ - "cts_support_defaults", - ], - srcs: [ - "src/**/*.java", - ], - test_suites: [ - "sts", - ], - static_libs: [ - "androidx.test.core", - "androidx.test.rules", - "androidx.test.uiautomator_uiautomator", - ], - sdk_version: "current", -} diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/AndroidManifest.xml deleted file mode 100644 index ec6a7752482..00000000000 --- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/AndroidManifest.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright 2022 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - --> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="android.security.cts.CVE_2022_20348" - android:versionCode="1" - android:versionName="1.0"> - <application> - <receiver android:name=".PocDeviceAdminReceiver" - android:permission="android.permission.BIND_DEVICE_ADMIN" - android:exported="true"> - <meta-data android:name="android.app.device_admin" - android:resource="@xml/device_policies" /> - <intent-filter> - <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" /> - </intent-filter> - </receiver> - </application> - - <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" - android:targetPackage="android.security.cts.CVE_2022_20348" /> -</manifest> diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/res/values/strings.xml deleted file mode 100644 index e79968d7bb8..00000000000 --- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/res/values/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright 2022 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - --> -<resources> - <string name="wifiScanningPattern">.*wi.fi scanning.*</string> - <string name="wifiScanningTimedOut">Timed out waiting on the text \'Wi-fi scanning\' to appear - </string> - <string name="failMsg">Device is vulnerable to b/228315529 !!</string> - <string name="locationIntentAction">android.settings.LOCATION_SCANNING_SETTINGS</string> - <string name="resWifiScanning">android:id/title</string> - <string name="setUserRestrictionFailed">Failed to set user restriction - UserManager.DISALLOW_CONFIG_LOCATION</string> -</resources> diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/res/xml/device_policies.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/res/xml/device_policies.xml deleted file mode 100644 index 65ce601d65f..00000000000 --- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/res/xml/device_policies.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright 2022 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - --> -<device-admin xmlns:android="http://schemas.android.com/apk/res/android"> - <uses-policies> - </uses-policies> -</device-admin> diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/src/android/security/cts/CVE_2022_20348/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/src/android/security/cts/CVE_2022_20348/DeviceTest.java deleted file mode 100644 index 9cdb35d6704..00000000000 --- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/src/android/security/cts/CVE_2022_20348/DeviceTest.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.security.cts.CVE_2022_20348; - -import static androidx.test.core.app.ApplicationProvider.getApplicationContext; -import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assume.assumeNoException; -import static org.junit.Assume.assumeTrue; - -import android.app.admin.DevicePolicyManager; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.os.UserManager; - -import androidx.test.runner.AndroidJUnit4; -import androidx.test.uiautomator.By; -import androidx.test.uiautomator.UiDevice; -import androidx.test.uiautomator.UiObject2; -import androidx.test.uiautomator.Until; - -import org.junit.After; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.regex.Pattern; - -@RunWith(AndroidJUnit4.class) -public class DeviceTest { - Context mContext; - UiDevice mDevice; - DevicePolicyManager mDevicePolicyManager; - ComponentName mComponentName; - static final String USER_RESTRICTION = UserManager.DISALLOW_CONFIG_LOCATION; - static final int UI_TIMEOUT_MS = 5000; - - String getStringRes(int key) { - return mContext.getResources().getString(key); - } - - int getIntegerRes(int key) { - return mContext.getResources().getInteger(key); - } - - @After - public void tearDown() { - try { - /* Return to home screen after test */ - mDevice.pressHome(); - - /* - * Clear user restriction "DISALLOW_CONFIG_LOCATION" set by the test and also clear the - * app as device owner. - */ - mDevicePolicyManager.clearUserRestriction(mComponentName, USER_RESTRICTION); - mDevicePolicyManager.clearDeviceOwnerApp(mContext.getPackageName()); - } catch (Exception e) { - // ignore the exception as the test is already complete - } - } - - @Test - public void testWifiScanningDisallowed() { - try { - mDevice = UiDevice.getInstance(getInstrumentation()); - mContext = getApplicationContext(); - mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class); - mComponentName = new ComponentName(PocDeviceAdminReceiver.class.getPackage().getName(), - PocDeviceAdminReceiver.class.getName()); - mDevicePolicyManager.addUserRestriction(mComponentName, USER_RESTRICTION); - UserManager userManager = mContext.getSystemService(UserManager.class); - assumeTrue(getStringRes(R.string.setUserRestrictionFailed), - userManager.getUserRestrictions().getBoolean(USER_RESTRICTION)); - - /* Start the window that contains option to toggle "Wi-Fi scanning" on/off */ - Intent intent = new Intent(getStringRes(R.string.locationIntentAction)); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - mContext.startActivity(intent); - - /* Wait for the window that contains option to toggle "Wi-Fi scanning" */ - Pattern wifiScanningPattern = Pattern - .compile(getStringRes(R.string.wifiScanningPattern), Pattern.CASE_INSENSITIVE); - boolean wifiScanningFound = mDevice.wait(Until.hasObject( - By.text(wifiScanningPattern).res(getStringRes(R.string.resWifiScanning))), - UI_TIMEOUT_MS); - assumeTrue(getStringRes(R.string.wifiScanningTimedOut), wifiScanningFound); - - /* - * Check if the toggle "Wi-Fi scanning" is enabled, it is supposed to be disabled by - * the Device Admin in presence of fix - */ - UiObject2 wifiScanningToggle = mDevice.findObject( - By.text(wifiScanningPattern).res(getStringRes(R.string.resWifiScanning))); - assertFalse(getStringRes(R.string.failMsg), wifiScanningToggle.isEnabled()); - } catch (Exception e) { - assumeNoException(e); - } - } -} diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/src/android/security/cts/CVE_2022_20348/PocDeviceAdminReceiver.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/src/android/security/cts/CVE_2022_20348/PocDeviceAdminReceiver.java deleted file mode 100644 index 129a6b52dc8..00000000000 --- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/src/android/security/cts/CVE_2022_20348/PocDeviceAdminReceiver.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.security.cts.CVE_2022_20348; - -import android.app.admin.DeviceAdminReceiver; - -public class PocDeviceAdminReceiver extends DeviceAdminReceiver { -} diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/Android.bp deleted file mode 100644 index 37d35eb74f2..00000000000 --- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/Android.bp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package { - default_applicable_licenses: ["Android-Apache-2.0"], -} - -android_test_helper_app { - name: "CVE-2022-20353", - defaults: [ - "cts_support_defaults", - ], - srcs: [ - "src/**/*.java", - ], - test_suites: [ - "sts", - ], - static_libs: [ - "androidx.test.core", - "androidx.test.rules", - "androidx.test.uiautomator_uiautomator", - ], - sdk_version: "current", -} diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/AndroidManifest.xml deleted file mode 100644 index d4129ac8823..00000000000 --- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/AndroidManifest.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright 2022 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - --> - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="android.security.cts.CVE_2022_20353"> - <application - android:label="@string/appName" - android:supportsRtl="true"> - <activity - android:name=".PocActivity" - android:exported="true"> - <intent-filter> - <action android:name="android.intent.action.RINGTONE_PICKER" /> - <category android:name="android.intent.category.DEFAULT" /> - </intent-filter> - </activity> - </application> - <instrumentation - android:name="androidx.test.runner.AndroidJUnitRunner" - android:targetPackage="android.security.cts.CVE_2022_20353" /> -</manifest> diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/res/values/integers.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/res/values/integers.xml deleted file mode 100644 index 3207c29a0bd..00000000000 --- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/res/values/integers.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright 2022 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - --> - -<resources> - <integer name="assumptionFailure">-1</integer> - <integer name="success">0</integer> - <integer name="timeoutMs">20000</integer> -</resources> diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/res/values/strings.xml deleted file mode 100644 index 27e87f65446..00000000000 --- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/res/values/strings.xml +++ /dev/null @@ -1,38 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright 2022 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - --> - -<resources> - <string name="alwaysButtonId">android:id/button_always</string> - <string name="appName">CVE-2022-20353</string> - <string name="defaultSemaphoreMsg">Could not get message key in shared preferences</string> - <string name="failureMessage"> - Device is vulnerable to b/221041256!! Privilege escalation possible in - com.android.settings.DefaultRingtonePreference - </string> - <string name="fileName">NOTICE.html</string> - <string name="getRingtoneCmd">settings get system ringtone</string> - <string name="messageKey">message</string> - <string name="noticeUri"> - content://com.android.settings.files/my_cache/NOTICE.html - </string> - <string name="resType">string</string> - <string name="resultKey">result</string> - <string name="setRingtoneCmd">settings put system ringtone</string> - <string name="sharedPreferences">sharedPreferences</string> - <string name="textResId">ringtone_title</string> - <string name="uiObjectNotFoundMsg">Unable to find UiObject with %1$s text/id</string> -</resources> diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/src/android/security/cts/CVE_2022_20353/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/src/android/security/cts/CVE_2022_20353/DeviceTest.java deleted file mode 100644 index af1f9782ab0..00000000000 --- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/src/android/security/cts/CVE_2022_20353/DeviceTest.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.security.cts.CVE_2022_20353; - -import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; -import static org.junit.Assert.assertFalse; -import static org.junit.Assume.assumeNoException; -import static org.junit.Assume.assumeTrue; - -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.SharedPreferences.OnSharedPreferenceChangeListener; -import android.content.res.Resources; -import android.provider.Settings; - -import androidx.test.runner.AndroidJUnit4; -import androidx.test.uiautomator.By; -import androidx.test.uiautomator.BySelector; -import androidx.test.uiautomator.UiDevice; -import androidx.test.uiautomator.UiScrollable; -import androidx.test.uiautomator.UiSelector; -import androidx.test.uiautomator.Until; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; - -@RunWith(AndroidJUnit4.class) -public class DeviceTest { - Resources mResources; - UiDevice mDevice; - Context mContext; - - // Wait for UiObject to appear and click on the UiObject if it is visible - private boolean clickUiObject(BySelector selector) { - boolean objectFound = - mDevice.wait(Until.hasObject(selector), mResources.getInteger(R.integer.timeoutMs)); - if (objectFound) { - mDevice.findObject(selector).click(); - } - return objectFound; - } - - @Test - public void testDefaultRingtonePreference() { - String defaultRingtone = null; - try { - mDevice = UiDevice.getInstance(getInstrumentation()); - mContext = getInstrumentation().getContext(); - mResources = mContext.getResources(); - defaultRingtone = - mDevice.executeShellCommand(mContext.getString(R.string.getRingtoneCmd)); - - Intent intent = new Intent(Settings.ACTION_SOUND_SETTINGS); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - mContext.startActivity(intent); - - String settingsPackageName = - intent.resolveActivity(mContext.getPackageManager()).getPackageName(); - Context settingsContext = mContext.createPackageContext(settingsPackageName, - Context.CONTEXT_IGNORE_SECURITY); - Resources res = settingsContext.getPackageManager() - .getResourcesForApplication(settingsPackageName); - String text = settingsContext - .getString(res.getIdentifier(mContext.getString(R.string.textResId), - mContext.getString(R.string.resType), settingsPackageName)); - // scroll until text 'Phone ringtone' is visible - UiScrollable uiScrollable = new UiScrollable(new UiSelector().scrollable(true)); - uiScrollable.scrollTextIntoView(text); - // click on 'Phone ringtone' - BySelector selector = By.text(text); - assumeTrue(mContext.getString(R.string.uiObjectNotFoundMsg, text), - clickUiObject(selector)); - // select CTS PoC app - text = mContext.getString(R.string.appName); - selector = By.text(text); - assumeTrue(mContext.getString(R.string.uiObjectNotFoundMsg, text), - clickUiObject(selector)); - // select 'Always' - String resId = mContext.getString(R.string.alwaysButtonId); - selector = By.res(resId); - assumeTrue(mContext.getString(R.string.uiObjectNotFoundMsg, resId), - clickUiObject(selector)); - - SharedPreferences sharedPrefs = mContext.getSharedPreferences( - mContext.getString(R.string.sharedPreferences), Context.MODE_APPEND); - Semaphore preferenceChanged = new Semaphore(0); - OnSharedPreferenceChangeListener sharedPrefListener = - new OnSharedPreferenceChangeListener() { - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, - String key) { - if (key.equals(mContext.getString(R.string.resultKey))) { - preferenceChanged.release(); - } - } - }; - sharedPrefs.registerOnSharedPreferenceChangeListener(sharedPrefListener); - // wait for PocActivity to complete - assumeTrue(preferenceChanged.tryAcquire(mResources.getInteger(R.integer.timeoutMs), - TimeUnit.MILLISECONDS)); - int result = sharedPrefs.getInt(mContext.getString(R.string.resultKey), - mResources.getInteger(R.integer.assumptionFailure)); - String message = sharedPrefs.getString(mContext.getString(R.string.messageKey), - mContext.getString(R.string.defaultSemaphoreMsg)); - assumeTrue(message, result != mResources.getInteger(R.integer.assumptionFailure)); - - String ringtoneUri = ""; - boolean isVulnerable = false; - long startTime = System.currentTimeMillis(); - while ((System.currentTimeMillis() - startTime) < mResources - .getInteger(R.integer.timeoutMs)) { - ringtoneUri = - mDevice.executeShellCommand(mContext.getString(R.string.getRingtoneCmd)); - if (ringtoneUri.contains(mContext.getString(R.string.fileName))) { - isVulnerable = true; - break; - } - } - assertFalse(mContext.getString(R.string.failureMessage), isVulnerable); - } catch (Exception e) { - assumeNoException(e); - } finally { - try { - // reset ringtone to default (other than 'null') present before test - mDevice.executeShellCommand( - mContext.getString(R.string.setRingtoneCmd) + " " + defaultRingtone); - mDevice.pressHome(); - } catch (Exception e) { - // ignore exception here - } - } - } -} diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/src/android/security/cts/CVE_2022_20353/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/src/android/security/cts/CVE_2022_20353/PocActivity.java deleted file mode 100644 index 977e647d2e2..00000000000 --- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/src/android/security/cts/CVE_2022_20353/PocActivity.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.security.cts.CVE_2022_20353; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.media.RingtoneManager; -import android.net.Uri; -import android.os.Bundle; - -/* PocActivity is required in this test since it is required that CTS PoC app is selected when */ -/* choosing an app for setting default ringtone. RingtonePicker appears due to actions done in */ -/* DeviceTest. */ -public class PocActivity extends Activity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - try { - super.onCreate(savedInstanceState); - Intent intent = new Intent(); - /* set NOTICE.html file uri as EXTRA_RINGTONE_PICKED_URI which sets NOTICE.html as */ - /* default ringtone if vulnerability is present */ - intent.putExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI, - Uri.parse(getString(R.string.noticeUri))); - setResult(Activity.RESULT_OK, intent); - finish(); - sendTestResult(getResources().getInteger(R.integer.success), ""); - } catch (Exception e) { - sendTestResult(getResources().getInteger(R.integer.assumptionFailure), e.getMessage()); - } - } - - void sendTestResult(int result, String message) { - try { - SharedPreferences sh = getSharedPreferences(getString(R.string.sharedPreferences), - Context.MODE_PRIVATE); - SharedPreferences.Editor edit = sh.edit(); - edit.putInt(getString(R.string.resultKey), result); - edit.putString(getString(R.string.messageKey), message); - edit.commit(); - } catch (Exception e) { - // ignore exception here - } - } - -} diff --git a/hostsidetests/stagedinstall/app/src/com/android/tests/stagedinstall/StagedInstallTest.java b/hostsidetests/stagedinstall/app/src/com/android/tests/stagedinstall/StagedInstallTest.java index 1edc04144ed..8d5df1bb754 100644 --- a/hostsidetests/stagedinstall/app/src/com/android/tests/stagedinstall/StagedInstallTest.java +++ b/hostsidetests/stagedinstall/app/src/com/android/tests/stagedinstall/StagedInstallTest.java @@ -884,7 +884,7 @@ public class StagedInstallTest { @Test public void testFailStagingMultipleSessionsIfNoCheckPoint() throws Exception { stageSingleApk(TestApp.A1).assertSuccessful(); - int sessionId = stageSingleApk(TestApp.B1).assertFailure().getSessionId(); + int sessionId = stageSingleApk(TestApp.B1).assertSuccessful().getSessionId(); PackageInstaller.SessionInfo info = getSessionInfo(sessionId); assertThat(info).isStagedSessionFailed(); assertThat(info.getStagedSessionErrorMessage()).contains( diff --git a/hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/StagedInstallTest.java b/hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/StagedInstallTest.java index 73ceea1b960..e98eeda39c9 100644 --- a/hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/StagedInstallTest.java +++ b/hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/StagedInstallTest.java @@ -536,9 +536,6 @@ public class StagedInstallTest extends BaseHostJUnit4Test { @Test public void testFailOverlappingMultipleStagedInstall_BothSinglePackage_Apk() throws Exception { - assumeTrue("Device does not support file-system checkpoint", - mHostUtils.isCheckpointSupported()); - runPhase("testFailOverlappingMultipleStagedInstall_BothSinglePackage_Apk"); } diff --git a/hostsidetests/statsdatom/src/android/cts/statsdatom/lib/ConfigUtils.java b/hostsidetests/statsdatom/src/android/cts/statsdatom/lib/ConfigUtils.java index 7f29d44673c..be665ba4013 100644 --- a/hostsidetests/statsdatom/src/android/cts/statsdatom/lib/ConfigUtils.java +++ b/hostsidetests/statsdatom/src/android/cts/statsdatom/lib/ConfigUtils.java @@ -69,6 +69,10 @@ public final class ConfigUtils { .addAllowedLogSource("AID_SYSTEM") .addAllowedLogSource("AID_BLUETOOTH") .addAllowedLogSource("com.android.bluetooth") + // TODO(b/236681553): Remove this. + .addAllowedLogSource("com.android.bluetooth.services") + // TODO(b/236681553): Remove this. + .addAllowedLogSource("com.google.android.bluetooth.services") .addAllowedLogSource("AID_LMKD") .addAllowedLogSource("AID_MEDIA") .addAllowedLogSource("AID_RADIO") diff --git a/hostsidetests/statsdatom/src/android/cts/statsdatom/sizecompatrestartbutton/SizeCompatRestartButtonStatsTests.java b/hostsidetests/statsdatom/src/android/cts/statsdatom/sizecompatrestartbutton/SizeCompatRestartButtonStatsTests.java index 68a71355e81..a6aaebf9916 100644 --- a/hostsidetests/statsdatom/src/android/cts/statsdatom/sizecompatrestartbutton/SizeCompatRestartButtonStatsTests.java +++ b/hostsidetests/statsdatom/src/android/cts/statsdatom/sizecompatrestartbutton/SizeCompatRestartButtonStatsTests.java @@ -28,11 +28,9 @@ import com.android.os.AtomsProto.SizeCompatRestartButtonEventReported; import com.android.os.AtomsProto.SizeCompatRestartButtonEventReported.Event; import com.android.os.StatsLog; import com.android.tradefed.build.IBuildInfo; -import com.android.tradefed.device.ITestDevice; import com.android.tradefed.log.LogUtil.CLog; import com.android.tradefed.testtype.DeviceTestCase; import com.android.tradefed.testtype.IBuildReceiver; -import com.android.tradefed.util.Pair; import java.util.Arrays; import java.util.List; @@ -106,11 +104,6 @@ public class SizeCompatRestartButtonStatsTests extends DeviceTestCase implements return; } - Pair<Integer, Integer> displaySizeClosed = getDisplayRealSize(getDevice()); - if (displaySizeClosed == null) { - CLog.i("Could not determine display size while CLOSED."); - return; - } try (AutoCloseable a = DeviceUtils.withActivity(getDevice(), DeviceUtils.STATSD_ATOM_TEST_PKG, NON_RESIZEABLE_PORTRAIT_ACTIVITY, "action", "action.sleep_top")) { @@ -119,15 +112,6 @@ public class SizeCompatRestartButtonStatsTests extends DeviceTestCase implements Thread.sleep(AtomTestUtils.WAIT_TIME_LONG); } - Pair<Integer, Integer> displaySizeOpened = getDisplayRealSize(getDevice()); - if (displaySizeOpened == null) { - CLog.i("Could not determine display size while OPENED."); - return; - } - if (displaySizeClosed.equals(displaySizeOpened)) { - CLog.i("Display size has not changed."); - return; - } List<StatsLog.EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice()); assertThat(data.size()).isEqualTo(1); @@ -143,25 +127,4 @@ public class SizeCompatRestartButtonStatsTests extends DeviceTestCase implements .map(Integer::valueOf) .anyMatch(availableState -> availableState == state); } - - /** - * Returns the physical size of the current display used. - */ - private Pair<Integer, Integer> getDisplayRealSize(ITestDevice device) throws Exception { - final String physicalSize = "Physical size: "; - String str = device.executeShellCommand("wm size"); - if (!str.isEmpty()) { - String[] lines = str.split(System.getProperty("line.separator")); - for (String s : lines) { - if (s.contains(physicalSize)) { - String substring = s.substring(physicalSize.length()); - if (!substring.isEmpty()) { - return Pair.create(Integer.parseInt(substring.split("x")[0]), - Integer.parseInt(substring.split("x")[1])); - } - } - } - } - return null; - } } diff --git a/hostsidetests/statsdatom/src/android/cts/statsdatom/statsd/UidAtomTests.java b/hostsidetests/statsdatom/src/android/cts/statsdatom/statsd/UidAtomTests.java index 42b9b5c9cd7..33422c1cec4 100644 --- a/hostsidetests/statsdatom/src/android/cts/statsdatom/statsd/UidAtomTests.java +++ b/hostsidetests/statsdatom/src/android/cts/statsdatom/statsd/UidAtomTests.java @@ -598,25 +598,30 @@ public class UidAtomTests extends DeviceTestCase implements IBuildReceiver { final int atomTag = Atom.SCREEN_BRIGHTNESS_CHANGED_FIELD_NUMBER; + Set<Integer> screenMin = new HashSet<>(Arrays.asList(47)); + Set<Integer> screen100 = new HashSet<>(Arrays.asList(100)); + + // Add state sets to the list in order. + List<Set<Integer>> stateSet = Arrays.asList(screenMin, screen100); + ConfigUtils.uploadConfigForPushedAtom(getDevice(), DeviceUtils.STATSD_ATOM_TEST_PKG, atomTag); DeviceUtils.runDeviceTestsOnStatsdApp(getDevice(), ".AtomTests", "testScreenBrightness"); - List<Integer> expectedValues = Arrays.asList(47, 100); - - // Sorted list of brightness values in order in which they occurred, filtered to only - // contain expectedValues if they are present. - List<Integer> data = ReportUtils.getEventMetricDataList(getDevice()) - .stream() - .map(e -> e.getAtom().getScreenBrightnessChanged().getLevel()) - .filter(expectedValues::contains) - .collect(Collectors.toList()); + // Sorted list of events in order in which they occurred. + List<EventMetricData> data = ReportUtils.getEventMetricDataList(getDevice()); // Restore initial screen brightness setScreenBrightness(initialBrightness); setScreenBrightnessMode(isInitialManual); - assertThat(data).containsExactlyElementsIn(expectedValues).inOrder(); + AtomTestUtils.popUntilFind(data, screenMin, + atom -> atom.getScreenBrightnessChanged().getLevel()); + AtomTestUtils.popUntilFindFromEnd(data, screen100, + atom -> atom.getScreenBrightnessChanged().getLevel()); + // Assert that the events happened in the expected order. + AtomTestUtils.assertStatesOccurredInOrder(stateSet, data, AtomTestUtils.WAIT_TIME_SHORT, + atom -> atom.getScreenBrightnessChanged().getLevel()); } public void testSyncState() throws Exception { diff --git a/tests/PhotoPicker/TEST_MAPPING b/tests/PhotoPicker/TEST_MAPPING index e0e0c9beff7..f48e90cf2a3 100644 --- a/tests/PhotoPicker/TEST_MAPPING +++ b/tests/PhotoPicker/TEST_MAPPING @@ -1,14 +1,4 @@ { - "mainline-presubmit": [ - { - "name": "CtsPhotoPickerTest[com.google.android.mediaprovider.apex]", - "options": [ - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] - } - ], "presubmit": [ { "name": "CtsPhotoPickerTest" diff --git a/tests/PhotoPicker/src/android/photopicker/cts/ActionGetContentOnlyTest.java b/tests/PhotoPicker/src/android/photopicker/cts/ActionGetContentOnlyTest.java deleted file mode 100644 index 7b7e9e03a60..00000000000 --- a/tests/PhotoPicker/src/android/photopicker/cts/ActionGetContentOnlyTest.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.photopicker.cts; - -import static android.photopicker.cts.util.GetContentActivityAliasUtils.clearPackageData; -import static android.photopicker.cts.util.GetContentActivityAliasUtils.getDocumentsUiPackageName; -import static android.photopicker.cts.util.PhotoPickerAssertionsUtils.assertReadOnlyAccess; -import static android.photopicker.cts.util.PhotoPickerFilesUtils.createImagesAndGetUriAndPath; -import static android.photopicker.cts.util.PhotoPickerFilesUtils.deleteMedia; -import static android.photopicker.cts.util.PhotoPickerUiUtils.SHORT_TIMEOUT; -import static android.photopicker.cts.util.PhotoPickerUiUtils.clickAndWait; -import static android.photopicker.cts.util.PhotoPickerUiUtils.findAndClickBrowse; - - -import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth.assertWithMessage; - -import android.content.ClipData; -import android.content.Intent; -import android.net.Uri; -import android.photopicker.cts.util.GetContentActivityAliasUtils; -import android.util.Pair; - -import androidx.test.uiautomator.UiObject; -import androidx.test.uiautomator.UiObjectNotFoundException; -import androidx.test.uiautomator.UiSelector; - -import org.junit.After; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - -import java.util.ArrayList; -import java.util.List; - -/** - * Photo Picker tests for PhotoPicker launched via {@link Intent#ACTION_GET_CONTENT} intent - * exclusively. - */ -public class ActionGetContentOnlyTest extends PhotoPickerBaseTest { - private static String sDocumentsUiPackageName; - private static int sGetContentTakeOverActivityAliasState; - - private List<Uri> mUriList = new ArrayList<>(); - - @After - public void tearDown() throws Exception { - for (Uri uri : mUriList) { - deleteMedia(uri, mContext); - } - mUriList.clear(); - - if (mActivity != null) { - mActivity.finish(); - } - } - - @BeforeClass - public static void setUpBeforeClass() throws Exception { - sDocumentsUiPackageName = getDocumentsUiPackageName(); - sGetContentTakeOverActivityAliasState = GetContentActivityAliasUtils.enableAndGetOldState(); - clearPackageData(sDocumentsUiPackageName); - } - - @AfterClass - public static void tearDownAfterClass() throws Exception { - GetContentActivityAliasUtils.restoreState(sGetContentTakeOverActivityAliasState); - } - - @Test - public void testBrowse_singleSelect() throws Exception { - final int itemCount = 1; - List<Pair<Uri, String>> createdImagesData = createImagesAndGetUriAndPath(itemCount, - mContext.getUserId(), /* isFavorite */ false); - - final List<String> fileNameList = new ArrayList<>(); - for (Pair<Uri, String> createdImageData: createdImagesData) { - mUriList.add(createdImageData.first); - fileNameList.add(createdImageData.second); - } - - final Intent intent = new Intent(Intent.ACTION_GET_CONTENT); - intent.setType("image/*"); - mActivity.startActivityForResult(intent, REQUEST_CODE); - - findAndClickBrowse(mDevice); - - findAndClickFilesInDocumentsUi(fileNameList); - - final Uri uri = mActivity.getResult().data.getData(); - - assertReadOnlyAccess(uri, mContext.getContentResolver()); - } - - @Test - public void testBrowse_multiSelect() throws Exception { - final int itemCount = 3; - List<Pair<Uri, String>> createdImagesData = createImagesAndGetUriAndPath(itemCount, - mContext.getUserId(), /* isFavorite */ false); - - final List<String> fileNameList = new ArrayList<>(); - for (Pair<Uri, String> createdImageData: createdImagesData) { - mUriList.add(createdImageData.first); - fileNameList.add(createdImageData.second); - } - - final Intent intent = new Intent(Intent.ACTION_GET_CONTENT); - intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); - intent.setType("image/*"); - mActivity.startActivityForResult(intent, REQUEST_CODE); - - findAndClickBrowse(mDevice); - - findAndClickFilesInDocumentsUi(fileNameList); - - final ClipData clipData = mActivity.getResult().data.getClipData(); - final int count = clipData.getItemCount(); - assertThat(count).isEqualTo(itemCount); - for (int i = 0; i < count; i++) { - assertReadOnlyAccess(clipData.getItemAt(i).getUri(), mContext.getContentResolver()); - } - } - - private UiObject findSaveButton() { - return new UiObject(new UiSelector().resourceId( - sDocumentsUiPackageName + ":id/container_save") - .childSelector(new UiSelector().resourceId("android:id/button1"))); - } - - private void findAndClickFilesInDocumentsUi(List<String> fileNameList) throws Exception { - for (String fileName : fileNameList) { - findAndClickFileInDocumentsUi(fileName); - } - findAndClickSelect(); - } - - private void findAndClickSelect() throws Exception { - final UiObject selectButton = new UiObject(new UiSelector().resourceId( - sDocumentsUiPackageName + ":id/action_menu_select")); - clickAndWait(mDevice, selectButton); - } - - private void findAndClickFileInDocumentsUi(String fileName) throws Exception { - final UiSelector docList = new UiSelector().resourceId(sDocumentsUiPackageName - + ":id/dir_list"); - - // Wait for the first list item to appear - assertWithMessage("First list item").that( - new UiObject(docList.childSelector(new UiSelector())) - .waitForExists(SHORT_TIMEOUT)).isTrue(); - - try { - // Enforce to set the list mode - // Because UiScrollable can't reach the real bottom (when WEB_LINKABLE_FILE item) - // in grid mode when screen landscape mode - clickAndWait(mDevice, new UiObject(new UiSelector().resourceId(sDocumentsUiPackageName - + ":id/sub_menu_list"))); - } catch (UiObjectNotFoundException ignored) { - // Do nothing, already be in list mode. - } - - // Repeat swipe gesture to find our item - // (UiScrollable#scrollIntoView does not seem to work well with SwipeRefreshLayout) - UiObject targetObject = new UiObject(docList.childSelector(new UiSelector() - .textContains(fileName))); - UiObject saveButton = findSaveButton(); - int stepLimit = 10; - while (stepLimit-- > 0) { - if (targetObject.exists()) { - boolean targetObjectFullyVisible = !saveButton.exists() - || targetObject.getVisibleBounds().bottom - <= saveButton.getVisibleBounds().top; - if (targetObjectFullyVisible) { - break; - } - } - - mDevice.swipe(/* startX= */ mDevice.getDisplayWidth() / 2, - /* startY= */ mDevice.getDisplayHeight() / 2, - /* endX= */ mDevice.getDisplayWidth() / 2, - /* endY= */ 0, - /* steps= */ 40); - } - - targetObject.longClick(); - } -} diff --git a/tests/PhotoPicker/src/android/photopicker/cts/ActionPickImagesOnlyTest.java b/tests/PhotoPicker/src/android/photopicker/cts/ActionPickImagesOnlyTest.java deleted file mode 100644 index bd173747fba..00000000000 --- a/tests/PhotoPicker/src/android/photopicker/cts/ActionPickImagesOnlyTest.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.photopicker.cts; - -import static android.photopicker.cts.util.PhotoPickerAssertionsUtils.assertPersistedGrant; -import static android.photopicker.cts.util.PhotoPickerAssertionsUtils.assertPickerUriFormat; -import static android.photopicker.cts.util.PhotoPickerAssertionsUtils.assertRedactedReadOnlyAccess; -import static android.photopicker.cts.util.PhotoPickerFilesUtils.createImagesAndGetUris; -import static android.photopicker.cts.util.PhotoPickerFilesUtils.deleteMedia; -import static android.photopicker.cts.util.PhotoPickerUiUtils.SHORT_TIMEOUT; -import static android.photopicker.cts.util.PhotoPickerUiUtils.clickAndWait; -import static android.photopicker.cts.util.PhotoPickerUiUtils.findAddButton; -import static android.photopicker.cts.util.PhotoPickerUiUtils.findItemList; - -import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth.assertWithMessage; - -import android.app.Activity; -import android.content.ClipData; -import android.content.Intent; -import android.net.Uri; -import android.provider.MediaStore; - -import androidx.test.runner.AndroidJUnit4; -import androidx.test.uiautomator.UiObject; -import androidx.test.uiautomator.UiSelector; - -import org.junit.After; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.ArrayList; -import java.util.List; - -/** - * Photo Picker tests for {@link MediaStore#ACTION_PICK_IMAGES} intent exclusively - */ -@RunWith(AndroidJUnit4.class) -public class ActionPickImagesOnlyTest extends PhotoPickerBaseTest { - - private List<Uri> mUriList = new ArrayList<>(); - - @After - public void tearDown() throws Exception { - for (Uri uri : mUriList) { - deleteMedia(uri, mContext); - } - mUriList.clear(); - - if (mActivity != null) { - mActivity.finish(); - } - } - - @Test - public void testMultiSelect_invalidParam() throws Exception { - final Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); - intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, MediaStore.getPickImagesMaxLimit() + 1); - mActivity.startActivityForResult(intent, REQUEST_CODE); - final GetResultActivity.Result res = mActivity.getResult(); - assertThat(res.resultCode).isEqualTo(Activity.RESULT_CANCELED); - } - - @Test - public void testMultiSelect_invalidNegativeParam() throws Exception { - final Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); - intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, -1); - mActivity.startActivityForResult(intent, REQUEST_CODE); - final GetResultActivity.Result res = mActivity.getResult(); - assertThat(res.resultCode).isEqualTo(Activity.RESULT_CANCELED); - } - - @Test - public void testMultiSelect_returnsNotMoreThanMax() throws Exception { - final int maxCount = 2; - final int imageCount = maxCount + 1; - mUriList.addAll(createImagesAndGetUris(imageCount, mContext.getUserId())); - - final Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); - intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, maxCount); - mActivity.startActivityForResult(intent, REQUEST_CODE); - - final List<UiObject> itemList = findItemList(imageCount); - final int itemCount = itemList.size(); - assertThat(itemCount).isEqualTo(imageCount); - // Select maxCount + 1 item - for (int i = 0; i < itemCount; i++) { - clickAndWait(mDevice, itemList.get(i)); - } - - UiObject snackbarTextView = mDevice.findObject(new UiSelector().text( - "Select up to 2 items")); - assertWithMessage("Timed out while waiting for snackbar to appear").that( - snackbarTextView.waitForExists(SHORT_TIMEOUT)).isTrue(); - - assertWithMessage("Timed out waiting for snackbar to disappear").that( - snackbarTextView.waitUntilGone(SHORT_TIMEOUT)).isTrue(); - - clickAndWait(mDevice, findAddButton()); - - final ClipData clipData = mActivity.getResult().data.getClipData(); - final int count = clipData.getItemCount(); - assertThat(count).isEqualTo(maxCount); - } - - @Test - public void testDoesNotRespectExtraAllowMultiple() throws Exception { - final int imageCount = 2; - mUriList.addAll(createImagesAndGetUris(imageCount, mContext.getUserId())); - final Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); - intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); - mActivity.startActivityForResult(intent, REQUEST_CODE); - - final List<UiObject> itemList = findItemList(imageCount); - final int itemCount = itemList.size(); - assertThat(itemCount).isEqualTo(imageCount); - // Select 1 item - clickAndWait(mDevice, itemList.get(0)); - - final Uri uri = mActivity.getResult().data.getData(); - assertPickerUriFormat(uri, mContext.getUserId()); - assertPersistedGrant(uri, mContext.getContentResolver()); - assertRedactedReadOnlyAccess(uri); - } -} diff --git a/tests/PhotoPicker/src/android/photopicker/cts/CloudPhotoPickerTest.java b/tests/PhotoPicker/src/android/photopicker/cts/CloudPhotoPickerTest.java index ceaf3b244e9..aa0c95459f1 100644 --- a/tests/PhotoPicker/src/android/photopicker/cts/CloudPhotoPickerTest.java +++ b/tests/PhotoPicker/src/android/photopicker/cts/CloudPhotoPickerTest.java @@ -21,7 +21,7 @@ import static android.photopicker.cts.PickerProviderMediaGenerator.MediaGenerato import static android.photopicker.cts.PickerProviderMediaGenerator.setCloudProvider; import static android.photopicker.cts.PickerProviderMediaGenerator.syncCloudProvider; import static android.photopicker.cts.util.PhotoPickerAssertionsUtils.assertRedactedReadOnlyAccess; -import static android.photopicker.cts.util.PhotoPickerFilesUtils.createImagesAndGetUris; +import static android.photopicker.cts.util.PhotoPickerFilesUtils.createImages; import static android.photopicker.cts.util.PhotoPickerFilesUtils.deleteMedia; import static android.photopicker.cts.util.PhotoPickerUiUtils.findAddButton; import static android.photopicker.cts.util.PhotoPickerUiUtils.findItemList; @@ -120,7 +120,7 @@ public class CloudPhotoPickerTest extends PhotoPickerBaseTest { @Test public void testCloudPlusLocalSyncWithoutDedupe() throws Exception { - mUriList.addAll(createImagesAndGetUris(1, mContext.getUserId())); + createImages(1, mContext.getUserId(), mUriList); initPrimaryCloudProviderWithImage(Pair.create(null, CLOUD_ID1)); final ClipData clipData = fetchPickerMedia(2); @@ -131,7 +131,7 @@ public class CloudPhotoPickerTest extends PhotoPickerBaseTest { @Test public void testCloudPlusLocalSyncWithDedupe() throws Exception { - mUriList.addAll(createImagesAndGetUris(1, mContext.getUserId())); + createImages(1, mContext.getUserId(), mUriList); initPrimaryCloudProviderWithImage(Pair.create(mUriList.get(0).getLastPathSegment(), CLOUD_ID1)); @@ -295,7 +295,7 @@ public class CloudPhotoPickerTest extends PhotoPickerBaseTest { // Create a placeholder local image to ensure that the picker UI is never empty. // The PhotoPickerUiUtils#findItemList needs to select an item and it times out if the // Picker UI is empty. - mUriList.addAll(createImagesAndGetUris(1, mContext.getUserId())); + createImages(1, mContext.getUserId(), mUriList); // Cloud provider isn't set assertThat(MediaStore.isCurrentCloudMediaProviderAuthority(mContext.getContentResolver(), diff --git a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerCrossProfileTest.java b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerCrossProfileTest.java index 913b004d0a1..1092406823f 100644 --- a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerCrossProfileTest.java +++ b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerCrossProfileTest.java @@ -18,7 +18,7 @@ package android.photopicker.cts; import static android.photopicker.cts.util.PhotoPickerAssertionsUtils.assertPickerUriFormat; import static android.photopicker.cts.util.PhotoPickerAssertionsUtils.assertRedactedReadOnlyAccess; -import static android.photopicker.cts.util.PhotoPickerFilesUtils.createImagesAndGetUris; +import static android.photopicker.cts.util.PhotoPickerFilesUtils.createImages; import static android.photopicker.cts.util.PhotoPickerFilesUtils.deleteMedia; import static android.photopicker.cts.util.PhotoPickerUiUtils.SHORT_TIMEOUT; import static android.photopicker.cts.util.PhotoPickerUiUtils.findAddButton; @@ -79,7 +79,7 @@ public class PhotoPickerCrossProfileTest extends PhotoPickerBaseTest { @SdkSuppress(minSdkVersion = 32, codeName = "T") public void testWorkApp_canAccessPersonalProfileContents() throws Exception { final int imageCount = 2; - mUriList.addAll(createImagesAndGetUris(imageCount, sDeviceState.primaryUser().id())); + createImages(imageCount, sDeviceState.primaryUser().id(), mUriList); Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, imageCount); diff --git a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerTest.java b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerTest.java index 3d0bcd3378f..28051e29fd9 100644 --- a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerTest.java +++ b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerTest.java @@ -16,19 +16,16 @@ package android.photopicker.cts; -import static android.photopicker.cts.util.GetContentActivityAliasUtils.clearPackageData; -import static android.photopicker.cts.util.GetContentActivityAliasUtils.getDocumentsUiPackageName; import static android.photopicker.cts.util.PhotoPickerAssertionsUtils.assertMimeType; import static android.photopicker.cts.util.PhotoPickerAssertionsUtils.assertPersistedGrant; import static android.photopicker.cts.util.PhotoPickerAssertionsUtils.assertPickerUriFormat; import static android.photopicker.cts.util.PhotoPickerAssertionsUtils.assertRedactedReadOnlyAccess; -import static android.photopicker.cts.util.PhotoPickerFilesUtils.createDNGVideosAndGetUris; -import static android.photopicker.cts.util.PhotoPickerFilesUtils.createImagesAndGetUris; -import static android.photopicker.cts.util.PhotoPickerFilesUtils.createVideosAndGetUris; +import static android.photopicker.cts.util.PhotoPickerFilesUtils.createDNGVideos; +import static android.photopicker.cts.util.PhotoPickerFilesUtils.createImages; +import static android.photopicker.cts.util.PhotoPickerFilesUtils.createVideos; import static android.photopicker.cts.util.PhotoPickerFilesUtils.deleteMedia; import static android.photopicker.cts.util.PhotoPickerUiUtils.REGEX_PACKAGE_NAME; import static android.photopicker.cts.util.PhotoPickerUiUtils.SHORT_TIMEOUT; -import static android.photopicker.cts.util.PhotoPickerUiUtils.clickAndWait; import static android.photopicker.cts.util.PhotoPickerUiUtils.findAddButton; import static android.photopicker.cts.util.PhotoPickerUiUtils.findItemList; import static android.photopicker.cts.util.PhotoPickerUiUtils.findPreviewAddButton; @@ -37,62 +34,35 @@ import static android.photopicker.cts.util.PhotoPickerUiUtils.findPreviewAddOrSe import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; +import android.app.Activity; import android.content.ClipData; import android.content.Intent; import android.media.AudioAttributes; import android.media.AudioFocusRequest; import android.media.AudioManager; import android.net.Uri; -import android.photopicker.cts.util.GetContentActivityAliasUtils; import android.provider.MediaStore; +import androidx.test.runner.AndroidJUnit4; import androidx.test.uiautomator.UiObject; import androidx.test.uiautomator.UiObjectNotFoundException; import androidx.test.uiautomator.UiSelector; import org.junit.After; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameter; -import org.junit.runners.Parameterized.Parameters; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; /** * Photo Picker Device only tests for common flows. */ -@RunWith(Parameterized.class) +@RunWith(AndroidJUnit4.class) public class PhotoPickerTest extends PhotoPickerBaseTest { - - @Parameter(0) - public String mAction; - - @Parameters(name = "intent={0}") - public static Iterable<? extends Object> data() { - return getTestParameters(); - } - private List<Uri> mUriList = new ArrayList<>(); - private static int sGetContentTakeOverActivityAliasState; - - @BeforeClass - public static void setUpBeforeClass() throws Exception { - sGetContentTakeOverActivityAliasState = GetContentActivityAliasUtils.enableAndGetOldState(); - clearPackageData(getDocumentsUiPackageName()); - } - - @AfterClass - public static void tearDownAfterClass() throws Exception { - GetContentActivityAliasUtils.restoreState(sGetContentTakeOverActivityAliasState); - } - @After public void tearDown() throws Exception { for (Uri uri : mUriList) { @@ -108,13 +78,13 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { @Test public void testSingleSelect() throws Exception { final int itemCount = 1; - mUriList.addAll(createImagesAndGetUris(itemCount, mContext.getUserId())); + createImages(itemCount, mContext.getUserId(), mUriList); - final Intent intent = new Intent(mAction); - launchPhotoPickerForIntent(intent); + final Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); + mActivity.startActivityForResult(intent, REQUEST_CODE); final UiObject item = findItemList(itemCount).get(0); - clickAndWait(mDevice, item); + clickAndWait(item); final Uri uri = mActivity.getResult().data.getData(); assertPickerUriFormat(uri, mContext.getUserId()); @@ -125,20 +95,19 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { @Test public void testSingleSelectForFavoritesAlbum() throws Exception { final int itemCount = 1; - mUriList.addAll(createImagesAndGetUris(itemCount, mContext.getUserId(), - /* isFavorite */ true)); + createImages(itemCount, mContext.getUserId(), mUriList, true); - final Intent intent = new Intent(mAction); - launchPhotoPickerForIntent(intent); + final Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); + mActivity.startActivityForResult(intent, REQUEST_CODE); UiObject albumsTab = mDevice.findObject(new UiSelector().text( "Albums")); - clickAndWait(mDevice, albumsTab); + clickAndWait(albumsTab); final UiObject album = findItemList(1).get(0); - clickAndWait(mDevice, album); + clickAndWait(album); final UiObject item = findItemList(itemCount).get(0); - clickAndWait(mDevice, item); + clickAndWait(item); final Uri uri = mActivity.getResult().data.getData(); assertPickerUriFormat(uri, mContext.getUserId()); @@ -148,18 +117,18 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { @Test public void testLaunchPreviewMultipleForVideoAlbum() throws Exception { final int videoCount = 2; - mUriList.addAll(createVideosAndGetUris(videoCount, mContext.getUserId())); + createVideos(videoCount, mContext.getUserId(), mUriList); - Intent intent = new Intent(mAction); + final Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); intent.setType("video/*"); - addMultipleSelectionFlag(intent); - launchPhotoPickerForIntent(intent); + intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, MediaStore.getPickImagesMaxLimit()); + mActivity.startActivityForResult(intent, REQUEST_CODE); UiObject albumsTab = mDevice.findObject(new UiSelector().text( "Albums")); - clickAndWait(mDevice, albumsTab); + clickAndWait(albumsTab); final UiObject album = findItemList(1).get(0); - clickAndWait(mDevice, album); + clickAndWait(album); final List<UiObject> itemList = findItemList(videoCount); final int itemCount = itemList.size(); @@ -167,10 +136,10 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { assertThat(itemCount).isEqualTo(videoCount); for (int i = 0; i < itemCount; i++) { - clickAndWait(mDevice, itemList.get(i)); + clickAndWait(itemList.get(i)); } - clickAndWait(mDevice, findViewSelectedButton()); + clickAndWait(findViewSelectedButton()); // Wait for playback to start. This is needed in some devices where playback // buffering -> ready state takes around 10s. @@ -181,10 +150,10 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { @Test public void testSingleSelectWithPreview() throws Exception { final int itemCount = 1; - mUriList.addAll(createImagesAndGetUris(itemCount, mContext.getUserId())); + createImages(itemCount, mContext.getUserId(), mUriList); - final Intent intent = new Intent(mAction); - launchPhotoPickerForIntent(intent); + final Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); + mActivity.startActivityForResult(intent, REQUEST_CODE); final UiObject item = findItemList(itemCount).get(0); item.longClick(); @@ -192,7 +161,7 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { final UiObject addButton = findPreviewAddOrSelectButton(); assertThat(addButton.waitForExists(1000)).isTrue(); - clickAndWait(mDevice, addButton); + clickAndWait(addButton); final Uri uri = mActivity.getResult().data.getData(); assertPickerUriFormat(uri, mContext.getUserId()); @@ -200,21 +169,91 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { } @Test + public void testMultiSelect_invalidParam() throws Exception { + final Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); + intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, MediaStore.getPickImagesMaxLimit() + 1); + mActivity.startActivityForResult(intent, REQUEST_CODE); + final GetResultActivity.Result res = mActivity.getResult(); + assertThat(res.resultCode).isEqualTo(Activity.RESULT_CANCELED); + } + + @Test + public void testMultiSelect_invalidNegativeParam() throws Exception { + final Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); + intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, -1); + mActivity.startActivityForResult(intent, REQUEST_CODE); + final GetResultActivity.Result res = mActivity.getResult(); + assertThat(res.resultCode).isEqualTo(Activity.RESULT_CANCELED); + } + + @Test + public void testMultiSelect_returnsNotMoreThanMax() throws Exception { + final int maxCount = 2; + final int imageCount = maxCount + 1; + createImages(imageCount, mContext.getUserId(), mUriList); + final Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); + intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, maxCount); + mActivity.startActivityForResult(intent, REQUEST_CODE); + + final List<UiObject> itemList = findItemList(imageCount); + final int itemCount = itemList.size(); + assertThat(itemCount).isEqualTo(imageCount); + // Select maxCount + 1 item + for (int i = 0; i < itemCount; i++) { + clickAndWait(itemList.get(i)); + } + + UiObject snackbarTextView = mDevice.findObject(new UiSelector().text( + "Select up to 2 items")); + assertWithMessage("Timed out while waiting for snackbar to appear").that( + snackbarTextView.waitForExists(SHORT_TIMEOUT)).isTrue(); + + assertWithMessage("Timed out waiting for snackbar to disappear").that( + snackbarTextView.waitUntilGone(SHORT_TIMEOUT)).isTrue(); + + clickAndWait(findAddButton()); + + final ClipData clipData = mActivity.getResult().data.getClipData(); + final int count = clipData.getItemCount(); + assertThat(count).isEqualTo(maxCount); + } + + @Test + public void testDoesNotRespectExtraAllowMultiple() throws Exception { + final int imageCount = 2; + createImages(imageCount, mContext.getUserId(), mUriList); + final Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); + intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); + mActivity.startActivityForResult(intent, REQUEST_CODE); + + final List<UiObject> itemList = findItemList(imageCount); + final int itemCount = itemList.size(); + assertThat(itemCount).isEqualTo(imageCount); + // Select 1 item + clickAndWait(itemList.get(0)); + + final Uri uri = mActivity.getResult().data.getData(); + assertPickerUriFormat(uri, mContext.getUserId()); + assertPersistedGrant(uri, mContext.getContentResolver()); + assertRedactedReadOnlyAccess(uri); + } + + @Test public void testMultiSelect() throws Exception { final int imageCount = 4; - mUriList.addAll(createImagesAndGetUris(imageCount, mContext.getUserId())); - Intent intent = new Intent(mAction); - addMultipleSelectionFlag(intent); - launchPhotoPickerForIntent(intent); + createImages(imageCount, mContext.getUserId(), mUriList); + final Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); + intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, MediaStore.getPickImagesMaxLimit()); + mActivity.startActivityForResult(intent, REQUEST_CODE); final List<UiObject> itemList = findItemList(imageCount); final int itemCount = itemList.size(); assertThat(itemCount).isEqualTo(imageCount); for (int i = 0; i < itemCount; i++) { - clickAndWait(mDevice, itemList.get(i)); + clickAndWait(itemList.get(i)); } - clickAndWait(mDevice, findAddButton()); + clickAndWait(findAddButton()); final ClipData clipData = mActivity.getResult().data.getClipData(); final int count = clipData.getItemCount(); @@ -230,19 +269,18 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { @Test public void testMultiSelect_longPress() throws Exception { final int videoCount = 3; - mUriList.addAll(createDNGVideosAndGetUris(videoCount, mContext.getUserId())); - - Intent intent = new Intent(mAction); + createDNGVideos(videoCount, mContext.getUserId(), mUriList); + final Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); + intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, MediaStore.getPickImagesMaxLimit()); intent.setType("video/*"); - addMultipleSelectionFlag(intent); - launchPhotoPickerForIntent(intent); + mActivity.startActivityForResult(intent, REQUEST_CODE); final List<UiObject> itemList = findItemList(videoCount); final int itemCount = itemList.size(); assertThat(itemCount).isEqualTo(videoCount); // Select one item from Photo grid - clickAndWait(mDevice, itemList.get(0)); + clickAndWait(itemList.get(0)); // Preview the item UiObject item = itemList.get(1); @@ -254,14 +292,14 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { .that(addOrSelectButton.waitForExists(1000)).isTrue(); // Select the item from Preview - clickAndWait(mDevice, addOrSelectButton); + clickAndWait(addOrSelectButton); mDevice.pressBack(); // Select one more item from Photo grid - clickAndWait(mDevice, itemList.get(2)); + clickAndWait(itemList.get(2)); - clickAndWait(mDevice, findAddButton()); + clickAndWait(findAddButton()); // Verify that all 3 items are returned final ClipData clipData = mActivity.getResult().data.getClipData(); @@ -278,20 +316,19 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { @Test public void testMultiSelect_preview() throws Exception { final int imageCount = 4; - mUriList.addAll(createImagesAndGetUris(imageCount, mContext.getUserId())); - - Intent intent = new Intent(mAction); - addMultipleSelectionFlag(intent); - launchPhotoPickerForIntent(intent); + createImages(imageCount, mContext.getUserId(), mUriList); + final Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); + intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, MediaStore.getPickImagesMaxLimit()); + mActivity.startActivityForResult(intent, REQUEST_CODE); final List<UiObject> itemList = findItemList(imageCount); final int itemCount = itemList.size(); assertThat(itemCount).isEqualTo(imageCount); for (int i = 0; i < itemCount; i++) { - clickAndWait(mDevice, itemList.get(i)); + clickAndWait(itemList.get(i)); } - clickAndWait(mDevice, findViewSelectedButton()); + clickAndWait(findViewSelectedButton()); // Swipe left three times swipeLeftAndWait(); @@ -299,10 +336,10 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { swipeLeftAndWait(); // Deselect one item - clickAndWait(mDevice, findPreviewSelectedCheckButton()); + clickAndWait(findPreviewSelectedCheckButton()); // Return selected items - clickAndWait(mDevice, findPreviewAddButton()); + clickAndWait(findPreviewAddButton()); final ClipData clipData = mActivity.getResult().data.getClipData(); final int count = clipData.getItemCount(); @@ -349,20 +386,20 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { // Test 2: Click Mute Button // Click to unmute the audio - clickAndWait(mDevice, muteButton); + clickAndWait(muteButton); waitForBinderCallsToComplete(); // Check that mute button state is unmute, i.e., it shows `volume up` icon assertMuteButtonState(muteButton, /* isMuted */ false); // Click on the muteButton and check that mute button status is now 'mute' - clickAndWait(mDevice, muteButton); + clickAndWait(muteButton); waitForBinderCallsToComplete(); assertMuteButtonState(muteButton, /* isMuted */ true); // Click on the muteButton and check that mute button status is now unmute - clickAndWait(mDevice, muteButton); + clickAndWait(muteButton); waitForBinderCallsToComplete(); @@ -371,7 +408,7 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { // Test 3: Next preview resumes mute state // Go back and launch preview again mDevice.pressBack(); - clickAndWait(mDevice, findViewSelectedButton()); + clickAndWait(findViewSelectedButton()); waitForBinderCallsToComplete(); @@ -407,7 +444,7 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { // Test 2: Swipe resumes mute state, with state of mute button 'volume up' / 'unmute' // Click muteButton again to check the next video resumes the previous video's mute state - clickAndWait(mDevice, muteButton); + clickAndWait(muteButton); waitForBinderCallsToComplete(); @@ -461,7 +498,7 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { final UiObject muteButton = findMuteButton(); // unmute the audio of video preview - clickAndWait(mDevice, muteButton); + clickAndWait(muteButton); // Remote video preview involves binder calls // Wait for Binder calls to complete and device to be idle @@ -511,7 +548,7 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { final UiObject playerView = findPlayerView(); // Click on StyledPlayerView to make the video controls visible - clickAndWait(mDevice, playerView); + clickAndWait(playerView); assertPlayerControlsVisible(playPauseButton, muteButton); // Wait for 1s and check that controls are still visible @@ -528,7 +565,7 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { assertPlayerControlsHidden(playPauseButton, muteButton); // Click on the StyledPlayerView and check that controls appear - clickAndWait(mDevice, playerView); + clickAndWait(playerView); assertPlayerControlsVisible(playPauseButton, muteButton); // Swipe left to check that controls are now visible on swipe @@ -545,26 +582,26 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { @Test public void testMimeTypeFilter() throws Exception { final int videoCount = 2; - mUriList.addAll(createDNGVideosAndGetUris(videoCount, mContext.getUserId())); + createDNGVideos(videoCount, mContext.getUserId(), mUriList); final int imageCount = 1; - mUriList.addAll(createImagesAndGetUris(imageCount, mContext.getUserId())); + createImages(imageCount, mContext.getUserId(), mUriList); final String mimeType = "video/dng"; - Intent intent = new Intent(mAction); - addMultipleSelectionFlag(intent); + final Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); + intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, MediaStore.getPickImagesMaxLimit()); intent.setType(mimeType); - launchPhotoPickerForIntent(intent); + mActivity.startActivityForResult(intent, REQUEST_CODE); // find all items final List<UiObject> itemList = findItemList(-1); final int itemCount = itemList.size(); assertThat(itemCount).isAtLeast(videoCount); for (int i = 0; i < itemCount; i++) { - clickAndWait(mDevice, itemList.get(i)); + clickAndWait(itemList.get(i)); } - clickAndWait(mDevice, findAddButton()); + clickAndWait(findAddButton()); final ClipData clipData = mActivity.getResult().data.getClipData(); final int count = clipData.getItemCount(); @@ -597,27 +634,26 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { assertPlayerControlsAutoHide(playPauseButton, muteButton); // Click on StyledPlayerView to make the video controls visible - clickAndWait(mDevice, findPlayerView()); + clickAndWait(findPlayerView()); // PlayPause button is now pause button, click the button to pause the video. - clickAndWait(mDevice, playPauseButton); + clickAndWait(playPauseButton); // Wait for 1s and check that play button is not auto hidden assertPlayerControlsDontAutoHide(playPauseButton, muteButton); // PlayPause button is now play button, click the button to play the video. - clickAndWait(mDevice, playPauseButton); + clickAndWait(playPauseButton); // Check that pause button auto-hides in 1s. assertPlayerControlsAutoHide(playPauseButton, muteButton); } private void launchPreviewMultipleWithVideos(int videoCount) throws Exception { - mUriList.addAll(createVideosAndGetUris(videoCount, mContext.getUserId())); - - Intent intent = new Intent(mAction); + createVideos(videoCount, mContext.getUserId(), mUriList); + final Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); + intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, MediaStore.getPickImagesMaxLimit()); intent.setType("video/*"); - addMultipleSelectionFlag(intent); - launchPhotoPickerForIntent(intent); + mActivity.startActivityForResult(intent, REQUEST_CODE); final List<UiObject> itemList = findItemList(videoCount); final int itemCount = itemList.size(); @@ -625,10 +661,10 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { assertThat(itemCount).isEqualTo(videoCount); for (int i = 0; i < itemCount; i++) { - clickAndWait(mDevice, itemList.get(i)); + clickAndWait(itemList.get(i)); } - clickAndWait(mDevice, findViewSelectedButton()); + clickAndWait(findViewSelectedButton()); // Wait for playback to start. This is needed in some devices where playback // buffering -> ready state takes around 10s. @@ -651,7 +687,7 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { // Wait for 1s or Play/Pause button to hide playPauseButton.waitUntilGone(1000); // Click on StyledPlayerView to make the video controls visible - clickAndWait(mDevice, playerView); + clickAndWait(playerView); assertPlayerControlsVisible(playPauseButton, muteButton); } @@ -726,41 +762,15 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { REGEX_PACKAGE_NAME + ":id/preview_video_image")); } + private void clickAndWait(UiObject uiObject) throws Exception { + uiObject.click(); + mDevice.waitForIdle(); + } + private void swipeLeftAndWait() { final int width = mDevice.getDisplayWidth(); final int height = mDevice.getDisplayHeight(); mDevice.swipe(15 * width / 20, height / 2, width / 20, height / 2, 10); mDevice.waitForIdle(); } - - private static List<String> getTestParameters() { - return Arrays.asList( - MediaStore.ACTION_PICK_IMAGES, - Intent.ACTION_GET_CONTENT - ); - } - - private void addMultipleSelectionFlag(Intent intent) { - switch (intent.getAction()) { - case MediaStore.ACTION_PICK_IMAGES: - intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, - MediaStore.getPickImagesMaxLimit()); - break; - case Intent.ACTION_GET_CONTENT: - intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); - break; - default: - // do nothing - } - } - - private void launchPhotoPickerForIntent(Intent intent) throws Exception { - // GET_CONTENT needs to have setType - if (Intent.ACTION_GET_CONTENT.equals(intent.getAction()) && intent.getType() == null) { - intent.setType("*/*"); - intent.putExtra(Intent.EXTRA_MIME_TYPES, new String[]{"image/*", "video/*"}); - } - - mActivity.startActivityForResult(intent, REQUEST_CODE); - } } diff --git a/tests/PhotoPicker/src/android/photopicker/cts/util/GetContentActivityAliasUtils.java b/tests/PhotoPicker/src/android/photopicker/cts/util/GetContentActivityAliasUtils.java deleted file mode 100644 index 493f6417f08..00000000000 --- a/tests/PhotoPicker/src/android/photopicker/cts/util/GetContentActivityAliasUtils.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.photopicker.cts.util; - -import android.Manifest; -import android.app.Instrumentation; -import android.content.ComponentName; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ProviderInfo; -import android.content.pm.ResolveInfo; -import android.provider.MediaStore; - -import androidx.test.InstrumentationRegistry; - -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.function.Supplier; - -public class GetContentActivityAliasUtils { - - private static final long POLLING_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(5); - private static final long POLLING_SLEEP_MILLIS = 100; - - private static ComponentName sComponentName = new ComponentName( - getMediaProviderPackageName(), - "com.android.providers.media.photopicker.PhotoPickerGetContentActivity"); - - public static int enableAndGetOldState() throws Exception { - final Instrumentation inst = InstrumentationRegistry.getInstrumentation(); - final PackageManager packageManager = inst.getContext().getPackageManager(); - if (isComponentEnabledSetAsExpected(packageManager, - PackageManager.COMPONENT_ENABLED_STATE_ENABLED)) { - return PackageManager.COMPONENT_ENABLED_STATE_ENABLED; - } - - final int currentState = packageManager.getComponentEnabledSetting(sComponentName); - - updateComponentEnabledSetting(packageManager, - PackageManager.COMPONENT_ENABLED_STATE_ENABLED); - - return currentState; - } - - public static void restoreState(int oldState) throws Exception { - final Instrumentation inst = InstrumentationRegistry.getInstrumentation(); - updateComponentEnabledSetting(inst.getContext().getPackageManager(), oldState); - } - - /** - * Clears the package data. - */ - public static void clearPackageData(String packageName) throws Exception { - InstrumentationRegistry.getInstrumentation().getUiAutomation() - .executeShellCommand("pm clear " + packageName); - } - - public static String getDocumentsUiPackageName() { - final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); - intent.setType("*/*"); - final Instrumentation inst = InstrumentationRegistry.getInstrumentation(); - final ResolveInfo ri = inst.getContext().getPackageManager().resolveActivity(intent, 0); - return ri.activityInfo.packageName; - } - - private static void updateComponentEnabledSetting(PackageManager packageManager, - int state) throws Exception { - final Instrumentation inst = InstrumentationRegistry.getInstrumentation(); - inst.getUiAutomation().adoptShellPermissionIdentity( - Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); - try { - packageManager.setComponentEnabledSetting(sComponentName, state, - PackageManager.DONT_KILL_APP); - } finally { - inst.getUiAutomation().dropShellPermissionIdentity(); - } - waitForComponentToBeInExpectedState(packageManager, state); - } - - private static void waitForComponentToBeInExpectedState(PackageManager packageManager, - int state) throws Exception { - pollForCondition(() -> isComponentEnabledSetAsExpected(packageManager, state), - "Timed out while waiting for component to be enabled"); - } - - private static void pollForCondition(Supplier<Boolean> condition, String errorMessage) - throws Exception { - for (int i = 0; i < POLLING_TIMEOUT_MILLIS / POLLING_SLEEP_MILLIS; i++) { - if (condition.get()) { - return; - } - Thread.sleep(POLLING_SLEEP_MILLIS); - } - throw new TimeoutException(errorMessage); - } - - private static boolean isComponentEnabledSetAsExpected(PackageManager packageManager, - int state) { - return packageManager.getComponentEnabledSetting(sComponentName) == state; - } - - private static String getMediaProviderPackageName() { - final Instrumentation inst = androidx.test.InstrumentationRegistry.getInstrumentation(); - final PackageManager packageManager = inst.getContext().getPackageManager(); - final ProviderInfo providerInfo = packageManager.resolveContentProvider( - MediaStore.AUTHORITY, PackageManager.MATCH_ALL); - return providerInfo.packageName; - } -} diff --git a/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerAssertionsUtils.java b/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerAssertionsUtils.java index d9749f27420..9eb7d597253 100644 --- a/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerAssertionsUtils.java +++ b/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerAssertionsUtils.java @@ -120,7 +120,11 @@ public class PhotoPickerAssertionsUtils { .that(xmp.contains("13166/7763")).isTrue(); } - assertNoWriteAccess(uri, resolver); + // assert no write access + try (ParcelFileDescriptor pfd = resolver.openFileDescriptor(uri, "w")) { + fail("Does not grant write access to uri " + uri.toString()); + } catch (SecurityException | FileNotFoundException expected) { + } } private static void assertImageRedactedReadOnlyAccess(Uri uri, ContentResolver resolver) @@ -149,7 +153,12 @@ public class PhotoPickerAssertionsUtils { assertImageExifRedacted(is); } - assertNoWriteAccess(uri, resolver); + // Assert no write access + try (ParcelFileDescriptor pfd = + ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE)) { + fail("Does not grant write access to file " + file); + } catch (IOException e) { + } } } @@ -170,19 +179,4 @@ public class PhotoPickerAssertionsUtils { assertWithMessage("Redacted non-location XMP") .that(xmp.contains("LensDefaults")).isTrue(); } - - public static void assertReadOnlyAccess(Uri uri, ContentResolver resolver) throws Exception { - try (ParcelFileDescriptor pfd = resolver.openFileDescriptor(uri, "r")) { - assertThat(pfd).isNotNull(); - } - - assertNoWriteAccess(uri, resolver); - } - - private static void assertNoWriteAccess(Uri uri, ContentResolver resolver) throws Exception { - try (ParcelFileDescriptor pfd = resolver.openFileDescriptor(uri, "w")) { - fail("Does not grant write access to uri " + uri.toString()); - } catch (SecurityException | FileNotFoundException expected) { - } - } } diff --git a/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerFilesUtils.java b/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerFilesUtils.java index 2732df71762..3705ddd8fb1 100644 --- a/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerFilesUtils.java +++ b/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerFilesUtils.java @@ -26,7 +26,6 @@ import android.photopicker.cts.R; import android.provider.MediaStore; import android.provider.cts.ProviderTestUtils; import android.provider.cts.media.MediaStoreUtils; -import android.util.Pair; import androidx.test.InstrumentationRegistry; @@ -35,7 +34,6 @@ import com.android.compatibility.common.util.ShellUtils; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.util.ArrayList; import java.util.List; /** @@ -44,55 +42,24 @@ import java.util.List; public class PhotoPickerFilesUtils { public static final String DISPLAY_NAME_PREFIX = "ctsPhotoPicker"; - public static List<Uri> createImagesAndGetUris(int count, int userId) + public static void createImages(int count, int userId, List<Uri> uriList) throws Exception { - return createImagesAndGetUris(count, userId, /* isFavorite */ false); + createImages(count, userId, uriList, false); } - public static List<Uri> createImagesAndGetUris(int count, int userId, boolean isFavorite) + public static void createImages(int count, int userId, List<Uri> uriList, boolean isFavorite) throws Exception { - List<Pair<Uri, String>> createdImagesData = createImagesAndGetUriAndPath(count, userId, - isFavorite); - - List<Uri> uriList = new ArrayList<>(); - for (Pair<Uri, String> createdImageData: createdImagesData) { - uriList.add(createdImageData.first); - } - - return uriList; - } - - /** - * Create multiple images according to the given parameters and returns the uris and filenames - * of the images created. - * - * @param count number of images to create - * @param userId user id to create images in - * - * @return list of data (uri and filename pair) about the images created - */ - public static List<Pair<Uri, String>> createImagesAndGetUriAndPath(int count, int userId, - boolean isFavorite) throws Exception { - List<Pair<Uri, String>> createdImagesData = new ArrayList<>(); - for (int i = 0; i < count; i++) { - Pair<Uri, String> createdImageData = createImage(userId, isFavorite); - createdImagesData.add(createdImageData); - clearMediaOwner(createdImageData.first, userId); + final Uri uri = createImage(userId, isFavorite); + uriList.add(uri); + clearMediaOwner(uri, userId); } // Wait for Picker db sync to complete MediaStore.waitForIdle(InstrumentationRegistry.getContext().getContentResolver()); - - return createdImagesData; } - public static Pair<Uri, String> createImage(int userId, boolean isFavorite) throws Exception { - return getPermissionAndStageMedia(R.raw.lg_g4_iso_800_jpg, - MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/jpeg", userId, isFavorite); - } - - public static List<Uri> createDNGVideosAndGetUris(int count, int userId) throws Exception { - List<Uri> uriList = new ArrayList<>(); + public static void createDNGVideos(int count, int userId, List<Uri> uriList) + throws Exception { for (int i = 0; i < count; i++) { final Uri uri = createDNGVideo(userId); uriList.add(uri); @@ -100,12 +67,10 @@ public class PhotoPickerFilesUtils { } // Wait for Picker db sync to complete MediaStore.waitForIdle(InstrumentationRegistry.getContext().getContentResolver()); - - return uriList; } - public static List<Uri> createVideosAndGetUris(int count, int userId) throws Exception { - List<Uri> uriList = new ArrayList<>(); + public static void createVideos(int count, int userId, List<Uri> uriList) + throws Exception { for (int i = 0; i < count; i++) { final Uri uri = createVideo(userId); uriList.add(uri); @@ -113,8 +78,6 @@ public class PhotoPickerFilesUtils { } // Wait for Picker db sync to complete MediaStore.waitForIdle(InstrumentationRegistry.getContext().getContentResolver()); - - return uriList; } public static void deleteMedia(Uri uri, Context context) throws Exception { @@ -132,19 +95,26 @@ public class PhotoPickerFilesUtils { } private static Uri createDNGVideo(int userId) throws Exception { - return getPermissionAndStageMedia(R.raw.test_video_dng, - MediaStore.Video.Media.EXTERNAL_CONTENT_URI, "video/mp4", userId, - /* isFavorite */ false).first; + final Uri uri = stageMedia(R.raw.test_video_dng, + MediaStore.Video.Media.EXTERNAL_CONTENT_URI, "video/mp4", userId); + return uri; } private static Uri createVideo(int userId) throws Exception { - return getPermissionAndStageMedia(R.raw.test_video, - MediaStore.Video.Media.EXTERNAL_CONTENT_URI, "video/mp4", userId, - /* isFavorite */ false).first; + final Uri uri = stageMedia(R.raw.test_video, + MediaStore.Video.Media.EXTERNAL_CONTENT_URI, "video/mp4", userId); + return uri; } - private static Pair<Uri, String> getPermissionAndStageMedia(int resId, Uri collectionUri, - String mimeType, int userId, boolean isFavorite) throws Exception { + private static Uri createImage(int userId, boolean isFavorite) throws Exception { + final Uri uri = stageMedia(R.raw.lg_g4_iso_800_jpg, + MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/jpeg", userId, isFavorite); + return uri; + } + + private static Uri stageMedia(int resId, Uri collectionUri, String mimeType, int userId, + boolean isFavorite) throws + Exception { UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); uiAutomation.adoptShellPermissionIdentity( android.Manifest.permission.INTERACT_ACROSS_USERS, @@ -160,8 +130,14 @@ public class PhotoPickerFilesUtils { } } - private static Pair<Uri, String> stageMedia(int resId, Uri collectionUri, String mimeType, - Context context, boolean isFavorite) throws IOException { + private static Uri stageMedia(int resId, Uri collectionUri, String mimeType, int userId) throws + Exception { + return stageMedia(resId, collectionUri, mimeType, userId, false); + } + + private static Uri stageMedia(int resId, Uri collectionUri, String mimeType, Context context, + boolean isFavorite) + throws IOException { final String displayName = DISPLAY_NAME_PREFIX + System.nanoTime(); final MediaStoreUtils.PendingParams params = new MediaStoreUtils.PendingParams( collectionUri, displayName, mimeType); @@ -173,7 +149,7 @@ public class PhotoPickerFilesUtils { OutputStream target = session.openOutputStream()) { FileUtils.copy(source, target); } - return new Pair(session.publish(), displayName); + return session.publish(); } } } diff --git a/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerUiUtils.java b/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerUiUtils.java index 8f58f3e3261..d20dcd6665b 100644 --- a/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerUiUtils.java +++ b/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerUiUtils.java @@ -20,8 +20,8 @@ import static com.google.common.truth.Truth.assertWithMessage; import android.text.format.DateUtils; -import androidx.test.uiautomator.UiDevice; import androidx.test.uiautomator.UiObject; +import androidx.test.uiautomator.UiObjectNotFoundException; import androidx.test.uiautomator.UiScrollable; import androidx.test.uiautomator.UiSelector; @@ -35,7 +35,6 @@ public class PhotoPickerUiUtils { public static final long SHORT_TIMEOUT = 5 * DateUtils.SECOND_IN_MILLIS; private static final long TIMEOUT = 30 * DateUtils.SECOND_IN_MILLIS; - public static final String REGEX_PACKAGE_NAME = "com(.google)?.android.providers.media(.module)?"; @@ -93,22 +92,4 @@ public class PhotoPickerUiUtils { return new UiObject(new UiSelector().resourceIdMatches( REGEX_PACKAGE_NAME + ":id/profile_button")); } - - public static void findAndClickBrowse(UiDevice uiDevice) throws Exception { - assertWithMessage("Timed out waiting for overflow menu to appear") - .that(new UiObject(new UiSelector().description("More options")) - .waitForExists(SHORT_TIMEOUT)) - .isTrue(); - - final UiObject overflowMenu = new UiObject(new UiSelector().description("More options")); - clickAndWait(uiDevice, overflowMenu); - - final UiObject browseButton = new UiObject(new UiSelector().textContains("Browse")); - clickAndWait(uiDevice, browseButton); - } - - public static void clickAndWait(UiDevice uiDevice, UiObject uiObject) throws Exception { - uiObject.click(); - uiDevice.waitForIdle(); - } } diff --git a/tests/app/shared/src/android/app/cts/NotificationTemplateTestBase.kt b/tests/app/shared/src/android/app/cts/NotificationTemplateTestBase.kt index 47da9fa4875..6b84cd30afb 100644 --- a/tests/app/shared/src/android/app/cts/NotificationTemplateTestBase.kt +++ b/tests/app/shared/src/android/app/cts/NotificationTemplateTestBase.kt @@ -146,7 +146,4 @@ open class NotificationTemplateTestBase : AndroidTestCase() { @BoolRes protected fun getAndroidRBool(boolName: String): Int = getAndroidRes("bool", boolName) - - @DimenRes - protected fun getAndroidRDimen(dimenName: String) : Int = getAndroidRes("dimen", dimenName) }
\ No newline at end of file diff --git a/tests/app/src/android/app/cts/NotificationTemplateTest.kt b/tests/app/src/android/app/cts/NotificationTemplateTest.kt index 6db8aa69bed..f5f0f130e93 100644 --- a/tests/app/src/android/app/cts/NotificationTemplateTest.kt +++ b/tests/app/src/android/app/cts/NotificationTemplateTest.kt @@ -21,7 +21,6 @@ import android.app.PendingIntent import android.app.Person import android.app.cts.CtsAppTestUtils.platformNull import android.content.Intent -import android.content.res.Resources import android.graphics.Bitmap import android.graphics.Canvas import android.graphics.Color @@ -298,8 +297,8 @@ class NotificationTemplateTest : NotificationTemplateTestBase() { assertThat(iconView.width.toFloat()) .isWithin(1f) .of((iconView.height * 4 / 3).toFloat()) - assertThat(iconView.drawable.intrinsicWidth).isEqualTo(rightIconSize()) - assertThat(iconView.drawable.intrinsicHeight).isEqualTo(rightIconSize() * 3 / 4) + assertThat(iconView.drawable.intrinsicWidth).isEqualTo(400) + assertThat(iconView.drawable.intrinsicHeight).isEqualTo(300) } } @@ -397,9 +396,8 @@ class NotificationTemplateTest : NotificationTemplateTestBase() { assertThat(iconView.width.toFloat()) .isWithin(1f) .of((iconView.height * 4 / 3).toFloat()) - - assertThat(iconView.drawable.intrinsicWidth).isEqualTo(rightIconSize()) - assertThat(iconView.drawable.intrinsicHeight).isEqualTo(rightIconSize() * 3 / 4) + assertThat(iconView.drawable.intrinsicWidth).isEqualTo(400) + assertThat(iconView.drawable.intrinsicHeight).isEqualTo(300) } } @@ -781,11 +779,6 @@ class NotificationTemplateTest : NotificationTemplateTestBase() { PendingIntent.getBroadcast(mContext, 0, Intent("test"), PendingIntent.FLAG_IMMUTABLE) } - private fun rightIconSize(): Int { - return mContext.resources.getDimensionPixelSize( - getAndroidRDimen("notification_right_icon_size")) - } - companion object { val TAG = NotificationTemplateTest::class.java.simpleName const val NOTIFICATION_CHANNEL_ID = "NotificationTemplateTest" diff --git a/tests/app/src/android/app/cts/UpdateMediaTapToTransferReceiverDisplayTest.kt b/tests/app/src/android/app/cts/UpdateMediaTapToTransferReceiverDisplayTest.kt index f4692c7036c..c2d02b33a09 100644 --- a/tests/app/src/android/app/cts/UpdateMediaTapToTransferReceiverDisplayTest.kt +++ b/tests/app/src/android/app/cts/UpdateMediaTapToTransferReceiverDisplayTest.kt @@ -33,7 +33,6 @@ import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionId import com.google.common.truth.Truth.assertThat import org.junit.After import org.junit.Before -import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -92,7 +91,6 @@ class UpdateMediaTapToTransferReceiverDisplayTest { } @Test - @Ignore("b/236749332") fun closeToSender_displaysChip() { statusBarManager.updateMediaTapToTransferReceiverDisplay( StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER, @@ -108,7 +106,6 @@ class UpdateMediaTapToTransferReceiverDisplayTest { } @Test - @Ignore("236749332") fun farFromSender_hidesChip() { // First, make sure we display the chip statusBarManager.updateMediaTapToTransferReceiverDisplay( diff --git a/tests/appsearch/src/com/android/cts/appsearch/external/app/AppSearchSessionCtsTestBase.java b/tests/appsearch/src/com/android/cts/appsearch/external/app/AppSearchSessionCtsTestBase.java index affdaa89759..70b68b4aa11 100644 --- a/tests/appsearch/src/com/android/cts/appsearch/external/app/AppSearchSessionCtsTestBase.java +++ b/tests/appsearch/src/com/android/cts/appsearch/external/app/AppSearchSessionCtsTestBase.java @@ -676,7 +676,6 @@ public abstract class AppSearchSessionCtsTestBase { .build()) .build(); mDb1.setSchemaAsync(new SetSchemaRequest.Builder().addSchemas(schema).build()).get(); - // Creates a large batch of Documents, since we have max document size in Framework which is // 512KiB, we will create 1KiB * 4000 docs = 4MiB total size > 1MiB binder transaction limit char[] chars = new char[1024]; // 1KiB @@ -3852,104 +3851,4 @@ public abstract class AppSearchSessionCtsTestBase { documents = convertSearchResultsToDocuments(searchResults); assertThat(documents).containsExactly(inEmail1); } - - @Test - public void testSetSchemaWithIncompatibleNestedSchema() throws Exception { - // 1. Set the original schema. This should succeed without any problems. - AppSearchSchema originalNestedSchema = - new AppSearchSchema.Builder("TypeA") - .addProperty( - new StringPropertyConfig.Builder("prop1") - .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL) - .build()) - .build(); - SetSchemaRequest originalRequest = - new SetSchemaRequest.Builder().addSchemas(originalNestedSchema).build(); - mDb1.setSchemaAsync(originalRequest).get(); - - // 2. Set a new schema with a new type that refers to "TypeA" and an incompatible change to - // "TypeA". This should fail. - AppSearchSchema newNestedSchema = - new AppSearchSchema.Builder("TypeA") - .addProperty( - new StringPropertyConfig.Builder("prop1") - .setCardinality(PropertyConfig.CARDINALITY_REQUIRED) - .build()) - .build(); - AppSearchSchema newSchema = - new AppSearchSchema.Builder("TypeB") - .addProperty( - new AppSearchSchema.DocumentPropertyConfig.Builder("prop2", "TypeA") - .build()) - .build(); - final SetSchemaRequest newRequest = - new SetSchemaRequest.Builder().addSchemas(newNestedSchema, newSchema).build(); - Throwable throwable = - assertThrows(ExecutionException.class, () -> mDb1.setSchemaAsync(newRequest).get()) - .getCause(); - assertThat(throwable).isInstanceOf(AppSearchException.class); - AppSearchException exception = (AppSearchException) throwable; - assertThat(exception.getResultCode()).isEqualTo(RESULT_INVALID_SCHEMA); - assertThat(exception).hasMessageThat().contains("Schema is incompatible."); - assertThat(exception).hasMessageThat().contains("Incompatible types: {TypeA}"); - - // 3. Now set that same set of schemas but with forceOverride=true. This should succeed. - SetSchemaRequest newRequestForced = - new SetSchemaRequest.Builder() - .addSchemas(newNestedSchema, newSchema) - .setForceOverride(true) - .build(); - mDb1.setSchemaAsync(newRequestForced).get(); - } - - @Test - public void testEmojiSnippet() throws Exception { - // Schema registration - mDb1.setSchemaAsync( - new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()) - .get(); - - // String: "Luca Brasi sleeps with the 🐟🐟🐟." - // ^ ^ ^ ^ ^ ^ ^ ^ ^ - // UTF8 idx: 0 5 11 18 23 27 3135 39 - // UTF16 idx: 0 5 11 18 23 27 2931 33 - // Breaks into segments: "Luca", "Brasi", "sleeps", "with", "the", "🐟", "🐟" - // and "🐟". - // Index a document to instance 1. - String sicilianMessage = "Luca Brasi sleeps with the 🐟🐟🐟."; - AppSearchEmail inEmail1 = - new AppSearchEmail.Builder("namespace", "uri1").setBody(sicilianMessage).build(); - checkIsBatchResultSuccess( - mDb1.putAsync( - new PutDocumentsRequest.Builder().addGenericDocuments(inEmail1).build())); - - AppSearchEmail inEmail2 = - new AppSearchEmail.Builder("namespace", "uri2") - .setBody("Some other content.") - .build(); - checkIsBatchResultSuccess( - mDb1.putAsync( - new PutDocumentsRequest.Builder().addGenericDocuments(inEmail2).build())); - - // Query for "🐟" - SearchResultsShim searchResults = - mDb1.search( - "🐟", - new SearchSpec.Builder() - .setTermMatch(SearchSpec.TERM_MATCH_PREFIX) - .setSnippetCount(1) - .setSnippetCountPerProperty(1) - .build()); - List<SearchResult> page = searchResults.getNextPageAsync().get(); - assertThat(page).hasSize(1); - assertThat(page.get(0).getGenericDocument()).isEqualTo(inEmail1); - List<SearchResult.MatchInfo> matches = page.get(0).getMatchInfos(); - assertThat(matches).hasSize(1); - assertThat(matches.get(0).getPropertyPath()).isEqualTo("body"); - assertThat(matches.get(0).getFullText()).isEqualTo(sicilianMessage); - assertThat(matches.get(0).getExactMatch()).isEqualTo("🐟"); - if (mDb1.getFeatures().isFeatureSupported(Features.SEARCH_RESULT_MATCH_INFO_SUBMATCH)) { - assertThat(matches.get(0).getSubmatch()).isEqualTo("🐟"); - } - } } diff --git a/tests/appsearch/src/com/android/cts/appsearch/external/app/GenericDocumentCtsTest.java b/tests/appsearch/src/com/android/cts/appsearch/external/app/GenericDocumentCtsTest.java index 0bfa6935634..5dd2eac0617 100644 --- a/tests/appsearch/src/com/android/cts/appsearch/external/app/GenericDocumentCtsTest.java +++ b/tests/appsearch/src/com/android/cts/appsearch/external/app/GenericDocumentCtsTest.java @@ -576,30 +576,6 @@ public class GenericDocumentCtsTest { } @Test - public void testNestedProperties_buildBlankPaths() { - Exception e = - assertThrows( - IllegalArgumentException.class, - () -> - new GenericDocument.Builder<>("namespace", "id1", "schema1") - .setPropertyString("", "foo")); - assertThat(e.getMessage()).isEqualTo("Property name cannot be blank."); - - e = - assertThrows( - IllegalArgumentException.class, - () -> - new GenericDocument.Builder<>("namespace", "id1", "schema1") - .setPropertyDocument( - "propDoc", - new GenericDocument.Builder<>( - "namespace", "id2", "schema1") - .setPropertyString("", "Bat", "Hawk") - .build())); - assertThat(e.getMessage()).isEqualTo("Property name cannot be blank."); - } - - @Test public void testNestedProperties_invalidPaths() { GenericDocument doc = new GenericDocument.Builder<>("namespace", "id1", "schema1") @@ -616,28 +592,25 @@ public class GenericDocumentCtsTest { .build()) .build(); - // These paths are invalid because they don't apply to the given document --- these should + // Some paths are invalid because they don't apply to the given document --- these should // return null. It's not the querier's fault. assertThat(doc.getPropertyStringArray("propString.propInts")).isNull(); assertThat(doc.getPropertyStringArray("propDocs.propFoo")).isNull(); assertThat(doc.getPropertyStringArray("propDocs.propNestedString.propFoo")).isNull(); - } - @Test - public void testNestedProperties_arrayTypesInvalidPath() { - GenericDocument doc = new GenericDocument.Builder<>("namespace", "id1", "schema1").build(); - assertThrows(IllegalArgumentException.class, () -> doc.getPropertyString(".")); - assertThrows(IllegalArgumentException.class, () -> doc.getPropertyDocument(".")); - assertThrows(IllegalArgumentException.class, () -> doc.getPropertyBoolean(".")); - assertThrows(IllegalArgumentException.class, () -> doc.getPropertyDouble(".")); - assertThrows(IllegalArgumentException.class, () -> doc.getPropertyLong(".")); - assertThrows(IllegalArgumentException.class, () -> doc.getPropertyBytes(".")); - assertThrows(IllegalArgumentException.class, () -> doc.getPropertyStringArray(".")); - assertThrows(IllegalArgumentException.class, () -> doc.getPropertyDocumentArray(".")); - assertThrows(IllegalArgumentException.class, () -> doc.getPropertyBooleanArray(".")); - assertThrows(IllegalArgumentException.class, () -> doc.getPropertyDoubleArray(".")); - assertThrows(IllegalArgumentException.class, () -> doc.getPropertyLongArray(".")); - assertThrows(IllegalArgumentException.class, () -> doc.getPropertyBytesArray(".")); + // Some paths are invalid because they are malformed. These throw an exception --- the + // querier shouldn't provide such paths. + assertThrows( + IllegalArgumentException.class, () -> doc.getPropertyStringArray("propString[0")); + assertThrows( + IllegalArgumentException.class, () -> doc.getPropertyStringArray("propString[0.]")); + assertThrows( + IllegalArgumentException.class, + () -> doc.getPropertyStringArray("propString[banana]")); + assertThrows( + IllegalArgumentException.class, () -> doc.getPropertyStringArray("propString[-1]")); + assertThrows( + IllegalArgumentException.class, () -> doc.getPropertyStringArray("propDocs[0]cat")); } @Test diff --git a/tests/appsearch/src/com/android/cts/appsearch/external/app/GlobalSearchSessionCtsTestBase.java b/tests/appsearch/src/com/android/cts/appsearch/external/app/GlobalSearchSessionCtsTestBase.java index 47337cac18e..71822ca59dd 100644 --- a/tests/appsearch/src/com/android/cts/appsearch/external/app/GlobalSearchSessionCtsTestBase.java +++ b/tests/appsearch/src/com/android/cts/appsearch/external/app/GlobalSearchSessionCtsTestBase.java @@ -1641,11 +1641,6 @@ public abstract class GlobalSearchSessionCtsTestBase { @Test public void testAddObserver_schemaChange_added() throws Exception { - assumeTrue( - mDb1.getFeatures() - .isFeatureSupported( - Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK)); - // Register an observer TestObserverCallback observer = new TestObserverCallback(); mGlobalSearchSession.registerObserverCallback( @@ -1693,11 +1688,6 @@ public abstract class GlobalSearchSessionCtsTestBase { @Test public void testAddObserver_schemaChange_removed() throws Exception { - assumeTrue( - mDb1.getFeatures() - .isFeatureSupported( - Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK)); - // Add a schema type mDb1.setSchemaAsync( new SetSchemaRequest.Builder() @@ -1733,11 +1723,6 @@ public abstract class GlobalSearchSessionCtsTestBase { @Test public void testAddObserver_schemaChange_contents() throws Exception { - assumeTrue( - mDb1.getFeatures() - .isFeatureSupported( - Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK)); - // Add a schema mDb1.setSchemaAsync( new SetSchemaRequest.Builder() @@ -1809,11 +1794,6 @@ public abstract class GlobalSearchSessionCtsTestBase { @Test public void testAddObserver_schemaChange_contents_skipBySpec() throws Exception { - assumeTrue( - mDb1.getFeatures() - .isFeatureSupported( - Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK)); - // Add a schema mDb1.setSchemaAsync( new SetSchemaRequest.Builder() @@ -1882,11 +1862,6 @@ public abstract class GlobalSearchSessionCtsTestBase { @Test public void testRegisterObserver_schemaMigration() throws Exception { - assumeTrue( - mDb1.getFeatures() - .isFeatureSupported( - Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK)); - // Add a schema with two types mDb1.setSchemaAsync( new SetSchemaRequest.Builder() diff --git a/tests/autofillservice/src/android/autofillservice/cts/dialog/LoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/dialog/LoginActivityTest.java index 70d7a083b44..a6251f5b254 100644 --- a/tests/autofillservice/src/android/autofillservice/cts/dialog/LoginActivityTest.java +++ b/tests/autofillservice/src/android/autofillservice/cts/dialog/LoginActivityTest.java @@ -66,12 +66,12 @@ public class LoginActivityTest extends AutoFillServiceTestCase.ManualActivityLau mUiBot.waitForIdleSync(); // Click on password field - mUiBot.selectByRelativeId(ID_PASSWORD); + mUiBot.selectByRelativeIdFromUiDevice(ID_PASSWORD); // Waits a while mUiBot.waitForIdleSync(); // Click on password field again - mUiBot.selectByRelativeId(ID_PASSWORD); + mUiBot.selectByRelativeIdFromUiDevice(ID_PASSWORD); // Waits a while mUiBot.waitForIdleSync(); @@ -104,7 +104,7 @@ public class LoginActivityTest extends AutoFillServiceTestCase.ManualActivityLau mUiBot.waitForIdleSync(); // Click on password field to trigger fill dialog - mUiBot.selectByRelativeId(ID_PASSWORD); + mUiBot.selectByRelativeIdFromUiDevice(ID_PASSWORD); mUiBot.waitForIdleSync(); mUiBot.assertFillDialogDatasets("Dialog Presentation"); @@ -114,7 +114,7 @@ public class LoginActivityTest extends AutoFillServiceTestCase.ManualActivityLau mUiBot.waitForIdle(); // Click on password field again - mUiBot.selectByRelativeId(ID_PASSWORD); + mUiBot.selectByRelativeIdFromUiDevice(ID_PASSWORD); mUiBot.waitForIdleSync(); // Verify IME is shown @@ -149,7 +149,7 @@ public class LoginActivityTest extends AutoFillServiceTestCase.ManualActivityLau mUiBot.waitForIdleSync(); // Click on password field to trigger fill dialog - mUiBot.selectByRelativeId(ID_PASSWORD); + mUiBot.selectByRelativeIdFromUiDevice(ID_PASSWORD); mUiBot.waitForIdleSync(); // Verify IME is not shown @@ -202,7 +202,7 @@ public class LoginActivityTest extends AutoFillServiceTestCase.ManualActivityLau mUiBot.waitForIdleSync(); // Click on password field to trigger fill dialog - mUiBot.selectByRelativeId(ID_PASSWORD); + mUiBot.selectByRelativeIdFromUiDevice(ID_PASSWORD); mUiBot.waitForIdleSync(); mUiBot.assertFillDialogDatasets("Dialog Presentation"); @@ -219,7 +219,7 @@ public class LoginActivityTest extends AutoFillServiceTestCase.ManualActivityLau // Click on the username field to trigger autofill. Although the username field supports // a fill dialog, the fill dialog only shown once, so shows the dropdown UI. - mUiBot.selectByRelativeId(ID_USERNAME); + mUiBot.selectByRelativeIdFromUiDevice(ID_USERNAME); mUiBot.waitForIdleSync(); mUiBot.assertNoFillDialog(); @@ -270,7 +270,7 @@ public class LoginActivityTest extends AutoFillServiceTestCase.ManualActivityLau mUiBot.waitForIdleSync(); // Click on password field - mUiBot.selectByRelativeId(ID_PASSWORD); + mUiBot.selectByRelativeIdFromUiDevice(ID_PASSWORD); mUiBot.waitForIdleSync(); // Verify IME is not shown @@ -314,7 +314,7 @@ public class LoginActivityTest extends AutoFillServiceTestCase.ManualActivityLau sReplier.getNextFillRequest(); mUiBot.waitForIdleSync(); - mUiBot.selectByRelativeId(ID_PASSWORD); + mUiBot.selectByRelativeIdFromUiDevice(ID_PASSWORD); mUiBot.waitForIdleSync(); mUiBot.assertFillDialogDatasets("Dialog presentation"); @@ -325,7 +325,7 @@ public class LoginActivityTest extends AutoFillServiceTestCase.ManualActivityLau mUiBot.waitForIdle(); // Click on username field, and verify dropdown UI is shown - mUiBot.selectByRelativeId(ID_USERNAME); + mUiBot.selectByRelativeIdFromUiDevice(ID_USERNAME); mUiBot.waitForIdleSync(); mUiBot.assertDatasets("Dropdown Presentation"); @@ -365,7 +365,7 @@ public class LoginActivityTest extends AutoFillServiceTestCase.ManualActivityLau mUiBot.waitForIdleSync(); // Click on username field, and verify dropdown UI is shown. - mUiBot.selectByRelativeId(ID_USERNAME); + mUiBot.selectByRelativeIdFromUiDevice(ID_USERNAME); mUiBot.waitForIdleSync(); mUiBot.assertDatasets("Dropdown Presentation"); @@ -417,7 +417,7 @@ public class LoginActivityTest extends AutoFillServiceTestCase.ManualActivityLau mUiBot.waitForIdleSync(); // Click on password field to trigger fill dialog, then select - mUiBot.selectByRelativeId(ID_PASSWORD); + mUiBot.selectByRelativeIdFromUiDevice(ID_PASSWORD); mUiBot.waitForIdleSync(); activity.expectAutoFill("dude", "sweet"); mUiBot.selectFillDialogDataset("Dialog Presentation"); @@ -462,7 +462,7 @@ public class LoginActivityTest extends AutoFillServiceTestCase.ManualActivityLau sReplier.addResponse(builder.build()); // Click on username field to trigger fill dialog - mUiBot.selectByRelativeId(ID_USERNAME); + mUiBot.selectByRelativeIdFromUiDevice(ID_USERNAME); mUiBot.waitForIdleSync(); // Check onFillRequest is called now, and the fill dialog is not shown @@ -538,7 +538,7 @@ public class LoginActivityTest extends AutoFillServiceTestCase.ManualActivityLau assertHasFlags(fillRequest.flags, FLAG_SUPPORTS_FILL_DIALOG); // Click on password field to trigger fill dialog - mUiBot.selectByRelativeId(ID_USERNAME); + mUiBot.selectByRelativeIdFromUiDevice(ID_USERNAME); mUiBot.waitForIdleSync(); // Verify IME is not shown @@ -576,7 +576,7 @@ public class LoginActivityTest extends AutoFillServiceTestCase.ManualActivityLau mUiBot.waitForIdleSync(); // Click on password field to trigger fill dialog - mUiBot.selectByRelativeId(ID_PASSWORD); + mUiBot.selectByRelativeIdFromUiDevice(ID_PASSWORD); mUiBot.waitForIdleSync(); // Verify IME is not shown @@ -622,7 +622,7 @@ public class LoginActivityTest extends AutoFillServiceTestCase.ManualActivityLau mUiBot.waitForIdleSync(); // Click on password field to trigger fill dialog - mUiBot.selectByRelativeId(ID_PASSWORD); + mUiBot.selectByRelativeIdFromUiDevice(ID_PASSWORD); mUiBot.waitForIdleSync(); // Verify the fill dialog shown @@ -669,7 +669,7 @@ public class LoginActivityTest extends AutoFillServiceTestCase.ManualActivityLau mUiBot.waitForIdleSync(); // Click on password field to trigger fill dialog - mUiBot.selectByRelativeId(ID_PASSWORD); + mUiBot.selectByRelativeIdFromUiDevice(ID_PASSWORD); mUiBot.waitForIdleSync(); // Verify the fill dialog shown diff --git a/tests/autofillservice/src/android/autofillservice/cts/testcore/UiBot.java b/tests/autofillservice/src/android/autofillservice/cts/testcore/UiBot.java index 50ef382cf5e..73639c08eaa 100644 --- a/tests/autofillservice/src/android/autofillservice/cts/testcore/UiBot.java +++ b/tests/autofillservice/src/android/autofillservice/cts/testcore/UiBot.java @@ -52,7 +52,6 @@ import android.os.SystemClock; import android.service.autofill.SaveInfo; import android.support.test.uiautomator.By; import android.support.test.uiautomator.BySelector; -import android.support.test.uiautomator.Configurator; import android.support.test.uiautomator.Direction; import android.support.test.uiautomator.SearchCondition; import android.support.test.uiautomator.StaleObjectException; @@ -66,8 +65,6 @@ import android.text.Html; import android.text.Spanned; import android.text.style.URLSpan; import android.util.Log; -import android.view.InputDevice; -import android.view.MotionEvent; import android.view.View; import android.view.WindowInsets; import android.view.accessibility.AccessibilityEvent; @@ -1280,6 +1277,20 @@ public class UiBot { } /** + * Selects a view by id via UiDevice. + * + * Note: This used to avoid IME issue that some case IME will be not shown via + * UiObject2.click(). + */ + public UiObject2 selectByRelativeIdFromUiDevice(String id) throws Exception { + Log.v(TAG, "selectByRelativeIdFromDevice(): " + id); + final UiObject2 object = waitForObject(By.res(mPackageName, id)); + final Point p = object.getVisibleCenter(); + mDevice.click(p.x, p.y); + return object; + } + + /** * Asserts the header in the fill dialog. */ public void assertFillDialogHeader(String expectedHeader) throws Exception { @@ -1363,7 +1374,7 @@ public class UiBot { public void touchOutsideDialog() throws Exception { Log.v(TAG, "touchOutsideDialog()"); final UiObject2 picker = findFillDialogPicker(); - assertThat(injectClick(new Point(1, picker.getVisibleBounds().top / 2))).isTrue(); + mDevice.click(1, picker.getVisibleBounds().top / 2); } /** @@ -1372,7 +1383,7 @@ public class UiBot { public void touchOutsideSaveDialog() throws Exception { Log.v(TAG, "touchOutsideSaveDialog()"); final UiObject2 picker = waitForObject(SAVE_UI_SELECTOR, SAVE_TIMEOUT); - assertThat(injectClick(new Point(1, picker.getVisibleBounds().top / 2))).isTrue(); + mDevice.click(1, picker.getVisibleBounds().top / 2); } /** @@ -1404,44 +1415,4 @@ public class UiBot { public void assertNoFillDialog() throws Exception { assertNeverShown("Fill dialog", FILL_DIALOG_SELECTOR, DATASET_PICKER_NOT_SHOWN_NAPTIME_MS); } - - /** - * Injects a click input event at the given point in the default display. - * We have this method because {@link UiObject2#click) cannot touch outside the object, and - * {@link UiDevice#click} is broken in multi windowing mode (b/238254060). - */ - private boolean injectClick(Point p) { - final long downTime = SystemClock.uptimeMillis(); - final MotionEvent downEvent = getMotionEvent(downTime, downTime, MotionEvent.ACTION_DOWN, - p); - if (!mAutoman.injectInputEvent(downEvent, true)) { - Log.e(TAG, "Failed to inject down event."); - return false; - } - - try { - Thread.sleep(100); - } catch (InterruptedException e) { - Log.e(TAG, "Interrupted while sleep between click", e); - } - - final MotionEvent upEvent = getMotionEvent(downTime, SystemClock.uptimeMillis(), - MotionEvent.ACTION_UP, p); - return mAutoman.injectInputEvent(upEvent, true); - } - - private static MotionEvent getMotionEvent(long downTime, long eventTime, int action, Point p) { - final MotionEvent.PointerProperties properties = new MotionEvent.PointerProperties(); - properties.id = 0; - properties.toolType = Configurator.getInstance().getToolType(); - final MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords(); - coords.pressure = 1.0F; - coords.size = 1.0F; - coords.x = p.x; - coords.y = p.y; - return MotionEvent.obtain(downTime, eventTime, action, 1, - new MotionEvent.PointerProperties[]{properties}, - new MotionEvent.PointerCoords[]{coords}, 0, 0, 1.0F, 1.0F, 0, 0, - InputDevice.SOURCE_TOUCHSCREEN, 0); - } } diff --git a/tests/camera/Android.bp b/tests/camera/Android.bp index c2334fc3b4c..aae58c689b7 100644 --- a/tests/camera/Android.bp +++ b/tests/camera/Android.bp @@ -65,7 +65,6 @@ android_test { "truth-prebuilt", "androidx.heifwriter_heifwriter", "androidx.test.rules", - "MediaPerformanceClassCommon", ], jni_libs: [ "libctscamera2_jni", diff --git a/tests/camera/api31test/src/android/camera/cts/api31test/SPerfClassTest.java b/tests/camera/api31test/src/android/camera/cts/api31test/SPerfClassTest.java index 772e7a599cb..feb5567963f 100644 --- a/tests/camera/api31test/src/android/camera/cts/api31test/SPerfClassTest.java +++ b/tests/camera/api31test/src/android/camera/cts/api31test/SPerfClassTest.java @@ -36,7 +36,6 @@ import android.hardware.camera2.params.SessionConfiguration; import android.hardware.camera2.TotalCaptureResult; import android.media.Image; import android.media.ImageReader; -import android.os.Build; import android.os.Handler; import android.os.HandlerThread; import android.test.AndroidTestCase; @@ -211,9 +210,8 @@ public class SPerfClassTest extends AndroidTestCase { * Version.MEDIA_PERFORMANCE_CLASS */ public void testSPerfClassJpegSizes() throws Exception { - final boolean isAtLeastSPerfClass = - (Build.VERSION.MEDIA_PERFORMANCE_CLASS >= Build.VERSION_CODES.S); - if (!isAtLeastSPerfClass) { + boolean isSPerfClass = CameraTestUtils.isSPerfClass(); + if (!isSPerfClass) { return; } diff --git a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java index d7dd63d1ff2..f80c36b843e 100644 --- a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java +++ b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java @@ -55,10 +55,6 @@ import android.hardware.camera2.params.DynamicRangeProfiles; import android.hardware.camera2.params.RecommendedStreamConfigurationMap; import android.hardware.camera2.params.StreamConfigurationMap; import android.hardware.cts.helpers.CameraUtils; -import android.mediapc.cts.common.Requirement; -import android.mediapc.cts.common.RequiredMeasurement; -import android.mediapc.cts.common.RequirementConstants; -import android.mediapc.cts.common.PerformanceClassEvaluator; import android.media.CamcorderProfile; import android.media.ImageReader; import android.os.Build; @@ -78,11 +74,15 @@ import android.view.WindowMetrics; import androidx.test.rule.ActivityTestRule; +import androidx.test.InstrumentationRegistry; + import com.android.compatibility.common.util.CddTest; +import com.android.compatibility.common.util.DeviceReportLog; +import com.android.compatibility.common.util.ResultType; +import com.android.compatibility.common.util.ResultUnit; import org.junit.Rule; import org.junit.Test; -import org.junit.rules.TestName; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -92,10 +92,12 @@ import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Set; -import java.util.function.BiPredicate; import java.util.regex.Matcher; import java.util.regex.Pattern; +import static android.hardware.camera2.cts.CameraTestUtils.MPC_REPORT_LOG_NAME; +import static android.hardware.camera2.cts.CameraTestUtils.MPC_STREAM_NAME; + /** * Extended tests for static camera characteristics. */ @@ -111,9 +113,6 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase { */ private static final int MIN_ALLOWABLE_WHITELEVEL = 32; // must have sensor bit depth > 5 - @Rule - public final TestName mTestName = new TestName(); - private List<CameraCharacteristics> mCharacteristics; private static final Size FULLHD = new Size(1920, 1080); @@ -132,6 +131,10 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase { private static final long PREVIEW_RUN_MS = 500; private static final long FRAME_DURATION_30FPS_NSEC = (long) 1e9 / 30; + private static final long MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION = 12000000; + private static final long MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION = 5000000; + private static final long MIN_FRONT_SENSOR_R_PERF_CLASS_RESOLUTION = 4000000; + private static final long MIN_UHR_SENSOR_RESOLUTION = 24000000; /* * HW Levels short hand @@ -2349,17 +2352,6 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase { // Sanitize the high speed FPS ranges for each size List<Range<Integer>> ranges = Arrays.asList(config.getHighSpeedVideoFpsRangesFor(size)); - int previewFps = Integer.MAX_VALUE; - for (Range<Integer> range : ranges) { - int rangeMin = range.getLower(); - if (previewFps > rangeMin) { - previewFps = rangeMin; - } - } - Log.v(TAG, "Advertised preview fps is: " + previewFps); - // We only support preview of 30fps or 60fps. - assertTrue("Preview fps " + previewFps + " is not valid.", - (previewFps == 30 || previewFps == 60)); for (Range<Integer> range : ranges) { assertTrue("The range " + range + " doesn't satisfy the" + " min/max boundary requirements.", @@ -2368,12 +2360,10 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase { assertTrue("The range " + range + " should be multiple of 30fps", range.getLower() % 30 == 0 && range.getUpper() % 30 == 0); // If the range is fixed high speed range, it should contain the - // [previewFps, fps_max] in the high speed range list; if it's variable FPS - // range, the corresponding fixed FPS Range must be included in the range - // list. + // [30, fps_max] in the high speed range list; if it's variable FPS range, + // the corresponding fixed FPS Range must be included in the range list. if (range.getLower() == range.getUpper()) { - Range<Integer> variableRange = new Range<Integer>(previewFps, - range.getUpper()); + Range<Integer> variableRange = new Range<Integer>(30, range.getUpper()); assertTrue("The variable FPS range " + variableRange + " shoould be included in the high speed ranges for size " + size, ranges.contains(variableRange)); @@ -2854,70 +2844,28 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase { } /** - * Camera hardware level requirement for Media Performance Class + * Update performance class level based on condition + * + * @param condition whether the condition is met for passLevel + * @param passLevel the highest performance class level when condition is true + * @param failLevel the performance class when condition is false */ - public static class PrimaryCameraHwLevelReq extends Requirement { - private static final String TAG = PrimaryCameraHwLevelReq.class.getSimpleName(); - - /** - * Creates a >= predicate for camera hardware level - */ - private static BiPredicate<Integer, Integer> camHwLevelGte() { - return new BiPredicate<Integer, Integer>() { - @Override - public boolean test(Integer actual, Integer expected) { - return StaticMetadata.hardwareLevelPredicate(actual, expected); - } + private int updatePerfClassLevel(boolean condition, int passLevel, int failLevel) { + return condition ? passLevel : failLevel; + } - @Override - public String toString() { - return "Camera Hardware Level Greater than or equal to"; - } - }; - } - private static final BiPredicate<Integer, Integer> CAM_HW_LEVEL_GTE = camHwLevelGte(); - private PrimaryCameraHwLevelReq(String id, RequiredMeasurement<?> ... reqs) { - super(id, reqs); - } - - public void setPrimaryRearCameraHwlLevel(Integer hwLevel) { - this.setMeasuredValue(RequirementConstants.REAR_CAMERA_HWL_LEVEL, hwLevel); - } - - public void setPrimaryFrontCameraHwlLevel(Integer hwLevel) { - this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_HWL_LEVEL, hwLevel); - } - - /** - * [2.2.7.2/7.5/H-1-3] MUST support android.info.supportedHardwareLevel property as FULL or - * better for back primary and LIMITED or better for front primary camera. - */ - public static PrimaryCameraHwLevelReq createPrimaryCameraHwLevelReq() { - RequiredMeasurement<Integer> rearCameraHwlLevel = RequiredMeasurement - .<Integer>builder() - .setId(RequirementConstants.REAR_CAMERA_HWL_LEVEL) - .setPredicate(CAM_HW_LEVEL_GTE) - .addRequiredValue(Build.VERSION_CODES.R, - CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL) - .addRequiredValue(Build.VERSION_CODES.S, - CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL) - .addRequiredValue(Build.VERSION_CODES.TIRAMISU, - CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL) - .build(); - RequiredMeasurement<Integer> frontCameraHwlLevel = RequiredMeasurement - .<Integer>builder() - .setId(RequirementConstants.FRONT_CAMERA_HWL_LEVEL) - .setPredicate(CAM_HW_LEVEL_GTE) - .addRequiredValue(Build.VERSION_CODES.R, - CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED) - .addRequiredValue(Build.VERSION_CODES.S, - CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL) - .addRequiredValue(Build.VERSION_CODES.TIRAMISU, - CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL) - .build(); - return new PrimaryCameraHwLevelReq(RequirementConstants.R7_5__H_1_3, - rearCameraHwlLevel, frontCameraHwlLevel); - } + /** + * Update perf class level based on meetSPerfClass and meetRPerfClass. + */ + private int updatePerfClassLevelRS(boolean meetSPerfClass, boolean meetRPerfClass, + int perfClassLevel) { + if (!meetRPerfClass) { + return CameraTestUtils.PERFORMANCE_CLASS_NOT_MET; + } else if (!meetSPerfClass && + perfClassLevel > CameraTestUtils.PERFORMANCE_CLASS_R) { + return Math.min(CameraTestUtils.PERFORMANCE_CLASS_R, perfClassLevel); + } + return perfClassLevel; } /** @@ -2932,31 +2880,30 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase { // ids. return; } - PerformanceClassEvaluator pce = new PerformanceClassEvaluator(this.mTestName); - PerformanceClassEvaluator.PrimaryCameraRequirement primaryRearReq = - pce.addPrimaryRearCameraReq(); - PerformanceClassEvaluator.PrimaryCameraRequirement primaryFrontReq = - pce.addPrimaryFrontCameraReq(); - PrimaryCameraHwLevelReq hwLevelReq = pce.addRequirement( - PrimaryCameraHwLevelReq.createPrimaryCameraHwLevelReq()); - PerformanceClassEvaluator.CameraTimestampSourceRequirement timestampSourceReq = - pce.addR7_5__H_1_4(); - PerformanceClassEvaluator.CameraRawRequirement rearRawReq = - pce.addR7_5__H_1_8(); - PerformanceClassEvaluator.Camera240FpsRequirement hfrReq = - pce.addR7_5__H_1_9(); - PerformanceClassEvaluator.UltraWideZoomRatioRequirement ultrawideZoomRatioReq = - pce.addR7_5__H_1_10(); - PerformanceClassEvaluator.ConcurrentRearFrontRequirement concurrentRearFrontReq = - pce.addR7_5__H_1_11(); - PerformanceClassEvaluator.PreviewStabilizationRequirement previewStabilizationReq = - pce.addR7_5__H_1_12(); - PerformanceClassEvaluator.LogicalMultiCameraRequirement logicalMultiCameraReq = - pce.addR7_5__H_1_13(); - PerformanceClassEvaluator.StreamUseCaseRequirement streamUseCaseReq = - pce.addR7_5__H_1_14(); - - HashSet<String> primaryCameras = new HashSet<String>(); + boolean assertRPerfClass = CameraTestUtils.isRPerfClass(); + boolean assertSPerfClass = CameraTestUtils.isSPerfClass(); + boolean assertTPerfClass = CameraTestUtils.isTPerfClass(); + boolean assertPerfClass = (assertRPerfClass || assertSPerfClass || assertTPerfClass); + + // R & S Performance Class + int perfClassLevelH11 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT; + int perfClassLevelH12 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT; + int perfClassLevelH13 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT; + int perfClassLevelH14 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT; + int perfClassLevelH18 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT; + + // T Performance Class + int perfClassLevelH19 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT; + int perfClassLevelH110 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT; + int perfClassLevelH111 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT; + int perfClassLevelH112 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT; + int perfClassLevelH113 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT; + int perfClassLevelH114 = CameraTestUtils.PERFORMANCE_CLASS_CURRENT; + + DeviceReportLog reportLog = new DeviceReportLog(MPC_REPORT_LOG_NAME, MPC_STREAM_NAME); + + String primaryRearId = null; + String primaryFrontId = null; for (int i = 0; i < mCameraIdsUnderTest.length; i++) { String cameraId = mCameraIdsUnderTest[i]; boolean isPrimaryRear = CameraTestUtils.isPrimaryRearFacingCamera( @@ -2980,27 +2927,42 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase { List<Size> videoSizes = CameraTestUtils.getSupportedVideoSizes(cameraId, mCameraManager, null /*bound*/); - Integer timestampSource = c.get(CameraCharacteristics.SENSOR_INFO_TIMESTAMP_SOURCE); if (isPrimaryRear) { - primaryCameras.add(cameraId); - primaryRearReq.setPrimaryCameraSupported(true); - primaryRearReq.setResolution(sensorResolution); - hwLevelReq.setPrimaryRearCameraHwlLevel(staticInfo.getHardwareLevelChecked()); - timestampSourceReq.setRearCameraTimestampSource(timestampSource); + primaryRearId = cameraId; + if (sensorResolution < MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION) { + mCollector.expectTrue("Primary rear camera resolution should be at least " + + MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION + " pixels, is "+ + sensorResolution, !assertPerfClass); + perfClassLevelH11 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET; + } + reportLog.addValue("rear camera resolution", sensorResolution, + ResultType.NEUTRAL, ResultUnit.NONE); // 4K @ 30fps boolean supportUHD = videoSizes.contains(UHD); boolean supportDC4K = videoSizes.contains(DC4K); - boolean support4K = (supportUHD || supportDC4K); - primaryRearReq.setVideoSizeReqSatisfied(support4K); - if (support4K) { + reportLog.addValue("rear camera 4k support", supportUHD | supportDC4K, + ResultType.NEUTRAL, ResultUnit.NONE); + if (!supportUHD && !supportDC4K) { + mCollector.expectTrue("Primary rear camera should support 4k video recording", + !assertPerfClass); + perfClassLevelH11 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET; + } else { long minFrameDuration = config.getOutputMinFrameDuration( android.media.MediaRecorder.class, supportDC4K ? DC4K : UHD); - primaryRearReq.setVideoFps(1e9 / minFrameDuration); + reportLog.addValue("rear camera 4k frame duration", minFrameDuration, + ResultType.NEUTRAL, ResultUnit.NONE); + if (minFrameDuration >= (1e9 / 29.9)) { + mCollector.expectTrue("Primary rear camera should support 4k video @ 30fps", + !assertPerfClass); + perfClassLevelH11 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET; + } } // H-1-9 boolean supportHighSpeed = staticInfo.isCapabilitySupported(CONSTRAINED_HIGH_SPEED); + mCollector.expectTrue("Primary rear camera should support high speed recording", + !assertTPerfClass || supportHighSpeed); boolean support240Fps = false; if (supportHighSpeed) { Size[] availableHighSpeedSizes = config.getHighSpeedVideoSizes(); @@ -3020,29 +2982,101 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase { break; } } + mCollector.expectTrue("Primary rear camera should support HD or FULLHD @ 240", + !assertTPerfClass || support240Fps); } - hfrReq.setRear240FpsSupported(support240Fps); + perfClassLevelH19 = updatePerfClassLevel(support240Fps, + perfClassLevelH19, CameraTestUtils.PERFORMANCE_CLASS_S); + reportLog.addValue("rear camera 720p/1080p @ 240fps support", support240Fps, + ResultType.NEUTRAL, ResultUnit.NONE); } else { - primaryCameras.add(cameraId); - primaryFrontReq.setPrimaryCameraSupported(true); - primaryFrontReq.setResolution(sensorResolution); - hwLevelReq.setPrimaryFrontCameraHwlLevel(staticInfo.getHardwareLevelChecked()); - timestampSourceReq.setFrontCameraTimestampSource(timestampSource); + primaryFrontId = cameraId; + if (sensorResolution < MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION) { + mCollector.expectTrue("Primary front camera resolution should be at least " + + MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION + " pixels, is " + + sensorResolution, !(assertSPerfClass || assertTPerfClass)); + perfClassLevelH12 = Math.min( + perfClassLevelH12, CameraTestUtils.PERFORMANCE_CLASS_R); + } + if (sensorResolution < MIN_FRONT_SENSOR_R_PERF_CLASS_RESOLUTION) { + mCollector.expectTrue("Primary front camera resolution should be at least " + + MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION + " pixels, is "+ + sensorResolution, !assertRPerfClass); + perfClassLevelH12 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET; + } + reportLog.addValue("front camera resolution", sensorResolution, + ResultType.NEUTRAL, ResultUnit.NONE); // 1080P @ 30fps boolean supportFULLHD = videoSizes.contains(FULLHD); - primaryFrontReq.setVideoSizeReqSatisfied(supportFULLHD); - if (supportFULLHD) { + reportLog.addValue("front camera 1080p support", supportFULLHD, + ResultType.NEUTRAL, ResultUnit.NONE); + if (!supportFULLHD) { + mCollector.expectTrue( + "Primary front camera should support 1080P video recording", + !assertPerfClass); + perfClassLevelH12 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET; + } else { long minFrameDuration = config.getOutputMinFrameDuration( android.media.MediaRecorder.class, FULLHD); - primaryFrontReq.setVideoFps(1e9 / minFrameDuration); + if (minFrameDuration >= (1e9 / 29.9)) { + mCollector.expectTrue( + "Primary front camera should support 1080P video @ 30fps", + !assertPerfClass); + perfClassLevelH12 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET; + } + reportLog.addValue("front camera 1080p frame duration", minFrameDuration, + ResultType.NEUTRAL, ResultUnit.NONE); } } + String facingString = isPrimaryRear ? "rear" : "front"; + // H-1-3 + if (assertTPerfClass || assertSPerfClass || (assertRPerfClass && isPrimaryRear)) { + mCollector.expectTrue("Primary " + facingString + + " camera should be at least FULL, but is " + + toStringHardwareLevel(staticInfo.getHardwareLevelChecked()), + staticInfo.isHardwareLevelAtLeastFull()); + } else if (assertRPerfClass) { + mCollector.expectTrue("Primary " + facingString + + " camera should be at least LIMITED, but is " + + toStringHardwareLevel(staticInfo.getHardwareLevelChecked()), + staticInfo.isHardwareLevelAtLeastLimited()); + } + + reportLog.addValue(facingString + " camera hardware level", + staticInfo.getHardwareLevelChecked(), ResultType.NEUTRAL, ResultUnit.NONE); + if (isPrimaryRear) { + perfClassLevelH13 = updatePerfClassLevel(staticInfo.isHardwareLevelAtLeastFull(), + perfClassLevelH13, CameraTestUtils.PERFORMANCE_CLASS_NOT_MET); + } else { + perfClassLevelH13 = updatePerfClassLevelRS(staticInfo.isHardwareLevelAtLeastFull(), + staticInfo.isHardwareLevelAtLeastLimited(), perfClassLevelH13); + } + + // H-1-4 + Integer timestampSource = c.get(CameraCharacteristics.SENSOR_INFO_TIMESTAMP_SOURCE); + reportLog.addValue(facingString + " timestampSource", + timestampSource, ResultType.NEUTRAL, ResultUnit.NONE); + boolean realtimeTimestamp = (timestampSource != null && + timestampSource.equals(CameraMetadata.SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME)); + mCollector.expectTrue( + "Primary " + facingString + " camera should support real-time timestamp source", + !assertPerfClass || realtimeTimestamp); + perfClassLevelH14 = updatePerfClassLevel(realtimeTimestamp, perfClassLevelH14, + CameraTestUtils.PERFORMANCE_CLASS_NOT_MET); + // H-1-8 if (isPrimaryRear) { boolean supportRaw = staticInfo.isCapabilitySupported(RAW); - rearRawReq.setRearRawSupported(supportRaw); + reportLog.addValue(facingString + " camera raw support", + supportRaw, ResultType.NEUTRAL, ResultUnit.NONE); + if (assertSPerfClass || assertTPerfClass) { + mCollector.expectTrue("Primary rear camera should support RAW capability", + supportRaw); + } + perfClassLevelH18 = updatePerfClassLevel(supportRaw, perfClassLevelH18, + CameraTestUtils.PERFORMANCE_CLASS_R); } // H-1-10 @@ -3051,45 +3085,96 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase { Range<Float> zoomRatioRange = staticInfo.getZoomRatioRangeChecked(); boolean meetH110 = (primaryToMaxFovRatio >= 1.0f - FOV_THRESHOLD) || (zoomRatioRange.getLower() < 1.0f - FOV_THRESHOLD); - if (isPrimaryRear) { - ultrawideZoomRatioReq.setRearUltraWideZoomRatioReqMet(meetH110); - } else { - ultrawideZoomRatioReq.setFrontUltraWideZoomRatioReqMet(meetH110); - } + mCollector.expectTrue("Primary " + facingString + " camera must support zoomRatio < " + + "1.0f if there is an ultrawide lens with the same facing", + !assertTPerfClass || meetH110); + perfClassLevelH110 = updatePerfClassLevel(meetH110, perfClassLevelH110, + CameraTestUtils.PERFORMANCE_CLASS_S); + reportLog.addValue(facingString + " camera supports maximum FOV using zoom ratio", + meetH110, ResultType.NEUTRAL, ResultUnit.NONE); // H-1-12 - boolean previewStab = staticInfo.isPreviewStabilizationSupported(); - if (isPrimaryRear) { - previewStabilizationReq.setRearPreviewStabilizationSupported(previewStab); - } else { - previewStabilizationReq.setFrontPreviewStabilizationSupported(previewStab); - } + boolean meetH112 = staticInfo.isPreviewStabilizationSupported(); + mCollector.expectTrue("Primary " + facingString + " camera must support preview " + + "stabilization", !assertTPerfClass || meetH112); + perfClassLevelH112 = updatePerfClassLevel(meetH112, perfClassLevelH112, + CameraTestUtils.PERFORMANCE_CLASS_S); + reportLog.addValue(facingString + " camera preview stabilization", meetH112, + ResultType.NEUTRAL, ResultUnit.NONE); // H-1-13 int facing = staticInfo.getLensFacingChecked(); int numOfPhysicalRgbCameras = getNumberOfRgbPhysicalCameras(facing); - boolean logicalMultiCameraReqMet = - (numOfPhysicalRgbCameras <= 1) || staticInfo.isLogicalMultiCamera(); - if (isPrimaryRear) { - logicalMultiCameraReq.setRearLogicalMultiCameraReqMet(logicalMultiCameraReqMet); - } else { - logicalMultiCameraReq.setFrontLogicalMultiCameraReqMet(logicalMultiCameraReqMet); - } + boolean meetH113 = (numOfPhysicalRgbCameras <= 1) || staticInfo.isLogicalMultiCamera(); + mCollector.expectTrue("Primary " + facingString + " camera must be LOGICAL_MULTI_CAMERA" + + " in case of multiple RGB cameras with same facing", + !assertTPerfClass || meetH113); + perfClassLevelH113 = updatePerfClassLevel(meetH113, perfClassLevelH113, + CameraTestUtils.PERFORMANCE_CLASS_S); + reportLog.addValue(facingString + " camera is LOGICAL_MULTI_CAMERA in case of multiple " + + "RGB cameras with same facing", meetH113, ResultType.NEUTRAL, + ResultUnit.NONE); // H-1-14 - boolean streamUseCaseSupported = staticInfo.isStreamUseCaseSupported(); - if (isPrimaryRear) { - streamUseCaseReq.setRearStreamUseCaseSupported(streamUseCaseSupported); - } else { - streamUseCaseReq.setFrontStreamUseCaseSupported(streamUseCaseSupported); - } + boolean meetH114 = staticInfo.isStreamUseCaseSupported(); + mCollector.expectTrue("Primary " + facingString + " camera must support stream " + + "use case", !assertTPerfClass || meetH114); + perfClassLevelH114 = updatePerfClassLevel(meetH114, perfClassLevelH114, + CameraTestUtils.PERFORMANCE_CLASS_S); + reportLog.addValue(facingString + " camera stream use case", meetH114, + ResultType.NEUTRAL, ResultUnit.NONE); } + HashSet<String> primaryCameras = new HashSet<String>(); + if (primaryRearId == null) { + mCollector.expectTrue("There must be a primary rear camera for performance class.", + !assertPerfClass); + perfClassLevelH11 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET; + } else { + primaryCameras.add(primaryRearId); + } + if (primaryFrontId == null) { + mCollector.expectTrue("There must be a primary front camera for performance class.", + !assertPerfClass); + perfClassLevelH12 = CameraTestUtils.PERFORMANCE_CLASS_NOT_MET; + } else { + primaryCameras.add(primaryFrontId); + } + // H-1-11 Set<Set<String>> concurrentCameraIds = mCameraManager.getConcurrentCameraIds(); boolean supportPrimaryFrontBack = concurrentCameraIds.contains(primaryCameras); - concurrentRearFrontReq.setConcurrentRearFrontSupported(supportPrimaryFrontBack); - - pce.submitAndCheck(); + mCollector.expectTrue("Concurrent primary front and primary back streaming must be " + + "supported", !assertTPerfClass || supportPrimaryFrontBack); + perfClassLevelH111 = updatePerfClassLevel(supportPrimaryFrontBack, + perfClassLevelH111, CameraTestUtils.PERFORMANCE_CLASS_S); + reportLog.addValue("concurrent front back support", supportPrimaryFrontBack, + ResultType.NEUTRAL, ResultUnit.NONE); + + reportLog.addValue("Version", "0.0.1", ResultType.NEUTRAL, ResultUnit.NONE); + final String PERF_CLASS_REQ_NUM_PREFIX = "2.2.7.2/7.5/"; + reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-1", + perfClassLevelH11, ResultType.NEUTRAL, ResultUnit.NONE); + reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-2", + perfClassLevelH12, ResultType.NEUTRAL, ResultUnit.NONE); + reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-3", + perfClassLevelH13, ResultType.NEUTRAL, ResultUnit.NONE); + reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-4", + perfClassLevelH14, ResultType.NEUTRAL, ResultUnit.NONE); + reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-8", + perfClassLevelH18, ResultType.NEUTRAL, ResultUnit.NONE); + reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-9", + perfClassLevelH19, ResultType.NEUTRAL, ResultUnit.NONE); + reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-10", + perfClassLevelH110, ResultType.NEUTRAL, ResultUnit.NONE); + reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-11", + perfClassLevelH111, ResultType.NEUTRAL, ResultUnit.NONE); + reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-12", + perfClassLevelH112, ResultType.NEUTRAL, ResultUnit.NONE); + reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-13", + perfClassLevelH113, ResultType.NEUTRAL, ResultUnit.NONE); + reportLog.addValue(PERF_CLASS_REQ_NUM_PREFIX + "H-1-14", + perfClassLevelH114, ResultType.NEUTRAL, ResultUnit.NONE); + reportLog.submit(InstrumentationRegistry.getInstrumentation()); } /** diff --git a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java index c9c28eac4bf..3c88a3a445c 100644 --- a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java +++ b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java @@ -1234,13 +1234,8 @@ public class RecordingTest extends Camera2SurfaceViewTestCase { mOutMediaFileName = mDebugFileNameBase + "/test_cslowMo_video_" + captureRate + "fps_" + id + "_" + size.toString() + ".mp4"; - - // b/239101664 It appears that video frame rates higher than 30 fps may not - // trigger slow motion recording consistently. - int videoFrameRate = previewFrameRate > VIDEO_FRAME_RATE ? - VIDEO_FRAME_RATE : previewFrameRate; - Log.v(TAG, "videoFrameRate:" + videoFrameRate); - prepareRecording(size, videoFrameRate, captureRate); + Log.v(TAG, "previewFrameRate:" + previewFrameRate); + prepareRecording(size, previewFrameRate, captureRate); SystemClock.sleep(PREVIEW_DURATION_MS); @@ -1248,7 +1243,7 @@ public class RecordingTest extends Camera2SurfaceViewTestCase { SimpleCaptureCallback resultListener = new SimpleCaptureCallback(); // Start recording - startSlowMotionRecording(/*useMediaRecorder*/true, videoFrameRate, + startSlowMotionRecording(/*useMediaRecorder*/true, previewFrameRate, captureRate, fpsRange, resultListener, /*useHighSpeedSession*/true); @@ -1261,7 +1256,7 @@ public class RecordingTest extends Camera2SurfaceViewTestCase { startConstrainedPreview(fpsRange, previewResultListener); // Convert number of frames camera produced into the duration in unit of ms. - float frameDurationMs = 1000.0f / videoFrameRate; + float frameDurationMs = 1000.0f / previewFrameRate; float durationMs = resultListener.getTotalNumFrames() * frameDurationMs; // Validation. diff --git a/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java b/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java index 4a86b49e51a..e8d616880e7 100644 --- a/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java +++ b/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java @@ -142,6 +142,8 @@ public class CameraTestUtils extends Assert { public static final String OFFLINE_CAMERA_ID = "offline_camera_id"; public static final String REPORT_LOG_NAME = "CtsCameraTestCases"; + public static final String MPC_REPORT_LOG_NAME = "MediaPerformanceClassLogs"; + public static final String MPC_STREAM_NAME = "CameraCts"; private static final int EXIF_DATETIME_LENGTH = 19; private static final int EXIF_DATETIME_ERROR_MARGIN_SEC = 60; @@ -3813,6 +3815,33 @@ public class CameraTestUtils extends Assert { return zoomRatios; } + public static final int PERFORMANCE_CLASS_NOT_MET = 0; + public static final int PERFORMANCE_CLASS_R = Build.VERSION_CODES.R; + public static final int PERFORMANCE_CLASS_S = Build.VERSION_CODES.R + 1; + public static final int PERFORMANCE_CLASS_T = Build.VERSION_CODES.S + 2; + public static final int PERFORMANCE_CLASS_CURRENT = PERFORMANCE_CLASS_T; + + /** + * Check whether this mobile device is R performance class as defined in CDD + */ + public static boolean isRPerfClass() { + return Build.VERSION.MEDIA_PERFORMANCE_CLASS == PERFORMANCE_CLASS_R; + } + + /** + * Check whether this mobile device is S performance class as defined in CDD + */ + public static boolean isSPerfClass() { + return Build.VERSION.MEDIA_PERFORMANCE_CLASS == PERFORMANCE_CLASS_S; + } + + /** + * Check whether this mobile device is T performance class as defined in CDD + */ + public static boolean isTPerfClass() { + return Build.VERSION.MEDIA_PERFORMANCE_CLASS == PERFORMANCE_CLASS_T; + } + /** * Check whether a camera Id is a primary rear facing camera */ diff --git a/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java b/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java index f1886859d67..fc8c4db5164 100644 --- a/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java +++ b/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java @@ -229,13 +229,6 @@ public class StaticMetadata { * at least the desired one (but could be higher) */ public boolean isHardwareLevelAtLeast(int level) { - int deviceLevel = getHardwareLevelChecked(); - - return hardwareLevelPredicate(deviceLevel, level); - } - - // Return true if level1 is at least level2 - public static boolean hardwareLevelPredicate(int level1, int level2) { final int[] sortedHwLevels = { CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY, CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL, @@ -243,19 +236,19 @@ public class StaticMetadata { CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL, CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3 }; - - if (level1 == level2) { + int deviceLevel = getHardwareLevelChecked(); + if (level == deviceLevel) { return true; } for (int sortedlevel : sortedHwLevels) { - if (sortedlevel == level2) { + if (sortedlevel == level) { return true; - } else if (sortedlevel == level1) { + } else if (sortedlevel == deviceLevel) { return false; } } - Assert.fail("Unknown hardwareLevel " + level1 + " and device hardware level " + level2); + Assert.fail("Unknown hardwareLevel " + level + " and device hardware level " + deviceLevel); return false; } diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagementRoleHolderTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagementRoleHolderTest.java index eee4b10d821..286ccae00a8 100644 --- a/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagementRoleHolderTest.java +++ b/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagementRoleHolderTest.java @@ -65,7 +65,6 @@ import com.android.bedstead.nene.utils.Poll; import com.android.bedstead.remotedpc.RemoteDpc; import com.android.bedstead.testapp.TestApp; import com.android.bedstead.testapp.TestAppInstance; -import com.android.compatibility.common.util.CddTest; import com.android.eventlib.truth.EventLogsSubject; import com.android.queryable.queries.ActivityQuery; @@ -141,7 +140,6 @@ public class DevicePolicyManagementRoleHolderTest { @EnsureHasNoDpc @EnsureHasNoSecondaryUser @Test - @CddTest(requirements = {"3.9.4/C-3-1"}) public void createAndProvisionManagedProfile_roleHolderIsInWorkProfile() throws ProvisioningException, InterruptedException { UserHandle profile = null; @@ -175,7 +173,6 @@ public class DevicePolicyManagementRoleHolderTest { @RequireRunOnPrimaryUser @EnsureHasNoSecondaryUser @Test - @CddTest(requirements = {"3.9.4/C-3-1"}) public void createAndManageUser_roleHolderIsInManagedUser() throws InterruptedException { UserHandle managedUser = null; String roleHolderPackageName = null; diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagerTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagerTest.java index ae9ced5fd3a..11b5fd40842 100644 --- a/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagerTest.java +++ b/tests/devicepolicy/src/android/devicepolicy/cts/DevicePolicyManagerTest.java @@ -54,6 +54,7 @@ import static org.junit.Assert.assertThrows; import android.accounts.Account; import android.accounts.AccountManager; +import android.annotation.RequiresFeature; import android.app.AppOpsManager; import android.app.admin.DevicePolicyManager; import android.app.admin.FullyManagedDeviceProvisioningParams; @@ -105,7 +106,6 @@ import com.android.bedstead.nene.users.UserReference; import com.android.bedstead.nene.users.UserType; import com.android.bedstead.remotedpc.RemoteDpc; import com.android.bedstead.testapp.TestAppInstance; -import com.android.compatibility.common.util.ApiTest; import com.android.compatibility.common.util.SystemUtil; import com.android.eventlib.events.broadcastreceivers.BroadcastReceivedEvent; @@ -1354,8 +1354,7 @@ public final class DevicePolicyManagerTest { @RequireRunOnSecondaryUser @EnsureHasNoProfileOwner @RequireNotHeadlessSystemUserMode - @RequireFeature(FEATURE_DEVICE_ADMIN) - @ApiTest(apis = "android.app.admin.DevicePolicyManager#checkProvisioningPrecondition") + @RequiresFeature(FEATURE_DEVICE_ADMIN) public void checkProvisioningPreCondition_actionDO_onNonSystemUser_returnsNotSystemUser() { boolean setupComplete = TestApis.users().current().getSetupComplete(); TestApis.users().current().setSetupComplete(false); @@ -1376,8 +1375,6 @@ public final class DevicePolicyManagerTest { @Postsubmit(reason = "New test") @Test @EnsureDoesNotHavePermission(MANAGE_PROFILE_AND_DEVICE_OWNERS) - @RequireFeature(FEATURE_DEVICE_ADMIN) - @ApiTest(apis = "android.app.admin.DevicePolicyManager#setUserProvisioningState") public void setUserProvisioningState_withoutRequiredPermission_throwsSecurityException() { assertThrows(SecurityException.class, () -> sDevicePolicyManager.setUserProvisioningState( @@ -1670,8 +1667,6 @@ public final class DevicePolicyManagerTest { @RequireRunOnPrimaryUser @EnsureHasSecondaryUser @EnsureHasPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS) - @RequireFeature(FEATURE_DEVICE_ADMIN) - @ApiTest(apis = "android.app.admin.DevicePolicyManager#finalizeWorkProfileProvisioning") public void finalizeWorkProfileProvisioning_managedUser_throwsException() { RemoteDpc dpc = RemoteDpc.setAsProfileOwner(sDeviceState.secondaryUser()); try { diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/UserControlDisabledPackagesTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/UserControlDisabledPackagesTest.java index dfe77fb4121..fcf71d0a19c 100644 --- a/tests/devicepolicy/src/android/devicepolicy/cts/UserControlDisabledPackagesTest.java +++ b/tests/devicepolicy/src/android/devicepolicy/cts/UserControlDisabledPackagesTest.java @@ -45,7 +45,6 @@ import com.android.bedstead.harrier.policies.UserControlDisabledPackages; import com.android.bedstead.metricsrecorder.EnterpriseMetricsRecorder; import com.android.bedstead.nene.TestApis; import com.android.bedstead.nene.packages.Package; -import com.android.bedstead.nene.utils.Poll; import com.android.bedstead.testapp.TestApp; import com.android.bedstead.testapp.TestAppInstance; import com.android.queryable.queries.StringQuery; @@ -236,11 +235,6 @@ public final class UserControlDisabledPackagesTest { private void assertPackageStopped(String packageName) throws Exception { - Poll.forValue("Package " + packageName + " stopped", () -> isPackageStopped(packageName)) - .toBeEqualTo(true) - .errorOnFail() - .await(); - assertWithMessage("Package %s not stopped", packageName) .that(isPackageStopped(packageName)).isTrue(); } diff --git a/tests/framework/base/biometrics/src/android/server/biometrics/BiometricActivityTests.java b/tests/framework/base/biometrics/src/android/server/biometrics/BiometricActivityTests.java index 2f7339ad1b7..07d6cc8f48e 100644 --- a/tests/framework/base/biometrics/src/android/server/biometrics/BiometricActivityTests.java +++ b/tests/framework/base/biometrics/src/android/server/biometrics/BiometricActivityTests.java @@ -40,7 +40,6 @@ import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import org.junit.Ignore; import org.junit.Test; /** @@ -238,8 +237,6 @@ public class BiometricActivityTests extends BiometricTestBase { assertEquals(callbackState.toString(), 1, callbackState.mNumAuthRejected); } - // TODO(b/236763921): fix this test and unignore. - @Ignore @Test public void testBiometricOnly_negativeButtonInvoked() throws Exception { assumeTrue(Utils.isFirstApiLevel29orGreater()); @@ -288,8 +285,6 @@ public class BiometricActivityTests extends BiometricTestBase { } - // TODO(b/236763921): fix this test and unignore. - @Ignore @Test public void testBiometricOrCredential_credentialButtonInvoked_biometricEnrolled() throws Exception { diff --git a/tests/framework/base/biometrics/src/android/server/biometrics/BiometricSimpleTests.java b/tests/framework/base/biometrics/src/android/server/biometrics/BiometricSimpleTests.java index 30af1e78562..fd42e71cc06 100644 --- a/tests/framework/base/biometrics/src/android/server/biometrics/BiometricSimpleTests.java +++ b/tests/framework/base/biometrics/src/android/server/biometrics/BiometricSimpleTests.java @@ -43,7 +43,6 @@ import android.util.Log; import com.android.server.biometrics.nano.SensorStateProto; -import org.junit.Ignore; import org.junit.Test; import org.mockito.ArgumentCaptor; @@ -302,10 +301,7 @@ public class BiometricSimpleTests extends BiometricTestBase { * * Upon successful authentication, checks that the result is * {@link BiometricPrompt#AUTHENTICATION_RESULT_TYPE_BIOMETRIC} - * - * TODO(b/236763921): fix this test and unignore. */ - @Ignore @Test public void testSimpleBiometricAuth_nonConvenience() throws Exception { assumeTrue(Utils.isFirstApiLevel29orGreater()); diff --git a/tests/framework/base/localeconfig/Android.bp b/tests/framework/base/localeconfig/Android.bp index a0485a43655..80b00f3e49d 100644 --- a/tests/framework/base/localeconfig/Android.bp +++ b/tests/framework/base/localeconfig/Android.bp @@ -43,7 +43,6 @@ android_test { sdk_version: "test_current", data: [ - ":CtsMalformedInputTests", ":CtsNoLocaleConfigTagTests", ], per_testcase_directory: true, diff --git a/tests/framework/base/windowmanager/Android.bp b/tests/framework/base/windowmanager/Android.bp index b786d833b67..168ee3f24b6 100644 --- a/tests/framework/base/windowmanager/Android.bp +++ b/tests/framework/base/windowmanager/Android.bp @@ -67,7 +67,6 @@ android_test { "cts-wm-overlayapp-base", "cts-wm-shared", "platform-compat-test-rules", - "cts_window_jetpack_utils", ], test_suites: [ diff --git a/tests/framework/base/windowmanager/AndroidManifest.xml b/tests/framework/base/windowmanager/AndroidManifest.xml index 1a86422e02c..39c3d3ecbfd 100644 --- a/tests/framework/base/windowmanager/AndroidManifest.xml +++ b/tests/framework/base/windowmanager/AndroidManifest.xml @@ -38,8 +38,6 @@ android:enableOnBackInvokedCallback="true" android:testOnly="true"> <uses-library android:name="android.test.runner"/> - <uses-library android:name="androidx.window.extensions" - android:required="false" /> <activity android:name="android.server.wm.ActivityManagerTestBase$ConfigChangeHandlingActivity" android:resizeableActivity="true" diff --git a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/ActivityEmbeddingUtil.java b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/ActivityEmbeddingUtil.java index 477cc8d7f4b..5dad58200b6 100644 --- a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/ActivityEmbeddingUtil.java +++ b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/ActivityEmbeddingUtil.java @@ -16,7 +16,6 @@ package android.server.wm.jetpack.utils; -import static android.server.wm.jetpack.utils.ExtensionUtil.assumeExtensionSupportedDevice; import static android.server.wm.jetpack.utils.ExtensionUtil.getWindowExtensions; import static android.server.wm.jetpack.utils.WindowManagerJetpackTestBase.getActivityBounds; import static android.server.wm.jetpack.utils.WindowManagerJetpackTestBase.getMaximumActivityBounds; @@ -29,7 +28,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static org.junit.Assume.assumeTrue; import android.app.Activity; import android.content.ComponentName; @@ -53,7 +51,6 @@ import com.android.compatibility.common.util.PollingCheck; import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.Objects; import java.util.function.Predicate; /** @@ -219,13 +216,19 @@ public class ActivityEmbeddingUtil { /** * Attempts to start an activity from a different UID into a split, verifies that activity - * did not start on splitContainer successfully and no new split is active. + * start did not succeed and no new split is active. */ public static void startActivityCrossUidInSplit_expectFail(@NonNull Activity primaryActivity, @NonNull ComponentName secondActivityComponent, @NonNull TestValueCountConsumer<List<SplitInfo>> splitInfoConsumer) { - startActivityFromActivity(primaryActivity, secondActivityComponent, "secondActivityId", + boolean startExceptionObserved = false; + try { + startActivityFromActivity(primaryActivity, secondActivityComponent, "secondActivityId", Bundle.EMPTY); + } catch (SecurityException e) { + startExceptionObserved = true; + } + assertTrue(startExceptionObserved); // No split should be active, primary activity should be covered by the new one. assertNoSplit(primaryActivity, splitInfoConsumer); @@ -450,13 +453,6 @@ public class ActivityEmbeddingUtil { } } - public static void assumeActivityEmbeddingSupportedDevice() { - assumeExtensionSupportedDevice(); - assumeTrue("Device does not support ActivityEmbedding", - Objects.requireNonNull(getWindowExtensions()) - .getActivityEmbeddingComponent() != null); - } - private static void assertSplitInfoTopSplitIsCorrect(@NonNull List<SplitInfo> splitInfoList, @NonNull Activity primaryActivity, @NonNull Activity secondaryActivity) { assertFalse("Split info callback should not be empty", splitInfoList.isEmpty()); diff --git a/tests/framework/base/windowmanager/src/android/server/wm/BackNavigationLegacyGestureTest.java b/tests/framework/base/windowmanager/src/android/server/wm/BackNavigationLegacyGestureTest.java deleted file mode 100644 index b6c43f1b490..00000000000 --- a/tests/framework/base/windowmanager/src/android/server/wm/BackNavigationLegacyGestureTest.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.server.wm; - -import static android.server.wm.WindowManagerState.STATE_RESUMED; -import static android.server.wm.WindowManagerState.STATE_STOPPED; -import static android.server.wm.backlegacyapp.Components.BACK_LEGACY; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import android.app.Instrumentation; -import android.server.wm.TestJournalProvider.TestJournalContainer; -import android.server.wm.backlegacyapp.Components; -import android.support.test.uiautomator.UiDevice; - -import androidx.test.platform.app.InstrumentationRegistry; - -import com.android.compatibility.common.util.GestureNavRule; - -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Test; - -/** - * Integration test for back navigation legacy mode - */ -public class BackNavigationLegacyGestureTest extends ActivityManagerTestBase { - private Instrumentation mInstrumentation; - - @ClassRule - public static GestureNavRule GESTURE_NAV_RULE = new GestureNavRule(); - private UiDevice mUiDevice; - - @Before - public void setup() { - GESTURE_NAV_RULE.assumeGestureNavigationMode(); - mInstrumentation = InstrumentationRegistry.getInstrumentation(); - } - - @Test - public void receiveOnBackPressed() { - TestJournalContainer.start(); - launchActivity(BACK_LEGACY); - mWmState.assertActivityDisplayed(BACK_LEGACY); - waitAndAssertActivityState(BACK_LEGACY, STATE_RESUMED, "Activity should be resumed"); - mUiDevice = UiDevice.getInstance(mInstrumentation); - doBackGesture(); - waitAndAssertActivityState(BACK_LEGACY, STATE_STOPPED, "Activity should be stopped"); - assertTrue("OnBackPressed should have been called", - TestJournalContainer.get(BACK_LEGACY).extras.getBoolean( - Components.KEY_ON_BACK_PRESSED_CALLED)); - assertFalse("OnBackInvoked should not have been called", - TestJournalContainer.get(BACK_LEGACY).extras.getBoolean( - Components.KEY_ON_BACK_INVOKED_CALLED)); - } - - /** - * Do a back gesture. (Swipe) - */ - private void doBackGesture() { - int midHeight = mUiDevice.getDisplayHeight() / 2; - int midWidth = mUiDevice.getDisplayWidth() / 2; - mUiDevice.swipe(0, midHeight, midWidth, midHeight, 100); - mUiDevice.waitForIdle(); - } -} diff --git a/tests/framework/base/windowmanager/src/android/server/wm/BackNavigationLegacyTest.java b/tests/framework/base/windowmanager/src/android/server/wm/BackNavigationLegacyTest.java index e7d6ba88412..38d9e6239fe 100644 --- a/tests/framework/base/windowmanager/src/android/server/wm/BackNavigationLegacyTest.java +++ b/tests/framework/base/windowmanager/src/android/server/wm/BackNavigationLegacyTest.java @@ -16,7 +16,6 @@ package android.server.wm; import static android.server.wm.WindowManagerState.STATE_RESUMED; -import static android.server.wm.WindowManagerState.STATE_STOPPED; import static android.server.wm.backlegacyapp.Components.BACK_LEGACY; import static org.junit.Assert.assertFalse; @@ -39,8 +38,6 @@ import org.junit.Test; public class BackNavigationLegacyTest extends ActivityManagerTestBase { private Instrumentation mInstrumentation; - private UiDevice mUiDevice; - @Before public void setup() { mInstrumentation = InstrumentationRegistry.getInstrumentation(); @@ -53,9 +50,7 @@ public class BackNavigationLegacyTest extends ActivityManagerTestBase { launchActivity(BACK_LEGACY); mWmState.assertActivityDisplayed(BACK_LEGACY); waitAndAssertActivityState(BACK_LEGACY, STATE_RESUMED, "Activity should be resumed"); - mUiDevice = UiDevice.getInstance(mInstrumentation); - mUiDevice.pressKeyCode(KeyEvent.KEYCODE_BACK); - waitAndAssertActivityState(BACK_LEGACY, STATE_STOPPED, "Activity should be stopped"); + UiDevice.getInstance(mInstrumentation).pressKeyCode(KeyEvent.KEYCODE_BACK); assertTrue("OnBackPressed should have been called", TestJournalContainer.get(BACK_LEGACY).extras.getBoolean( Components.KEY_ON_BACK_PRESSED_CALLED)); diff --git a/tests/framework/base/windowmanager/src/android/server/wm/TaskFragmentOrganizerPolicyTest.java b/tests/framework/base/windowmanager/src/android/server/wm/TaskFragmentOrganizerPolicyTest.java index d49948ffb5d..318e6f76104 100644 --- a/tests/framework/base/windowmanager/src/android/server/wm/TaskFragmentOrganizerPolicyTest.java +++ b/tests/framework/base/windowmanager/src/android/server/wm/TaskFragmentOrganizerPolicyTest.java @@ -27,13 +27,11 @@ import static android.server.wm.app30.Components.SDK_30_TEST_ACTIVITY; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth.assertWithMessage; import static org.junit.Assert.assertEquals; import android.app.Activity; import android.app.Instrumentation; -import android.content.ComponentName; import android.content.Intent; import android.graphics.Rect; import android.os.Binder; @@ -41,7 +39,6 @@ import android.os.IBinder; import android.platform.test.annotations.Presubmit; import android.server.wm.TaskFragmentOrganizerTestBase.BasicTaskFragmentOrganizer; import android.server.wm.WindowContextTests.TestActivity; -import android.server.wm.WindowManagerState.Task; import android.window.TaskAppearedInfo; import android.window.TaskFragmentCreationParams; import android.window.TaskFragmentInfo; @@ -199,13 +196,18 @@ public class TaskFragmentOrganizerPolicyTest extends ActivityManagerTestBase { null /* activityOptions */); mTaskFragmentOrganizer.applyTransaction(wct); + + mTaskFragmentOrganizer.waitForTaskFragmentCreated(); + + TaskFragmentInfo info = mTaskFragmentOrganizer.getTaskFragmentInfo(taskFragToken); + + // TaskFragment must remain empty because embedding activities in a new task is not allowed. + assertEmptyTaskFragment(info, taskFragToken); + mTaskFragmentOrganizer.waitForTaskFragmentError(); assertThat(mTaskFragmentOrganizer.getThrowable()).isInstanceOf(SecurityException.class); assertThat(mTaskFragmentOrganizer.getErrorCallbackToken()).isEqualTo(errorCallbackToken); - - // Activity must be launched on a new task instead. - waitAndAssertActivityLaunchOnTask(LAUNCHING_ACTIVITY); } /** @@ -231,20 +233,9 @@ public class TaskFragmentOrganizerPolicyTest extends ActivityManagerTestBase { mTaskFragmentOrganizer.waitForTaskFragmentError(); assertThat(mTaskFragmentOrganizer.getThrowable()).isInstanceOf(SecurityException.class); - // Making sure activity is not launched on the TaskFragment + // Making sure no activity launched TaskFragmentInfo info = mTaskFragmentOrganizer.getTaskFragmentInfo(taskFragToken); assertEmptyTaskFragment(info, taskFragToken); - - // Activity must be launched on a new task instead. - waitAndAssertActivityLaunchOnTask(SDK_30_TEST_ACTIVITY); - } - - private void waitAndAssertActivityLaunchOnTask(ComponentName activityName) { - waitAndAssertResumedActivity(activityName, "Activity must be resumed."); - - Task task = mWmState.getTaskByActivity(activityName); - assertWithMessage("Launching activity must be started on Task") - .that(task.getActivities()).contains(mWmState.getActivity(activityName)); } /** diff --git a/tests/framework/base/windowmanager/src/android/server/wm/TaskFragmentTrustedModeTest.java b/tests/framework/base/windowmanager/src/android/server/wm/TaskFragmentTrustedModeTest.java index 9fd1a41a416..385a5af9ed6 100644 --- a/tests/framework/base/windowmanager/src/android/server/wm/TaskFragmentTrustedModeTest.java +++ b/tests/framework/base/windowmanager/src/android/server/wm/TaskFragmentTrustedModeTest.java @@ -18,10 +18,8 @@ package android.server.wm; import static android.server.wm.WindowManagerState.STATE_RESUMED; import static android.server.wm.jetpack.second.Components.SECOND_UNTRUSTED_EMBEDDING_ACTIVITY; -import static android.server.wm.jetpack.utils.ActivityEmbeddingUtil.assumeActivityEmbeddingSupportedDevice; import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth.assertWithMessage; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -34,7 +32,6 @@ import android.content.Intent; import android.graphics.Rect; import android.os.Binder; import android.os.IBinder; -import android.platform.test.annotations.Presubmit; import android.server.wm.WindowManagerState.Task; import android.window.TaskFragmentCreationParams; import android.window.TaskFragmentInfo; @@ -42,7 +39,6 @@ import android.window.WindowContainerTransaction; import androidx.annotation.NonNull; -import org.junit.Before; import org.junit.Test; /** @@ -51,19 +47,11 @@ import org.junit.Test; * Build/Install/Run: * atest CtsWindowManagerDeviceTestCases:TaskFragmentTrustedModeTest */ -@Presubmit public class TaskFragmentTrustedModeTest extends TaskFragmentOrganizerTestBase { private final ComponentName mTranslucentActivity = new ComponentName(mContext, TranslucentActivity.class); - @Before - @Override - public void setUp() throws Exception { - super.setUp(); - assumeActivityEmbeddingSupportedDevice(); - } - /** * Verifies the visibility of a task fragment that has overlays on top of activities embedded * in untrusted mode when there is an overlay over the task fragment. @@ -251,7 +239,7 @@ public class TaskFragmentTrustedModeTest extends TaskFragmentOrganizerTestBase { */ @Test public void testUntrustedModeTaskFragment_startActivityInTaskFragmentOutsideOfParentBounds() { - Task parentTask = mWmState.getRootTask(mOwnerTaskId); + final Task parentTask = mWmState.getRootTask(mOwnerTaskId); final Rect parentBounds = new Rect(parentTask.getBounds()); final IBinder errorCallbackToken = new Binder(); final WindowContainerTransaction wct = new WindowContainerTransaction() @@ -266,11 +254,8 @@ public class TaskFragmentTrustedModeTest extends TaskFragmentOrganizerTestBase { // It is disallowed to start activity to TaskFragment with bounds outside of its parent // in untrusted mode. assertTaskFragmentError(errorCallbackToken, SecurityException.class); - - parentTask = mWmState.getRootTask(mOwnerTaskId); - assertWithMessage("Activity must be started in parent Task because it's not" - + " allowed to be embedded").that(parentTask.mActivities).contains( - mWmState.getActivity(SECOND_UNTRUSTED_EMBEDDING_ACTIVITY)); + mWmState.waitForAppTransitionIdleOnDisplay(mOwnerActivity.getDisplayId()); + mWmState.assertNotExist(SECOND_UNTRUSTED_EMBEDDING_ACTIVITY); } /** diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsControllerTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsControllerTests.java index 8dc33b1f745..65465b27895 100644 --- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsControllerTests.java +++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsControllerTests.java @@ -59,7 +59,6 @@ import android.app.AlertDialog; import android.app.Instrumentation; import android.content.Context; import android.content.pm.PackageManager; -import android.content.res.Resources; import android.os.Bundle; import android.os.SystemClock; import android.platform.test.annotations.Presubmit; @@ -227,11 +226,6 @@ public class WindowInsetsControllerTests extends WindowManagerTestBase { final Instrumentation instrumentation = getInstrumentation(); assumeThat(MockImeSession.getUnavailabilityReason(instrumentation.getContext()), nullValue()); - final Resources resources = instrumentation.getContext().getResources(); - final boolean isHideNavBarForKeyboardEnabled = resources.getBoolean( - resources.getIdentifier("config_hideNavBarForKeyboard", "bool", "android")); - assumeFalse("Device is configured to not show navigation bar for keyboard", - isHideNavBarForKeyboardEnabled); final MockImeSession imeSession = MockImeHelper.createManagedMockImeSession(this); final ImeEventStream stream = imeSession.openEventStream(); final TestActivity activity = startActivityInWindowingModeFullScreen(TestActivity.class); diff --git a/tests/inputmethod/mockime/src/com/android/cts/mockime/Watermark.java b/tests/inputmethod/mockime/src/com/android/cts/mockime/Watermark.java index 8855dee537b..ccd8659e3de 100644 --- a/tests/inputmethod/mockime/src/com/android/cts/mockime/Watermark.java +++ b/tests/inputmethod/mockime/src/com/android/cts/mockime/Watermark.java @@ -32,7 +32,7 @@ public final class Watermark { * * <p>See Bug 174534092 about why we ended up having this.</p> */ - private static final int TOLERANCE = 6; + private static final int TOLERANCE = 4; /** * A utility class that represents A8R8G8B bitmap as an integer array. diff --git a/tests/media/src/android/mediav2/cts/CodecInfoTest.java b/tests/media/src/android/mediav2/cts/CodecInfoTest.java index 39b90fff698..5f9aa09c891 100644 --- a/tests/media/src/android/mediav2/cts/CodecInfoTest.java +++ b/tests/media/src/android/mediav2/cts/CodecInfoTest.java @@ -158,10 +158,10 @@ public class CodecInfoTest { .noneMatch(x -> x == COLOR_FormatSurface)); } - // For devices launching with Android T, if a codec supports an HDR profile and device - // supports HDR display, it must advertise P010 support + // For devices launching with Android T, if a codec supports an HDR profile, it must + // advertise P010 support int[] HdrProfileArray = mProfileHdrMap.get(mMediaType); - if (FIRST_SDK_IS_AT_LEAST_T && HdrProfileArray != null && DISPLAY_HDR_TYPES.length > 0) { + if (FIRST_SDK_IS_AT_LEAST_T && HdrProfileArray != null) { for (CodecProfileLevel pl : caps.profileLevels) { if (IntStream.of(HdrProfileArray).anyMatch(x -> x == pl.profile)) { assertFalse(mCodecInfo.getName() + " supports HDR profile " + pl.profile + "," + diff --git a/tests/media/src/android/mediav2/cts/EncodeDecodeAccuracyTest.java b/tests/media/src/android/mediav2/cts/EncodeDecodeAccuracyTest.java index ebed139fc53..b11343c6632 100644 --- a/tests/media/src/android/mediav2/cts/EncodeDecodeAccuracyTest.java +++ b/tests/media/src/android/mediav2/cts/EncodeDecodeAccuracyTest.java @@ -55,10 +55,9 @@ public class EncodeDecodeAccuracyTest extends CodecDecoderTestBase { // qp of the encoded clips shall drop down to < 10. Further the color bands are aligned to 2, // so from downsampling rgb24 to yuv420p, even if bilinear filters are used as opposed to // skipping samples, we may not see large color loss. Hence allowable tolerance is kept to 5. - // until QP stabilizes, the tolerance is set at 7. For devices upgrading to T, thresholds are - // relaxed to 8 and 10. - private final int TRANSIENT_STATE_COLOR_DELTA = FIRST_SDK_IS_AT_LEAST_T ? 7: 10; - private final int STEADY_STATE_COLOR_DELTA = FIRST_SDK_IS_AT_LEAST_T ? 5: 8; + // until QP stabilizes, the tolerance is set at 7. + private final int TRANSIENT_STATE_COLOR_DELTA = 7; + private final int STEADY_STATE_COLOR_DELTA = 5; private final int[][] mColorBars = new int[][]{ {66, 133, 244}, {219, 68, 55}, diff --git a/tests/mediapc/AndroidTest.xml b/tests/mediapc/AndroidTest.xml index dc36e586b2d..dcc8995c3a6 100644 --- a/tests/mediapc/AndroidTest.xml +++ b/tests/mediapc/AndroidTest.xml @@ -24,11 +24,6 @@ <option name="config-filename" value="CtsMediaPerformanceClassTestCases" /> <option name="version" value="1.0"/> </target_preparer> - <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher"> - <option name="target" value="device" /> - <option name="config-filename" value="CtsMediaPerformanceClassTestCases" /> - <option name="version" value="1.0"/> - </target_preparer> <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer"> <option name="push-all" value="true" /> <option name="media-folder-name" value="CtsMediaPerformanceClassTestCases-1.2" /> 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 d3fd2921d5a..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,7 +20,6 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assume.assumeTrue; -import android.hardware.camera2.CameraMetadata; import android.media.MediaFormat; import android.os.Build; @@ -850,493 +849,7 @@ public class PerformanceClassEvaluator { } } - public static class PrimaryCameraRequirement extends Requirement { - private static final long MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION = 12000000; - private static final long MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION = 5000000; - private static final long MIN_FRONT_SENSOR_R_PERF_CLASS_RESOLUTION = 4000000; - private static final String TAG = PrimaryCameraRequirement.class.getSimpleName(); - - private PrimaryCameraRequirement(String id, RequiredMeasurement<?> ... reqs) { - super(id, reqs); - } - - public void setPrimaryCameraSupported(boolean hasPrimaryCamera) { - this.setMeasuredValue(RequirementConstants.PRIMARY_CAMERA_AVAILABLE, - hasPrimaryCamera); - } - - public void setResolution(long resolution) { - this.setMeasuredValue(RequirementConstants.PRIMARY_CAMERA_RESOLUTION, - resolution); - } - - public void setVideoSizeReqSatisfied(boolean videoSizeReqSatisfied) { - this.setMeasuredValue(RequirementConstants.PRIMARY_CAMERA_VIDEO_SIZE_REQ_SATISFIED, - videoSizeReqSatisfied); - } - - public void setVideoFps(double videoFps) { - this.setMeasuredValue(RequirementConstants.PRIMARY_CAMERA_VIDEO_FPS, videoFps); - } - - /** - * [2.2.7.2/7.5/H-1-1] MUST have a primary rear facing camera with a resolution of at - * least 12 megapixels supporting video capture at 4k@30fps - */ - public static PrimaryCameraRequirement createRearPrimaryCamera() { - RequiredMeasurement<Boolean> hasPrimaryCamera = RequiredMeasurement - .<Boolean>builder() - .setId(RequirementConstants.PRIMARY_CAMERA_AVAILABLE) - .setPredicate(RequirementConstants.BOOLEAN_EQ) - .addRequiredValue(Build.VERSION_CODES.R, true) - .addRequiredValue(Build.VERSION_CODES.S, true) - .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true) - .build(); - - RequiredMeasurement<Long> cameraResolution = RequiredMeasurement - .<Long>builder() - .setId(RequirementConstants.PRIMARY_CAMERA_RESOLUTION) - .setPredicate(RequirementConstants.LONG_GTE) - .addRequiredValue(Build.VERSION_CODES.R, MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION) - .addRequiredValue(Build.VERSION_CODES.S, MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION) - .addRequiredValue(Build.VERSION_CODES.TIRAMISU, MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION) - .build(); - - RequiredMeasurement<Boolean> videoSizeReqSatisfied = RequiredMeasurement - .<Boolean>builder() - .setId(RequirementConstants.PRIMARY_CAMERA_VIDEO_SIZE_REQ_SATISFIED) - .setPredicate(RequirementConstants.BOOLEAN_EQ) - .addRequiredValue(Build.VERSION_CODES.R, true) - .addRequiredValue(Build.VERSION_CODES.S, true) - .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true) - .build(); - - RequiredMeasurement<Double> videoFps = RequiredMeasurement - .<Double>builder() - .setId(RequirementConstants.PRIMARY_CAMERA_VIDEO_FPS) - .setPredicate(RequirementConstants.DOUBLE_GTE) - .addRequiredValue(Build.VERSION_CODES.R, 29.9) - .addRequiredValue(Build.VERSION_CODES.S, 29.9) - .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 29.9) - .build(); - - return new PrimaryCameraRequirement(RequirementConstants.R7_5__H_1_1, - hasPrimaryCamera, cameraResolution, videoSizeReqSatisfied, - videoFps); - } - - /** - * [2.2.7.2/7.5/H-1-2] MUST have a primary front facing camera with a resolution of - * at least 4 megapixels supporting video capture at 1080p@30fps. - */ - public static PrimaryCameraRequirement createFrontPrimaryCamera() { - RequiredMeasurement<Boolean> hasPrimaryCamera = RequiredMeasurement - .<Boolean>builder() - .setId(RequirementConstants.PRIMARY_CAMERA_AVAILABLE) - .setPredicate(RequirementConstants.BOOLEAN_EQ) - .addRequiredValue(Build.VERSION_CODES.R, true) - .addRequiredValue(Build.VERSION_CODES.S, true) - .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true) - .build(); - - RequiredMeasurement<Long> cameraResolution = RequiredMeasurement - .<Long>builder() - .setId(RequirementConstants.PRIMARY_CAMERA_RESOLUTION) - .setPredicate(RequirementConstants.LONG_GTE) - .addRequiredValue(Build.VERSION_CODES.R, MIN_FRONT_SENSOR_R_PERF_CLASS_RESOLUTION) - .addRequiredValue(Build.VERSION_CODES.S, MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION) - .addRequiredValue(Build.VERSION_CODES.TIRAMISU, - MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION) - .build(); - - RequiredMeasurement<Boolean> videoSizeReqSatisfied = RequiredMeasurement - .<Boolean>builder() - .setId(RequirementConstants.PRIMARY_CAMERA_VIDEO_SIZE_REQ_SATISFIED) - .setPredicate(RequirementConstants.BOOLEAN_EQ) - .addRequiredValue(Build.VERSION_CODES.R, true) - .addRequiredValue(Build.VERSION_CODES.S, true) - .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true) - .build(); - - RequiredMeasurement<Double> videoFps = RequiredMeasurement - .<Double>builder() - .setId(RequirementConstants.PRIMARY_CAMERA_VIDEO_FPS) - .setPredicate(RequirementConstants.DOUBLE_GTE) - .addRequiredValue(Build.VERSION_CODES.R, 29.9) - .addRequiredValue(Build.VERSION_CODES.S, 29.9) - .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 29.9) - .build(); - - return new PrimaryCameraRequirement(RequirementConstants.R7_5__H_1_2, - hasPrimaryCamera, cameraResolution, videoSizeReqSatisfied, - videoFps); - } - } - - public static class CameraTimestampSourceRequirement extends Requirement { - private static final String TAG = CameraTimestampSourceRequirement.class.getSimpleName(); - private static final int TIMESTAMP_REALTIME = - CameraMetadata.SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME; - - private CameraTimestampSourceRequirement(String id, RequiredMeasurement<?> ... reqs) { - super(id, reqs); - } - - public void setRearCameraTimestampSource(Integer timestampSource) { - this.setMeasuredValue(RequirementConstants.REAR_CAMERA_TIMESTAMP_SOURCE, - timestampSource); - } - - public void setFrontCameraTimestampSource(Integer timestampSource) { - this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_TIMESTAMP_SOURCE, - timestampSource); - } - /** - * [2.2.7.2/7.5/H-1-4] MUST support CameraMetadata.SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME - * for both primary cameras. - */ - public static CameraTimestampSourceRequirement createTimestampSourceReq() { - RequiredMeasurement<Integer> rearTimestampSource = RequiredMeasurement - .<Integer>builder() - .setId(RequirementConstants.REAR_CAMERA_TIMESTAMP_SOURCE) - .setPredicate(RequirementConstants.INTEGER_EQ) - .addRequiredValue(Build.VERSION_CODES.R, TIMESTAMP_REALTIME) - .addRequiredValue(Build.VERSION_CODES.S, TIMESTAMP_REALTIME) - .addRequiredValue(Build.VERSION_CODES.TIRAMISU, TIMESTAMP_REALTIME) - .build(); - RequiredMeasurement<Integer> frontTimestampSource = RequiredMeasurement - .<Integer>builder() - .setId(RequirementConstants.FRONT_CAMERA_TIMESTAMP_SOURCE) - .setPredicate(RequirementConstants.INTEGER_EQ) - .addRequiredValue(Build.VERSION_CODES.R, TIMESTAMP_REALTIME) - .addRequiredValue(Build.VERSION_CODES.S, TIMESTAMP_REALTIME) - .addRequiredValue(Build.VERSION_CODES.TIRAMISU, TIMESTAMP_REALTIME) - .build(); - - return new CameraTimestampSourceRequirement(RequirementConstants.R7_5__H_1_4, - rearTimestampSource, frontTimestampSource); - } - } - - public static class CameraLatencyRequirement extends Requirement { - private static final String TAG = CameraTimestampSourceRequirement.class.getSimpleName(); - - private CameraLatencyRequirement(String id, RequiredMeasurement<?> ... reqs) { - super(id, reqs); - } - - public void setRearCameraLatency(float latency) { - this.setMeasuredValue(RequirementConstants.REAR_CAMERA_LATENCY, latency); - } - - public void setFrontCameraLatency(float latency) { - this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_LATENCY, latency); - } - - /** - * [2.2.7.2/7.5/H-1-5] MUST have camera2 JPEG capture latency < 1000ms for 1080p resolution - * as measured by the CTS camera PerformanceTest under ITS lighting conditions - * (3000K) for both primary cameras. - */ - public static CameraLatencyRequirement createJpegLatencyReq() { - RequiredMeasurement<Float> rearJpegLatency = RequiredMeasurement - .<Float>builder() - .setId(RequirementConstants.REAR_CAMERA_LATENCY) - .setPredicate(RequirementConstants.FLOAT_LTE) - .addRequiredValue(Build.VERSION_CODES.R, 1000.0f) - .addRequiredValue(Build.VERSION_CODES.S, 1000.0f) - .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1000.0f) - .build(); - RequiredMeasurement<Float> frontJpegLatency = RequiredMeasurement - .<Float>builder() - .setId(RequirementConstants.FRONT_CAMERA_LATENCY) - .setPredicate(RequirementConstants.FLOAT_LTE) - .addRequiredValue(Build.VERSION_CODES.R, 1000.0f) - .addRequiredValue(Build.VERSION_CODES.S, 1000.0f) - .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1000.0f) - .build(); - - return new CameraLatencyRequirement(RequirementConstants.R7_5__H_1_5, - rearJpegLatency, frontJpegLatency); - } - - /** - * [2.2.7.2/7.5/H-1-6] MUST have camera2 startup latency (open camera to first - * preview frame) < 600ms as measured by the CTS camera PerformanceTest under ITS lighting - * conditions (3000K) for both primary cameras. - */ - public static CameraLatencyRequirement createLaunchLatencyReq() { - RequiredMeasurement<Float> rearLaunchLatency = RequiredMeasurement - .<Float>builder() - .setId(RequirementConstants.REAR_CAMERA_LATENCY) - .setPredicate(RequirementConstants.FLOAT_LTE) - .addRequiredValue(Build.VERSION_CODES.R, 600.0f) - .addRequiredValue(Build.VERSION_CODES.S, 600.0f) - .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 600.0f) - .build(); - RequiredMeasurement<Float> frontLaunchLatency = RequiredMeasurement - .<Float>builder() - .setId(RequirementConstants.FRONT_CAMERA_LATENCY) - .setPredicate(RequirementConstants.FLOAT_LTE) - .addRequiredValue(Build.VERSION_CODES.R, 600.0f) - .addRequiredValue(Build.VERSION_CODES.S, 600.0f) - .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 600.0f) - .build(); - - return new CameraLatencyRequirement(RequirementConstants.R7_5__H_1_6, - rearLaunchLatency, frontLaunchLatency); - } - } - - public static class CameraRawRequirement extends Requirement { - private static final String TAG = CameraRawRequirement.class.getSimpleName(); - - private CameraRawRequirement(String id, RequiredMeasurement<?> ... reqs) { - super(id, reqs); - } - - public void setRearRawSupported(boolean rearRawSupported) { - this.setMeasuredValue(RequirementConstants.REAR_CAMERA_RAW_SUPPORTED, - rearRawSupported); - } - - /** - * [2.2.7.2/7.5/H-1-8] MUST support CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_RAW and - * android.graphics.ImageFormat.RAW_SENSOR for the primary back camera. - */ - public static CameraRawRequirement createRawReq() { - RequiredMeasurement<Boolean> requirement = RequiredMeasurement - .<Boolean>builder() - .setId(RequirementConstants.REAR_CAMERA_RAW_SUPPORTED) - .setPredicate(RequirementConstants.BOOLEAN_EQ) - .addRequiredValue(Build.VERSION_CODES.S, true) - .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true) - .build(); - - return new CameraRawRequirement(RequirementConstants.R7_5__H_1_8, requirement); - } - } - - public static class Camera240FpsRequirement extends Requirement { - private static final String TAG = Camera240FpsRequirement.class.getSimpleName(); - - private Camera240FpsRequirement(String id, RequiredMeasurement<?> ... reqs) { - super(id, reqs); - } - - public void setRear240FpsSupported(boolean rear240FpsSupported) { - this.setMeasuredValue(RequirementConstants.REAR_CAMERA_240FPS_SUPPORTED, - rear240FpsSupported); - } - - /** - * [2.2.7.2/7.5/H-1-9] MUST have a rear-facing primary camera supporting 720p or 1080p @ 240fps. - */ - public static Camera240FpsRequirement create240FpsReq() { - RequiredMeasurement<Boolean> requirement = RequiredMeasurement - .<Boolean>builder() - .setId(RequirementConstants.REAR_CAMERA_240FPS_SUPPORTED) - .setPredicate(RequirementConstants.BOOLEAN_EQ) - .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true) - .build(); - - return new Camera240FpsRequirement(RequirementConstants.R7_5__H_1_9, requirement); - } - } - - public static class UltraWideZoomRatioRequirement extends Requirement { - private static final String TAG = - UltraWideZoomRatioRequirement.class.getSimpleName(); - - private UltraWideZoomRatioRequirement(String id, RequiredMeasurement<?> ... reqs) { - super(id, reqs); - } - - public void setRearUltraWideZoomRatioReqMet(boolean ultrawideZoomRatioReqMet) { - this.setMeasuredValue(RequirementConstants.REAR_CAMERA_ULTRAWIDE_ZOOMRATIO_REQ_MET, - ultrawideZoomRatioReqMet); - } - - public void setFrontUltraWideZoomRatioReqMet(boolean ultrawideZoomRatioReqMet) { - this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_ULTRAWIDE_ZOOMRATIO_REQ_MET, - ultrawideZoomRatioReqMet); - } - - /** - * [2.2.7.2/7.5/H-1-10] MUST have min ZOOM_RATIO < 1.0 for the primary cameras if - * there is an ultrawide RGB camera facing the same direction. - */ - public static UltraWideZoomRatioRequirement createUltrawideZoomRatioReq() { - RequiredMeasurement<Boolean> rearRequirement = RequiredMeasurement - .<Boolean>builder() - .setId(RequirementConstants.REAR_CAMERA_ULTRAWIDE_ZOOMRATIO_REQ_MET) - .setPredicate(RequirementConstants.BOOLEAN_EQ) - .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true) - .build(); - RequiredMeasurement<Boolean> frontRequirement = RequiredMeasurement - .<Boolean>builder() - .setId(RequirementConstants.FRONT_CAMERA_ULTRAWIDE_ZOOMRATIO_REQ_MET) - .setPredicate(RequirementConstants.BOOLEAN_EQ) - .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true) - .build(); - - return new UltraWideZoomRatioRequirement(RequirementConstants.R7_5__H_1_10, - rearRequirement, frontRequirement); - } - } - - public static class ConcurrentRearFrontRequirement extends Requirement { - private static final String TAG = ConcurrentRearFrontRequirement.class.getSimpleName(); - - private ConcurrentRearFrontRequirement(String id, RequiredMeasurement<?> ... reqs) { - super(id, reqs); - } - - public void setConcurrentRearFrontSupported(boolean concurrentRearFrontSupported) { - this.setMeasuredValue(RequirementConstants.CONCURRENT_REAR_FRONT_SUPPORTED, - concurrentRearFrontSupported); - } - - /** - * [2.2.7.2/7.5/H-1-11] MUST implement concurrent front-back streaming on primary cameras. - */ - public static ConcurrentRearFrontRequirement createConcurrentRearFrontReq() { - RequiredMeasurement<Boolean> requirement = RequiredMeasurement - .<Boolean>builder() - .setId(RequirementConstants.CONCURRENT_REAR_FRONT_SUPPORTED) - .setPredicate(RequirementConstants.BOOLEAN_EQ) - .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true) - .build(); - - return new ConcurrentRearFrontRequirement(RequirementConstants.R7_5__H_1_11, - requirement); - } - } - - public static class PreviewStabilizationRequirement extends Requirement { - private static final String TAG = - PreviewStabilizationRequirement.class.getSimpleName(); - - private PreviewStabilizationRequirement(String id, RequiredMeasurement<?> ... reqs) { - super(id, reqs); - } - - public void setRearPreviewStabilizationSupported(boolean supported) { - this.setMeasuredValue(RequirementConstants.REAR_CAMERA_PREVIEW_STABILIZATION_SUPPORTED, - supported); - } - - public void setFrontPreviewStabilizationSupported(boolean supported) { - this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_PREVIEW_STABILIZATION_SUPPORTED, - supported); - } - - /** - * [2.2.7.2/7.5/H-1-12] MUST support CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION - * for both primary front and primary back camera. - */ - public static PreviewStabilizationRequirement createPreviewStabilizationReq() { - RequiredMeasurement<Boolean> rearRequirement = RequiredMeasurement - .<Boolean>builder() - .setId(RequirementConstants.REAR_CAMERA_PREVIEW_STABILIZATION_SUPPORTED) - .setPredicate(RequirementConstants.BOOLEAN_EQ) - .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true) - .build(); - RequiredMeasurement<Boolean> frontRequirement = RequiredMeasurement - .<Boolean>builder() - .setId(RequirementConstants.FRONT_CAMERA_PREVIEW_STABILIZATION_SUPPORTED) - .setPredicate(RequirementConstants.BOOLEAN_EQ) - .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true) - .build(); - - return new PreviewStabilizationRequirement(RequirementConstants.R7_5__H_1_12, - rearRequirement, frontRequirement); - } - } - - public static class LogicalMultiCameraRequirement extends Requirement { - private static final String TAG = - LogicalMultiCameraRequirement.class.getSimpleName(); - - private LogicalMultiCameraRequirement(String id, RequiredMeasurement<?> ... reqs) { - super(id, reqs); - } - - public void setRearLogicalMultiCameraReqMet(boolean reqMet) { - this.setMeasuredValue(RequirementConstants.REAR_CAMERA_LOGICAL_MULTI_CAMERA_REQ_MET, - reqMet); - } - - public void setFrontLogicalMultiCameraReqMet(boolean reqMet) { - this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_LOGICAL_MULTI_CAMERA_REQ_MET, - reqMet); - } - - /** - * [2.2.7.2/7.5/H-1-13] MUST support LOGICAL_MULTI_CAMERA capability for the primary - * cameras if there are greater than 1 RGB cameras facing the same direction. - */ - public static LogicalMultiCameraRequirement createLogicalMultiCameraReq() { - RequiredMeasurement<Boolean> rearRequirement = RequiredMeasurement - .<Boolean>builder() - .setId(RequirementConstants.REAR_CAMERA_LOGICAL_MULTI_CAMERA_REQ_MET) - .setPredicate(RequirementConstants.BOOLEAN_EQ) - .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true) - .build(); - RequiredMeasurement<Boolean> frontRequirement = RequiredMeasurement - .<Boolean>builder() - .setId(RequirementConstants.FRONT_CAMERA_LOGICAL_MULTI_CAMERA_REQ_MET) - .setPredicate(RequirementConstants.BOOLEAN_EQ) - .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true) - .build(); - - return new LogicalMultiCameraRequirement(RequirementConstants.R7_5__H_1_13, - rearRequirement, frontRequirement); - } - } - - public static class StreamUseCaseRequirement extends Requirement { - private static final String TAG = - StreamUseCaseRequirement.class.getSimpleName(); - - private StreamUseCaseRequirement(String id, RequiredMeasurement<?> ... reqs) { - super(id, reqs); - } - - public void setRearStreamUseCaseSupported(boolean supported) { - this.setMeasuredValue(RequirementConstants.REAR_CAMERA_STREAM_USECASE_SUPPORTED, - supported); - } - - public void setFrontStreamUseCaseSupported(boolean supported) { - this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_STREAM_USECASE_SUPPORTED, - supported); - } - - /** - * [2.2.7.2/7.5/H-1-14] MUST support STREAM_USE_CASE capability for both primary - * front and primary back camera. - */ - public static StreamUseCaseRequirement createStreamUseCaseReq() { - RequiredMeasurement<Boolean> rearRequirement = RequiredMeasurement - .<Boolean>builder() - .setId(RequirementConstants.REAR_CAMERA_STREAM_USECASE_SUPPORTED) - .setPredicate(RequirementConstants.BOOLEAN_EQ) - .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true) - .build(); - RequiredMeasurement<Boolean> frontRequirement = RequiredMeasurement - .<Boolean>builder() - .setId(RequirementConstants.FRONT_CAMERA_STREAM_USECASE_SUPPORTED) - .setPredicate(RequirementConstants.BOOLEAN_EQ) - .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true) - .build(); - - return new StreamUseCaseRequirement(RequirementConstants.R7_5__H_1_14, - rearRequirement, frontRequirement); - } - } - - public <R extends Requirement> R addRequirement(R req) { + private <R extends Requirement> R addRequirement(R req) { if (!this.mRequirements.add(req)) { throw new IllegalStateException("Requirement " + req.id() + " already added"); } @@ -1487,69 +1000,16 @@ public class PerformanceClassEvaluator { return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_10()); } - public PrimaryCameraRequirement addPrimaryRearCameraReq() { - return this.addRequirement(PrimaryCameraRequirement.createRearPrimaryCamera()); - } - - public PrimaryCameraRequirement addPrimaryFrontCameraReq() { - return this.addRequirement(PrimaryCameraRequirement.createFrontPrimaryCamera()); - } - - public CameraTimestampSourceRequirement addR7_5__H_1_4() { - return this.addRequirement(CameraTimestampSourceRequirement.createTimestampSourceReq()); - } - - public CameraLatencyRequirement addR7_5__H_1_5() { - return this.addRequirement(CameraLatencyRequirement.createJpegLatencyReq()); - } - - public CameraLatencyRequirement addR7_5__H_1_6() { - return this.addRequirement(CameraLatencyRequirement.createLaunchLatencyReq()); - } - - public CameraRawRequirement addR7_5__H_1_8() { - return this.addRequirement(CameraRawRequirement.createRawReq()); - } - - public Camera240FpsRequirement addR7_5__H_1_9() { - return this.addRequirement(Camera240FpsRequirement.create240FpsReq()); - } - - public UltraWideZoomRatioRequirement addR7_5__H_1_10() { - return this.addRequirement(UltraWideZoomRatioRequirement.createUltrawideZoomRatioReq()); - } - - public ConcurrentRearFrontRequirement addR7_5__H_1_11() { - return this.addRequirement(ConcurrentRearFrontRequirement.createConcurrentRearFrontReq()); - } - - public PreviewStabilizationRequirement addR7_5__H_1_12() { - return this.addRequirement(PreviewStabilizationRequirement.createPreviewStabilizationReq()); - } - - public LogicalMultiCameraRequirement addR7_5__H_1_13() { - return this.addRequirement(LogicalMultiCameraRequirement.createLogicalMultiCameraReq()); - } - - public StreamUseCaseRequirement addR7_5__H_1_14() { - return this.addRequirement(StreamUseCaseRequirement.createStreamUseCaseReq()); - } - public void submitAndCheck() { - boolean perfClassMet = submit(); + boolean perfClassMet = true; + for (Requirement req: this.mRequirements) { + perfClassMet &= req.writeLogAndCheck(this.mTestName); + } // check performance class assumeTrue("Build.VERSION.MEDIA_PERFORMANCE_CLASS is not declared", Utils.isPerfClass()); assertThat(perfClassMet).isTrue(); - } - public boolean submit() { - boolean perfClassMet = true; - for (Requirement req: this.mRequirements) { - perfClassMet &= req.writeLogAndCheck(this.mTestName); - } this.mRequirements.clear(); // makes sure report isn't submitted twice - return perfClassMet; } - } diff --git a/tests/mediapc/common/src/android/mediapc/cts/common/RequirementConstants.java b/tests/mediapc/common/src/android/mediapc/cts/common/RequirementConstants.java index ad0d0d5694f..d93cb2e0a00 100644 --- a/tests/mediapc/common/src/android/mediapc/cts/common/RequirementConstants.java +++ b/tests/mediapc/common/src/android/mediapc/cts/common/RequirementConstants.java @@ -16,6 +16,8 @@ package android.mediapc.cts.common; +import android.os.Build; + import java.util.function.BiPredicate; public class RequirementConstants { @@ -52,13 +54,8 @@ public class RequirementConstants { public static final String R7_5__H_1_4 = "r7_5__h_1_4"; // 7.5/H-1-4 public static final String R7_5__H_1_5 = "r7_5__h_1_5"; // 7.5/H-1-5 public static final String R7_5__H_1_6 = "r7_5__h_1_6"; // 7.5/H-1-6 + public static final String R7_5__H_1_7 = "r7_5__h_1_7"; // 7.5/H-1-7 public static final String R7_5__H_1_8 = "r7_5__h_1_8"; // 7.5/H-1-8 - public static final String R7_5__H_1_9 = "r7_5__h_1_9"; // 7.5/H-1-9 - public static final String R7_5__H_1_10 = "r7_5__h_1_10"; // 7.5/H-1-10 - public static final String R7_5__H_1_11 = "r7_5__h_1_11"; // 7.5/H-1-11 - public static final String R7_5__H_1_12 = "r7_5__h_1_12"; // 7.5/H-1-12 - public static final String R7_5__H_1_13 = "r7_5__h_1_13"; // 7.5/H-1-13 - public static final String R7_5__H_1_14 = "r7_5__h_1_14"; // 7.5/H-1-14 public static final String R7_1_1_1__H_1_1 = "r7_1_1_1__h_1_1"; // 7.1.1.1/H-1-1 public static final String R7_1_1_3__H_1_1 = "r7_1_1_3__h_1_1"; // 7.1.1.3/H-1-1 public static final String R7_6_1__H_1_1 = "r7_6_1__h_1_1"; // 7.6.1/H-1-1 @@ -93,50 +90,14 @@ public class RequirementConstants { public static final String NUM_CRYPTO_HW_SECURE_ALL_SUPPORT = "number_crypto_hw_secure_all_support"; - public static final String PRIMARY_CAMERA_AVAILABLE = "primary_camera_available"; - public static final String PRIMARY_CAMERA_RESOLUTION = "primary_camera_resolution"; - public static final String PRIMARY_CAMERA_VIDEO_SIZE_REQ_SATISFIED = - "primary_camera_video_size_req_satisfied"; - public static final String PRIMARY_CAMERA_VIDEO_FPS = - "primary_camera_video_fps"; - public static final String REAR_CAMERA_HWL_LEVEL = "rear_primary_camera_hwl_level"; - public static final String FRONT_CAMERA_HWL_LEVEL = "front_primary_camera_hwl_level"; - public static final String REAR_CAMERA_TIMESTAMP_SOURCE = - "rear_primary_camera_timestamp_source"; - public static final String FRONT_CAMERA_TIMESTAMP_SOURCE = - "front_primary_camera_timestamp_source"; - public static final String REAR_CAMERA_LATENCY = "rear_camera_latency"; - public static final String FRONT_CAMERA_LATENCY = "front_camera_latency"; - public static final String REAR_CAMERA_RAW_SUPPORTED = "rear_camera_raw_supported"; - public static final String REAR_CAMERA_240FPS_SUPPORTED = "rear_camera_240fps_supported"; - public static final String REAR_CAMERA_ULTRAWIDE_ZOOMRATIO_REQ_MET = - "rear_camera_ultrawide_zoom_req_met"; - public static final String FRONT_CAMERA_ULTRAWIDE_ZOOMRATIO_REQ_MET = - "front_camera_ultrawide_zoom_req_met"; - public static final String CONCURRENT_REAR_FRONT_SUPPORTED = "rear_front_concurrent_camera"; - public static final String REAR_CAMERA_PREVIEW_STABILIZATION_SUPPORTED = - "rear_camera_preview_stabilization_supported"; - public static final String FRONT_CAMERA_PREVIEW_STABILIZATION_SUPPORTED = - "front_camera_preview_stabilization_supported"; - public static final String REAR_CAMERA_LOGICAL_MULTI_CAMERA_REQ_MET = - "rear_camera_logical_multi_camera_req_met"; - public static final String FRONT_CAMERA_LOGICAL_MULTI_CAMERA_REQ_MET = - "front_camera_logical_multi_camera_req_met"; - public static final String REAR_CAMERA_STREAM_USECASE_SUPPORTED = - "rear_camera_stream_usecase_supported"; - public static final String FRONT_CAMERA_STREAM_USECASE_SUPPORTED = - "front_camera_stream_usecase_supported"; - public enum Result { NA, MET, UNMET } public static final BiPredicate<Long, Long> LONG_GTE = RequirementConstants.gte(); public static final BiPredicate<Long, Long> LONG_LTE = RequirementConstants.lte(); - public static final BiPredicate<Float, Float> FLOAT_LTE = RequirementConstants.lte(); public static final BiPredicate<Integer, Integer> INTEGER_GTE = RequirementConstants.gte(); public static final BiPredicate<Integer, Integer> INTEGER_LTE = RequirementConstants.lte(); - public static final BiPredicate<Integer, Integer> INTEGER_EQ = RequirementConstants.eq(); public static final BiPredicate<Double, Double> DOUBLE_EQ = RequirementConstants.eq(); public static final BiPredicate<Boolean, Boolean> BOOLEAN_EQ = RequirementConstants.eq(); public static final BiPredicate<Double, Double> DOUBLE_GTE = RequirementConstants.gte(); diff --git a/tests/mediapc/common/src/android/mediapc/cts/common/Utils.java b/tests/mediapc/common/src/android/mediapc/cts/common/Utils.java index 28a122b4521..ac03705a1a2 100644 --- a/tests/mediapc/common/src/android/mediapc/cts/common/Utils.java +++ b/tests/mediapc/common/src/android/mediapc/cts/common/Utils.java @@ -73,24 +73,16 @@ public class Utils { Context context = InstrumentationRegistry.getInstrumentation().getContext(); DisplayMetrics metrics = new DisplayMetrics(); - // When used from ItsService, context will be null - if (context != null) { - WindowManager windowManager = context.getSystemService(WindowManager.class); - windowManager.getDefaultDisplay().getMetrics(metrics); - DISPLAY_DPI = metrics.densityDpi; - DISPLAY_LONG_PIXELS = Math.max(metrics.widthPixels, metrics.heightPixels); - DISPLAY_SHORT_PIXELS = Math.min(metrics.widthPixels, metrics.heightPixels); - - ActivityManager activityManager = context.getSystemService(ActivityManager.class); - ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); - activityManager.getMemoryInfo(memoryInfo); - TOTAL_MEMORY_MB = memoryInfo.totalMem / 1024 / 1024; - } else { - DISPLAY_DPI = 0; - DISPLAY_LONG_PIXELS = 0; - DISPLAY_SHORT_PIXELS = 0; - TOTAL_MEMORY_MB = 0; - } + WindowManager windowManager = context.getSystemService(WindowManager.class); + windowManager.getDefaultDisplay().getMetrics(metrics); + DISPLAY_DPI = metrics.densityDpi; + DISPLAY_LONG_PIXELS = Math.max(metrics.widthPixels, metrics.heightPixels); + DISPLAY_SHORT_PIXELS = Math.min(metrics.widthPixels, metrics.heightPixels); + + ActivityManager activityManager = context.getSystemService(ActivityManager.class); + ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); + activityManager.getMemoryInfo(memoryInfo); + TOTAL_MEMORY_MB = memoryInfo.totalMem / 1024 / 1024; } /** diff --git a/tests/mediapc/src/android/mediapc/cts/PerformanceClassTest.java b/tests/mediapc/src/android/mediapc/cts/PerformanceClassTest.java index 8da22f32ba0..2508845049b 100644 --- a/tests/mediapc/src/android/mediapc/cts/PerformanceClassTest.java +++ b/tests/mediapc/src/android/mediapc/cts/PerformanceClassTest.java @@ -41,7 +41,6 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; import org.junit.Assume; -import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestName; @@ -59,11 +58,6 @@ public class PerformanceClassTest { @Rule public final TestName mTestName = new TestName(); - @Before - public void isPerformanceClassCandidate() { - Utils.assumeDeviceMeetsPerformanceClassPreconditions(); - } - static { mMimeSecureSupport.add(MediaFormat.MIMETYPE_VIDEO_AVC); mMimeSecureSupport.add(MediaFormat.MIMETYPE_VIDEO_HEVC); diff --git a/tests/mediapc/src/android/mediapc/cts/VideoCodecRequirementsTest.java b/tests/mediapc/src/android/mediapc/cts/VideoCodecRequirementsTest.java index 2ee8b3bf8c5..bbe26dce0ac 100644 --- a/tests/mediapc/src/android/mediapc/cts/VideoCodecRequirementsTest.java +++ b/tests/mediapc/src/android/mediapc/cts/VideoCodecRequirementsTest.java @@ -21,14 +21,12 @@ import static android.mediapc.cts.CodecTestBase.SELECT_HARDWARE; import static android.mediapc.cts.CodecTestBase.SELECT_VIDEO; import static android.mediapc.cts.CodecTestBase.getMimesOfAvailableCodecs; import static android.mediapc.cts.CodecTestBase.selectHardwareCodecs; -import static org.junit.Assert.assertTrue; import android.media.MediaCodec; import android.media.MediaCodecInfo.CodecCapabilities; import android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint; import android.media.MediaFormat; import android.mediapc.cts.common.PerformanceClassEvaluator; -import android.mediapc.cts.common.Utils; import android.util.Log; import androidx.test.filters.LargeTest; import com.android.compatibility.common.util.CddTest; @@ -37,7 +35,6 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; -import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestName; @@ -50,11 +47,6 @@ public class VideoCodecRequirementsTest { @Rule public final TestName mTestName = new TestName(); - @Before - public void isPerformanceClassCandidate() { - Utils.assumeDeviceMeetsPerformanceClassPreconditions(); - } - private Set<String> get4k60HwCodecSet(boolean isEncoder) throws IOException { Set<String> codecSet = new HashSet<>(); Set<String> codecMediaTypes = getMimesOfAvailableCodecs(SELECT_VIDEO, SELECT_HARDWARE); @@ -68,7 +60,6 @@ public class VideoCodecRequirementsTest { codec.getCodecInfo().getCapabilitiesForType(codecMediaType); List<PerformancePoint> pps = capabilities.getVideoCapabilities().getSupportedPerformancePoints(); - assertTrue(hwVideoCodec + " doesn't advertise performance points", pps.size() > 0); for (PerformancePoint pp : pps) { if (pp.covers(PP4k60)) { codecSet.add(hwVideoCodec); diff --git a/tests/signature/api-check/src/java/android/signature/cts/api/BaseKillswitchTest.java b/tests/signature/api-check/src/java/android/signature/cts/api/BaseKillswitchTest.java index 9cb5fb10c08..2f77728f06b 100644 --- a/tests/signature/api-check/src/java/android/signature/cts/api/BaseKillswitchTest.java +++ b/tests/signature/api-check/src/java/android/signature/cts/api/BaseKillswitchTest.java @@ -59,7 +59,7 @@ public abstract class BaseKillswitchTest extends AbstractApiTest { doTestKillswitchMechanism(FIELD_FILTER, /* reflection= */ true, /* jni= */ false); } - @Test(timeout = 900000) + @Test public void testKillswitchMechanismFieldsThroughJni() { doTestKillswitchMechanism(FIELD_FILTER, /* reflection= */ false, /* jni= */ true); } diff --git a/tests/signature/intent-check/DynamicConfig.xml b/tests/signature/intent-check/DynamicConfig.xml index cb5f08c1296..b72af1f7dce 100644 --- a/tests/signature/intent-check/DynamicConfig.xml +++ b/tests/signature/intent-check/DynamicConfig.xml @@ -27,7 +27,6 @@ Bug: 150153196 android.intent.action.PACKAGE_UNSUSPENDED_MANUALLY (system in API 30) Bug: 186495404 android.intent.action.REBOOT_READY Bug: 218245704 android.intent.action.ACTION_PACKAGE_CHANGED (fixed in TTS 20220209) - Bug: 237978237 android.intent.action.REMOTE_COPY --> <dynamicConfig> <entry key ="intent_whitelist"> @@ -43,6 +42,5 @@ <value>android.intent.action.PACKAGE_UNSUSPENDED_MANUALLY</value> <value>android.intent.action.REBOOT_READY</value> <value>android.intent.action.ACTION_PACKAGE_CHANGED</value> - <value>android.intent.action.REMOTE_COPY</value> </entry> </dynamicConfig> diff --git a/tests/suspendapps/tests/src/android/suspendapps/cts/DialogTests.java b/tests/suspendapps/tests/src/android/suspendapps/cts/DialogTests.java index ef14ce6d8a7..e8caff2cff0 100644 --- a/tests/suspendapps/tests/src/android/suspendapps/cts/DialogTests.java +++ b/tests/suspendapps/tests/src/android/suspendapps/cts/DialogTests.java @@ -18,6 +18,7 @@ package android.suspendapps.cts; import static android.content.pm.SuspendDialogInfo.BUTTON_ACTION_UNSUSPEND; import static android.suspendapps.cts.Constants.TEST_APP_PACKAGE_NAME; +import static android.suspendapps.cts.SuspendTestUtils.assertSameExtras; import static android.suspendapps.cts.SuspendTestUtils.createExtras; import static android.suspendapps.cts.SuspendTestUtils.startTestAppActivity; @@ -31,6 +32,7 @@ import android.content.Context; import android.content.Intent; import android.content.pm.SuspendDialogInfo; import android.os.Bundle; +import android.platform.test.annotations.SystemUserOnly; import android.support.test.uiautomator.By; import android.support.test.uiautomator.UiDevice; import android.support.test.uiautomator.UiObject2; @@ -124,7 +126,9 @@ public class DialogTests { final Intent activityIntent = mTestAppInterface.awaitTestActivityStart(); assertNotNull("Test activity did not start on neutral button tap", activityIntent); - // TODO(b/237707107): Verify that activityIntent has the expected extras. + assertSameExtras("Different extras passed to startActivity on unsuspend", + extrasForStart, activityIntent.getExtras()); + assertFalse("Test package still suspended", mTestAppInterface.isTestAppSuspended()); } diff --git a/tests/tests/assist/common/src/android/assist/common/Utils.java b/tests/tests/assist/common/src/android/assist/common/Utils.java index 98e857689cf..0ffcb271093 100755 --- a/tests/tests/assist/common/src/android/assist/common/Utils.java +++ b/tests/tests/assist/common/src/android/assist/common/Utils.java @@ -56,7 +56,6 @@ public class Utils { public static final String COMPARE_SCREENSHOT_KEY = "compare_screenshot"; public static final String DISPLAY_WIDTH_KEY = "display_width"; public static final String DISPLAY_HEIGHT_KEY = "dislay_height"; - public static final String DISPLAY_AREA_BOUNDS_KEY = "display_area_bounds"; public static final String SCROLL_X_POSITION = "scroll_x_position"; public static final String SCROLL_Y_POSITION = "scroll_y_position"; public static final String SHOW_SESSION_FLAGS_TO_SET = "show_session_flags_to_set"; diff --git a/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java b/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java index 25c080b9c0c..7f35367333a 100644 --- a/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java +++ b/tests/tests/assist/service/src/android/assist/service/MainInteractionSession.java @@ -56,7 +56,6 @@ public class MainInteractionSession extends VoiceInteractionSession { private int mCurColor; private int mDisplayHeight; private int mDisplayWidth; - private Rect mDisplayAreaBounds; private BroadcastReceiver mReceiver; private String mTestName; private View mContentView; @@ -107,7 +106,7 @@ public class MainInteractionSession extends VoiceInteractionSession { public void onPrepareShow(Bundle args, int showFlags) { if (Utils.LIFECYCLE_NOUI.equals(args.getString(Utils.TESTCASE_TYPE, ""))) { setUiEnabled(false); - } else { + } else { setUiEnabled(true); } } @@ -123,7 +122,6 @@ public class MainInteractionSession extends VoiceInteractionSession { mCurColor = args.getInt(Utils.SCREENSHOT_COLOR_KEY); mDisplayHeight = args.getInt(Utils.DISPLAY_HEIGHT_KEY); mDisplayWidth = args.getInt(Utils.DISPLAY_WIDTH_KEY); - mDisplayAreaBounds = args.getParcelable(Utils.DISPLAY_AREA_BOUNDS_KEY); mRemoteCallback = args.getParcelable(Utils.EXTRA_REMOTE_CALLBACK); super.onShow(args, showFlags); if (mContentView == null) return; // Happens when ui is not enabled. @@ -258,11 +256,6 @@ public class MainInteractionSession extends VoiceInteractionSession { int[] pixels = new int[size.x * size.y]; screenshot.getPixels(pixels, 0, size.x, 0, 0, size.x, size.y); - // screenshot bitmap contains the screenshot for the entire physical display. A single - // physical display could have multiple display area with different applications. - // Let's grab the region of the display area from the original screenshot. - Bitmap displayAreaScreenshot = Bitmap.createBitmap(screenshot, mDisplayAreaBounds.left, - mDisplayAreaBounds.top, mDisplayAreaBounds.width(), mDisplayAreaBounds.height()); int expectedColor = 0; for (int pixel : pixels) { // Check for roughly the same because there are rounding errors converting from the @@ -274,7 +267,7 @@ public class MainInteractionSession extends VoiceInteractionSession { } } - int pixelCount = displayAreaScreenshot.getWidth() * displayAreaScreenshot.getHeight(); + int pixelCount = screenshot.getWidth() * screenshot.getHeight(); double colorRatio = (double) expectedColor / pixelCount; Log.i(TAG, "the ratio is " + colorRatio); return colorRatio >= 0.6; diff --git a/tests/tests/assist/src/android/assist/cts/AssistTestBase.java b/tests/tests/assist/src/android/assist/cts/AssistTestBase.java index c89119bdea1..44a3109a740 100644 --- a/tests/tests/assist/src/android/assist/cts/AssistTestBase.java +++ b/tests/tests/assist/src/android/assist/cts/AssistTestBase.java @@ -35,9 +35,9 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.graphics.Point; -import android.graphics.Rect; import android.os.Bundle; import android.os.Handler; +import android.os.HandlerThread; import android.os.LocaleList; import android.os.RemoteCallback; import android.provider.Settings; @@ -341,8 +341,6 @@ abstract class AssistTestBase { Display.Mode dMode = mTestActivity.getWindowManager().getDefaultDisplay().getMode(); mDisplaySize = new Point(dMode.getPhysicalWidth(), dMode.getPhysicalHeight()); } - Rect bounds = mTestActivity.getWindowManager().getMaximumWindowMetrics().getBounds(); - intent.putExtra(Utils.DISPLAY_AREA_BOUNDS_KEY, bounds); intent.putExtra(Utils.DISPLAY_WIDTH_KEY, mDisplaySize.x); intent.putExtra(Utils.DISPLAY_HEIGHT_KEY, mDisplaySize.y); } diff --git a/tests/tests/bluetooth/AndroidTest.xml b/tests/tests/bluetooth/AndroidTest.xml index 98189620bab..9a3075beee6 100644 --- a/tests/tests/bluetooth/AndroidTest.xml +++ b/tests/tests/bluetooth/AndroidTest.xml @@ -33,6 +33,6 @@ <!-- Only run Cts Tests in MTS if the Bluetooth Mainline module is installed. --> <object type="module_controller" class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController"> - <option name="mainline-module-package-name" value="com.android.btservices" /> + <option name="mainline-module-package-name" value="com.google.android.bluetooth" /> </object> </configuration> diff --git a/tests/tests/carrierapi/targetprep/device/src/android/carrierapi/cts/targetprep/ApduScriptUtil.java b/tests/tests/carrierapi/targetprep/device/src/android/carrierapi/cts/targetprep/ApduScriptUtil.java index 5793fe2bd43..fba6e737bbc 100644 --- a/tests/tests/carrierapi/targetprep/device/src/android/carrierapi/cts/targetprep/ApduScriptUtil.java +++ b/tests/tests/carrierapi/targetprep/device/src/android/carrierapi/cts/targetprep/ApduScriptUtil.java @@ -30,7 +30,6 @@ import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.UiccSlotMapping; import android.util.Log; -import android.util.Pair; import androidx.test.InstrumentationRegistry; @@ -41,14 +40,12 @@ import com.android.compatibility.common.util.UiccUtil.ApduResponse; import java.util.Collection; import java.util.List; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; class ApduScriptUtil { private static final String TAG = "ApduScriptUtil"; private static final long SET_SIM_POWER_TIMEOUT_SECONDS = 30; - private static final long APP_STATE_ADDITIONAL_WAIT_MILLIS = TimeUnit.SECONDS.toMillis(3); // TelephonyManager constants are @hide, so manually copy them here private static final int CARD_POWER_DOWN = 0; private static final int CARD_POWER_UP = 1; @@ -109,77 +106,33 @@ class ApduScriptUtil { "Unable to determine physical slot + port from logical slot: " + logicalSlotId); } - Pair<Integer, Integer> halVersion = getContext().getSystemService(TelephonyManager.class) - .getRadioHalVersion(); - Log.i(TAG, "runApduScript with hal version: " + halVersion.first + "." + halVersion.second); - boolean listenToSimCardStateChange = true; - // After hal version 1.6, powers SIM card down will not generate SIM ABSENT or - // SIM PRESENT events, we have to switch to listen to SIM application states instead. - if ((halVersion.first == 1 && halVersion.second == 6) || halVersion.first == 2) { - listenToSimCardStateChange = false; - } - try { - // Note: Even if it won't wipe out subId after hal version 1.6, we still use the - // slot/port-based APDU method while in pass-through mode to make compatible with - // older hal version. - rebootSimCard(subId, - logicalSlotId, CARD_POWER_UP_PASS_THROUGH, listenToSimCardStateChange); + // Note: this may wipe out subId, so we need to use the slot/port-based APDU method + // while in pass-through mode. + rebootSimCard(logicalSlotId, CARD_POWER_UP_PASS_THROUGH); sendApdus(physicalSlotId, portIndex, apdus); } finally { // Even if rebootSimCard failed midway through (leaving the SIM in POWER_DOWN) or timed // out waiting for the right SIM state after rebooting in POWER_UP_PASS_THROUGH, we try // to bring things back to the normal POWER_UP state to avoid breaking other suites. - rebootSimCard(subId, logicalSlotId, CARD_POWER_UP, listenToSimCardStateChange); + rebootSimCard(logicalSlotId, CARD_POWER_UP); } } /** - * Powers the SIM card down firstly and then powers it back up on the {@code - * targetPowerState} - * - * Due to the RADIO HAL interface behavior changed after version 1.6, we have to - * listen to SIM card states before hal version 1.6 and SIM application states after. - * In specific, the behavior of the method is below: - * <p> Before hal version 1.6, powers the SIM card down and waits for it to become - * ABSENT, then powers it back up in {@code targetPowerState} and waits for it to - become PRESENT. - * <p> After hal version 1.6, powers the SIM card down and waits for the SIM application - * state to become NOT_READY, then powers it back up in {@code targetPowerState} and - * waits for it to become NOT_READY {@code CARD_POWER_UP_PASS_THROUGH} or - * LOADED {@code CARD_POWER_UP}. - * The SIM application state keeps in NOT_READY state after simPower moving from - * CARD_POWER_DOWN to CARD_POWER_UP_PASS_THROUGH. + * Powers the SIM card down, waits for it to become ABSENT, then powers it back up in {@code + * targetPowerState} and waits for it to become PRESENT. */ - private static void rebootSimCard(int subId, - int logicalSlotId, int targetPowerState, boolean listenToSimCardStateChange) + private static void rebootSimCard(int logicalSlotId, int targetPowerState) throws InterruptedException { - if (listenToSimCardStateChange) { - setSimPowerAndWaitForCardState(subId, - logicalSlotId, CARD_POWER_DOWN, - TelephonyManager.SIM_STATE_ABSENT, listenToSimCardStateChange); - setSimPowerAndWaitForCardState(subId, - logicalSlotId, targetPowerState, - TelephonyManager.SIM_STATE_PRESENT, listenToSimCardStateChange); - } else { - setSimPowerAndWaitForCardState(subId, - logicalSlotId, CARD_POWER_DOWN, - TelephonyManager.SIM_STATE_NOT_READY, listenToSimCardStateChange); - if (targetPowerState == CARD_POWER_UP) { - setSimPowerAndWaitForCardState(subId, - logicalSlotId, targetPowerState, - TelephonyManager.SIM_STATE_LOADED, listenToSimCardStateChange); - } else if (targetPowerState == CARD_POWER_UP_PASS_THROUGH) { - setSimPowerAndWaitForCardState(subId, - logicalSlotId, targetPowerState, - TelephonyManager.SIM_STATE_NOT_READY, listenToSimCardStateChange); - } - } + setSimPowerAndWaitForCardState( + logicalSlotId, CARD_POWER_DOWN, TelephonyManager.SIM_STATE_ABSENT); + setSimPowerAndWaitForCardState( + logicalSlotId, targetPowerState, TelephonyManager.SIM_STATE_PRESENT); } private static void setSimPowerAndWaitForCardState( - int subId, int logicalSlotId, int targetPowerState, - int targetSimState, boolean listenToSimCardStateChange) + int logicalSlotId, int targetPowerState, int targetSimState) throws InterruptedException { // A small little state machine: // 1. Call setSimPower(targetPowerState) @@ -193,10 +146,8 @@ class ApduScriptUtil { new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - if ((!TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED.equals( - intent.getAction())) && - (!TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED.equals( - intent.getAction()))) { + if (!TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED.equals( + intent.getAction())) { return; } int slotId = @@ -232,10 +183,11 @@ class ApduScriptUtil { uiAutomation.adoptShellPermissionIdentity( Manifest.permission.MODIFY_PHONE_STATE, Manifest.permission.READ_PRIVILEGED_PHONE_STATE); - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED); - intentFilter.addAction(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED); - getContext().registerReceiver(cardStateReceiver, intentFilter); + getContext() + .registerReceiver( + cardStateReceiver, + new IntentFilter(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED)); + Log.i( TAG, "Setting SIM " + logicalSlotId + " power state to " + targetPowerState + "..."); @@ -261,15 +213,8 @@ class ApduScriptUtil { // Once the RIL request completes successfully, wait for the SIM to move to the desired // state (from the broadcast). - int simApplicationState = getContext().getSystemService(TelephonyManager.class) - .createForSubscriptionId(subId).getSimApplicationState(); - Log.i(TAG, "Waiting for SIM " + logicalSlotId - + " to become " + targetSimState + " from " + simApplicationState); - // TODO(b/236950019): Find a deterministic way to detect SIM power state change - // from DOWN to PASS_THROUGH. - if ((!listenToSimCardStateChange) && (targetSimState == simApplicationState)) { - Thread.sleep(APP_STATE_ADDITIONAL_WAIT_MILLIS); - } else if (!cardStateLatch.await(SET_SIM_POWER_TIMEOUT_SECONDS, SECONDS)) { + Log.i(TAG, "Waiting for SIM " + logicalSlotId + " to become " + targetSimState + "..."); + if (!cardStateLatch.await(SET_SIM_POWER_TIMEOUT_SECONDS, SECONDS)) { throw new IllegalStateException( "Failed to receive SIM state " + targetSimState diff --git a/tests/tests/content/CtsSyncAccountAccessOtherCertTests/src/com/android/cts/content/CtsSyncAccountAccessOtherCertTestCases.java b/tests/tests/content/CtsSyncAccountAccessOtherCertTests/src/com/android/cts/content/CtsSyncAccountAccessOtherCertTestCases.java index 8bd1bb8fb33..49b72549b7e 100644 --- a/tests/tests/content/CtsSyncAccountAccessOtherCertTests/src/com/android/cts/content/CtsSyncAccountAccessOtherCertTestCases.java +++ b/tests/tests/content/CtsSyncAccountAccessOtherCertTests/src/com/android/cts/content/CtsSyncAccountAccessOtherCertTestCases.java @@ -43,9 +43,6 @@ import android.content.res.Configuration; import android.support.test.uiautomator.By; import android.support.test.uiautomator.UiDevice; import android.support.test.uiautomator.UiObject2; -import android.support.test.uiautomator.UiObjectNotFoundException; -import android.support.test.uiautomator.UiScrollable; -import android.support.test.uiautomator.UiSelector; import android.support.test.uiautomator.Until; import android.util.Log; @@ -143,7 +140,7 @@ public class CtsSyncAccountAccessOtherCertTestCases { } catch (Throwable t) { if (scrollUps < 10) { // The notification we search for is below the fold, scroll to find it - scrollNotifications(); + swipeUp(uiDevice); scrollUps++; continue; } @@ -203,18 +200,6 @@ public class CtsSyncAccountAccessOtherCertTestCases { 50 /* numberOfSteps */); } - private boolean scrollNotifications() { - UiScrollable scrollable = new UiScrollable(new UiSelector().scrollable(true)); - if (!scrollable.exists()) { - return false; - } - try { - return scrollable.scrollForward(50); - } catch (UiObjectNotFoundException e) { - return false; - } - } - private boolean isRunningInVR() { final Context context = InstrumentationRegistry.getTargetContext(); return ((context.getResources().getConfiguration().uiMode & diff --git a/tests/tests/graphics/src/android/graphics/cts/BitmapFactoryTest.java b/tests/tests/graphics/src/android/graphics/cts/BitmapFactoryTest.java index 47662682d36..9600df2d63e 100644 --- a/tests/tests/graphics/src/android/graphics/cts/BitmapFactoryTest.java +++ b/tests/tests/graphics/src/android/graphics/cts/BitmapFactoryTest.java @@ -35,8 +35,6 @@ import android.graphics.BitmapFactory; import android.graphics.BitmapFactory.Options; import android.graphics.Color; import android.graphics.Rect; -import android.media.MediaCodecInfo; -import android.media.MediaCodecList; import android.media.MediaFormat; import android.os.Build; import android.os.Parcel; @@ -1012,8 +1010,9 @@ public class BitmapFactoryTest { public void testDecode10BitHEIFTo10BitBitmap() { assumeTrue( "Test needs Android T.", ApiLevelUtil.isFirstApiAtLeast(Build.VERSION_CODES.TIRAMISU)); - assumeTrue("No 10-bit HEVC decoder, skip the test.", has10BitHEVCDecoder()); - + if (!MediaUtils.hasDecoder(MediaFormat.MIMETYPE_VIDEO_HEVC)) { + return; + } BitmapFactory.Options opt = new BitmapFactory.Options(); opt.inPreferredConfig = Config.RGBA_1010102; Bitmap bm = BitmapFactory.decodeStream(obtainInputStream(R.raw.heifimage_10bit), null, opt); @@ -1028,8 +1027,9 @@ public class BitmapFactoryTest { public void testDecode10BitHEIFTo8BitBitmap() { assumeTrue( "Test needs Android T.", ApiLevelUtil.isFirstApiAtLeast(Build.VERSION_CODES.TIRAMISU)); - assumeTrue("No 10-bit HEVC decoder, skip the test.", has10BitHEVCDecoder()); - + if (!MediaUtils.hasDecoder(MediaFormat.MIMETYPE_VIDEO_HEVC)) { + return; + } BitmapFactory.Options opt = new BitmapFactory.Options(); opt.inPreferredConfig = Config.ARGB_8888; Bitmap bm1 = @@ -1091,19 +1091,4 @@ public class BitmapFactoryTest { private String obtainPath() throws IOException { return Utils.obtainPath(R.drawable.start, 0); } - - private static boolean has10BitHEVCDecoder() { - MediaFormat format = new MediaFormat(); - format.setString(MediaFormat.KEY_MIME, "video/hevc"); - format.setInteger( - MediaFormat.KEY_PROFILE, MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10); - format.setInteger( - MediaFormat.KEY_LEVEL, MediaCodecInfo.CodecProfileLevel.HEVCMainTierLevel5); - - MediaCodecList mcl = new MediaCodecList(MediaCodecList.ALL_CODECS); - if (mcl.findDecoderForFormat(format) == null) { - return false; - } - return true; - } } diff --git a/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java b/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java index 6741c07ec21..5b179d6bfc7 100644 --- a/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java +++ b/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java @@ -44,8 +44,6 @@ import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.NinePatchDrawable; -import android.media.MediaCodecInfo; -import android.media.MediaCodecList; import android.media.MediaFormat; import android.net.Uri; import android.os.Build; @@ -246,8 +244,9 @@ public class ImageDecoderTest { public void testDecode10BitHeif() { assumeTrue( "Test needs Android T.", ApiLevelUtil.isFirstApiAtLeast(Build.VERSION_CODES.TIRAMISU)); - assumeTrue("No 10-bit HEVC decoder, skip the test.", has10BitHEVCDecoder()); - + if (!MediaUtils.hasDecoder(MediaFormat.MIMETYPE_VIDEO_HEVC)) { + return; + } try { ImageDecoder.Source src = ImageDecoder .createSource(getResources(), R.raw.heifimage_10bit); @@ -267,8 +266,9 @@ public class ImageDecoderTest { @Test @RequiresDevice public void testDecode10BitHeifWithLowRam() { - assumeTrue("No 10-bit HEVC decoder, skip the test.", has10BitHEVCDecoder()); - + if (!MediaUtils.hasDecoder(MediaFormat.MIMETYPE_VIDEO_HEVC)) { + return; + } ImageDecoder.Source src = ImageDecoder.createSource(getResources(), R.raw.heifimage_10bit); assertNotNull(src); try { @@ -2770,19 +2770,4 @@ public class ImageDecoderTest { ImageDecoder.Source src = ImageDecoder.createSource(() -> null); ImageDecoder.decodeDrawable(src); } - - private static boolean has10BitHEVCDecoder() { - MediaFormat format = new MediaFormat(); - format.setString(MediaFormat.KEY_MIME, "video/hevc"); - format.setInteger( - MediaFormat.KEY_PROFILE, MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10); - format.setInteger( - MediaFormat.KEY_LEVEL, MediaCodecInfo.CodecProfileLevel.HEVCMainTierLevel5); - - MediaCodecList mcl = new MediaCodecList(MediaCodecList.ALL_CODECS); - if (mcl.findDecoderForFormat(format) == null) { - return false; - } - return true; - } } diff --git a/tests/tests/graphics/src/android/graphics/cts/SystemPaletteTest.java b/tests/tests/graphics/src/android/graphics/cts/SystemPaletteTest.java index caccc0b70b2..fb3d7ed5fa6 100644 --- a/tests/tests/graphics/src/android/graphics/cts/SystemPaletteTest.java +++ b/tests/tests/graphics/src/android/graphics/cts/SystemPaletteTest.java @@ -34,7 +34,6 @@ import androidx.core.graphics.ColorUtils; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; -import com.android.compatibility.common.util.CddTest; import com.android.compatibility.common.util.PollingCheck; import org.junit.Assert; @@ -75,7 +74,6 @@ public class SystemPaletteTest { } @Test - @CddTest(requirements = {"3.8.6/C-1-4,C-1-5,C-1-6"}) public void testThemeStyles() { final Context context = getInstrumentation().getTargetContext(); forEachThemeDefinition((color, style, expectedPalette) -> { 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 aff4b337b21..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 @@ -95,9 +95,6 @@ public abstract class VirtualDeviceTestCase extends InputTestCase { final PackageManager packageManager = context.getPackageManager(); // TVs do not support companion assumeTrue(packageManager.hasSystemFeature(PackageManager.FEATURE_COMPANION_DEVICE_SETUP)); - // Virtual input devices only operate on virtual displays - assumeTrue(packageManager.hasSystemFeature( - PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS)); final String packageName = context.getPackageName(); associateCompanionDevice(packageName); diff --git a/tests/tests/media/audio/AndroidTest.xml b/tests/tests/media/audio/AndroidTest.xml index 26210bd4dd2..53265befc6a 100644 --- a/tests/tests/media/audio/AndroidTest.xml +++ b/tests/tests/media/audio/AndroidTest.xml @@ -35,8 +35,8 @@ <option name="package" value="android.media.audio.cts" /> <!-- setup can be expensive so limit the number of shards --> <option name="ajur-max-shard" value="5" /> - <!-- test-timeout unit is ms, value = 240 min --> - <option name="test-timeout" value="14400000" /> + <!-- test-timeout unit is ms, value = 25 min --> + <option name="test-timeout" value="1500000" /> <option name="runtime-hint" value="1h" /> <option name="exclude-annotation" value="org.junit.Ignore" /> <option name="hidden-api-checks" value="false" /> diff --git a/tests/tests/media/audio/src/android/media/audio/cts/DirectAudioProfilesForAttributesTest.kt b/tests/tests/media/audio/src/android/media/audio/cts/DirectAudioProfilesForAttributesTest.kt index f6548a253ac..04cbf70846f 100644 --- a/tests/tests/media/audio/src/android/media/audio/cts/DirectAudioProfilesForAttributesTest.kt +++ b/tests/tests/media/audio/src/android/media/audio/cts/DirectAudioProfilesForAttributesTest.kt @@ -57,7 +57,11 @@ class DirectAudioProfilesForAttributesTest { val audioAttributes = AudioAttributes.Builder() .setUsage(usage) .build() + val allProfilesForAttributes = + audioManager.getAudioDevicesForAttributes(audioAttributes).map { it.audioProfiles } + .flatten() val directProfiles = audioManager.getDirectProfilesForAttributes(audioAttributes) + val nonDirectProfiles = allProfilesForAttributes.subtractAll(directProfiles) // All compressed format (non pcm) profiles can create direct AudioTracks. // getDirectProfilesForAttributes does not include profiles supporting @@ -67,6 +71,13 @@ class DirectAudioProfilesForAttributesTest { for (directProfile in compressedProfiles) { checkCreateAudioTracks(audioAttributes, directProfile, true) } + + // Any other available but not returned compressed format profile + // can't create any direct AudioTrack + val otherCompressedProfiles = nonDirectProfiles.filterOutPcmFormats() + for (nonDirectProfile in otherCompressedProfiles) { + checkCreateAudioTracks(audioAttributes, nonDirectProfile, false) + } } } @@ -90,7 +101,7 @@ class DirectAudioProfilesForAttributesTest { .build() .release() // allow a short time to free the AudioTrack resources - Thread.sleep(100) + Thread.sleep(150) if (!expectedCreationSuccess) { fail( "Created AudioTrack for attributes ($audioAttributes) and " + @@ -109,6 +120,13 @@ class DirectAudioProfilesForAttributesTest { } // Utils + private fun AudioProfile.isSame(profile: AudioProfile) = + format == profile.format && + encapsulationType == profile.encapsulationType && + sampleRates.contentEquals(profile.sampleRates) && + channelMasks.contentEquals(profile.channelMasks) && + channelIndexMasks.contentEquals(profile.channelIndexMasks) + private fun AudioProfile.getAllAudioFormats() = sampleRates.map { sampleRate -> channelMasks.map { channelMask -> @@ -128,6 +146,12 @@ class DirectAudioProfilesForAttributesTest { ) }.flatten() + private fun List<AudioProfile>.subtractAll(elements: List<AudioProfile>) = + filter { profile -> elements.none { it.isSame(profile) } } + + private fun List<AudioProfile>.includesAll(elements: List<AudioProfile>) = + elements.all { profile -> this@includesAll.any { it.isSame(profile) } } + private fun List<AudioProfile>.filterOutPcmFormats() = filter { it.format !in pcmFormats } companion object { diff --git a/tests/tests/media/audio/src/android/media/audio/cts/RoutingTest.java b/tests/tests/media/audio/src/android/media/audio/cts/RoutingTest.java index c273a18fe51..848d74c9abb 100644 --- a/tests/tests/media/audio/src/android/media/audio/cts/RoutingTest.java +++ b/tests/tests/media/audio/src/android/media/audio/cts/RoutingTest.java @@ -808,7 +808,7 @@ public class RoutingTest extends AndroidTestCase { } private MediaRecorder allocMediaRecorder() throws Exception { - final String outputPath = new File(mContext.getExternalFilesDir(null), + final String outputPath = new File(Environment.getExternalStorageDirectory(), "record.out").getAbsolutePath(); mOutFile = new File(outputPath); MediaRecorder mediaRecorder = new MediaRecorder(); diff --git a/tests/tests/media/codec/AndroidTest.xml b/tests/tests/media/codec/AndroidTest.xml index a2f5d2b4ea1..ce2b7edbff1 100644 --- a/tests/tests/media/codec/AndroidTest.xml +++ b/tests/tests/media/codec/AndroidTest.xml @@ -33,11 +33,6 @@ <option name="dynamic-config-name" value="CtsMediaCodecTestCases" /> <option name="version" value="1.0"/> </target_preparer> - <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher"> - <option name="target" value="device" /> - <option name="config-filename" value="CtsMediaCodecTestCases" /> - <option name="version" value="7.0"/> - </target_preparer> <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer"> <option name="push-all" value="true" /> <option name="media-folder-name" value="CtsMediaCodecTestCases-1.0" /> @@ -47,6 +42,11 @@ <option name="cleanup-apks" value="true" /> <option name="test-file-name" value="CtsMediaCodecTestCases.apk" /> </target_preparer> + <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher"> + <option name="target" value="device" /> + <option name="config-filename" value="CtsMediaCodecTestCases" /> + <option name="version" value="7.0"/> + </target_preparer> <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="android.media.codec.cts" /> <!-- setup can be expensive so limit the number of shards --> diff --git a/tests/tests/media/codec/src/android/media/codec/cts/MediaCodecTest.java b/tests/tests/media/codec/src/android/media/codec/cts/MediaCodecTest.java index 4294059d0cd..a7bb37fe152 100644 --- a/tests/tests/media/codec/src/android/media/codec/cts/MediaCodecTest.java +++ b/tests/tests/media/codec/src/android/media/codec/cts/MediaCodecTest.java @@ -35,13 +35,14 @@ import android.media.MediaCodecInfo.CodecProfileLevel; import android.media.MediaCodecInfo.EncoderCapabilities; import android.media.MediaCodecInfo.VideoCapabilities; import android.media.MediaCodecList; +import android.media.MediaCrypto; import android.media.MediaExtractor; import android.media.MediaFormat; +import android.media.cts.AudioHelper; import android.media.cts.InputSurface; import android.media.cts.OutputSurface; import android.media.cts.Preconditions; import android.media.cts.StreamUtils; -import android.media.cts.TestUtils; import android.opengl.GLES20; import android.os.Build; import android.os.ConditionVariable; @@ -63,9 +64,13 @@ import androidx.test.filters.SmallTest; import com.android.compatibility.common.util.ApiLevelUtil; import com.android.compatibility.common.util.MediaUtils; +import java.io.BufferedInputStream; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.nio.ByteBuffer; +import java.nio.FloatBuffer; +import java.nio.ShortBuffer; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -2424,11 +2429,6 @@ public class MediaCodecTest extends AndroidTestCase { continue; } MediaCodec codec = null; - if (!TestUtils.isTestableCodecInCurrentMode(info.getName())) { - Log.d(TAG, "skip testing codec " + info.getName() + " in current mode:" - + (TestUtils.isMtsMode() ? " MTS" : " CTS")); - continue; - } try { codec = MediaCodec.createByCodecName(info.getName()); List<String> vendorParams = codec.getSupportedVendorParameters(); diff --git a/tests/tests/media/common/src/android/media/cts/CodecState.java b/tests/tests/media/common/src/android/media/cts/CodecState.java index 3565fc85e2b..13e56f85b59 100644 --- a/tests/tests/media/common/src/android/media/cts/CodecState.java +++ b/tests/tests/media/common/src/android/media/cts/CodecState.java @@ -358,7 +358,7 @@ public class CodecState { return null; } - if (mIsTunneled) { + if (mIsTunneled && !mIsAudio) { if (mFirstSampleTimeUs == -1) { mFirstSampleTimeUs = sampleTime; } diff --git a/tests/tests/media/common/src/android/media/cts/TestUtils.java b/tests/tests/media/common/src/android/media/cts/TestUtils.java index f98b3abf936..b09d333d958 100644 --- a/tests/tests/media/common/src/android/media/cts/TestUtils.java +++ b/tests/tests/media/common/src/android/media/cts/TestUtils.java @@ -25,10 +25,8 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.Bundle; -import android.text.TextUtils; import android.util.Log; -import androidx.test.InstrumentationRegistry; import androidx.test.core.app.ApplicationProvider; import org.junit.Assert; @@ -153,46 +151,6 @@ public final class TestUtils { return true; } - /* - * Report whether we are in MTS mode (vs in CTS) mode. - * Some tests (or parts of tests) are restricted to a particular mode. - */ - public static boolean isMtsMode() { - Bundle bundle = InstrumentationRegistry.getArguments(); - // null if not set - boolean isMTS = TextUtils.equals("true", bundle.getString("mts-media")); - - return isMTS; - } - - /* - * Report whether we want to test a particular code in the current test mode. - * CTS is pretty much "test them all". - * MTS should only be testing codecs that are part of the swcodec module; all of these - * begin with "c2.android." - * - * Used in spots throughout the test suite where we want to limit our testing to relevant - * codecs. This avoids false alarms that are sometimes triggered by non-compliant, - * non-mainline codecs. - * - * @param name the name of a codec - * @return {@code} true is the codec should be tested in the current operating mode. - */ - public static boolean isTestableCodecInCurrentMode(String name) { - if (name == null) { - return false; - } - if (!isMtsMode()) { - // CTS mode -- test everything - return true; - } - // MTS mode, just the codecs that live in the modules - if (name.startsWith("c2.android.")) { - return true; - } - return false; - } - private TestUtils() { } diff --git a/tests/tests/media/decoder/AndroidTest.xml b/tests/tests/media/decoder/AndroidTest.xml index 55fe608afdb..c7d4550a016 100644 --- a/tests/tests/media/decoder/AndroidTest.xml +++ b/tests/tests/media/decoder/AndroidTest.xml @@ -33,11 +33,6 @@ <option name="dynamic-config-name" value="CtsMediaDecoderTestCases" /> <option name="version" value="1.0"/> </target_preparer> - <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher"> - <option name="target" value="device" /> - <option name="config-filename" value="CtsMediaDecoderTestCases" /> - <option name="version" value="1.0"/> - </target_preparer> <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer"> <option name="push-all" value="true" /> <option name="media-folder-name" value="CtsMediaDecoderTestCases-1.1" /> @@ -47,6 +42,11 @@ <option name="cleanup-apks" value="true" /> <option name="test-file-name" value="CtsMediaDecoderTestCases.apk" /> </target_preparer> + <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher"> + <option name="target" value="device" /> + <option name="config-filename" value="CtsMediaDecoderTestCases" /> + <option name="version" value="1.0"/> + </target_preparer> <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="android.media.decoder.cts" /> <!-- setup can be expensive so limit the number of shards --> 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 0b8c50598b1..a424edbd8c5 100644 --- a/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTest.java +++ b/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTest.java @@ -124,10 +124,10 @@ public class DecoderTest extends MediaTestBase { private static final int CONFIG_MODE_NONE = 0; private static final int CONFIG_MODE_QUEUE = 1; - public static final int CODEC_ALL = 0; // All codecs must support - public static final int CODEC_ANY = 1; // At least one codec must support - public static final int CODEC_DEFAULT = 2; // Default codec must support - public static final int CODEC_OPTIONAL = 3; // Codec support is optional + private static final int CODEC_ALL = 0; // All codecs must support + private static final int CODEC_ANY = 1; // At least one codec must support + private static final int CODEC_DEFAULT = 2; // Default codec must support + private static final int CODEC_OPTIONAL = 3; // Codec support is optional short[] mMasterBuffer; static final String mInpPrefix = WorkDir.getMediaDirString(); diff --git a/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTestAacFormat.java b/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTestAacFormat.java index 0857809211e..f34f9e23146 100644 --- a/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTestAacFormat.java +++ b/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTestAacFormat.java @@ -81,9 +81,9 @@ public class DecoderTestAacFormat { AudioFormat.CHANNEL_OUT_QUAD | AudioFormat.CHANNEL_OUT_FRONT_CENTER}, {"noise_6ch_44khz_aot5_dr_sbr_sig2_mp4.m4a", 6, AudioFormat.CHANNEL_OUT_5POINT1}, }; - for (Object[] sample: samples) { - for (String codecName : DecoderTest.codecsFor((String)sample[0] /* resource */, - DecoderTest.CODEC_DEFAULT)) { + + for (Object [] sample: samples) { + for (String codecName : DecoderTest.codecsFor((String)sample[0] /* resource */)) { // verify correct number of channels is observed without downmixing AudioParameter chanParams = new AudioParameter(); decodeUpdateFormat(codecName, (String) sample[0] /*resource*/, chanParams, diff --git a/tests/tests/media/drmframework/AndroidTest.xml b/tests/tests/media/drmframework/AndroidTest.xml index 28aaadc3c6d..c6e311de86e 100644 --- a/tests/tests/media/drmframework/AndroidTest.xml +++ b/tests/tests/media/drmframework/AndroidTest.xml @@ -26,11 +26,6 @@ <option name="dynamic-config-name" value="CtsMediaDrmFrameworkTestCases" /> <option name="version" value="9.0_r1"/> </target_preparer> - <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher"> - <option name="target" value="device" /> - <option name="config-filename" value="CtsMediaDrmFrameworkTestCases" /> - <option name="version" value="7.0"/> - </target_preparer> <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer"> <option name="push-all" value="true" /> <option name="media-folder-name" value="CtsMediaDrmFrameworkTestCases-1.0" /> @@ -40,6 +35,11 @@ <option name="cleanup-apks" value="true" /> <option name="test-file-name" value="CtsMediaDrmFrameworkTestCases.apk" /> </target_preparer> + <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher"> + <option name="target" value="device" /> + <option name="config-filename" value="CtsMediaDrmFrameworkTestCases" /> + <option name="version" value="7.0"/> + </target_preparer> <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="android.media.drmframework.cts" /> <!-- setup can be expensive so limit the number of shards --> diff --git a/tests/tests/media/encoder/AndroidTest.xml b/tests/tests/media/encoder/AndroidTest.xml index 4de5615b84e..65d8d6d62f1 100644 --- a/tests/tests/media/encoder/AndroidTest.xml +++ b/tests/tests/media/encoder/AndroidTest.xml @@ -33,11 +33,6 @@ <option name="dynamic-config-name" value="CtsMediaEncoderTestCases" /> <option name="version" value="1.0"/> </target_preparer> - <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher"> - <option name="target" value="device" /> - <option name="config-filename" value="CtsMediaEncoderTestCases" /> - <option name="version" value="1.0"/> - </target_preparer> <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer"> <option name="push-all" value="true" /> <option name="media-folder-name" value="CtsMediaEncoderTestCases-1.0" /> @@ -47,6 +42,11 @@ <option name="cleanup-apks" value="true" /> <option name="test-file-name" value="CtsMediaEncoderTestCases.apk" /> </target_preparer> + <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher"> + <option name="target" value="device" /> + <option name="config-filename" value="CtsMediaEncoderTestCases" /> + <option name="version" value="1.0"/> + </target_preparer> <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="android.media.encoder.cts" /> <!-- setup can be expensive so limit the number of shards --> diff --git a/tests/tests/media/extractor/AndroidTest.xml b/tests/tests/media/extractor/AndroidTest.xml index fbe2d48fad5..007a65b74a3 100644 --- a/tests/tests/media/extractor/AndroidTest.xml +++ b/tests/tests/media/extractor/AndroidTest.xml @@ -33,11 +33,6 @@ <option name="dynamic-config-name" value="CtsMediaExtractorTestCases" /> <option name="version" value="1.0"/> </target_preparer> - <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher"> - <option name="target" value="device" /> - <option name="config-filename" value="CtsMediaExtractorTestCases" /> - <option name="version" value="1.0"/> - </target_preparer> <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer"> <option name="push-all" value="true" /> <option name="media-folder-name" value="CtsMediaExtractorTestCases-1.0" /> @@ -47,6 +42,11 @@ <option name="cleanup-apks" value="true" /> <option name="test-file-name" value="CtsMediaExtractorTestCases.apk" /> </target_preparer> + <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher"> + <option name="target" value="device" /> + <option name="config-filename" value="CtsMediaExtractorTestCases" /> + <option name="version" value="1.0"/> + </target_preparer> <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="android.media.extractor.cts" /> <!-- setup can be expensive so limit the number of shards --> diff --git a/tests/tests/media/misc/AndroidTest.xml b/tests/tests/media/misc/AndroidTest.xml index 4a2ffaf9d33..58cea2c8df6 100644 --- a/tests/tests/media/misc/AndroidTest.xml +++ b/tests/tests/media/misc/AndroidTest.xml @@ -33,11 +33,6 @@ <option name="dynamic-config-name" value="CtsMediaMiscTestCases" /> <option name="version" value="9.0_r1"/> </target_preparer> - <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher"> - <option name="target" value="device" /> - <option name="config-filename" value="CtsMediaMiscTestCases" /> - <option name="version" value="1.0"/> - </target_preparer> <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer"> <option name="push-all" value="true" /> <option name="media-folder-name" value="CtsMediaMiscTestCases-1.0" /> @@ -47,6 +42,11 @@ <option name="cleanup-apks" value="true" /> <option name="test-file-name" value="CtsMediaMiscTestCases.apk" /> </target_preparer> + <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher"> + <option name="target" value="device" /> + <option name="config-filename" value="CtsMediaMiscTestCases" /> + <option name="version" value="1.0"/> + </target_preparer> <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="android.media.misc.cts" /> <!-- setup can be expensive so limit the number of shards --> diff --git a/tests/tests/media/muxer/AndroidTest.xml b/tests/tests/media/muxer/AndroidTest.xml index 0c361e96d36..502f2ca2628 100644 --- a/tests/tests/media/muxer/AndroidTest.xml +++ b/tests/tests/media/muxer/AndroidTest.xml @@ -33,11 +33,6 @@ <option name="dynamic-config-name" value="CtsMediaMuxerTestCases" /> <option name="version" value="1.0"/> </target_preparer> - <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher"> - <option name="target" value="device" /> - <option name="config-filename" value="CtsMediaMuxerTestCases" /> - <option name="version" value="1.0"/> - </target_preparer> <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer"> <option name="push-all" value="true" /> <option name="media-folder-name" value="CtsMediaMuxerTestCases-1.1" /> @@ -47,6 +42,11 @@ <option name="cleanup-apks" value="true" /> <option name="test-file-name" value="CtsMediaMuxerTestCases.apk" /> </target_preparer> + <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher"> + <option name="target" value="device" /> + <option name="config-filename" value="CtsMediaMuxerTestCases" /> + <option name="version" value="1.0"/> + </target_preparer> <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="android.media.muxer.cts" /> <!-- setup can be expensive so limit the number of shards --> diff --git a/tests/tests/media/player/AndroidTest.xml b/tests/tests/media/player/AndroidTest.xml index a0041ac2af8..e3e8b0215cc 100644 --- a/tests/tests/media/player/AndroidTest.xml +++ b/tests/tests/media/player/AndroidTest.xml @@ -33,11 +33,6 @@ <option name="dynamic-config-name" value="CtsMediaPlayerTestCases" /> <option name="version" value="1.0"/> </target_preparer> - <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher"> - <option name="target" value="device" /> - <option name="config-filename" value="CtsMediaPlayerTestCases" /> - <option name="version" value="1.0"/> - </target_preparer> <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer"> <option name="push-all" value="true" /> <option name="media-folder-name" value="CtsMediaPlayerTestCases-1.0" /> @@ -47,6 +42,11 @@ <option name="cleanup-apks" value="true" /> <option name="test-file-name" value="CtsMediaPlayerTestCases.apk" /> </target_preparer> + <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher"> + <option name="target" value="device" /> + <option name="config-filename" value="CtsMediaPlayerTestCases" /> + <option name="version" value="1.0"/> + </target_preparer> <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="android.media.player.cts" /> <!-- setup can be expensive so limit the number of shards --> diff --git a/tests/tests/media/player/src/android/media/player/cts/MediaPlayerTest.java b/tests/tests/media/player/src/android/media/player/cts/MediaPlayerTest.java index fdf85076427..b46366cb5d8 100644 --- a/tests/tests/media/player/src/android/media/player/cts/MediaPlayerTest.java +++ b/tests/tests/media/player/src/android/media/player/cts/MediaPlayerTest.java @@ -406,10 +406,9 @@ public class MediaPlayerTest extends MediaPlayerTestBase { } @Test - public void testConcurrentPlayAudio() throws Exception { + public void testConcurentPlayAudio() throws Exception { final String res = "test1m1s.mp3"; // MP3 longer than 1m are usualy offloaded - final int recommendedTolerance = 70; - final List<Integer> offsets = new ArrayList<>(); + final int tolerance = 70; Preconditions.assertTestFileExists(mInpPrefix + res); List<MediaPlayer> mps = Stream.generate( @@ -432,25 +431,13 @@ public class MediaPlayerTest extends MediaPlayerTestBase { int pos = mp.getCurrentPosition(); assertTrue(pos >= 0); - Thread.sleep(SLEEP_TIME); // Delay each track to be able to hear them + Thread.sleep(SLEEP_TIME); // Delay each track to be able to ear them } - // Check that all mp3 are playing concurrently here - // Record the offsets between streams, but don't enforce them for (MediaPlayer mp : mps) { int pos = mp.getCurrentPosition(); Thread.sleep(SLEEP_TIME); - offsets.add(Math.abs(pos + SLEEP_TIME - mp.getCurrentPosition())); - } - - if (offsets.stream().anyMatch(offset -> offset > recommendedTolerance)) { - Log.w(LOG_TAG, "testConcurrentPlayAudio: some concurrent playing offsets " - + offsets + " are above the recommended tolerance of " - + recommendedTolerance + "ms."); - } else { - Log.i(LOG_TAG, "testConcurrentPlayAudio: all concurrent playing offsets " - + offsets + " are under the recommended tolerance of " - + recommendedTolerance + "ms."); + assertEquals(pos + SLEEP_TIME, mp.getCurrentPosition(), tolerance); } } finally { mps.forEach(MediaPlayer::release); diff --git a/tests/tests/os/Android.bp b/tests/tests/os/Android.bp index c50c6a70dd7..8bc82220b10 100644 --- a/tests/tests/os/Android.bp +++ b/tests/tests/os/Android.bp @@ -40,7 +40,6 @@ android_test { "hamcrest-library", "modules-utils-build_system", "platformprotosnano", - "safety-center-internal-data", ], jni_uses_platform_apis: true, jni_libs: [ diff --git a/tests/tests/os/src/android/os/cts/AppHibernationUtils.kt b/tests/tests/os/src/android/os/cts/AppHibernationUtils.kt index ec8b7c862c4..4b91ee0c3ec 100644 --- a/tests/tests/os/src/android/os/cts/AppHibernationUtils.kt +++ b/tests/tests/os/src/android/os/cts/AppHibernationUtils.kt @@ -50,19 +50,17 @@ import com.android.compatibility.common.util.UiDumpUtils import com.android.compatibility.common.util.click import com.android.compatibility.common.util.depthFirstSearch import com.android.compatibility.common.util.textAsString -import java.io.InputStream -import java.util.concurrent.CountDownLatch -import java.util.concurrent.TimeUnit import org.hamcrest.Matcher import org.hamcrest.Matchers import org.junit.Assert import org.junit.Assert.assertThat import org.junit.Assert.assertTrue +import java.io.InputStream +import java.util.concurrent.CountDownLatch +import java.util.concurrent.TimeUnit private const val BROADCAST_TIMEOUT_MS = 60000L -const val PROPERTY_SAFETY_CENTER_ENABLED = "safety_center_is_enabled" - const val SYSUI_PKG_NAME = "com.android.systemui" const val NOTIF_LIST_ID = "com.android.systemui:id/notification_stack_scroller" const val CLEAR_ALL_BUTTON_ID = "dismiss_text" @@ -199,12 +197,6 @@ inline fun <T> withUnusedThresholdMs(threshold: Long, action: () -> T): T { threshold.toString(), action) } -inline fun <T> withSafetyCenterEnabled(action: () -> T): T { - return withDeviceConfig( - DeviceConfig.NAMESPACE_PRIVACY, PROPERTY_SAFETY_CENTER_ENABLED, - true.toString(), action) -} - fun awaitAppState(pkg: String, stateMatcher: Matcher<Int>) { val context: Context = InstrumentationRegistry.getTargetContext() eventually { diff --git a/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt b/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt index b5db2fd8f76..b724be82b36 100644 --- a/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt +++ b/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt @@ -28,11 +28,8 @@ import android.content.pm.PackageManager.PERMISSION_GRANTED import android.content.res.Resources import android.net.Uri import android.os.Build -import android.os.UserHandle import android.platform.test.annotations.AppModeFull import android.provider.DeviceConfig -import android.safetycenter.SafetyCenterIssue -import android.safetycenter.SafetyCenterManager import android.support.test.uiautomator.By import android.support.test.uiautomator.BySelector import android.support.test.uiautomator.UiObject2 @@ -57,13 +54,6 @@ import com.android.compatibility.common.util.click import com.android.compatibility.common.util.depthFirstSearch import com.android.compatibility.common.util.uiDump import com.android.modules.utils.build.SdkLevel -import com.android.safetycenter.internaldata.SafetyCenterIds -import com.android.safetycenter.internaldata.SafetyCenterIssueId -import com.android.safetycenter.internaldata.SafetyCenterIssueKey -import java.lang.reflect.Modifier -import java.util.concurrent.TimeUnit -import java.util.concurrent.atomic.AtomicReference -import java.util.regex.Pattern import org.hamcrest.CoreMatchers.containsString import org.hamcrest.CoreMatchers.containsStringIgnoringCase import org.hamcrest.CoreMatchers.equalTo @@ -81,6 +71,10 @@ import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith +import java.lang.reflect.Modifier +import java.util.concurrent.TimeUnit +import java.util.concurrent.atomic.AtomicReference +import java.util.regex.Pattern private const val READ_CALENDAR = "android.permission.READ_CALENDAR" private const val BLUETOOTH_CONNECT = "android.permission.BLUETOOTH_CONNECT" @@ -109,8 +103,6 @@ class AutoRevokeTest { companion object { const val LOG_TAG = "AutoRevokeTest" private const val STORE_EXACT_TIME_KEY = "permission_changes_store_exact_time" - private const val UNUSED_APPS_SOURCE_ID = "AndroidPermissionAutoRevoke" - private const val UNUSED_APPS_ISSUE_ID = "unused_apps_issue" @JvmStatic @BeforeClass @@ -442,84 +434,6 @@ class AutoRevokeTest { } } - @AppModeFull(reason = "Uses separate apps for testing") - @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU, codeName = "Tiramisu") - @Test - fun testAutoRevoke_showsUpInSafetyCenter() { - withSafetyCenterEnabled { - withUnusedThresholdMs(3L) { - withDummyApp { - startAppAndAcceptPermission() - - killDummyApp() - - // Run - runAppHibernationJob(context, LOG_TAG) - - // Verify - val safetyCenterManager = - context.getSystemService(SafetyCenterManager::class.java)!! - val issues = ArrayList<SafetyCenterIssue>() - runWithShellPermissionIdentity { - val safetyCenterData = safetyCenterManager!!.safetyCenterData - issues.addAll(safetyCenterData.issues) - } - val issueId = SafetyCenterIds.encodeToString( - SafetyCenterIssueId.newBuilder() - .setSafetyCenterIssueKey(SafetyCenterIssueKey.newBuilder() - .setSafetySourceId(UNUSED_APPS_SOURCE_ID) - .setSafetySourceIssueId(UNUSED_APPS_ISSUE_ID) - .setUserId(UserHandle.myUserId()) - .build()) - .setIssueTypeId(UNUSED_APPS_ISSUE_ID) - .build()) - assertTrue(issues.any {it.id == issueId}) - } - } - } - } - - @AppModeFull(reason = "Uses separate apps for testing") - @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU, codeName = "Tiramisu") - @Test - fun testAutoRevoke_goToUnusedAppsPage_removesSafetyCenterIssue() { - withSafetyCenterEnabled { - withUnusedThresholdMs(3L) { - withDummyApp { - startAppAndAcceptPermission() - - killDummyApp() - - // Run - runAppHibernationJob(context, LOG_TAG) - - // Go to unused apps page - openUnusedAppsNotification() - waitFindObject(By.text(supportedAppPackageName)) - - // Verify - val safetyCenterManager = - context.getSystemService(SafetyCenterManager::class.java)!! - val issues = ArrayList<SafetyCenterIssue>() - runWithShellPermissionIdentity { - val safetyCenterData = safetyCenterManager!!.safetyCenterData - issues.addAll(safetyCenterData.issues) - } - val issueId = SafetyCenterIds.encodeToString( - SafetyCenterIssueId.newBuilder() - .setSafetyCenterIssueKey(SafetyCenterIssueKey.newBuilder() - .setSafetySourceId(UNUSED_APPS_SOURCE_ID) - .setSafetySourceIssueId(UNUSED_APPS_ISSUE_ID) - .setUserId(UserHandle.myUserId()) - .build()) - .setIssueTypeId(UNUSED_APPS_ISSUE_ID) - .build()) - assertFalse(issues.any {it.id == issueId}) - } - } - } - } - private fun isAutomotiveDevice(): Boolean { return context.packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) } diff --git a/tests/tests/permission/src/android/permission/cts/AccessibilityPrivacySourceTest.kt b/tests/tests/permission/src/android/permission/cts/AccessibilityPrivacySourceTest.kt index 86a680ecd7f..58238e3b5be 100644 --- a/tests/tests/permission/src/android/permission/cts/AccessibilityPrivacySourceTest.kt +++ b/tests/tests/permission/src/android/permission/cts/AccessibilityPrivacySourceTest.kt @@ -35,7 +35,6 @@ import android.permission.cts.SafetyCenterUtils.assertSafetyCenterIssueExist import android.permission.cts.SafetyCenterUtils.assertSafetyCenterStarted import android.permission.cts.SafetyCenterUtils.deviceSupportsSafetyCenter import android.permission.cts.SafetyCenterUtils.setDeviceConfigPrivacyProperty -import android.platform.test.annotations.AppModeFull import android.provider.DeviceConfig import android.safetycenter.SafetyCenterManager import androidx.test.filters.SdkSuppress @@ -56,10 +55,6 @@ import org.junit.Test import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) -@AppModeFull( - reason = "Cannot set system settings as instant app. Also we never show an accessibility " + - "notification for instant apps." -) @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU, codeName = "Tiramisu") class AccessibilityPrivacySourceTest { diff --git a/tests/tests/permission/src/android/permission/cts/SafetyCenterUtils.kt b/tests/tests/permission/src/android/permission/cts/SafetyCenterUtils.kt index 931ecd1bc6b..f057b21a849 100644 --- a/tests/tests/permission/src/android/permission/cts/SafetyCenterUtils.kt +++ b/tests/tests/permission/src/android/permission/cts/SafetyCenterUtils.kt @@ -67,7 +67,7 @@ object SafetyCenterUtils { @JvmStatic fun assertSafetyCenterStarted() { // CollapsingToolbar title can't be found by text, so using description instead. - waitFindObject(By.desc("Security & privacy")) + waitFindObject(By.desc("Security & Privacy")) } @JvmStatic diff --git a/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt b/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt index 872a243ce2e..598a59a1727 100644 --- a/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt +++ b/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt @@ -78,8 +78,6 @@ private const val IDLE_TIMEOUT_MILLIS: Long = 1000 private const val UNEXPECTED_TIMEOUT_MILLIS = 1000 private const val TIMEOUT_MILLIS: Long = 20000 private const val TV_MIC_INDICATOR_WINDOW_TITLE = "MicrophoneCaptureIndicator" -private const val MIC_LABEL_NAME = "microphone_toggle_label_qs" -private const val CAMERA_LABEL_NAME = "camera_toggle_label_qs" class CameraMicIndicatorsPermissionTest { private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() @@ -92,9 +90,11 @@ class CameraMicIndicatorsPermissionTest { private val isTv = packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK) private val isCar = packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) - private val micLabel = getPermissionControllerString(MIC_LABEL_NAME) - private val cameraLabel = getPermissionControllerString(CAMERA_LABEL_NAME) private var wasEnabled = false + private val micLabel = packageManager.getPermissionGroupInfo( + Manifest.permission_group.MICROPHONE, 0).loadLabel(packageManager).toString() + private val cameraLabel = packageManager.getPermissionGroupInfo( + Manifest.permission_group.CAMERA, 0).loadLabel(packageManager).toString() private var isScreenOn = false private var screenTimeoutBeforeTest: Long = 0L @@ -520,18 +520,4 @@ class CameraMicIndicatorsPermissionTest { automatorMethod(remainingTime) } } - - private fun getPermissionControllerString(resourceName: String): String { - val permissionControllerPkg = context.packageManager.permissionControllerPackageName - try { - val permissionControllerContext = - context.createPackageContext(permissionControllerPkg, 0) - val resourceId = - permissionControllerContext.resources.getIdentifier( - resourceName, "string", "com.android.permissioncontroller") - return permissionControllerContext.getString(resourceId) - } catch (e: PackageManager.NameNotFoundException) { - throw RuntimeException(e) - } - } }
\ No newline at end of file diff --git a/tests/tests/permission5/src/android/permission5/cts/RuntimePermissionsAppOpTrackingTest.kt b/tests/tests/permission5/src/android/permission5/cts/RuntimePermissionsAppOpTrackingTest.kt index 67fa1bc3207..8cff38a67a9 100644 --- a/tests/tests/permission5/src/android/permission5/cts/RuntimePermissionsAppOpTrackingTest.kt +++ b/tests/tests/permission5/src/android/permission5/cts/RuntimePermissionsAppOpTrackingTest.kt @@ -25,7 +25,6 @@ import android.content.Context import android.content.ContextParams import android.content.Intent import android.content.pm.PackageManager.FEATURE_LEANBACK -import android.content.pm.PackageManager.FEATURE_TELEPHONY import android.net.Uri import android.os.Bundle import android.os.Process @@ -45,7 +44,6 @@ import com.android.compatibility.common.util.SystemUtil import com.google.common.truth.Truth.assertThat import org.junit.After import org.junit.Assume.assumeFalse -import org.junit.Assume.assumeTrue import org.junit.Before import org.junit.Test import org.mockito.ArgumentMatcher @@ -107,7 +105,6 @@ class RuntimePermissionsAppOpTrackingTest { @Throws(Exception::class) fun testSelfSmsAccess() { assumeNotTv() - assumeHasTelephony() testSelfAccess(Telephony.Sms.CONTENT_URI, Manifest.permission.READ_SMS) } @@ -181,7 +178,6 @@ class RuntimePermissionsAppOpTrackingTest { @Throws(Exception::class) fun testUntrustedSmsAccessAttributeToAnother() { assumeNotTv() - assumeHasTelephony() testUntrustedAccessAttributeToAnother(Telephony.Sms.CONTENT_URI, Manifest.permission.READ_SMS) } @@ -229,7 +225,6 @@ class RuntimePermissionsAppOpTrackingTest { @Throws(Exception::class) fun testUntrustedSmsAccessAttributeToAnotherThroughIntermediary() { assumeNotTv() - assumeHasTelephony() testUntrustedAccessAttributeToAnotherThroughIntermediary( Telephony.Sms.CONTENT_URI, Manifest.permission.READ_SMS) @@ -328,7 +323,6 @@ class RuntimePermissionsAppOpTrackingTest { @Throws(Exception::class) fun testTrustedAccessSmsAttributeToAnother() { assumeNotTv() - assumeHasTelephony() testTrustedAccessAttributeToAnother(Telephony.Sms.CONTENT_URI, Manifest.permission.READ_SMS) } @@ -672,7 +666,6 @@ class RuntimePermissionsAppOpTrackingTest { get() = InstrumentationRegistry.getInstrumentation() private val isTv = context.packageManager.hasSystemFeature(FEATURE_LEANBACK) - private val isTel = context.packageManager.hasSystemFeature(FEATURE_TELEPHONY) fun ensureAuxiliaryAppsNotRunningAndNoResidualProcessState() { SystemUtil.runShellCommand("am force-stop $RECEIVER_PACKAGE_NAME") @@ -1185,6 +1178,5 @@ class RuntimePermissionsAppOpTrackingTest { } private fun assumeNotTv() = assumeFalse(isTv) - private fun assumeHasTelephony() = assumeTrue(isTel) } } diff --git a/tests/tests/preference/src/android/preference/cts/PreferenceActivityLegacyFlowTest.java b/tests/tests/preference/src/android/preference/cts/PreferenceActivityLegacyFlowTest.java index 782f30c6508..29cf672a829 100644 --- a/tests/tests/preference/src/android/preference/cts/PreferenceActivityLegacyFlowTest.java +++ b/tests/tests/preference/src/android/preference/cts/PreferenceActivityLegacyFlowTest.java @@ -103,8 +103,7 @@ public class PreferenceActivityLegacyFlowTest { } private void assertScreenshotsAreEqual(Bitmap before, Bitmap after) { - // TODO(b/227553681): remove the precision=0.99 arg so it does a pixel-by-pixel check - assertTrue("Screenshots do not match!", BitmapUtils.compareBitmaps(before, after, 0.99)); + assertTrue("Screenshots do not match!", BitmapUtils.compareBitmaps(before, after)); } private void assertTextShown(String text) { diff --git a/tests/tests/security/res/raw/cve_2022_22087.mkv b/tests/tests/security/res/raw/cve_2022_22087.mkv Binary files differdeleted file mode 100644 index 0b25fe47095..00000000000 --- a/tests/tests/security/res/raw/cve_2022_22087.mkv +++ /dev/null diff --git a/tests/tests/security/res/raw/cve_2022_25657.mkv b/tests/tests/security/res/raw/cve_2022_25657.mkv Binary files differdeleted file mode 100644 index 3d5f70ed561..00000000000 --- a/tests/tests/security/res/raw/cve_2022_25657.mkv +++ /dev/null diff --git a/tests/tests/security/src/android/security/cts/BitmapTest.java b/tests/tests/security/src/android/security/cts/BitmapTest.java index e824deb2e74..5ce81fd9d95 100644 --- a/tests/tests/security/src/android/security/cts/BitmapTest.java +++ b/tests/tests/security/src/android/security/cts/BitmapTest.java @@ -48,7 +48,6 @@ public class BitmapTest extends StsExtraBusinessLogicTestCase { private Instrumentation mInstrumentation; private PeerConnection mRemoteConnection; private IBitmapService mRemote; - private Intent mIntent; public static class PeerConnection extends AbstractFuture<IBitmapService> implements ServiceConnection { @@ -80,7 +79,6 @@ public class BitmapTest extends StsExtraBusinessLogicTestCase { public void tearDown() { if (mRemoteConnection != null) { final Context context = mInstrumentation.getContext(); - context.stopService(mIntent); context.unbindService(mRemoteConnection); mRemote = null; mRemoteConnection = null; @@ -90,11 +88,11 @@ public class BitmapTest extends StsExtraBusinessLogicTestCase { IBitmapService getRemoteService() throws ExecutionException, InterruptedException { if (mRemote == null) { final Context context = mInstrumentation.getContext(); - mIntent = new Intent(); - mIntent.setComponent(new ComponentName( + Intent intent = new Intent(); + intent.setComponent(new ComponentName( "android.security.cts", "android.security.cts.BitmapService")); mRemoteConnection = new PeerConnection(); - context.bindService(mIntent, mRemoteConnection, + context.bindService(intent, mRemoteConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT); mRemote = mRemoteConnection.get(); } diff --git a/tests/tests/security/src/android/security/cts/CVE_2019_9376.java b/tests/tests/security/src/android/security/cts/CVE_2019_9376.java index 5c0f342fa68..b5896f179de 100644 --- a/tests/tests/security/src/android/security/cts/CVE_2019_9376.java +++ b/tests/tests/security/src/android/security/cts/CVE_2019_9376.java @@ -25,13 +25,12 @@ import android.platform.test.annotations.AppModeFull; import android.platform.test.annotations.AsbSecurityTest; import android.os.Parcel; import androidx.test.runner.AndroidJUnit4; -import com.android.sts.common.util.StsExtraBusinessLogicTestCase; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) -public class CVE_2019_9376 extends StsExtraBusinessLogicTestCase { +public class CVE_2019_9376 { @AppModeFull @AsbSecurityTest(cveBugId = 129287265) diff --git a/tests/tests/security/src/android/security/cts/LocationDisabledAppOpsTest.java b/tests/tests/security/src/android/security/cts/LocationDisabledAppOpsTest.java deleted file mode 100644 index c6b7e35b4ef..00000000000 --- a/tests/tests/security/src/android/security/cts/LocationDisabledAppOpsTest.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.security.cts; - -import static android.app.AppOpsManager.MODE_ALLOWED; -import static android.app.AppOpsManager.OPSTR_FINE_LOCATION; - -import static com.android.compatibility.common.util.SystemUtil.eventually; -import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity; - -import android.app.ActivityManager; -import android.app.AppOpsManager; -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInfo; -import android.location.LocationManager; -import android.os.PackageTagsList; -import android.os.Process; -import android.os.UserHandle; -import android.platform.test.annotations.AsbSecurityTest; - -import androidx.test.InstrumentationRegistry; -import androidx.test.runner.AndroidJUnit4; - -import com.android.sts.common.util.StsExtraBusinessLogicTestCase; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.ArrayList; -import java.util.List; - -@RunWith(AndroidJUnit4.class) -public class LocationDisabledAppOpsTest extends StsExtraBusinessLogicTestCase { - - private final Context mContext = InstrumentationRegistry.getContext(); - private LocationManager mLm; - private AppOpsManager mAom; - - @Before - public void setUp() { - mLm = mContext.getSystemService(LocationManager.class); - mAom = mContext.getSystemService(AppOpsManager.class); - } - - @Test - @AsbSecurityTest(cveBugId = 231496105) - public void testLocationAppOpIsIgnoredForAppsWhenLocationIsDisabled() { - PackageTagsList ignoreList = mLm.getIgnoreSettingsAllowlist(); - - UserHandle[] userArr = {UserHandle.SYSTEM}; - runWithShellPermissionIdentity(() -> { - userArr[0] = UserHandle.of(ActivityManager.getCurrentUser()); - }); - - UserHandle user = userArr[0]; - - boolean wasEnabled = mLm.isLocationEnabledForUser(user); - - try { - runWithShellPermissionIdentity(() -> { - mLm.setLocationEnabledForUser(false, user); - }); - List<PackageInfo> pkgs = - mContext.getPackageManager().getInstalledPackagesAsUser( - 0, user.getIdentifier()); - - eventually(() -> { - List<String> bypassedNoteOps = new ArrayList<>(); - List<String> bypassedCheckOps = new ArrayList<>(); - for (PackageInfo pi : pkgs) { - ApplicationInfo ai = pi.applicationInfo; - if (ai.uid != Process.SYSTEM_UID) { - final int[] mode = {MODE_ALLOWED}; - runWithShellPermissionIdentity(() -> { - mode[0] = mAom.noteOpNoThrow( - OPSTR_FINE_LOCATION, ai.uid, ai.packageName); - }); - if (mode[0] == MODE_ALLOWED && !ignoreList.containsAll(pi.packageName)) { - bypassedNoteOps.add(pi.packageName); - } - - - mode[0] = MODE_ALLOWED; - runWithShellPermissionIdentity(() -> { - mode[0] = mAom - .checkOpNoThrow(OPSTR_FINE_LOCATION, ai.uid, ai.packageName); - }); - if (mode[0] == MODE_ALLOWED && !ignoreList.includes(pi.packageName)) { - bypassedCheckOps.add(pi.packageName); - } - - } - } - - String msg = ""; - if (!bypassedNoteOps.isEmpty()) { - msg += "Apps which still have access from noteOp " + bypassedNoteOps; - } - if (!bypassedCheckOps.isEmpty()) { - msg += (msg.isEmpty() ? "" : "\n\n") - + "Apps which still have access from checkOp " + bypassedCheckOps; - } - if (!msg.isEmpty()) { - Assert.fail(msg); - } - }); - } finally { - runWithShellPermissionIdentity(() -> { - mLm.setLocationEnabledForUser(wasEnabled, user); - }); - } - } - -} - diff --git a/tests/tests/security/src/android/security/cts/PackageInstallerTest.java b/tests/tests/security/src/android/security/cts/PackageInstallerTest.java index ddea21385d8..887538ba2c8 100644 --- a/tests/tests/security/src/android/security/cts/PackageInstallerTest.java +++ b/tests/tests/security/src/android/security/cts/PackageInstallerTest.java @@ -21,24 +21,23 @@ import android.platform.test.annotations.AppModeFull; import android.platform.test.annotations.AsbSecurityTest; import androidx.test.platform.app.InstrumentationRegistry; -import androidx.test.runner.AndroidJUnit4; import com.android.cts.install.lib.Install; import com.android.cts.install.lib.TestApp; import com.android.cts.install.lib.Uninstall; -import com.android.sts.common.util.StsExtraBusinessLogicTestCase; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; import java.util.concurrent.TimeUnit; -@RunWith(AndroidJUnit4.class) +@RunWith(JUnit4.class) @AppModeFull -public class PackageInstallerTest extends StsExtraBusinessLogicTestCase { +public class PackageInstallerTest { private static final String TEST_APP_NAME = "android.security.cts.packageinstallertestapp"; diff --git a/tests/tests/security/src/android/security/cts/RunningAppProcessInfoTest.java b/tests/tests/security/src/android/security/cts/RunningAppProcessInfoTest.java index a46e142e4d5..293200e5541 100644 --- a/tests/tests/security/src/android/security/cts/RunningAppProcessInfoTest.java +++ b/tests/tests/security/src/android/security/cts/RunningAppProcessInfoTest.java @@ -16,21 +16,17 @@ package android.security.cts; -import static org.junit.Assert.*; - import android.app.ActivityManager; import android.content.Context; import android.platform.test.annotations.AsbSecurityTest; - import androidx.test.runner.AndroidJUnit4; - import com.android.sts.common.util.StsExtraBusinessLogicTestCase; - -import org.junit.Test; import org.junit.runner.RunWith; +import org.junit.Test; + +import static org.junit.Assert.*; import java.util.List; -import java.util.stream.Collectors; @RunWith(AndroidJUnit4.class) public class RunningAppProcessInfoTest extends StsExtraBusinessLogicTestCase { @@ -44,23 +40,12 @@ public class RunningAppProcessInfoTest extends StsExtraBusinessLogicTestCase { @Test public void testRunningAppProcessInfo() { ActivityManager amActivityManager = - (ActivityManager) - getInstrumentation() - .getContext() - .getSystemService(Context.ACTIVITY_SERVICE); + (ActivityManager) getInstrumentation().getContext().getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningAppProcessInfo> appList = amActivityManager.getRunningAppProcesses(); - - // Assembles app list for logging - List<String> processNames = - appList.stream() - .map((processInfo) -> processInfo.processName) - .collect(Collectors.toList()); - // The test will pass if it is able to get only its process info - assertTrue( - "Device is vulnerable to CVE-2015-3833. Running app processes: " - + processNames.toString(), - (appList.size() == 1)); + assertTrue("Device is vulnerable to CVE-2015-3833. For more information, see " + + "https://android.googlesource.com/platform/frameworks/base/+" + + "/aaa0fee0d7a8da347a0c47cef5249c70efee209e", (appList.size() == 1)); } } diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java index f0d4ab3c228..d9c0039f9fa 100644 --- a/tests/tests/security/src/android/security/cts/StagefrightTest.java +++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java @@ -1809,18 +1809,6 @@ public class StagefrightTest extends StsExtraBusinessLogicTestCase { before any existing test methods ***********************************************************/ @Test - @AsbSecurityTest(cveBugId = 223209610) - public void testStagefright_cve_2022_22087() throws Exception { - doStagefrightTest(R.raw.cve_2022_22087); - } - - @Test - @AsbSecurityTest(cveBugId = 228101835) - public void testStagefright_cve_2022_25657() throws Exception { - doStagefrightTest(R.raw.cve_2022_25657); - } - - @Test @AsbSecurityTest(cveBugId = 231156126) public void testStagefright_cve_2022_22059() throws Exception { doStagefrightTest(R.raw.cve_2022_22059); @@ -2449,11 +2437,6 @@ public class StagefrightTest extends StsExtraBusinessLogicTestCase { } catch (Exception e) { // local exceptions ignored, not security issues } finally { - try { - codec.stop(); - } catch (Exception e) { - // local exceptions ignored, not security issues - } codec.release(); renderTarget.destroy(); } diff --git a/tests/tests/systemui/src/android/systemui/cts/MediaOutputDialogTest.java b/tests/tests/systemui/src/android/systemui/cts/MediaOutputDialogTest.java index b74678bc3af..0905e57c379 100644 --- a/tests/tests/systemui/src/android/systemui/cts/MediaOutputDialogTest.java +++ b/tests/tests/systemui/src/android/systemui/cts/MediaOutputDialogTest.java @@ -21,12 +21,10 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assume.assumeFalse; import static org.junit.Assume.assumeTrue; -import android.app.ActivityManager; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; -import android.server.wm.WindowManagerStateHelper; import android.support.test.uiautomator.By; import android.support.test.uiautomator.BySelector; import android.support.test.uiautomator.UiDevice; @@ -35,8 +33,6 @@ import android.support.test.uiautomator.Until; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; -import com.android.compatibility.common.util.SystemUtil; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -57,14 +53,11 @@ public class MediaOutputDialogTest { public static final String TEST_PACKAGE_NAME = "com.android.package.test"; private static final BySelector MEDIA_DIALOG_SELECTOR = By.res(SYSTEMUI_PACKAGE_NAME, "media_output_dialog"); - private WindowManagerStateHelper mWmState = new WindowManagerStateHelper(); private Context mContext; private UiDevice mDevice; private String mLauncherPackage; private boolean mHasTouchScreen; - private ActivityManager mActivityManager; - private static final int DURATION_SCREEN_TOGGLE = 2000; @Before public void setUp() { @@ -84,35 +77,14 @@ public class MediaOutputDialogTest { packageManager.hasSystemFeature( PackageManager.FEATURE_AUTOMOTIVE)); mLauncherPackage = resolveInfo.activityInfo.packageName; - mActivityManager = mContext.getSystemService(ActivityManager.class); } @Test - public void mediaOutputDialog_correctDialog() throws Exception { - prepareDevice(); + public void mediaOutputDialog_correctDialog() { assumeTrue(mHasTouchScreen); - try { - if (mActivityManager.isLowRamDevice()) { - SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(), - "appops set " + SYSTEMUI_PACKAGE_NAME + " SYSTEM_ALERT_WINDOW allow"); - } - - launchMediaOutputDialog(); - - assertThat(mDevice.wait(Until.hasObject(MEDIA_DIALOG_SELECTOR), TIMEOUT)).isTrue(); - } finally { - if (mActivityManager.isLowRamDevice()) { - SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(), - "appops set " + SYSTEMUI_PACKAGE_NAME + " SYSTEM_ALERT_WINDOW ignore"); - } - } - } + launchMediaOutputDialog(); - private void prepareDevice() throws Exception { - mDevice.executeShellCommand("input keyevent KEYCODE_WAKEUP"); - mDevice.executeShellCommand("wm dismiss-keyguard"); - // Since the screen on/off intent is ordered, they will not be sent right now. - mWmState.waitForKeyguardGone(); + assertThat(mDevice.wait(Until.hasObject(MEDIA_DIALOG_SELECTOR), TIMEOUT)).isTrue(); } private void launchMediaOutputDialog() { diff --git a/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/MockModemService.java b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/MockModemService.java index 0bed8a7fa6d..f2523a4018e 100644 --- a/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/MockModemService.java +++ b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/MockModemService.java @@ -34,7 +34,6 @@ import java.util.concurrent.TimeUnit; public class MockModemService extends Service { private static final String TAG = "MockModemService"; - private static final String RESOURCE_PACKAGE_NAME = "android"; public static final int TEST_TIMEOUT_MS = 30000; public static final String IRADIOCONFIG_INTERFACE = "android.telephony.mockmodem.iradioconfig"; @@ -234,18 +233,9 @@ public class MockModemService extends Service { } public int getNumPhysicalSlots() { - int numPhysicalSlots = MockSimService.MOCK_SIM_SLOT_MIN; - int resourceId = + int numPhysicalSlots = sContext.getResources() - .getIdentifier( - "config_num_physical_slots", "integer", RESOURCE_PACKAGE_NAME); - - if (resourceId > 0) { - numPhysicalSlots = sContext.getResources().getInteger(resourceId); - } else { - Log.d(TAG, "Fail to get the resource Id, using default: " + numPhysicalSlots); - } - + .getInteger(com.android.internal.R.integer.config_num_physical_slots); if (numPhysicalSlots > MockSimService.MOCK_SIM_SLOT_MAX) { Log.d( TAG, @@ -255,15 +245,6 @@ public class MockModemService extends Service { + MockSimService.MOCK_SIM_SLOT_MAX + ")."); numPhysicalSlots = MockSimService.MOCK_SIM_SLOT_MAX; - } else if (numPhysicalSlots <= MockSimService.MOCK_SIM_SLOT_MIN) { - Log.d( - TAG, - "Number of physical Slot (" - + numPhysicalSlots - + ") < mock sim slot support. Reset to min number supported (" - + MockSimService.MOCK_SIM_SLOT_MIN - + ")."); - numPhysicalSlots = MockSimService.MOCK_SIM_SLOT_MIN; } return numPhysicalSlots; diff --git a/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/MockSimService.java b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/MockSimService.java index 026710b67d1..81839255dec 100644 --- a/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/MockSimService.java +++ b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/MockSimService.java @@ -63,7 +63,6 @@ public class MockSimService { private static final int MOCK_SIM_SLOT_1 = 0; private static final int MOCK_SIM_SLOT_2 = 1; private static final int MOCK_SIM_SLOT_3 = 2; - public static final int MOCK_SIM_SLOT_MIN = 1; public static final int MOCK_SIM_SLOT_MAX = 3; /* Default value definition */ diff --git a/tests/tests/telephony/current/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java index e5cf5d465c1..24a994083dc 100644 --- a/tests/tests/telephony/current/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java +++ b/tests/tests/telephony/current/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java @@ -288,19 +288,8 @@ public class SmsUsageMonitorShortCodeTest { new ShortCodeTest("it", "116117", SMS_CATEGORY_FREE_SHORT_CODE), new ShortCodeTest("it", "4567", SMS_CATEGORY_NOT_SHORT_CODE), new ShortCodeTest("it", "48000", SMS_CATEGORY_PREMIUM_SHORT_CODE), - new ShortCodeTest("it", "45678", SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE), + new ShortCodeTest("it", "45678", SMS_CATEGORY_PREMIUM_SHORT_CODE), new ShortCodeTest("it", "56789", SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE), - new ShortCodeTest("it", "44000", SMS_CATEGORY_PREMIUM_SHORT_CODE), - new ShortCodeTest("it", "47000", SMS_CATEGORY_PREMIUM_SHORT_CODE), - new ShortCodeTest("it", "48000", SMS_CATEGORY_PREMIUM_SHORT_CODE), - new ShortCodeTest("it", "4450000", SMS_CATEGORY_PREMIUM_SHORT_CODE), - new ShortCodeTest("it", "4750000", SMS_CATEGORY_PREMIUM_SHORT_CODE), - new ShortCodeTest("it", "4850000", SMS_CATEGORY_PREMIUM_SHORT_CODE), - new ShortCodeTest("it", "44500", SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE), - new ShortCodeTest("it", "47500", SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE), - new ShortCodeTest("it", "48500", SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE), - new ShortCodeTest("it", "45500", SMS_CATEGORY_PREMIUM_SHORT_CODE), - new ShortCodeTest("it", "49900", SMS_CATEGORY_PREMIUM_SHORT_CODE), new ShortCodeTest("it", "456789", SMS_CATEGORY_NOT_SHORT_CODE), new ShortCodeTest("kg", "112", SMS_CATEGORY_NOT_SHORT_CODE), diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java index f00f0b13b5c..7d73da9dad1 100644 --- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java +++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java @@ -125,8 +125,6 @@ public class ExactCanvasTests extends ActivityTestBase { canvas.drawColor(Color.WHITE); p.setColor(Color.BLACK); p.setAntiAlias(false); - // ensure the lines do not hit pixel edges - canvas.translate(0.05f, 0.05f); float[] pts = { 0, 0, 80, 80, 80, 0, 0, 80, 40, 50, 60, 50 }; diff --git a/tests/tests/virtualdevice/src/android/virtualdevice/cts/VirtualAudioTest.java b/tests/tests/virtualdevice/src/android/virtualdevice/cts/VirtualAudioTest.java index 62cc0bfdce6..1dd4bd9fbd2 100644 --- a/tests/tests/virtualdevice/src/android/virtualdevice/cts/VirtualAudioTest.java +++ b/tests/tests/virtualdevice/src/android/virtualdevice/cts/VirtualAudioTest.java @@ -152,10 +152,9 @@ public class VirtualAudioTest { public void setUp() throws Exception { MockitoAnnotations.initMocks(this); Context context = getApplicationContext(); - PackageManager packageManager = context.getPackageManager(); - assumeTrue(packageManager.hasSystemFeature(PackageManager.FEATURE_COMPANION_DEVICE_SETUP)); - assumeTrue(packageManager.hasSystemFeature( - PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS)); + assumeTrue( + context.getPackageManager() + .hasSystemFeature(PackageManager.FEATURE_COMPANION_DEVICE_SETUP)); assumeFalse("Skipping test: not supported on automotive", isAutomotive()); VirtualDeviceManager vdm = context.getSystemService(VirtualDeviceManager.class); diff --git a/tests/tests/widget/src/android/widget/cts/BackInvokedOnWidgetsTest.java b/tests/tests/widget/src/android/widget/cts/BackInvokedOnWidgetsTest.java index a4ef244f232..dc56f57167e 100644 --- a/tests/tests/widget/src/android/widget/cts/BackInvokedOnWidgetsTest.java +++ b/tests/tests/widget/src/android/widget/cts/BackInvokedOnWidgetsTest.java @@ -36,6 +36,7 @@ import com.android.compatibility.common.util.GestureNavRule; import org.junit.Before; import org.junit.ClassRule; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -57,11 +58,11 @@ public class BackInvokedOnWidgetsTest { @Before public void setUp() { - rule.assumeGestureNavigationMode(); mInstrumentation = InstrumentationRegistry.getInstrumentation(); mUiDevice = UiDevice.getInstance(mInstrumentation); } + @Ignore("b/229946481") @Test public void popupWindowDismissedOnBackGesture() { PopupWindow[] popupWindow = new PopupWindow[1]; diff --git a/tests/tests/wifi/src/android/net/wifi/cts/ConcurrencyTest.java b/tests/tests/wifi/src/android/net/wifi/cts/ConcurrencyTest.java index 464fb4c40b8..f7322dde5e1 100644 --- a/tests/tests/wifi/src/android/net/wifi/cts/ConcurrencyTest.java +++ b/tests/tests/wifi/src/android/net/wifi/cts/ConcurrencyTest.java @@ -274,29 +274,6 @@ public class ConcurrencyTest extends WifiJUnit3TestBase { new LinkedList<Integer>(Arrays.asList(waitSingleSync))); } - private NetworkInfo.DetailedState waitForNextNetworkState() { - assertTrue(waitForBroadcasts(MySync.NETWORK_INFO)); - assertNotNull(mMySync.expectedNetworkInfo); - return mMySync.expectedNetworkInfo.getDetailedState(); - } - - private boolean waitForConnectedNetworkState() { - // The possible orders of network states are: - // * IDLE > CONNECTING > CONNECTED for lazy initialization - // * DISCONNECTED > CONNECTING > CONNECTED for previous group removal - // * CONNECTING > CONNECTED - NetworkInfo.DetailedState state = waitForNextNetworkState(); - if (state == NetworkInfo.DetailedState.IDLE - || state == NetworkInfo.DetailedState.DISCONNECTED) { - state = waitForNextNetworkState(); - } - if (state != NetworkInfo.DetailedState.CONNECTING) { - return false; - } - state = waitForNextNetworkState(); - return state == NetworkInfo.DetailedState.CONNECTED; - } - private boolean waitForServiceResponse(MyResponse waitResponse) { synchronized (waitResponse) { long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; @@ -531,7 +508,21 @@ public class ConcurrencyTest extends WifiJUnit3TestBase { mWifiP2pManager.createGroup(mWifiP2pChannel, mActionListener); assertTrue(waitForServiceResponse(mMyResponse)); assertTrue(mMyResponse.success); - assertTrue(waitForConnectedNetworkState()); + + // The first network state might be IDLE due to + // lazy initialization, but not CONNECTED. + for (int i = 0; i < 2; i++) { + assertTrue(waitForBroadcasts(MySync.NETWORK_INFO)); + assertNotNull(mMySync.expectedNetworkInfo); + if (NetworkInfo.DetailedState.CONNECTED == + mMySync.expectedNetworkInfo.getDetailedState()) { + break; + } + assertEquals(NetworkInfo.DetailedState.IDLE, + mMySync.expectedNetworkInfo.getDetailedState()); + } + assertEquals(NetworkInfo.DetailedState.CONNECTED, + mMySync.expectedNetworkInfo.getDetailedState()); resetResponse(mMyResponse); mWifiP2pManager.requestNetworkInfo(mWifiP2pChannel, @@ -669,7 +660,21 @@ public class ConcurrencyTest extends WifiJUnit3TestBase { mWifiP2pManager.createGroup(mWifiP2pChannel, mActionListener); assertTrue(waitForServiceResponse(mMyResponse)); assertTrue(mMyResponse.success); - assertTrue(waitForConnectedNetworkState()); + + // The first network state might be IDLE due to + // lazy initialization, but not CONNECTED. + for (int i = 0; i < 2; i++) { + assertTrue(waitForBroadcasts(MySync.NETWORK_INFO)); + assertNotNull(mMySync.expectedNetworkInfo); + if (NetworkInfo.DetailedState.CONNECTED == + mMySync.expectedNetworkInfo.getDetailedState()) { + break; + } + assertEquals(NetworkInfo.DetailedState.IDLE, + mMySync.expectedNetworkInfo.getDetailedState()); + } + assertEquals(NetworkInfo.DetailedState.CONNECTED, + mMySync.expectedNetworkInfo.getDetailedState()); resetResponse(mMyResponse); mWifiP2pManager.removeGroup(mWifiP2pChannel, mActionListener); @@ -702,7 +707,10 @@ public class ConcurrencyTest extends WifiJUnit3TestBase { mWifiP2pManager.createGroup(mWifiP2pChannel, mActionListener); assertTrue(waitForServiceResponse(mMyResponse)); assertTrue(mMyResponse.success); - assertTrue(waitForConnectedNetworkState()); + assertTrue(waitForBroadcasts(MySync.NETWORK_INFO)); + assertNotNull(mMySync.expectedNetworkInfo); + assertEquals(NetworkInfo.DetailedState.CONNECTED, + mMySync.expectedNetworkInfo.getDetailedState()); resetResponse(mMyResponse); mWifiP2pManager.removeGroup(mWifiP2pChannel, mActionListener); @@ -804,7 +812,21 @@ public class ConcurrencyTest extends WifiJUnit3TestBase { mWifiP2pManager.createGroup(mWifiP2pChannel, mActionListener); assertTrue(waitForServiceResponse(mMyResponse)); assertTrue(mMyResponse.success); - assertTrue(waitForConnectedNetworkState()); + + // The first network state might be IDLE due to + // lazy initialization, but not CONNECTED. + for (int i = 0; i < 2; i++) { + assertTrue(waitForBroadcasts(MySync.NETWORK_INFO)); + assertNotNull(mMySync.expectedNetworkInfo); + if (NetworkInfo.DetailedState.CONNECTED + == mMySync.expectedNetworkInfo.getDetailedState()) { + break; + } + assertEquals(NetworkInfo.DetailedState.IDLE, + mMySync.expectedNetworkInfo.getDetailedState()); + } + assertEquals(NetworkInfo.DetailedState.CONNECTED, + mMySync.expectedNetworkInfo.getDetailedState()); resetResponse(mMyResponse); MacAddress peerMacAddress = MacAddress.fromString(mTestWifiP2pPeerConfig.deviceAddress); diff --git a/tests/tests/wifi/src/android/net/wifi/cts/MultiStaConcurrencyMultiInternetWifiNetworkTest.java b/tests/tests/wifi/src/android/net/wifi/cts/MultiStaConcurrencyMultiInternetWifiNetworkTest.java index 314d0975c73..b61f11db59f 100644 --- a/tests/tests/wifi/src/android/net/wifi/cts/MultiStaConcurrencyMultiInternetWifiNetworkTest.java +++ b/tests/tests/wifi/src/android/net/wifi/cts/MultiStaConcurrencyMultiInternetWifiNetworkTest.java @@ -151,8 +151,6 @@ public class MultiStaConcurrencyMultiInternetWifiNetworkTest extends WifiJUnit4T () -> wifiManager.setScanThrottleEnabled(false)); // Enable Wifi - sWasWifiEnabled = ShellIdentityUtils.invokeWithShellPermissions( - () -> wifiManager.isWifiEnabled()); ShellIdentityUtils.invokeWithShellPermissions(() -> wifiManager.setWifiEnabled(true)); // Make sure wifi is enabled PollingCheck.check("Wifi not enabled", DURATION_MILLIS, () -> wifiManager.isWifiEnabled()); diff --git a/tests/tests/wifi/src/android/net/wifi/cts/WifiSsidTest.java b/tests/tests/wifi/src/android/net/wifi/cts/WifiSsidTest.java index d4b5ec1db65..c162f9ef064 100644 --- a/tests/tests/wifi/src/android/net/wifi/cts/WifiSsidTest.java +++ b/tests/tests/wifi/src/android/net/wifi/cts/WifiSsidTest.java @@ -57,6 +57,13 @@ public class WifiSsidTest extends WifiJUnit3TestBase { WifiSsid wifiSsidNull = WifiSsid.fromBytes(null); assertThat(wifiSsidNull).isNotNull(); assertThat(wifiSsidNull.getBytes()).isEmpty(); + + try { + WifiSsid.fromBytes(new byte[33]); + fail("Expected IllegalArgumentException for byte array length greater than 32."); + } catch (IllegalArgumentException e) { + // Success + } } /** diff --git a/tests/tests/wifi/src/android/net/wifi/rtt/cts/WifiRttTest.java b/tests/tests/wifi/src/android/net/wifi/rtt/cts/WifiRttTest.java index 6205ee8806f..2a3f67acb55 100644 --- a/tests/tests/wifi/src/android/net/wifi/rtt/cts/WifiRttTest.java +++ b/tests/tests/wifi/src/android/net/wifi/rtt/cts/WifiRttTest.java @@ -605,7 +605,7 @@ public class WifiRttTest extends TestBase { builder.setRttBurstSize(RangingRequest.getMaxRttBurstSize()); RangingRequest request = builder.build(); - // Perform the request + // Perform the rquest rangeNon11mcApRequest(request, testAp, MAX_NON11MC_VARIATION_FROM_AVERAGE_DISTANCE_MM); } @@ -639,9 +639,7 @@ public class WifiRttTest extends TestBase { builder.setRttBurstSize(RangingRequest.getMaxRttBurstSize()); RangingRequest request = builder.build(); - - - // Perform the request + // Perform the rquest rangeNon11mcApRequest(request, testAp, MAX_NON11MC_VARIATION_FROM_AVERAGE_DISTANCE_MM); } @@ -749,13 +747,15 @@ public class WifiRttTest extends TestBase { ResultType.NEUTRAL, ResultUnit.NONE); reportLog.submit(); - /** TODO(b/237011062): enable the performance verification new API to check capabilities - // Analyze results + // This bug below has been addressed by making the test parameters for Non-80211mc devices + // less stringent. Please update the bug if this does not solve the problem. + // TODO(b/192909380): enable the performance verification after device fix. + + // Analyze results assertTrue("Wi-Fi RTT failure rate exceeds threshold: FAIL=" + numFailures + ", ITERATIONS=" + NUM_OF_RTT_ITERATIONS + ", AP=" + testAp, numFailures <= NUM_OF_RTT_ITERATIONS * MAX_NON11MC_FAILURE_RATE_PERCENT / 100); - */ if (numFailures != NUM_OF_RTT_ITERATIONS) { // Calculate an initial average using all measurements to determine distance outliers diff --git a/tools/cts-media-preparer-app/src/android/mediastress/cts/preconditions/app/MediaPreparerAppTest.java b/tools/cts-media-preparer-app/src/android/mediastress/cts/preconditions/app/MediaPreparerAppTest.java index 7f80e5601e8..0f4fd691170 100644 --- a/tools/cts-media-preparer-app/src/android/mediastress/cts/preconditions/app/MediaPreparerAppTest.java +++ b/tools/cts-media-preparer-app/src/android/mediastress/cts/preconditions/app/MediaPreparerAppTest.java @@ -82,12 +82,8 @@ public class MediaPreparerAppTest { @Test public void testGetResolutions() throws Exception { - String moduleName = InstrumentationRegistry.getArguments().getString("module-name"); - if (moduleName == null) { - moduleName = MODULE_NAME; - } Resolution maxRes = new Resolution(DEFAULT_MAX_WIDTH, DEFAULT_MAX_HEIGHT); - DynamicConfigDeviceSide config = new DynamicConfigDeviceSide(moduleName); + DynamicConfigDeviceSide config = new DynamicConfigDeviceSide(MODULE_NAME); for (String key : config.keySet()) { int width = 0; int height = 0; diff --git a/tools/cts-tradefed/res/config/cts-known-failures.xml b/tools/cts-tradefed/res/config/cts-known-failures.xml index d785d9686cd..83209926b35 100644 --- a/tools/cts-tradefed/res/config/cts-known-failures.xml +++ b/tools/cts-tradefed/res/config/cts-known-failures.xml @@ -127,7 +127,6 @@ <!-- b/38464828 --> <option name="compatibility:exclude-filter" value="CtsFileSystemTestCases android.filesystem.cts.AlmostFullTest" /> - <option name="compatibility:exclude-filter" value="CtsFileSystemTestCases[instant] android.filesystem.cts.AlmostFullTest" /> <!-- b/37271927 --> <option name="compatibility:exclude-filter" value="CtsViewTestCases android.view.cts.ViewTest#testUpdateDragShadow" /> @@ -282,8 +281,4 @@ <!-- b/208909067 --> <option name="compatibility:exclude-filter" value="CtsDisplayTestCases android.display.cts.DisplayTest#testActivityContextGetMetrics" /> - <!-- b/237035040 --> - <option name="compatibility:exclude-filter" value="CtsGraphicsTestCases android.graphics.cts.ImageDecoderTest#testDecode10BitHeifWithLowRam" /> - <option name="compatibility:exclude-filter" value="CtsGraphicsTestCases[instant] android.graphics.cts.ImageDecoderTest#testDecode10BitHeifWithLowRam" /> - </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 54d3f7e83f5..a6e59acd469 100644 --- a/tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml +++ b/tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml @@ -114,11 +114,4 @@ <!-- 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"/> - - <!-- b/235453601 --> - <option name="compatibility:exclude-filter" value="CtsMediaPerformanceClassTestCases android.mediapc.cts.MultiDecoderPerfTest" /> - - <!-- b/238155422 --> - <option name="compatibility:exclude-filter" value="CtsNetTestCases android.net.cts.ConnectivityManagerTest#testSetAirplaneMode" /> - </configuration> |