diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-01-10 18:43:25 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-01-10 18:43:25 +0000 |
commit | 0db37e5d887410e020d1b83e7b05225b7253878f (patch) | |
tree | 0f85b16e7193d40131e7a7adcd53ba606fc337a8 | |
parent | 361e7940620ea53efdce09f3d9fbaa072fad6bbd (diff) | |
parent | 9aa105e97418ffeaf179cdf355176f8f227121dc (diff) | |
download | cts-aml_tz5_341510010.tar.gz |
Snap for 11296156 from 9aa105e97418ffeaf179cdf355176f8f227121dc to mainline-tzdata5-releaseaml_tz5_341510070aml_tz5_341510050aml_tz5_341510010aml_tz5_341510010
Change-Id: I64a8ae2d42bb80b12bfee35dc20370a09aea0523
153 files changed, 1472 insertions, 514 deletions
diff --git a/apps/CameraITS/tests/scene0/test_param_sensitivity_burst.py b/apps/CameraITS/tests/scene0/test_param_sensitivity_burst.py index a56a130e33e..a409f1c51f7 100644 --- a/apps/CameraITS/tests/scene0/test_param_sensitivity_burst.py +++ b/apps/CameraITS/tests/scene0/test_param_sensitivity_burst.py @@ -22,7 +22,7 @@ import capture_request_utils import its_session_utils _NUM_STEPS = 3 -_ERROR_TOLERANCE = 0.96 # Allow ISO to be rounded down by 4% +_ERROR_TOLERANCE = 0.95 # Allow ISO to be rounded down by 5% class ParamSensitivityBurstTest(its_base_test.ItsBaseTest): diff --git a/apps/CameraITS/tests/scene2_a/test_preview_min_frame_rate.py b/apps/CameraITS/tests/scene2_a/test_preview_min_frame_rate.py index 0647b1d163a..815f3cf7df1 100644 --- a/apps/CameraITS/tests/scene2_a/test_preview_min_frame_rate.py +++ b/apps/CameraITS/tests/scene2_a/test_preview_min_frame_rate.py @@ -31,7 +31,7 @@ import video_processing_utils _NAME = os.path.splitext(os.path.basename(__file__))[0] _PREVIEW_RECORDING_DURATION_SECONDS = 10 _MAX_VAR_FRAME_DELTA = 0.001 # variance of frame deltas, units: seconds^2 -_FPS_ATOL = 0.5 +_FPS_ATOL = 0.8 _DARKNESS_ATOL = 0.1 diff --git a/apps/CameraITS/tests/scene_extensions/scene_night/test_night_extension.py b/apps/CameraITS/tests/scene_extensions/scene_night/test_night_extension.py index 376b47b89f3..56a93c95f6e 100644 --- a/apps/CameraITS/tests/scene_extensions/scene_night/test_night_extension.py +++ b/apps/CameraITS/tests/scene_extensions/scene_night/test_night_extension.py @@ -18,6 +18,7 @@ import logging import os.path import time +import cv2 from mobly import test_runner import numpy as np @@ -37,8 +38,7 @@ _TEST_REQUIRED_MPC = 34 _MIN_AREA = 0.001 # Circle must be >= 0.1% of image size _WHITE = 255 -_FMT_NAME = 'yuv' # To detect noise without conversion to RGB -_IMAGE_FORMAT_YUV_420_888_INT = 35 +_IMAGE_FORMATS_TO_CONSTANTS = (('yuv', 35), ('jpeg', 256)) _DOT_INTENSITY_DIFF_TOL = 20 # Min diff between dot/circle intensities [0:255] _DURATION_DIFF_TOL = 0.5 # Night mode ON captures must take 0.5 seconds longer @@ -79,7 +79,19 @@ def _convert_captures(cap, file_stem=None): Returns: Tuple of y_plane, numpy image. """ - y, _, _ = image_processing_utils.convert_capture_to_planes(cap) + if cap['format'] == 'jpeg' or cap['format'] == 'jpeg_r': + # openCV needs [0, 255] images + rgb_image = ( + image_processing_utils.decompress_jpeg_to_rgb_image(cap['data']) * 255 + ).astype(np.uint8) + yuv_image = cv2.cvtColor(rgb_image, cv2.COLOR_RGB2YUV) + y, _, _ = cv2.split(yuv_image) + # Convert back to [0, 1] and cast numpy array + y = (y / 255.0) + elif cap['format'] == 'yuv': + y, _, _ = image_processing_utils.convert_capture_to_planes(cap) + else: + raise ValueError(f'Unsupported format: {cap["format"]}') img = image_processing_utils.convert_capture_to_rgb_image(cap) if file_stem: image_processing_utils.write_image(img, f'{file_stem}.jpg') @@ -276,28 +288,36 @@ class NightExtensionTest(its_base_test.ItsBaseTest): self.tablet.adb.shell( f'input tap {_TAP_COORDINATES[0]} {_TAP_COORDINATES[1]}') - # Determine capture width and height - width, height = None, None - capture_sizes = capture_request_utils.get_available_output_sizes( - _FMT_NAME, props) - extension_capture_sizes_str = cam.get_supported_extension_sizes( - self.camera_id, _EXTENSION_NIGHT, _IMAGE_FORMAT_YUV_420_888_INT - ) - extension_capture_sizes = [ - tuple(int(size_part) for size_part in s.split(_X_STRING)) - for s in extension_capture_sizes_str - ] - # Extension capture sizes are ordered in ascending area order by default - extension_capture_sizes.reverse() - logging.debug('Capture sizes: %s', capture_sizes) - logging.debug('Extension capture sizes: %s', extension_capture_sizes) - width, height = extension_capture_sizes[0] + # Determine capture width, height, and format + for format_name, format_constant in _IMAGE_FORMATS_TO_CONSTANTS: + capture_sizes = capture_request_utils.get_available_output_sizes( + format_name, props) + extension_capture_sizes_str = cam.get_supported_extension_sizes( + self.camera_id, _EXTENSION_NIGHT, format_constant + ) + if not extension_capture_sizes_str: + continue + extension_capture_sizes = [ + tuple(int(size_part) for size_part in s.split(_X_STRING)) + for s in extension_capture_sizes_str + ] + # Extension capture sizes ordered in ascending area order by default + extension_capture_sizes.reverse() + logging.debug('Capture sizes: %s', capture_sizes) + logging.debug('Extension capture sizes: %s', extension_capture_sizes) + logging.debug('Accepted capture format: %s', format_name) + width, height = extension_capture_sizes[0] + accepted_format = format_name + break + else: + raise AssertionError('No supported sizes/formats found!') # Set tablet brightness to darken scene self.set_screen_brightness(_TABLET_BRIGHTNESS) - file_stem = f'{test_name}_{_FMT_NAME}_{width}x{height}' - out_surfaces = {'format': _FMT_NAME, 'width': width, 'height': height} + file_stem = f'{test_name}_{accepted_format}_{width}x{height}' + out_surfaces = { + 'format': accepted_format, 'width': width, 'height': height} req = capture_request_utils.auto_capture_request() # Take auto capture with night mode on diff --git a/apps/CameraITS/utils/its_session_utils.py b/apps/CameraITS/utils/its_session_utils.py index a13172391b1..3d62ba5a52a 100644 --- a/apps/CameraITS/utils/its_session_utils.py +++ b/apps/CameraITS/utils/its_session_utils.py @@ -843,7 +843,8 @@ class ItsSession(object): if data[_TAG_STR] != 'supportedExtensionSizes': raise error_util.CameraItsError('Invalid command response') if not data[_STR_VALUE]: - raise error_util.CameraItsError('No supported extensions') + logging.debug('No supported extension sizes') + return '' return data[_STR_VALUE].split(';') def get_display_size(self): diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml index cb33001c060..7fa840cf559 100644 --- a/apps/CtsVerifier/AndroidManifest.xml +++ b/apps/CtsVerifier/AndroidManifest.xml @@ -4835,7 +4835,7 @@ </intent-filter> <meta-data android:name="test_category" android:value="@string/test_category_managed_provisioning" /> <meta-data android:name="test_excluded_features" - android:value="android.software.lockscreen_disabled" /> + android:value="android.software.lockscreen_disabled:com.google.android.feature.AMATI_EXPERIENCE" /> <meta-data android:name="test_required_features" android:value="android.software.device_admin" /> <meta-data android:name="display_mode" android:value="single_display_mode" /> @@ -4870,7 +4870,7 @@ </intent-filter> <meta-data android:name="test_category" android:value="@string/test_category_managed_provisioning" /> <meta-data android:name="test_excluded_features" - android:value="android.software.lockscreen_disabled" /> + android:value="android.software.lockscreen_disabled:com.google.android.feature.AMATI_EXPERIENCE" /> <meta-data android:name="test_required_features" android:value="android.software.device_admin" /> <meta-data android:name="display_mode" android:value="single_display_mode" /> @@ -4903,6 +4903,7 @@ <meta-data android:name="test_required_features" android:value="android.software.device_admin" /> <meta-data android:name="display_mode" android:value="single_display_mode" /> + <meta-data android:name="test_excluded_features" android:value="com.google.android.feature.AMATI_EXPERIENCE" /> </activity> <activity android:name=".managedprovisioning.NonMarketAppsActivity" @@ -5460,6 +5461,8 @@ <meta-data android:name="test_category" android:value="@string/test_category_tunnel" /> <meta-data android:name="test_required_features" android:value="android.software.leanback" /> + <meta-data android:name="test_required_configs" + android:value="config_changeable_volume" /> <meta-data android:name="test_excluded_features" android:value="android.hardware.type.automotive" /> <meta-data android:name="display_mode" diff --git a/apps/CtsVerifier/res/layout/capture_content_for_notes.xml b/apps/CtsVerifier/res/layout/capture_content_for_notes.xml index 623d60a9b5e..c165cff961e 100644 --- a/apps/CtsVerifier/res/layout/capture_content_for_notes.xml +++ b/apps/CtsVerifier/res/layout/capture_content_for_notes.xml @@ -33,26 +33,28 @@ <TextView android:id="@+id/test_instructions" android:layout_width="match_parent" - android:layout_height="wrap_content" - android:text="@string/ccfn_tests_info" /> + android:layout_height="wrap_content" /> <Button android:id="@+id/set_default_notes" android:layout_width="match_parent" android:layout_height="wrap_content" - android:text="@string/set_default_notes_button_label" /> + android:text="@string/set_default_notes_button_label" + android:visibility="gone" /> <Button android:id="@+id/setup_device_owner" android:layout_width="match_parent" android:layout_height="wrap_content" - android:text="@string/setup_device_owner_button_label" /> + android:text="@string/setup_device_owner_button_label" + android:visibility="gone" /> <Button android:id="@+id/clear_device_owner" android:layout_width="match_parent" android:layout_height="wrap_content" - android:text="@string/clear_device_owner_button_label" /> + android:text="@string/clear_device_owner_button_label" + android:visibility="gone" /> <ListView android:id="@+id/android:list" diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml index d2000b7f7fc..09fdcc34bb6 100644 --- a/apps/CtsVerifier/res/values/strings.xml +++ b/apps/CtsVerifier/res/values/strings.xml @@ -1235,7 +1235,7 @@ <string name="nfc_scan_tag">Place device on a writable %s tag...</string> <string name="nfc_write_tag_title">Writable tag discovered!</string> - <string name="nfc_write_tag_message">Press OK to write to this tag...</string> + <string name="nfc_write_tag_message">Press OK to write to this tag(or auto write to this tag after 3s)...</string> <string name="nfc_scan_tag_again">Tap the same %s tag again to confirm that its contents match...</string> <string name="nfc_wrong_tag_title">Wrong type of tag scanned</string> <string name="nfc_no_tech">No tag technologies detected...</string> @@ -7066,11 +7066,15 @@ Follow the instructions on the screen to measure the frequency response for the keyboards, or styluses that are connected through USB or Bluetooth.\n\n Found %1$d built-in display(s). Are you ready to proceed? </string> + <string name="usi_test_verify_display_usi_support">Does the display \"%1$s\" support styluses + that use the USI protocol? \n\n + For more information about the Universal Stylus Initiative (USI) protocol, see: + http://universalstylus.org + </string> <string name="usi_test_verify_display_usi_version">The display \"%1$s\" reports its USI version as %2$s.\n\n Is this correct? </string> - <string name="usi_version_not_supported">not supported</string> <string name="usi_test_passed">Test Passed\n\n Press Pass. </string> @@ -7078,7 +7082,12 @@ Follow the instructions on the screen to measure the frequency response for the Reason: %1$s </string> <string name="usi_fail_reason_not_ready">Not ready to check for USI stylus versions.</string> - <string name="usi_fail_reason_incorrect_version">The USI version was incorrectly reported. + <string name="usi_fail_reason_version_not_found">The USI version for the display was not found. + </string> + <string name="usi_fail_reason_found_unexpected_version">The display reports support for a valid + USI version, even though it does not support USI. + </string> + <string name="usi_fail_reason_incorrect_version">The reported USI version is incorrect. </string> <!-- Strings for PreferredMixerAttributesTestActivity --> @@ -7105,9 +7114,6 @@ Follow the instructions on the screen to measure the frequency response for the This test verifies the support for Content Capture For Notes APIs on devices that have the ROLE_NOTES enabled. - \n\nIf the ROLE_NOTES is not enabled, no test should be shown in the list below, and you - should mark the CTS test as passed. - \n\nFor this test you need to install CtsDefaultNotesApp.apk and set it as the Default notes app. @@ -7115,6 +7121,12 @@ Follow the instructions on the screen to measure the frequency response for the \n\nPlease clear the device owner after all the test cases are run, if it was set up. </string> + <string name="ccfn_tests_info_skip"> + This test verifies the support for Content Capture For Notes APIs on devices that have the + ROLE_NOTES enabled. + + \n\nPlease mark this test as passed since ROLE_NOTES is not enabled on this device. + </string> <!-- Dialogs --> <string name="set_default_notes_button_label">Set default notes app</string> <string name="set_default_notes_button_info"> diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/ManifestTestListAdapter.java b/apps/CtsVerifier/src/com/android/cts/verifier/ManifestTestListAdapter.java index c37788d97a7..a6d536aeecc 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/ManifestTestListAdapter.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/ManifestTestListAdapter.java @@ -157,6 +157,8 @@ public class ManifestTestListAdapter extends TestListAdapter { private static final String CONFIG_HAS_CAMERA_TOGGLE = "config_has_camera_toggle"; + private static final String CONFIG_CHANGEABLE_VOLUME = "config_changeable_volume"; + /** * The config to represent that a test is only needed to run in the main display mode (i.e. * unfolded). @@ -535,6 +537,8 @@ public class ManifestTestListAdapter extends TestListAdapter { case CONFIG_HAS_CAMERA_TOGGLE: return isHardwareToggleSupported( context, SensorPrivacyManager.Sensors.CAMERA); + case CONFIG_CHANGEABLE_VOLUME: + return !getSystemResourceFlag(context, "config_useFixedVolume"); default: break; } 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 c403893f003..1528386f408 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 @@ -166,6 +166,7 @@ public class ItsService extends Service implements SensorEventListener { // State transition timeouts, in ms. private static final long TIMEOUT_IDLE_MS = 2000; + private static final long TIMEOUT_IDLE_MS_EXTENSIONS = 20000; private static final long TIMEOUT_STATE_MS = 500; private static final long TIMEOUT_SESSION_CLOSE = 3000; @@ -2990,7 +2991,7 @@ public class ItsService extends Service implements SensorEventListener { sessionListener, has10bitOutput); - mExtensionSession = sessionListener.waitAndGetSession(TIMEOUT_IDLE_MS); + mExtensionSession = sessionListener.waitAndGetSession(TIMEOUT_IDLE_MS_EXTENSIONS); CaptureRequest.Builder captureBuilder = requests.get(0); @@ -3000,19 +3001,22 @@ public class ItsService extends Service implements SensorEventListener { } // Set repeating request and wait for AE convergence, using another ImageReader. Logt.i(TAG, "Waiting for AE to converge before taking extensions capture."); - captureBuilder.addTarget(mExtensionPreviewImageReader.getSurface()); + CaptureRequest.Builder previewRequestBuilder = mCamera.createCaptureRequest( + CameraDevice.TEMPLATE_PREVIEW); + previewRequestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT, + CaptureRequest.CONTROL_CAPTURE_INTENT_PREVIEW); + previewRequestBuilder.addTarget(mExtensionPreviewImageReader.getSurface()); ImageReader.OnImageAvailableListener dropperListener = createAvailableListenerDropper(); mExtensionPreviewImageReader.setOnImageAvailableListener(dropperListener, mSaveHandlers[0]); - mExtensionSession.setRepeatingRequest(captureBuilder.build(), + mExtensionSession.setRepeatingRequest(previewRequestBuilder.build(), new HandlerExecutor(mResultHandler), mExtAEResultListener); mCountCallbacksRemaining.set(1); long timeout = TIMEOUT_CALLBACK * 1000; waitForCallbacks(timeout); mExtensionSession.stopRepeating(); - captureBuilder.removeTarget(mExtensionPreviewImageReader.getSurface()); mResultThread.sleep(PIPELINE_WARMUP_TIME_MS); } @@ -3904,8 +3908,9 @@ public class ItsService extends Service implements SensorEventListener { if (request == null || result == null) { throw new ItsException("Request/result is invalid"); } - if (result.get(CaptureResult.CONTROL_AE_STATE) == - CaptureResult.CONTROL_AE_STATE_CONVERGED) { + int aeState = result.get(CaptureResult.CONTROL_AE_STATE); + if (aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED + || aeState == CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED) { synchronized(mCountCallbacksRemaining) { mCountCallbacksRemaining.decrementAndGet(); mCountCallbacksRemaining.notify(); diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/capturecontentfornotes/CaptureContentForNotesVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/capturecontentfornotes/CaptureContentForNotesVerifierActivity.java index f05c636a838..84d30973785 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/capturecontentfornotes/CaptureContentForNotesVerifierActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/capturecontentfornotes/CaptureContentForNotesVerifierActivity.java @@ -31,6 +31,7 @@ import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; +import android.widget.TextView; import androidx.annotation.Nullable; @@ -123,7 +124,6 @@ public class CaptureContentForNotesVerifierActivity extends PassFailButtons.Test public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.capture_content_for_notes); - setInfoResources(R.string.ccfn_tests, R.string.ccfn_tests_info, 0); setPassFailButtonClickListeners(); ArrayTestListAdapter adapter = new ArrayTestListAdapter(this); @@ -135,23 +135,37 @@ public class CaptureContentForNotesVerifierActivity extends PassFailButtons.Test } }); + TextView testInstructionsView = findViewById(R.id.test_instructions); + if (isNotesRoleAvailable()) { // If the notes role is available, disable the pass button and setup tests. getPassButton().setEnabled(false); addTestsToAdapter(adapter); + + // Set up test info resources to ask user to go through the test cases. + setInfoResources(R.string.ccfn_tests, R.string.ccfn_tests_info, 0); + testInstructionsView.setText(R.string.ccfn_tests_info); + + // Add these buttons only if the Notes role is available to avoid confusion. + Button setDefaultNotesButton = findViewById(R.id.set_default_notes); + setDefaultNotesButton.setOnClickListener(this); + setDefaultNotesButton.setVisibility(View.VISIBLE); + + Button setupDeviceOwner = findViewById(R.id.setup_device_owner); + setupDeviceOwner.setOnClickListener(this); + setupDeviceOwner.setVisibility(View.VISIBLE); + + Button clearDeviceOwner = findViewById(R.id.clear_device_owner); + clearDeviceOwner.setOnClickListener(this); + clearDeviceOwner.setVisibility(View.VISIBLE); } else { // Notes role is unavailable, let the verifier skip this test altogether. getPassButton().setEnabled(true); - } - - Button setDefaultNotesButton = findViewById(R.id.set_default_notes); - setDefaultNotesButton.setOnClickListener(this); - Button setupDeviceOwner = findViewById(R.id.setup_device_owner); - setupDeviceOwner.setOnClickListener(this); - - Button clearDeviceOwner = findViewById(R.id.clear_device_owner); - clearDeviceOwner.setOnClickListener(this); + // Set up test info resources to ask user to skip the test. + setInfoResources(R.string.ccfn_tests, R.string.ccfn_tests_info_skip, 0); + testInstructionsView.setText(R.string.ccfn_tests_info_skip); + } } @Override 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 53f23a82208..7ba284e6544 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureUtil.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureUtil.java @@ -223,4 +223,12 @@ public final class FeatureUtil { public static boolean isKeyguardShownWhenUserDoesntHaveCredentials(Context context) { return !isAutomotive(context) && !isWatch(context); } + + /** + * Checks whether the device supports camera. + */ + public static boolean supportCameraFeature(Context context) { + PackageManager pm = context.getPackageManager(); + return pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY); + } } diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/input/UsiVersionActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/input/UsiVersionActivity.java index e9b15e8c349..9662aecc15f 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/input/UsiVersionActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/input/UsiVersionActivity.java @@ -20,6 +20,7 @@ import android.hardware.display.DisplayManager; import android.hardware.input.HostUsiVersion; import android.hardware.input.InputManager; import android.os.Bundle; +import android.util.ArrayMap; import android.view.Display; import android.widget.Button; import android.widget.TextView; @@ -28,8 +29,6 @@ import com.android.compatibility.common.util.ApiTest; import com.android.cts.verifier.PassFailButtons; import com.android.cts.verifier.R; -import java.util.ArrayList; -import java.util.List; import java.util.Objects; /** @@ -45,7 +44,7 @@ public class UsiVersionActivity extends PassFailButtons.Activity { Button mNoButton; TestStage mCurrentStage; - final List<Display> mInternalDisplays = new ArrayList<>(); + final ArrayMap<Display, HostUsiVersion> mInternalDisplays = new ArrayMap<>(); /** Used for {@link TestStage#VERIFY_USI_VERSIONS}. */ int mCurrentDisplayIndex; @@ -55,8 +54,10 @@ public class UsiVersionActivity extends PassFailButtons.Activity { private enum TestStage { // Ask whether the tester is ready to start. START_INSTRUCTIONS, - // Ask if the USI version reported for each of the built-in displays is correct. - VERIFY_USI_VERSIONS, + // Ask if the current display supports USI. + VERIFY_USI_SUPPORT, + // If the current display does support USI, ask if the reported USI version is correct. + VERIFY_USI_VERSION, // Test passed. PASSED, // Test failed. @@ -85,16 +86,39 @@ public class UsiVersionActivity extends PassFailButtons.Activity { switch (mCurrentStage) { case START_INSTRUCTIONS: mCurrentStage = fromYesButton - ? TestStage.VERIFY_USI_VERSIONS + ? TestStage.VERIFY_USI_SUPPORT : getFailState(R.string.usi_fail_reason_not_ready); break; - case VERIFY_USI_VERSIONS: + case VERIFY_USI_SUPPORT: + final var usiVersion = mInternalDisplays.valueAt(mCurrentDisplayIndex); + if (fromYesButton) { + // The user said that the display supports USI. + if (usiVersion != null) { + mCurrentStage = TestStage.VERIFY_USI_VERSION; + } else { + mCurrentStage = getFailState(R.string.usi_fail_reason_version_not_found); + } + } else { + // The user said that the display DOES NOT support USI. + if (usiVersion == null) { + mCurrentDisplayIndex++; + mCurrentStage = mCurrentDisplayIndex >= mInternalDisplays.size() + ? TestStage.PASSED + : TestStage.VERIFY_USI_SUPPORT; + } else { + mCurrentStage = getFailState( + R.string.usi_fail_reason_found_unexpected_version); + } + } + break; + + case VERIFY_USI_VERSION: if (fromYesButton) { mCurrentDisplayIndex++; mCurrentStage = mCurrentDisplayIndex >= mInternalDisplays.size() ? TestStage.PASSED - : TestStage.VERIFY_USI_VERSIONS; + : TestStage.VERIFY_USI_SUPPORT; } else { mCurrentStage = getFailState(R.string.usi_fail_reason_incorrect_version); } @@ -115,7 +139,7 @@ public class UsiVersionActivity extends PassFailButtons.Activity { private void processTestStage() { switch (mCurrentStage) { - case START_INSTRUCTIONS: + case START_INSTRUCTIONS: { mFailReason = null; mCurrentDisplayIndex = 0; populateInternalDisplays(); @@ -125,44 +149,55 @@ public class UsiVersionActivity extends PassFailButtons.Activity { mYesButton.setEnabled(true); mNoButton.setEnabled(true); break; + } - case VERIFY_USI_VERSIONS: - final Display display = mInternalDisplays.get(mCurrentDisplayIndex); - final HostUsiVersion usiVersion = - Objects.requireNonNull(getSystemService(InputManager.class)) - .getHostUsiVersion(display); - final String version = usiVersion != null - ? usiVersion.getMajorVersion() + "." + usiVersion.getMinorVersion() - : getString(R.string.usi_version_not_supported); + case VERIFY_USI_SUPPORT: { + final Display display = mInternalDisplays.keyAt(mCurrentDisplayIndex); + mInstructionsTextView.setText( + getString(R.string.usi_test_verify_display_usi_support, display.getName())); + break; + } + + case VERIFY_USI_VERSION: { + final Display display = mInternalDisplays.keyAt(mCurrentDisplayIndex); + final HostUsiVersion usiVersion = mInternalDisplays.valueAt(mCurrentDisplayIndex); + assert (usiVersion != null); + + final String version = + usiVersion.getMajorVersion() + "." + usiVersion.getMinorVersion(); mInstructionsTextView.setText( getString(R.string.usi_test_verify_display_usi_version, display.getName(), version)); break; + } - case PASSED: + case PASSED: { if (mFailReason != null) throw new IllegalStateException("Fail reason is non null"); mInstructionsTextView.setText(getString(R.string.usi_test_passed)); getPassButton().setEnabled(true); mYesButton.setEnabled(false); mNoButton.setEnabled(false); break; + } - case FAILED: + case FAILED: { Objects.requireNonNull(mFailReason); mInstructionsTextView.setText(getString(R.string.usi_test_failed, mFailReason)); getPassButton().setEnabled(false); mYesButton.setEnabled(false); mNoButton.setEnabled(false); break; + } } } private void populateInternalDisplays() { final Display[] displays = Objects.requireNonNull(getSystemService(DisplayManager.class)) .getDisplays(); + final var inputManager = Objects.requireNonNull(getSystemService(InputManager.class)); for (Display display : displays) { if (display.getType() == Display.TYPE_INTERNAL) { - mInternalDisplays.add(display); + mInternalDisplays.put(display, inputManager.getHostUsiVersion(display)); } } } diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/EnterprisePrivacyTestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/EnterprisePrivacyTestListActivity.java index 66e3d91a60e..902a6b0d94f 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/EnterprisePrivacyTestListActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/EnterprisePrivacyTestListActivity.java @@ -170,10 +170,12 @@ public class EnterprisePrivacyTestListActivity extends PassFailButtons.TestListA R.string.enterprise_privacy_admin_granted_microphone_access, R.string.enterprise_privacy_admin_granted_microphone_access_info, Manifest.permission.RECORD_AUDIO)); - adapter.add(buildAdminGrantedPermissionTest(ENTERPRISE_PRIVACY_CAMERA_ACCESS, - R.string.enterprise_privacy_admin_granted_camera_access, - R.string.enterprise_privacy_admin_granted_camera_access_info, - Manifest.permission.CAMERA)); + if (FeatureUtil.supportCameraFeature(this)) { + adapter.add(buildAdminGrantedPermissionTest(ENTERPRISE_PRIVACY_CAMERA_ACCESS, + R.string.enterprise_privacy_admin_granted_camera_access, + R.string.enterprise_privacy_admin_granted_camera_access_info, + Manifest.permission.CAMERA)); + } adapter.add(createInteractiveTestItem(this, ENTERPRISE_PRIVACY_DEFAULT_APPS, R.string.enterprise_privacy_default_apps, R.string.enterprise_privacy_default_apps_info, diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/TagVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/TagVerifierActivity.java index faee902bddf..07b7821d796 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/TagVerifierActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/TagVerifierActivity.java @@ -42,6 +42,9 @@ import android.widget.ArrayAdapter; import android.widget.TextView; import android.widget.Toast; +import android.os.Handler; +import android.os.HandlerThread; + /** * Test activity for reading and writing NFC tags using different technologies. * First, it asks the user to write some random data to the tag. Then it asks @@ -82,6 +85,11 @@ public class TagVerifierActivity<T> extends PassFailButtons.ListActivity { private ArrayAdapter<String> mTechListAdapter; private TextView mEmptyText; + private HandlerThread mHandlerThread; + private Handler mHandler; + // Auto write to this tag(DISCOVERED_DIALOG will be dismissed) when the waiting time out + private static final int WAIT_TIME_AUTO_WRITE_TAG = 3 * 1000; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -90,6 +98,10 @@ public class TagVerifierActivity<T> extends PassFailButtons.ListActivity { setPassFailButtonClickListeners(); getPassButton().setEnabled(false); + mHandlerThread = new HandlerThread("waitTimeAutoWriteTag"); + mHandlerThread.start(); + mHandler = new Handler(mHandlerThread.getLooper()); + parseIntentExtras(); if (mTechClass != null) { mTagTester = getTagTester(mTechClass); @@ -307,6 +319,23 @@ public class TagVerifierActivity<T> extends PassFailButtons.ListActivity { } } + @Override + protected void onPrepareDialog(int id, Dialog dialog) { + super.onPrepareDialog(id, dialog); + if (id == TESTABLE_TAG_DISCOVERED_DIALOG_ID) { + mHandler.removeCallbacks(waitTimeAutoWriteTagRunnable); + mHandler.postDelayed(waitTimeAutoWriteTagRunnable, WAIT_TIME_AUTO_WRITE_TAG); + } + } + + private final Runnable waitTimeAutoWriteTagRunnable = new Runnable() { + @Override + public void run() { + brutallyDismissDialog(TESTABLE_TAG_DISCOVERED_DIALOG_ID); + runOnUiThread(() -> new WriteTagTask().execute(mTag)); + } + }; + private AlertDialog createTestableTagDiscoveredDialog() { return new AlertDialog.Builder(this) .setIcon(android.R.drawable.ic_dialog_info) @@ -315,12 +344,14 @@ public class TagVerifierActivity<T> extends PassFailButtons.ListActivity { .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { + mHandler.removeCallbacks(waitTimeAutoWriteTagRunnable); new WriteTagTask().execute(mTag); } }) .setOnCancelListener(new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { + mHandler.removeCallbacks(waitTimeAutoWriteTagRunnable); goToWriteStep(); } }) diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/BubbleActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/BubbleActivity.java index a813454061f..214e79d965b 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/BubbleActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/BubbleActivity.java @@ -6,6 +6,7 @@ import static android.view.View.VISIBLE; import android.app.Activity; import android.content.Intent; import android.graphics.Insets; +import android.graphics.Rect; import android.os.Bundle; import android.view.View; import android.view.ViewTreeObserver; @@ -95,8 +96,9 @@ public class BubbleActivity extends Activity { WindowMetrics bubbleWindowMetrics = getSystemService(WindowManager.class).getCurrentWindowMetrics(); if (mIsLargeScreen) { - final float percentOfScreen = windowMetricsMax.getBounds().height() * 0.70f; - if (bubbleWindowMetrics.getBounds().height() < percentOfScreen) { + Rect bounds = windowMetricsMax.getBounds(); + final float percentOfScreen = Math.min(bounds.height(), bounds.width()) * 0.70f; + if (bubbleWindowMetrics.getBounds().height() <= percentOfScreen) { mTestMessage.setText("Test failed --" + " the bubble expanded view is too small, it is: " + bubbleWindowMetrics.getBounds().height() diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/security/FingerprintBoundKeysTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/security/FingerprintBoundKeysTest.java index a0f5bd0003c..d3e9b1f6d91 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/security/FingerprintBoundKeysTest.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/security/FingerprintBoundKeysTest.java @@ -66,7 +66,7 @@ public class FingerprintBoundKeysTest extends PassFailButtons.Activity { /** Alias for our key in the Android Key Store. */ private static final String KEY_NAME = "my_key"; private static final byte[] SECRET_BYTE_ARRAY = new byte[] {1, 2, 3, 4, 5, 6}; - private static final int AUTHENTICATION_DURATION_SECONDS = 2; + private static final int AUTHENTICATION_DURATION_SECONDS = 4; private static final int CONFIRM_CREDENTIALS_REQUEST_CODE = 1; private static final int BIOMETRIC_REQUEST_PERMISSION_CODE = 0; @@ -344,7 +344,7 @@ public class FingerprintBoundKeysTest extends PassFailButtons.Activity { if (mActivity.tryEncrypt() && mActivity.doValidityDurationTest(false)) { try { - Thread.sleep(3000); + Thread.sleep((AUTHENTICATION_DURATION_SECONDS+1)*1000); } catch (Exception e) { throw new RuntimeException("Failed to sleep", e); } diff --git a/common/device-side/bedstead/harrier/common/src/main/java/com/android/bedstead/harrier/annotations/RequireAutomotive.java b/common/device-side/bedstead/harrier/common/src/main/java/com/android/bedstead/harrier/annotations/RequireAutomotive.java new file mode 100644 index 00000000000..6bc6e4c580a --- /dev/null +++ b/common/device-side/bedstead/harrier/common/src/main/java/com/android/bedstead/harrier/annotations/RequireAutomotive.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.bedstead.harrier.annotations; + +import static com.android.bedstead.harrier.annotations.AnnotationRunPrecedence.FIRST; +import static com.android.bedstead.nene.packages.CommonPackages.FEATURE_AUTOMOTIVE; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +// TODO(b/314835345): move this out to a separate target. +@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@RequireFeature(FEATURE_AUTOMOTIVE) +public @interface RequireAutomotive { + + String reason(); + + /** + * Weight sets the order that annotations will be resolved. + * + * <p>Annotations with a lower weight will be resolved before annotations with a higher weight. + * + * <p>If there is an order requirement between annotations, ensure that the weight of the + * annotation which must be resolved first is lower than the one which must be resolved later. + * + * <p>Weight can be set to a {@link AnnotationRunPrecedence} constant, or to any {@link int}. + */ + int weight() default FIRST; +} diff --git a/common/device-side/bedstead/harrier/common/src/main/java/com/android/bedstead/harrier/annotations/RequireNotAutomotive.java b/common/device-side/bedstead/harrier/common/src/main/java/com/android/bedstead/harrier/annotations/RequireNotAutomotive.java new file mode 100644 index 00000000000..73e459030d6 --- /dev/null +++ b/common/device-side/bedstead/harrier/common/src/main/java/com/android/bedstead/harrier/annotations/RequireNotAutomotive.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.bedstead.harrier.annotations; + +import static com.android.bedstead.harrier.annotations.AnnotationRunPrecedence.FIRST; +import static com.android.bedstead.nene.packages.CommonPackages.FEATURE_AUTOMOTIVE; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +// TODO(b/314835345): move this out to a separate target. +@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@RequireDoesNotHaveFeature(FEATURE_AUTOMOTIVE) +public @interface RequireNotAutomotive { + + String reason(); + + /** + * Weight sets the order that annotations will be resolved. + * + * <p>Annotations with a lower weight will be resolved before annotations with a higher weight. + * + * <p>If there is an order requirement between annotations, ensure that the weight of the + * annotation which must be resolved first is lower than the one which must be resolved later. + * + * <p>Weight can be set to a {@link AnnotationRunPrecedence} constant, or to any {@link int}. + */ + int weight() default FIRST; +} diff --git a/common/device-side/interactive/src/main/java/com/android/interactive/ScreenshotUtil.java b/common/device-side/interactive/src/main/java/com/android/interactive/ScreenshotUtil.java new file mode 100644 index 00000000000..f53f6a660c4 --- /dev/null +++ b/common/device-side/interactive/src/main/java/com/android/interactive/ScreenshotUtil.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.interactive; + +import android.os.Environment; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.uiautomator.UiDevice; + +import java.io.File; + +/** + * Utility class for taking screenshots during xTS-Interactive tests. + * + * <p>It saves screenshots as files to the /Documents/xts/screenshots/ directory on the external + * storage. + */ +public final class ScreenshotUtil { + + /** + * Captures a screenshot and saves it as a file. + * + * <p>The screenshot file is named using the provided screenshot name, appended with the current + * system time. + * + * @param screenshotName the screenshot name + * @throws IOException if fails to create and save the screenshot file + */ + public static void captureScreenshot(String screenshotName) { + String screenshotDir = + Environment.getExternalStorageDirectory().getAbsolutePath() + + "/Documents/xts/screenshots/"; + File file = new File(screenshotDir); + if (!file.exists()) { + file.mkdirs(); + } + + File screenshotFile = + new File(screenshotDir, screenshotName + "_" + System.currentTimeMillis() + ".png"); + UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) + .takeScreenshot(screenshotFile); + } +} diff --git a/common/device-side/interactive/src/main/java/com/android/interactive/Step.java b/common/device-side/interactive/src/main/java/com/android/interactive/Step.java index faf347d571f..bc8bf6eb8de 100644 --- a/common/device-side/interactive/src/main/java/com/android/interactive/Step.java +++ b/common/device-side/interactive/src/main/java/com/android/interactive/Step.java @@ -55,12 +55,13 @@ import java.util.concurrent.atomic.AtomicBoolean; */ public abstract class Step<E> { - private static final TestLifecycleListener sLifecycleListener = new TestLifecycleListener() { - @Override - public void testFinished(String testName) { - sForceManual.set(false); - } - }; + private static final TestLifecycleListener sLifecycleListener = + new TestLifecycleListener() { + @Override + public void testFinished(String testName) { + sForceManual.set(false); + } + }; private static final String LOG_TAG = "Interactive.Step"; @@ -71,11 +72,13 @@ public abstract class Step<E> { // We timeout 10 seconds before the infra would timeout private static final Duration MAX_STEP_DURATION = Duration.ofMillis( - Long.parseLong(TestApis.instrumentation().arguments().getString( - "timeout_msec", "600000")) - 10000); + Long.parseLong( + TestApis.instrumentation() + .arguments() + .getString("timeout_msec", "600000")) + - 10000); - private static final Automator sAutomator = - new Automator(AUTOMATION_FILE); + private static final Automator sAutomator = new Automator(AUTOMATION_FILE); private View mInstructionView; @@ -90,8 +93,8 @@ public abstract class Step<E> { /** * Executes a step. * - * <p>This will first try to execute the step automatically, falling back to manual - * interaction if that fails. + * <p>This will first try to execute the step automatically, falling back to manual interaction + * if that fails. */ public static <E> E execute(Class<? extends Step<E>> stepClass) throws Exception { Step<E> step; @@ -107,10 +110,10 @@ public abstract class Step<E> { } if (!sForceManual.get() - && TestApis.instrumentation().arguments().getBoolean( - "ENABLE_AUTOMATION", true)) { + && TestApis.instrumentation().arguments().getBoolean("ENABLE_AUTOMATION", true)) { if (sAutomator.canAutomate(step)) { - AutomatingStep automatingStep = new AutomatingStep("Automating " + stepClass.getCanonicalName()); + AutomatingStep automatingStep = + new AutomatingStep("Automating " + stepClass.getCanonicalName()); try { automatingStep.interact(); @@ -119,7 +122,8 @@ public abstract class Step<E> { // If it reaches this point then it has passed Log.i(LOG_TAG, "Succeeded with automatic resolution of " + step); - boolean stepIsCacheable = stepClass.getAnnotationsByType(CacheableStep.class).length > 0; + boolean stepIsCacheable = + stepClass.getAnnotationsByType(CacheableStep.class).length > 0; if (stepIsCacheable) { sStepCache.put(stepClass, returnValue); } @@ -127,24 +131,28 @@ public abstract class Step<E> { } catch (Exception t) { Log.e(LOG_TAG, "Error attempting automation of " + step, t); - if (TestApis.instrumentation().arguments().getBoolean( - "ENABLE_MANUAL", false)) { + if (TestApis.instrumentation().arguments().getBoolean("ENABLE_MANUAL", false)) { AutomatingFailedStep automatingFailedStep = - new AutomatingFailedStep("Automation " - + stepClass.getCanonicalName() - + " Failed due to " + t.toString()); + new AutomatingFailedStep( + "Automation " + + stepClass.getCanonicalName() + + " Failed due to " + + t.toString()); automatingFailedStep.interact(); - Integer value = Poll.forValue("value", automatingFailedStep::getValue) - .toMeet(Optional::isPresent) - .terminalValue((b) -> step.hasFailed()) - .errorOnFail("Expected value from step. No value provided or step failed.") - .timeout(MAX_STEP_DURATION) - .await() - .get(); + Integer value = + Poll.forValue("value", automatingFailedStep::getValue) + .toMeet(Optional::isPresent) + .terminalValue((b) -> step.hasFailed()) + .errorOnFail( + "Expected value from step. No value provided or" + + " step failed.") + .timeout(MAX_STEP_DURATION) + .await() + .get(); if (value == AutomatingFailedStep.FAIL) { - throw(t); + throw (t); } else if (value == AutomatingFailedStep.CONTINUE_MANUALLY) { // Do nothing - we will fall through to the manual resolution } else if (value == AutomatingFailedStep.RETRY) { @@ -158,7 +166,7 @@ public abstract class Step<E> { "Restarting manually after automatic failure"); } } else { - throw(t); + throw (t); } } finally { automatingStep.close(); @@ -168,17 +176,17 @@ public abstract class Step<E> { } } - if (TestApis.instrumentation().arguments().getBoolean( - "ENABLE_MANUAL", false)) { + if (TestApis.instrumentation().arguments().getBoolean("ENABLE_MANUAL", false)) { step.interact(); // Wait until we've reached a valid ending point try { - Optional<E> valueOptional = Poll.forValue("value", step::getValue) - .toMeet(Optional::isPresent) - .terminalValue((b) -> step.hasFailed()) - .timeout(MAX_STEP_DURATION) - .await(); + Optional<E> valueOptional = + Poll.forValue("value", step::getValue) + .toMeet(Optional::isPresent) + .terminalValue((b) -> step.hasFailed()) + .timeout(MAX_STEP_DURATION) + .await(); if (step.hasFailed()) { throw new StepFailedException(stepClass); @@ -190,14 +198,16 @@ public abstract class Step<E> { E value = valueOptional.get(); // After the test has been marked passed, we validate ourselves - E returnValue = Poll.forValue("validated", () -> step.validate(value)) - .toMeet(Optional::isPresent) - .errorOnFail("Step did not pass validation.") - .timeout(MAX_STEP_DURATION) - .await() - .get(); - - boolean stepIsCacheable = stepClass.getAnnotationsByType(CacheableStep.class).length > 0; + E returnValue = + Poll.forValue("validated", () -> step.validate(value)) + .toMeet(Optional::isPresent) + .errorOnFail("Step did not pass validation.") + .timeout(MAX_STEP_DURATION) + .await() + .get(); + + boolean stepIsCacheable = + stepClass.getAnnotationsByType(CacheableStep.class).length > 0; if (stepIsCacheable) { sStepCache.put(stepClass, returnValue); } @@ -214,11 +224,10 @@ public abstract class Step<E> { try { pass((E) Nothing.NOTHING); } catch (ClassCastException e) { - throw new IllegalStateException("You cannot call pass() for a step which requires a" - + " return value. If no return value is required, the step should use Nothing" - + " (not Void)"); + throw new IllegalStateException( + "You cannot call pass() for a step which requires a return value. If no return" + + " value is required, the step should use Nothing (not Void)"); } - } protected final void pass(E value) { @@ -231,23 +240,17 @@ public abstract class Step<E> { close(); } - /** - * Returns present if the manual step has concluded successfully. - */ + /** Returns present if the manual step has concluded successfully. */ public Optional<E> getValue() { return mValue; } - /** - * Returns true if the manual step has failed. - */ + /** Returns true if the manual step has failed. */ public boolean hasFailed() { return mFailed; } - /** - * Adds a button to the interaction prompt. - */ + /** Adds a button to the interaction prompt. */ protected void addButton(String title, Runnable onClick) { // Push to UI thread to avoid animation issues when adding the button new Handler(Looper.getMainLooper()).post(() -> { @@ -261,8 +264,8 @@ public abstract class Step<E> { } /** - * Adds small button with a single up/down arrow, used for moving the text box to the - * bottom of the screen in case it covers some critical area of the app + * Adds small button with a single up/down arrow, used for moving the text box to the bottom of + * the screen in case it covers some critical area of the app */ protected void addSwapButton() { // Push to UI thread to avoid animation issues when adding the button @@ -291,38 +294,48 @@ public abstract class Step<E> { * <p>This should be called before any other methods on this class. */ protected void show(String instruction) { - mInstructionView = LayoutInflater.from(TestApis.context().instrumentationContext()) - .inflate(R.layout.instruction, null); + mInstructionView = + LayoutInflater.from(TestApis.context().instrumentationContext()) + .inflate(R.layout.instruction, null); TextView text = mInstructionView.findViewById(R.id.text); text.setText(instruction); - WindowManager.LayoutParams params = new WindowManager.LayoutParams( - WindowManager.LayoutParams.MATCH_PARENT, - WindowManager.LayoutParams.WRAP_CONTENT, - WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, - WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, - PixelFormat.TRANSLUCENT); + WindowManager.LayoutParams params = + new WindowManager.LayoutParams( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.WRAP_CONTENT, + WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, + WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, + PixelFormat.TRANSLUCENT); params.gravity = Gravity.TOP; // TMP params.x = 0; params.y = 0; - TestApis.context().instrumentationContext().getMainExecutor().execute(() -> { - try (PermissionContext p = TestApis.permissions().withPermission( - SYSTEM_ALERT_WINDOW, SYSTEM_APPLICATION_OVERLAY, INTERNAL_SYSTEM_WINDOW)) { - params.setSystemApplicationOverlay(true); - params.privateFlags = WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS; - sWindowManager.addView(mInstructionView, params); - } - }); + TestApis.context() + .instrumentationContext() + .getMainExecutor() + .execute( + () -> { + try (PermissionContext p = + TestApis.permissions() + .withPermission( + SYSTEM_ALERT_WINDOW, + SYSTEM_APPLICATION_OVERLAY, + INTERNAL_SYSTEM_WINDOW)) { + params.setSystemApplicationOverlay(true); + params.privateFlags = + WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS; + sWindowManager.addView(mInstructionView, params); + } + }); } - /** - * Swaps the prompt from the top to the bottom of the user screen - */ + /** Swaps the prompt from the top to the bottom of the user screen */ protected void swap() { - WindowManager.LayoutParams params = (WindowManager.LayoutParams) mInstructionView.getLayoutParams(); + WindowManager.LayoutParams params = + (WindowManager.LayoutParams) mInstructionView.getLayoutParams(); if (params.gravity == Gravity.TOP) { params.gravity = Gravity.BOTTOM; } else { @@ -332,22 +345,27 @@ public abstract class Step<E> { } protected void close() { + if (TestApis.instrumentation().arguments().getBoolean("TAKE_SCREENSHOT", false)) { + ScreenshotUtil.captureScreenshot(getClass().getCanonicalName()); + } if (mInstructionView != null) { - TestApis.context().instrumentationContext().getMainExecutor().execute(() -> { - try { - sWindowManager.removeViewImmediate(mInstructionView); - mInstructionView = null; - } catch (IllegalArgumentException e) { - // This can happen if the view is no longer attached - Log.i(LOG_TAG, "Error removing instruction view", e); - } - }); + TestApis.context() + .instrumentationContext() + .getMainExecutor() + .execute( + () -> { + try { + sWindowManager.removeViewImmediate(mInstructionView); + mInstructionView = null; + } catch (IllegalArgumentException e) { + // This can happen if the view is no longer attached + Log.i(LOG_TAG, "Error removing instruction view", e); + } + }); } } - /** - * Executes the manual step. - */ + /** Executes the manual step. */ public abstract void interact(); /** diff --git a/common/device-side/interactive/src/main/res/layout/instruction.xml b/common/device-side/interactive/src/main/res/layout/instruction.xml index e286ad6c8d5..cb9d3bffeb6 100644 --- a/common/device-side/interactive/src/main/res/layout/instruction.xml +++ b/common/device-side/interactive/src/main/res/layout/instruction.xml @@ -31,7 +31,7 @@ android:paddingBottom="10dp" android:text="" android:textAlignment="center" - android:textColor="#000000" /> + android:textColor="?android:textColorPrimary" /> <GridLayout android:id="@+id/buttons" android:layout_width="match_parent" diff --git a/hostsidetests/appcloning/Android.bp b/hostsidetests/appcloning/Android.bp index 0409c901fca..b4e5d60c10e 100644 --- a/hostsidetests/appcloning/Android.bp +++ b/hostsidetests/appcloning/Android.bp @@ -36,6 +36,7 @@ java_test_host { test_suites: [ "general-tests", "mts-mediaprovider", + "mcts-mediaprovider", "cts", ], test_config: "AndroidTestAppCloning.xml", diff --git a/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesValidConfigTest.java b/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesValidConfigTest.java index e6257f735fd..9640e7b761e 100644 --- a/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesValidConfigTest.java +++ b/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesValidConfigTest.java @@ -69,6 +69,7 @@ public final class CompatChangesValidConfigTest extends CompatChangeGatingTestCa "DOWNSCALE_85", "DOWNSCALE_90", "DO_NOT_DOWNSCALE_TO_1080P_ON_TV", + "ENFORCE_MINIMUM_TIME_WINDOWS", "FGS_BG_START_RESTRICTION_CHANGE_ID", "FGS_TYPE_DATA_SYNC_DEPRECATION_CHANGE_ID", "FGS_TYPE_DATA_SYNC_DISABLED_CHANGE_ID", @@ -97,6 +98,7 @@ public final class CompatChangesValidConfigTest extends CompatChangeGatingTestCa "OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR", "OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE", "OVERRIDE_ANY_ORIENTATION", + "OVERRIDE_ANY_ORIENTATION_TO_USER", "OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION", "OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION", "OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA", @@ -110,6 +112,7 @@ public final class CompatChangesValidConfigTest extends CompatChangeGatingTestCa "DEFAULT_RESCIND_BAL_FG_PRIVILEGES_BOUND_SERVICE", "DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_SENDER", "RETURN_DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY", + "OVERRIDE_ENABLE_EXPECTED_PRSENTATION_TIME", "ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS" ); diff --git a/hostsidetests/appcompat/strictjavapackages/Android.bp b/hostsidetests/appcompat/strictjavapackages/Android.bp index 2656bbc1363..f6cffe55162 100644 --- a/hostsidetests/appcompat/strictjavapackages/Android.bp +++ b/hostsidetests/appcompat/strictjavapackages/Android.bp @@ -35,6 +35,7 @@ java_test_host { "cts", "general-tests", "mts-mainline-infra", + "mcts-mainline-infra", ], data: [ ":SharedLibraryInfoTestApp", diff --git a/hostsidetests/appsearch/Android.bp b/hostsidetests/appsearch/Android.bp index 62162989589..e1fa3383840 100644 --- a/hostsidetests/appsearch/Android.bp +++ b/hostsidetests/appsearch/Android.bp @@ -35,6 +35,7 @@ java_test_host { "cts", "general-tests", "mts-appsearch", + "mcts-appsearch", ], data: [ ":CtsAppSearchHostTestHelperA", diff --git a/hostsidetests/appsecurity/Android.bp b/hostsidetests/appsecurity/Android.bp index 9a4a8c402e9..e6f7c0c1054 100644 --- a/hostsidetests/appsecurity/Android.bp +++ b/hostsidetests/appsecurity/Android.bp @@ -50,6 +50,9 @@ java_test_host { "mts-documentsui", "mts-mainline-infra", "mts-mediaprovider", + "mcts-documentsui", + "mcts-mainline-infra", + "mcts-mediaprovider", "sts", ], diff --git a/hostsidetests/backup/Android.bp b/hostsidetests/backup/Android.bp index c46a54ab98a..d89c9be3ee5 100644 --- a/hostsidetests/backup/Android.bp +++ b/hostsidetests/backup/Android.bp @@ -23,7 +23,8 @@ java_test_host { test_suites: [ "cts", "general-tests", - "mts", + "mts-permission", + "mcts-permission", "sts", ], libs: [ diff --git a/hostsidetests/devicepolicy/Android.bp b/hostsidetests/devicepolicy/Android.bp index b09e4dbd329..b1880d4938a 100644 --- a/hostsidetests/devicepolicy/Android.bp +++ b/hostsidetests/devicepolicy/Android.bp @@ -33,6 +33,7 @@ java_test_host { "cts", "general-tests", "mts-permission", + "mcts-permission", ], static_libs: [ "cts-statsd-atom-host-test-utils", diff --git a/hostsidetests/incrementalinstall/src/android/incrementalinstall/cts/IncrementalInstallTest.java b/hostsidetests/incrementalinstall/src/android/incrementalinstall/cts/IncrementalInstallTest.java index 12668afb967..b5821acd375 100644 --- a/hostsidetests/incrementalinstall/src/android/incrementalinstall/cts/IncrementalInstallTest.java +++ b/hostsidetests/incrementalinstall/src/android/incrementalinstall/cts/IncrementalInstallTest.java @@ -107,7 +107,7 @@ public class IncrementalInstallTest extends BaseHostJUnit4Test { @Before public void setup() throws Exception { // Increase default timeout to 5 mins to accommodate for slow restarting devices. - TestDeviceOptions options = new TestDeviceOptions(); + TestDeviceOptions options = getDevice().getOptions(); options.setAdbCommandTimeout(DEFAULT_ADB_TIMEOUT_MS); getDevice().setOptions(options); diff --git a/hostsidetests/neuralnetworks/Android.bp b/hostsidetests/neuralnetworks/Android.bp index ba128cf0e22..92f6e032082 100644 --- a/hostsidetests/neuralnetworks/Android.bp +++ b/hostsidetests/neuralnetworks/Android.bp @@ -25,6 +25,7 @@ java_test_host { "general-tests", "mts", "mts-neuralnetworks", + "mcts-neuralnetworks", ], libs: [ "tradefed", diff --git a/hostsidetests/scopedstorage/Android.bp b/hostsidetests/scopedstorage/Android.bp index 3f911187a8d..a2aab1757f1 100644 --- a/hostsidetests/scopedstorage/Android.bp +++ b/hostsidetests/scopedstorage/Android.bp @@ -397,6 +397,7 @@ java_test_host { test_suites: [ "general-tests", "mts-mediaprovider", + "mcts-mediaprovider", "cts", ], test_config: "CoreTest.xml", @@ -426,6 +427,7 @@ java_test_host { test_suites: [ "general-tests", "mts-mediaprovider", + "mcts-mediaprovider", "cts", ], test_config: "AndroidTest.xml", @@ -458,6 +460,7 @@ java_test_host { test_suites: [ "general-tests", "mts-mediaprovider", + "mcts-mediaprovider", "cts", ], test_config: "AndroidTestAppCloning.xml", @@ -537,6 +540,7 @@ android_test { test_suites: [ "general-tests", "mts-mediaprovider", + "mcts-mediaprovider", "cts", ], sdk_version: "test_current", @@ -594,6 +598,7 @@ android_test { test_suites: [ "general-tests", "mts-mediaprovider", + "mcts-mediaprovider", "cts", ], sdk_version: "test_current", @@ -640,6 +645,7 @@ android_test { test_suites: [ "general-tests", "mts-mediaprovider", + "mcts-mediaprovider", "cts", ], sdk_version: "test_current", @@ -686,6 +692,7 @@ android_test { test_suites: [ "general-tests", "mts-mediaprovider", + "mcts-mediaprovider", "cts", ], sdk_version: "test_current", diff --git a/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/RedactUriDeviceTest.java b/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/RedactUriDeviceTest.java index 4b17b65b93b..e2e640fa868 100644 --- a/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/RedactUriDeviceTest.java +++ b/hostsidetests/scopedstorage/device/src/android/scopedstorage/cts/device/RedactUriDeviceTest.java @@ -41,6 +41,8 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; + import android.Manifest; import android.content.ContentValues; @@ -59,6 +61,7 @@ import android.system.Os; import androidx.test.filters.SdkSuppress; import com.android.cts.install.lib.TestApp; +import com.android.modules.utils.build.SdkLevel; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -485,6 +488,7 @@ public class RedactUriDeviceTest extends ScopedStorageBaseDeviceTest { @Test public void testOpenOnRedactedUri_readFuzzer() throws Exception { + assumeTrue(SdkLevel.isAtLeastV()); final File img = stageFuzzerImageFileWithMetadata(FUZZER_HEIC_FILE_NAME); final Uri redactedUri = getRedactedUri(img); try { @@ -591,4 +595,4 @@ public class RedactUriDeviceTest extends ScopedStorageBaseDeviceTest { return img; } -}
\ No newline at end of file +} diff --git a/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java b/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java index 3db6007cf43..21b863c8514 100644 --- a/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java +++ b/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java @@ -2212,7 +2212,7 @@ public class TestUtils { return MediaStore.Files.getContentUri(sStorageVolumeName); } - private static void pollForCondition(Supplier<Boolean> condition, String errorMessage) + public 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()) { diff --git a/hostsidetests/scopedstorage/redacturi/src/android/scopedstorage/cts/redacturi/RedactUriDeviceTest.java b/hostsidetests/scopedstorage/redacturi/src/android/scopedstorage/cts/redacturi/RedactUriDeviceTest.java index b228dfe7e7b..ff8d505d65c 100644 --- a/hostsidetests/scopedstorage/redacturi/src/android/scopedstorage/cts/redacturi/RedactUriDeviceTest.java +++ b/hostsidetests/scopedstorage/redacturi/src/android/scopedstorage/cts/redacturi/RedactUriDeviceTest.java @@ -40,6 +40,8 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; + import android.Manifest; import android.content.ContentValues; @@ -58,6 +60,7 @@ import android.system.Os; import androidx.test.filters.SdkSuppress; import com.android.cts.install.lib.TestApp; +import com.android.modules.utils.build.SdkLevel; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -477,6 +480,7 @@ public class RedactUriDeviceTest extends ScopedStorageBaseDeviceTest { @Test public void testOpenOnRedactedUri_readFuzzer() throws Exception { + assumeTrue(SdkLevel.isAtLeastV()); final File img = stageFuzzerImageFileWithMetadata(FUZZER_HEIC_FILE_NAME); final Uri redactedUri = getRedactedUri(img); try { @@ -583,4 +587,4 @@ public class RedactUriDeviceTest extends ScopedStorageBaseDeviceTest { return img; } -}
\ No newline at end of file +} diff --git a/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java b/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java index d35db7bb9af..023f4a0591c 100644 --- a/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java +++ b/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java @@ -57,6 +57,7 @@ import static android.scopedstorage.cts.lib.TestUtils.getMoviesDir; import static android.scopedstorage.cts.lib.TestUtils.getMusicDir; import static android.scopedstorage.cts.lib.TestUtils.getPicturesDir; import static android.scopedstorage.cts.lib.TestUtils.openWithMediaProvider; +import static android.scopedstorage.cts.lib.TestUtils.pollForCondition; import static android.scopedstorage.cts.lib.TestUtils.pollForExternalStorageState; import static android.scopedstorage.cts.lib.TestUtils.pollForManageExternalStorageAllowed; import static android.scopedstorage.cts.lib.TestUtils.pollForPermission; @@ -84,6 +85,7 @@ import static org.junit.Assume.assumeTrue; import android.Manifest; import android.content.ContentValues; +import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -165,10 +167,15 @@ public class ScopedStorageTest { @Before public void setup() throws Exception { - if (!getContext().getPackageManager().isInstantApp()) { + PackageManager packageManager = getContext().getPackageManager(); + if (!packageManager.isInstantApp()) { pollForExternalStorageState(); getExternalFilesDir().mkdirs(); } + + pollForCondition( + () -> packageManager.resolveContentProvider(MediaStore.AUTHORITY, 0) != null, + "ContentProvider not available for authority media."); } /** diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_21277.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_21277.java new file mode 100644 index 00000000000..6dd20d8d29b --- /dev/null +++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_21277.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.security.cts; + +import static org.junit.Assume.assumeNoException; +import static org.junit.Assume.assumeTrue; + +import android.platform.test.annotations.AsbSecurityTest; + +import com.android.sts.common.UserUtils; +import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase; +import com.android.tradefed.device.ITestDevice; +import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; +import com.android.tradefed.util.RunUtil; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(DeviceJUnit4ClassRunner.class) +public class CVE_2023_21277 extends NonRootSecurityTestCase { + + @AsbSecurityTest(cveBugId = 281018094) + @Test + public void testPocCVE_2023_21277() { + try { + ITestDevice device = getDevice(); + final String testPkg = "android.security.cts.CVE_2023_21277"; + + // Install test app in device + installPackage("CVE-2023-21277.apk", "-g"); + + // Create new user and save a screenshot in that user + final int currentUserId = device.getCurrentUser(); + try (AutoCloseable asSecondaryUser = + new UserUtils.SecondaryUser(device) + .name("cve_2023_21277_user") + .doSwitch() + .withUser()) { + int userId = device.getCurrentUser(); + device.executeShellCommand("input keyevent KEYCODE_SYSRQ"); + + // Wait for screenshot to get saved in the created user + final long timeout = 5_000L; + final long waitPerIteration = 500L; + boolean screenshotSaved = false; + long start = System.currentTimeMillis(); + do { + screenshotSaved = + device.executeShellCommand( + "content query --user " + + userId + + " --projection _id --uri" + + " content://media/external/images/media/") + .contains("Row"); + if (screenshotSaved) { + break; + } + RunUtil.getDefault().sleep(waitPerIteration); + } while (System.currentTimeMillis() - start <= timeout); + assumeTrue( + "Screenshot was not saved in the created userId = " + userId, + screenshotSaved); + + // Switch back to original user + assumeTrue(device.switchUser(currentUserId)); + + // Run DeviceTest + runDeviceTests(testPkg, testPkg + ".DeviceTest", "testPocCVE_2023_21277"); + } + } catch (Exception e) { + assumeNoException(e); + } + } +} diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21277/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2023-21277/Android.bp new file mode 100644 index 00000000000..cfa2553a0da --- /dev/null +++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21277/Android.bp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +android_test_helper_app { + name: "CVE-2023-21277", + defaults: [ + "cts_defaults", + ], + srcs: [ + "src/**/*.java", + ], + test_suites: [ + "sts", + ], + static_libs: [ + "androidx.test.core", + "androidx.test.rules", + "androidx.test.uiautomator_uiautomator", + "compatibility-device-util-axt", + "truth", + ], +} diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21277/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-21277/AndroidManifest.xml new file mode 100644 index 00000000000..6c53c8bc8e3 --- /dev/null +++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21277/AndroidManifest.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright 2023 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="android.security.cts.CVE_2023_21277"> + <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> + + <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" + android:targetPackage="android.security.cts.CVE_2023_21277" /> +</manifest> diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21277/res/layout/cve_2023_21277_layout.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-21277/res/layout/cve_2023_21277_layout.xml new file mode 100644 index 00000000000..23f16c1336d --- /dev/null +++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21277/res/layout/cve_2023_21277_layout.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright 2023 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<ImageView xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/cve_2023_21277_img" + android:layout_width="match_parent" + android:layout_height="match_parent" /> diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21277/src/android/security/cts/CVE_2023_21277/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-21277/src/android/security/cts/CVE_2023_21277/DeviceTest.java new file mode 100644 index 00000000000..af05e768544 --- /dev/null +++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21277/src/android/security/cts/CVE_2023_21277/DeviceTest.java @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.security.cts.CVE_2023_21277; + +import static android.Manifest.permission.CREATE_USERS; +import static android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + +import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; + +import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity; + +import static com.google.common.truth.Truth.assertWithMessage; +import static com.google.common.truth.TruthJUnit.assume; + +import static org.junit.Assume.assumeNoException; + +import android.app.Instrumentation; +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.UiAutomation; +import android.content.ContentProvider; +import android.content.Context; +import android.content.pm.UserInfo; +import android.graphics.drawable.Icon; +import android.os.UserManager; +import android.widget.RemoteViews; + +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.Test; +import org.junit.runner.RunWith; + +import java.util.List; + +@RunWith(AndroidJUnit4.class) +public class DeviceTest { + + @Test + public void testPocCVE_2023_21277() { + UiDevice uiDevice = null; + try { + final String cveId = "cve_2023_21277_"; + final String title = cveId + "title"; + + Instrumentation instrumentation = getInstrumentation(); + Context context = instrumentation.getContext(); + UiAutomation uiAutomation = instrumentation.getUiAutomation(); + uiDevice = UiDevice.getInstance(instrumentation); + UserManager userManager = context.getSystemService(UserManager.class); + final String packageName = context.getPackageName(); + + // Check if the device supports multiple users + assume().withMessage("This device does not support multiple users") + .that(userManager.supportsMultipleUsers()) + .isTrue(); + + // Retrieve created user Id + final int userId = + runWithShellPermissionIdentity( + () -> { + List<UserInfo> list = userManager.getUsers(); + for (UserInfo info : list) { + if (info.name.contains(cveId)) { + return info.getUserHandle().getIdentifier(); + } + } + return -1; + }, + CREATE_USERS); + assume().withMessage("Could not find user id of created user") + .that(userId != -1) + .isTrue(); + + // Post a notification with a content view containing image from other user + RemoteViews remoteView = new RemoteViews(packageName, R.layout.cve_2023_21277_layout); + Icon remoteViewIcon = + Icon.createWithContentUri( + ContentProvider.maybeAddUserId(EXTERNAL_CONTENT_URI, userId)); + remoteView.setIcon( + R.id.cve_2023_21277_img, "setImageIcon", remoteViewIcon, remoteViewIcon); + NotificationChannel notificationChannel = + new NotificationChannel(cveId, cveId, NotificationManager.IMPORTANCE_DEFAULT); + NotificationManager notificationManager = + context.getSystemService(NotificationManager.class); + notificationManager.createNotificationChannel(notificationChannel); + Notification notification = + new Notification.Builder(context, cveId) + .setContentTitle(title) + .setSmallIcon( + Icon.createWithData( + new byte[0] /* data */, 0 /* offset */, 0 /* length */)) + .setCustomContentView(remoteView) + .setCustomBigContentView(remoteView) + .build(); + try { + notificationManager.notify(0 /* id */, notification); + } catch (SecurityException securityException) { + if (securityException + .getLocalizedMessage() + .toLowerCase() + .contains(EXTERNAL_CONTENT_URI.toString())) { + // Ignore exception thrown with fix and exit the test + return; + } else { + throw securityException; + } + } + + // Open notification shade + assume().withMessage("Opening notification shade unsuccessful") + .that(uiDevice.openNotification()) + .isTrue(); + + // Wait for notification to appear and detect if the remote view is present + uiDevice.wait(Until.hasObject(By.text(title)), 3000 /* timeout */); + UiObject2 exposedImg = uiDevice.findObject(By.res(packageName, cveId + "img")); + assertWithMessage( + "Device is vulnerable to b/277740848, Other user's images can be" + + " exposed in notifications using remote views") + .that(exposedImg) + .isNull(); + } catch (Exception e) { + assumeNoException(e); + } finally { + try { + uiDevice.pressHome(); + } catch (Exception e) { + // Ignore exceptions as the test has finished + } + } + } +} diff --git a/tests/AlarmManager/Android.bp b/tests/AlarmManager/Android.bp index e62687a7dc6..c47fcb7dd93 100644 --- a/tests/AlarmManager/Android.bp +++ b/tests/AlarmManager/Android.bp @@ -34,6 +34,7 @@ android_test { "cts", "general-tests", "mts-scheduling", + "mcts-scheduling", ], platform_apis: true, data: [ diff --git a/tests/AlarmManager/src/android/alarmmanager/cts/AppStandbyTests.java b/tests/AlarmManager/src/android/alarmmanager/cts/AppStandbyTests.java index e8254cc053f..49b25a045da 100644 --- a/tests/AlarmManager/src/android/alarmmanager/cts/AppStandbyTests.java +++ b/tests/AlarmManager/src/android/alarmmanager/cts/AppStandbyTests.java @@ -281,8 +281,7 @@ public class AppStandbyTests { private void updateAlarmManagerConstants() { mConfigHelper.with("min_futurity", MIN_FUTURITY) .with("app_standby_window", APP_STANDBY_WINDOW) - .with("min_window", MIN_WINDOW) - .with("exact_alarm_deny_list", TEST_APP_PACKAGE); + .with("min_window", MIN_WINDOW); for (int i = 0; i < APP_STANDBY_QUOTAS.length; i++) { mConfigHelper.with(APP_BUCKET_QUOTA_KEYS[i], APP_STANDBY_QUOTAS[i]); } diff --git a/tests/AlarmManager/src/android/alarmmanager/cts/ExactAlarmsTest.java b/tests/AlarmManager/src/android/alarmmanager/cts/ExactAlarmsTest.java index ad258860bac..34ad67800ce 100644 --- a/tests/AlarmManager/src/android/alarmmanager/cts/ExactAlarmsTest.java +++ b/tests/AlarmManager/src/android/alarmmanager/cts/ExactAlarmsTest.java @@ -230,21 +230,11 @@ public class ExactAlarmsTest { public void hasPermissionWhenAllowed() throws Exception { setAppOp(TEST_APP_PACKAGE, AppOpsManager.MODE_ALLOWED); assertTrue(getCanScheduleExactAlarmFromTestApp(TEST_APP_PACKAGE)); - - // The deny list shouldn't matter in this case. - mDeviceConfigHelper.with("exact_alarm_deny_list", TEST_APP_PACKAGE) - .commitAndAwaitPropagation(); - assertTrue(getCanScheduleExactAlarmFromTestApp(TEST_APP_PACKAGE)); } @Test public void canScheduleExactAlarmWithPolicyPermission() { assertTrue(mAlarmManager.canScheduleExactAlarms()); - - // The deny list shouldn't do anything. - mDeviceConfigHelper.with("exact_alarm_deny_list", sContext.getOpPackageName()) - .commitAndAwaitPropagation(); - assertTrue(mAlarmManager.canScheduleExactAlarms()); } @Test @@ -257,12 +247,6 @@ public class ExactAlarmsTest { public void canScheduleExactAlarmWithUserPermissionSdk32() throws Exception { // Should be allowed by default. assertTrue(getCanScheduleExactAlarmFromTestApp(TEST_APP_WITH_SCHEDULE_EXACT_ALARM_32)); - - mDeviceConfigHelper.with("exact_alarm_deny_list", TEST_APP_WITH_SCHEDULE_EXACT_ALARM_32) - .commitAndAwaitPropagation(); - - assertFalse("canScheduleExactAlarm returned true when app was in deny list", - getCanScheduleExactAlarmFromTestApp(TEST_APP_WITH_SCHEDULE_EXACT_ALARM_32)); } @Test @@ -344,7 +328,7 @@ public class ExactAlarmsTest { alarmLatch.countDown(); } }; - sContext.registerReceiver(receiver, filter, Context.RECEIVER_EXPORTED_UNAUDITED); + sContext.registerReceiver(receiver, filter, Context.RECEIVER_EXPORTED); try { Thread.sleep(5_000); assertTrue("AlarmClock expiration not reported", @@ -638,7 +622,7 @@ public class ExactAlarmsTest { latch.countDown(); } }; - sContext.registerReceiver(receiver, filter, Context.RECEIVER_EXPORTED_UNAUDITED); + sContext.registerReceiver(receiver, filter, Context.RECEIVER_EXPORTED); try { Log.d(TAG, "Granting the appop"); setAppOp(TEST_APP_PACKAGE, AppOpsManager.MODE_ALLOWED); @@ -650,45 +634,4 @@ public class ExactAlarmsTest { sContext.unregisterReceiver(receiver); } } - - @Test - public void scheduleExactAlarmPermissionStateChangedSentDenyListSdk32() throws Exception { - // App is targeting SDK 32, deny list will dictate the default grant state. - prepareTestAppForBroadcast(mPermissionChangeReceiver32); - - // App op hasn't been touched, should be default. - Log.d(TAG, "Putting in deny list"); - mDeviceConfigHelper.with("exact_alarm_deny_list", TEST_APP_WITH_SCHEDULE_EXACT_ALARM_32) - .commitAndAwaitPropagation(); - removeFromWhitelists(TEST_APP_WITH_SCHEDULE_EXACT_ALARM_32); - - final int uid = Utils.getPackageUid(TEST_APP_WITH_SCHEDULE_EXACT_ALARM_32); - TestUtils.waitUntil("Package still allowlisted", - () -> !checkThisAppTempAllowListed(uid)); - - final IntentFilter filter = new IntentFilter( - PermissionStateChangedReceiver.ACTION_FGS_START_RESULT); - final AtomicReference<String> resultHolder = new AtomicReference<>(); - final CountDownLatch latch = new CountDownLatch(1); - final BroadcastReceiver receiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - Log.d(TAG, "Received response intent: " + intent); - resultHolder.set(intent.getStringExtra( - FgsTester.EXTRA_FGS_START_RESULT)); - latch.countDown(); - } - }; - sContext.registerReceiver(receiver, filter, Context.RECEIVER_EXPORTED_UNAUDITED); - try { - Log.d(TAG, "Removing from deny list"); - mDeviceConfigHelper.without("exact_alarm_deny_list").commitAndAwaitPropagation(); - - assertTrue("Didn't receive response", - latch.await(30, TimeUnit.SECONDS)); - assertEquals("Failure message should be empty", "", resultHolder.get()); - } finally { - sContext.unregisterReceiver(receiver); - } - } } diff --git a/tests/MediaProviderTranscode/Android.bp b/tests/MediaProviderTranscode/Android.bp index cbf6fe2dd21..7b24ed22a62 100644 --- a/tests/MediaProviderTranscode/Android.bp +++ b/tests/MediaProviderTranscode/Android.bp @@ -8,6 +8,7 @@ android_test { "device-tests", "cts", "mts-mediaprovider", + "mcts-mediaprovider", ], compile_multilib: "both", diff --git a/tests/PhotoPicker/Android.bp b/tests/PhotoPicker/Android.bp index bac0320a7e6..fd4373fd2f9 100644 --- a/tests/PhotoPicker/Android.bp +++ b/tests/PhotoPicker/Android.bp @@ -29,6 +29,7 @@ android_test { test_suites: [ "general-tests", "mts-mediaprovider", + "mcts-mediaprovider", "cts", ], sdk_version: "core_current", diff --git a/tests/PhotoPicker/src/android/photopicker/cts/ActionGetContentOnlyTest.java b/tests/PhotoPicker/src/android/photopicker/cts/ActionGetContentOnlyTest.java index 25e8ebdfb40..16dec1bb9cb 100644 --- a/tests/PhotoPicker/src/android/photopicker/cts/ActionGetContentOnlyTest.java +++ b/tests/PhotoPicker/src/android/photopicker/cts/ActionGetContentOnlyTest.java @@ -34,6 +34,7 @@ import android.content.Intent; import android.net.Uri; import android.photopicker.cts.util.PhotoPickerComponentUtils; import android.photopicker.cts.util.UiAssertionUtils; +import android.provider.MediaStore; import android.util.Pair; import androidx.test.uiautomator.UiObject; @@ -203,6 +204,20 @@ public class ActionGetContentOnlyTest extends PhotoPickerBaseTest { UiAssertionUtils.assertThatShowsPickerUi(intent.getType()); } + @Test + public void testPickerLaunchTabWithGetContent() throws Exception { + final Intent intent = new Intent(Intent.ACTION_GET_CONTENT); + intent.setType("*/*"); + intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_LAUNCH_TAB, MediaStore.PICK_IMAGES_TAB_ALBUMS); + + mActivity.startActivityForResult(Intent.createChooser(intent, TAG), REQUEST_CODE); + + findAndClickMediaIcon(); + + // Should open Picker + UiAssertionUtils.assertThatShowsPickerUi(intent.getType()); + } + private void findAndClickMediaIcon() throws Exception { final UiSelector appList = new UiSelector().resourceId(sDocumentsUiPackageName + ":id/apps_row"); @@ -245,8 +260,9 @@ public class ActionGetContentOnlyTest extends PhotoPickerBaseTest { } private void findAndClickFilesInDocumentsUi(List<String> fileNameList) throws Exception { + final UiSelector docList = getDirectoryListSelector(); for (String fileName : fileNameList) { - findAndClickFileInDocumentsUi(fileName); + findAndClickFileInDocumentsUi(docList, fileName); } findAndClickSelect(); } @@ -257,7 +273,7 @@ public class ActionGetContentOnlyTest extends PhotoPickerBaseTest { clickAndWait(sDevice, selectButton); } - private void findAndClickFileInDocumentsUi(String fileName) throws Exception { + private UiSelector getDirectoryListSelector() throws Exception { final UiSelector docList = new UiSelector().resourceId(sDocumentsUiPackageName + ":id/dir_list"); @@ -275,6 +291,11 @@ public class ActionGetContentOnlyTest extends PhotoPickerBaseTest { } catch (UiObjectNotFoundException ignored) { // Do nothing, already be in list mode. } + return docList; + } + + private void findAndClickFileInDocumentsUi(UiSelector docList, String fileName) + throws Exception { // Repeat swipe gesture to find our item // (UiScrollable#scrollIntoView does not seem to work well with SwipeRefreshLayout) diff --git a/tests/PhotoPicker/src/android/photopicker/cts/ActionPickImagesOnlyTest.java b/tests/PhotoPicker/src/android/photopicker/cts/ActionPickImagesOnlyTest.java index b6180df5968..d29ee64fa23 100644 --- a/tests/PhotoPicker/src/android/photopicker/cts/ActionPickImagesOnlyTest.java +++ b/tests/PhotoPicker/src/android/photopicker/cts/ActionPickImagesOnlyTest.java @@ -26,6 +26,7 @@ import static android.photopicker.cts.util.PhotoPickerUiUtils.findItemList; import static android.photopicker.cts.util.ResultsAssertionsUtils.assertPersistedGrant; import static android.photopicker.cts.util.ResultsAssertionsUtils.assertPickerUriFormat; import static android.photopicker.cts.util.ResultsAssertionsUtils.assertRedactedReadOnlyAccess; +import static android.provider.MediaStore.ACTION_PICK_IMAGES; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; @@ -75,7 +76,7 @@ public class ActionPickImagesOnlyTest extends PhotoPickerBaseTest { @Test public void testPhotoPickerIntentDelegation() throws Exception { - final Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); + final Intent intent = new Intent(ACTION_PICK_IMAGES); for (String mimeType: new String[] { null, @@ -94,7 +95,7 @@ public class ActionPickImagesOnlyTest extends PhotoPickerBaseTest { @Test public void testMultiSelect_invalidParam() throws Exception { - final Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); + final Intent intent = new Intent(ACTION_PICK_IMAGES); intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, MediaStore.getPickImagesMaxLimit() + 1); mActivity.startActivityForResult(intent, REQUEST_CODE); final GetResultActivity.Result res = mActivity.getResult(); @@ -103,7 +104,7 @@ public class ActionPickImagesOnlyTest extends PhotoPickerBaseTest { @Test public void testMultiSelect_invalidNegativeParam() throws Exception { - final Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); + final Intent intent = new Intent(ACTION_PICK_IMAGES); intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, -1); mActivity.startActivityForResult(intent, REQUEST_CODE); final GetResultActivity.Result res = mActivity.getResult(); @@ -116,7 +117,7 @@ public class ActionPickImagesOnlyTest extends PhotoPickerBaseTest { final int imageCount = maxCount + 1; mUriList.addAll(createImagesAndGetUris(imageCount, mContext.getUserId())); - final Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); + final Intent intent = new Intent(ACTION_PICK_IMAGES); intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, maxCount); mActivity.startActivityForResult(intent, REQUEST_CODE); @@ -175,7 +176,7 @@ public class ActionPickImagesOnlyTest extends PhotoPickerBaseTest { public void testDoesNotRespectExtraAllowMultiple() throws Exception { final int imageCount = 2; mUriList.addAll(createImagesAndGetUris(imageCount, mContext.getUserId())); - final Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); + final Intent intent = new Intent(ACTION_PICK_IMAGES); intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); mActivity.startActivityForResult(intent, REQUEST_CODE); @@ -186,14 +187,14 @@ public class ActionPickImagesOnlyTest extends PhotoPickerBaseTest { clickAndWait(sDevice, itemList.get(0)); final Uri uri = mActivity.getResult().data.getData(); - assertPickerUriFormat(uri, mContext.getUserId()); + assertPickerUriFormat(ACTION_PICK_IMAGES, uri, mContext.getUserId()); assertPersistedGrant(uri, mContext.getContentResolver()); assertRedactedReadOnlyAccess(uri); } @Test public void testMimeTypeFilter() throws Exception { - final Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); + final Intent intent = new Intent(ACTION_PICK_IMAGES); intent.setType("audio/*"); assertThrows(ActivityNotFoundException.class, () -> mActivity.startActivityForResult(intent, REQUEST_CODE)); @@ -201,12 +202,13 @@ public class ActionPickImagesOnlyTest extends PhotoPickerBaseTest { @Test public void testExtraMimeTypeFilter() throws Exception { - final Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); + final Intent intent = new Intent(ACTION_PICK_IMAGES); intent.putExtra(Intent.EXTRA_MIME_TYPES, new String[]{"audio/*"}); mActivity.startActivityForResult(intent, REQUEST_CODE); final GetResultActivity.Result res = mActivity.getResult(); assertThat(res.resultCode).isEqualTo(Activity.RESULT_CANCELED); } + private void addOrderedSelectionFlag(Intent intent) { intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, MediaStore.getPickImagesMaxLimit()); intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_IN_ORDER, true); @@ -221,4 +223,33 @@ public class ActionPickImagesOnlyTest extends PhotoPickerBaseTest { mActivity.startActivityForResult(intent, REQUEST_CODE); } + + @Test + public void testExtraPickerLaunchTabOptions() throws Exception { + final Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); + + for (int launchOption: new int [] { + MediaStore.PICK_IMAGES_TAB_ALBUMS, + MediaStore.PICK_IMAGES_TAB_IMAGES + }) { + intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_LAUNCH_TAB, launchOption); + mActivity.startActivityForResult(intent, REQUEST_CODE); + + UiAssertionUtils.assertThatShowsPickerUi( + intent.getType(), intent.getExtras().getInt( + MediaStore.EXTRA_PICK_IMAGES_LAUNCH_TAB), sDevice); + sDevice.pressBack(); + } + } + + @Test + public void testExtraPickerLaunchTabInvalidOption() throws Exception { + final Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); + intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_LAUNCH_TAB, -1); + mActivity.startActivityForResult(intent, REQUEST_CODE); + + final GetResultActivity.Result res = mActivity.getResult(); + assertThat(res.resultCode).isEqualTo(Activity.RESULT_CANCELED); + + } } diff --git a/tests/PhotoPicker/src/android/photopicker/cts/ActionUserSelectImagesForAppTest.java b/tests/PhotoPicker/src/android/photopicker/cts/ActionUserSelectImagesForAppTest.java index baa884042fe..7d5642929d1 100644 --- a/tests/PhotoPicker/src/android/photopicker/cts/ActionUserSelectImagesForAppTest.java +++ b/tests/PhotoPicker/src/android/photopicker/cts/ActionUserSelectImagesForAppTest.java @@ -55,7 +55,6 @@ import androidx.test.runner.AndroidJUnit4; 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; @@ -85,7 +84,9 @@ public class ActionUserSelectImagesForAppTest extends PhotoPickerBaseTest { @AfterClass public static void tearDownClass() throws Exception { - sDeviceStatePreserver.restoreCloudProviderState(); + if (sDeviceStatePreserver != null) { + sDeviceStatePreserver.restoreCloudProviderState(); + } } @After @@ -160,7 +161,6 @@ public class ActionUserSelectImagesForAppTest extends PhotoPickerBaseTest { } @Test - @Ignore("Test have changed after Android U CTS cut") public void testNoCloudContent() throws Exception { final List<Uri> uriList = new ArrayList<>(); final String cloudId = "cloud_id1"; diff --git a/tests/PhotoPicker/src/android/photopicker/cts/CloudPhotoPickerTest.java b/tests/PhotoPicker/src/android/photopicker/cts/CloudPhotoPickerTest.java index bfbf33527f1..6cf5863b3d8 100644 --- a/tests/PhotoPicker/src/android/photopicker/cts/CloudPhotoPickerTest.java +++ b/tests/PhotoPicker/src/android/photopicker/cts/CloudPhotoPickerTest.java @@ -54,7 +54,6 @@ import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; @@ -99,7 +98,9 @@ public class CloudPhotoPickerTest extends PhotoPickerBaseTest { @AfterClass public static void tearDownClass() throws Exception { - sDeviceStatePreserver.restoreCloudProviderState(); + if (sDeviceStatePreserver != null) { + sDeviceStatePreserver.restoreCloudProviderState(); + } } @Before public void setUp() throws Exception { @@ -134,7 +135,6 @@ public class CloudPhotoPickerTest extends PhotoPickerBaseTest { } @Test - @Ignore("Test have changed after Android U CTS cut") public void testCloudOnlySync() throws Exception { initPrimaryCloudProviderWithImage(Pair.create(null, CLOUD_ID1)); @@ -145,7 +145,6 @@ public class CloudPhotoPickerTest extends PhotoPickerBaseTest { } @Test - @Ignore("Test have changed after Android U CTS cut") public void testCloudPlusLocalSyncWithoutDedupe() throws Exception { mUriList.addAll(createImagesAndGetUris(1, mContext.getUserId())); initPrimaryCloudProviderWithImage(Pair.create(null, CLOUD_ID1)); @@ -169,7 +168,6 @@ public class CloudPhotoPickerTest extends PhotoPickerBaseTest { } @Test - @Ignore("Test have changed after Android U CTS cut") public void testDeleteCloudMedia() throws Exception { initPrimaryCloudProviderWithImage(Pair.create(null, CLOUD_ID1), Pair.create(null, CLOUD_ID2)); @@ -190,7 +188,6 @@ public class CloudPhotoPickerTest extends PhotoPickerBaseTest { } @Test - @Ignore("Test have changed after Android U CTS cut") public void testVersionChange() throws Exception { initPrimaryCloudProviderWithImage(Pair.create(null, CLOUD_ID1), Pair.create(null, CLOUD_ID2)); @@ -232,7 +229,6 @@ public class CloudPhotoPickerTest extends PhotoPickerBaseTest { } @Test - @Ignore("Test have changed after Android U CTS cut") public void testProviderSwitchSuccess() throws Exception { setCloudProvider(CloudProviderPrimary.AUTHORITY); assertThat(MediaStore.isCurrentCloudMediaProviderAuthority(mContext.getContentResolver(), @@ -270,7 +266,6 @@ public class CloudPhotoPickerTest extends PhotoPickerBaseTest { } @Test - @Ignore("Test have changed after Android U CTS cut") public void testUriAccessWithValidProjection() throws Exception { initPrimaryCloudProviderWithImage(Pair.create(null, CLOUD_ID1)); @@ -306,7 +301,6 @@ public class CloudPhotoPickerTest extends PhotoPickerBaseTest { } @Test - @Ignore("Test have changed after Android U CTS cut") public void testUriAccessWithInvalidProjection() throws Exception { initPrimaryCloudProviderWithImage(Pair.create(null, CLOUD_ID1)); @@ -328,7 +322,6 @@ public class CloudPhotoPickerTest extends PhotoPickerBaseTest { } @Test - @Ignore("Test have changed after Android U CTS cut") public void testCloudEventNotification() throws Exception { // 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 diff --git a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerCrossProfileTest.java b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerCrossProfileTest.java index a4f7b902a9e..98d1df02d8f 100644 --- a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerCrossProfileTest.java +++ b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerCrossProfileTest.java @@ -24,6 +24,7 @@ import static android.photopicker.cts.util.PhotoPickerUiUtils.findItemList; import static android.photopicker.cts.util.PhotoPickerUiUtils.findProfileButton; import static android.photopicker.cts.util.ResultsAssertionsUtils.assertPickerUriFormat; import static android.photopicker.cts.util.ResultsAssertionsUtils.assertRedactedReadOnlyAccess; +import static android.provider.MediaStore.ACTION_PICK_IMAGES; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; @@ -93,7 +94,7 @@ public class PhotoPickerCrossProfileTest extends PhotoPickerBaseTest { final int imageCount = 2; mUriList.addAll(createImagesAndGetUris(imageCount, primaryUserId)); - Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); + Intent intent = new Intent(ACTION_PICK_IMAGES); intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, imageCount); mActivity.startActivityForResult(intent, REQUEST_CODE); @@ -120,7 +121,7 @@ public class PhotoPickerCrossProfileTest extends PhotoPickerBaseTest { assertThat(count).isEqualTo(imageCount); for (int i = 0; i < count; i++) { Uri uri = clipData.getItemAt(i).getUri(); - assertPickerUriFormat(uri, primaryUserId); + assertPickerUriFormat(ACTION_PICK_IMAGES, uri, primaryUserId); assertRedactedReadOnlyAccess(uri); } } @@ -147,7 +148,7 @@ public class PhotoPickerCrossProfileTest extends PhotoPickerBaseTest { } private void assertBlockedByAdmin(boolean isInvokedFromWorkProfile) throws Exception { - Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); + Intent intent = new Intent(ACTION_PICK_IMAGES); intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, MediaStore.getPickImagesMaxLimit()); mActivity.startActivityForResult(intent, REQUEST_CODE); diff --git a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerSettingsTest.java b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerSettingsTest.java index 78b3ae8c247..8005ed1507f 100644 --- a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerSettingsTest.java +++ b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerSettingsTest.java @@ -46,8 +46,6 @@ import androidx.annotation.Nullable; import androidx.test.filters.LargeTest; import androidx.test.filters.SdkSuppress; import androidx.test.uiautomator.UiObject; -import androidx.test.uiautomator.UiObjectNotFoundException; -import androidx.test.uiautomator.UiSelector; import com.android.bedstead.harrier.BedsteadJUnit4; import com.android.bedstead.harrier.DeviceState; @@ -114,7 +112,7 @@ public class PhotoPickerSettingsTest extends PhotoPickerBaseTest { sPhotoPickerSettingsActivityState); // Reset CloudMedia configs. - if (SdkLevel.isAtLeastS()) { + if (SdkLevel.isAtLeastS() && sDeviceStatePreserver != null) { sDeviceStatePreserver.restoreCloudProviderState(); } } @@ -157,7 +155,9 @@ public class PhotoPickerSettingsTest extends PhotoPickerBaseTest { verifySettingsTabContainerIsVisible(); assertWithMessage("Personal tab is not selected") - .that(isSelectedTabTitle(PERSONAL_TAB_TITLE_ENGLISH)).isTrue(); + .that(PhotoPickerUiUtils.isSelectedTabTitle( + PERSONAL_TAB_TITLE_ENGLISH, TAB_LAYOUT_RESOURCE_ID, sDevice)) + .isTrue(); } @Test @@ -171,32 +171,23 @@ public class PhotoPickerSettingsTest extends PhotoPickerBaseTest { verifySettingsTabContainerIsVisible(); assertWithMessage("Work tab is not selected") - .that(isSelectedTabTitle(WORK_TAB_TITLE_ENGLISH)).isTrue(); + .that(PhotoPickerUiUtils.isSelectedTabTitle( + WORK_TAB_TITLE_ENGLISH, TAB_LAYOUT_RESOURCE_ID, sDevice)).isTrue(); } private static void verifySettingsTabContainerIsVisible() { assertWithMessage("Timed out waiting for settings profile select tab container to appear") - .that(findObject(TAB_CONTAINER_RESOURCE_ID).waitForExists(SHORT_TIMEOUT)) + .that(PhotoPickerUiUtils.findObject( + TAB_CONTAINER_RESOURCE_ID, sDevice).waitForExists(SHORT_TIMEOUT)) .isTrue(); } private static void verifySettingsTabContainerIsNotVisible() { assertWithMessage("Found the settings profile select tab container") - .that(findObject(TAB_CONTAINER_RESOURCE_ID).waitForExists(SHORT_TIMEOUT)) + .that(PhotoPickerUiUtils.findObject( + TAB_CONTAINER_RESOURCE_ID, sDevice).waitForExists(SHORT_TIMEOUT)) .isFalse(); } - - private static boolean isSelectedTabTitle(@NonNull String tabTitle) - throws UiObjectNotFoundException { - final UiObject tabLayout = findObject(TAB_LAYOUT_RESOURCE_ID); - final UiObject tab = tabLayout.getChild(new UiSelector().textContains(tabTitle)); - return tab.isSelected(); - } - - private static UiObject findObject(@NonNull String resourceId) { - return sDevice.findObject(new UiSelector().resourceIdMatches(resourceId)); - } - @Test // This test is required for API coverage in Android R public void testSettingsLaunchFromIntent() throws InterruptedException { diff --git a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerTest.java b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerTest.java index 3d7e6f19281..5fef7375ef0 100644 --- a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerTest.java +++ b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerTest.java @@ -40,6 +40,7 @@ import static android.photopicker.cts.util.ResultsAssertionsUtils.assertMimeType import static android.photopicker.cts.util.ResultsAssertionsUtils.assertPersistedGrant; import static android.photopicker.cts.util.ResultsAssertionsUtils.assertPickerUriFormat; import static android.photopicker.cts.util.ResultsAssertionsUtils.assertRedactedReadOnlyAccess; +import static android.provider.MediaStore.ACTION_PICK_IMAGES; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; @@ -125,7 +126,7 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { clickAndWait(sDevice, item); final Uri uri = mActivity.getResult().data.getData(); - assertPickerUriFormat(uri, mContext.getUserId()); + assertPickerUriFormat(mAction, uri, mContext.getUserId()); assertPersistedGrant(uri, mContext.getContentResolver()); assertRedactedReadOnlyAccess(uri); } @@ -149,7 +150,7 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { clickAndWait(sDevice, item); final Uri uri = mActivity.getResult().data.getData(); - assertPickerUriFormat(uri, mContext.getUserId()); + assertPickerUriFormat(mAction, uri, mContext.getUserId()); assertRedactedReadOnlyAccess(uri); } @@ -203,7 +204,7 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { clickAndWait(sDevice, addButton); final Uri uri = mActivity.getResult().data.getData(); - assertPickerUriFormat(uri, mContext.getUserId()); + assertPickerUriFormat(mAction, uri, mContext.getUserId()); assertRedactedReadOnlyAccess(uri); } @@ -229,7 +230,7 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { assertThat(count).isEqualTo(itemCount); for (int i = 0; i < count; i++) { final Uri uri = clipData.getItemAt(i).getUri(); - assertPickerUriFormat(uri, mContext.getUserId()); + assertPickerUriFormat(mAction, uri, mContext.getUserId()); assertPersistedGrant(uri, mContext.getContentResolver()); assertRedactedReadOnlyAccess(uri); } @@ -277,7 +278,7 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { assertThat(count).isEqualTo(3); for (int i = 0; i < count; i++) { final Uri uri = clipData.getItemAt(i).getUri(); - assertPickerUriFormat(uri, mContext.getUserId()); + assertPickerUriFormat(mAction, uri, mContext.getUserId()); assertPersistedGrant(uri, mContext.getContentResolver()); assertRedactedReadOnlyAccess(uri); } @@ -317,7 +318,7 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { assertThat(count).isEqualTo(itemCount - 1); for (int i = 0; i < count; i++) { final Uri uri = clipData.getItemAt(i).getUri(); - assertPickerUriFormat(uri, mContext.getUserId()); + assertPickerUriFormat(mAction, uri, mContext.getUserId()); assertPersistedGrant(uri, mContext.getContentResolver()); assertRedactedReadOnlyAccess(uri); } @@ -579,7 +580,7 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { assertThat(count).isEqualTo(itemCount); for (int i = 0; i < count; i++) { final Uri uri = clipData.getItemAt(i).getUri(); - assertPickerUriFormat(uri, mContext.getUserId()); + assertPickerUriFormat(mAction, uri, mContext.getUserId()); assertPersistedGrant(uri, mContext.getContentResolver()); assertRedactedReadOnlyAccess(uri); assertMimeType(uri, mimeType); @@ -625,7 +626,7 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { .that(clipData.getItemCount()).isEqualTo(itemCount); for (int i = 0; i < itemCount; i++) { final Uri uri = clipData.getItemAt(i).getUri(); - assertPickerUriFormat(uri, mContext.getUserId()); + assertPickerUriFormat(mAction, uri, mContext.getUserId()); assertPersistedGrant(uri, mContext.getContentResolver()); assertRedactedReadOnlyAccess(uri); assertContainsMimeType(uri, mimeTypes); @@ -662,7 +663,7 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { .that(clipData.getItemCount()).isEqualTo(itemCount); for (int i = 0; i < itemCount; i++) { final Uri uri = clipData.getItemAt(i).getUri(); - assertPickerUriFormat(uri, mContext.getUserId()); + assertPickerUriFormat(mAction, uri, mContext.getUserId()); assertPersistedGrant(uri, mContext.getContentResolver()); assertRedactedReadOnlyAccess(uri); assertMimeType(uri, mimeType); @@ -873,14 +874,14 @@ public class PhotoPickerTest extends PhotoPickerBaseTest { private static List<String> getTestParameters() { return Arrays.asList( - MediaStore.ACTION_PICK_IMAGES, + ACTION_PICK_IMAGES, Intent.ACTION_GET_CONTENT ); } private void addMultipleSelectionFlag(Intent intent) { switch (intent.getAction()) { - case MediaStore.ACTION_PICK_IMAGES: + case ACTION_PICK_IMAGES: intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, MediaStore.getPickImagesMaxLimit()); break; diff --git a/tests/PhotoPicker/src/android/photopicker/cts/RemoteVideoPreviewTest.java b/tests/PhotoPicker/src/android/photopicker/cts/RemoteVideoPreviewTest.java index ab1100db72d..be7cad0371d 100644 --- a/tests/PhotoPicker/src/android/photopicker/cts/RemoteVideoPreviewTest.java +++ b/tests/PhotoPicker/src/android/photopicker/cts/RemoteVideoPreviewTest.java @@ -107,7 +107,9 @@ public class RemoteVideoPreviewTest extends PhotoPickerBaseTest { @AfterClass public static void tearDownClass() throws Exception { - sDeviceStatePreserver.restoreCloudProviderState(); + if (sDeviceStatePreserver != null) { + sDeviceStatePreserver.restoreCloudProviderState(); + } } @Before @@ -246,7 +248,6 @@ public class RemoteVideoPreviewTest extends PhotoPickerBaseTest { } @Test - @Ignore("Test have changed after Android U CTS cut") public void testVideoPreviewProgressIndicator() throws Exception { initCloudProviderWithVideo(Arrays.asList(Pair.create(null, CLOUD_ID1))); launchPreviewMultiple(/* count */ 1); @@ -257,7 +258,6 @@ public class RemoteVideoPreviewTest extends PhotoPickerBaseTest { } @Test - @Ignore("Test have changed after Android U CTS cut") public void testVideoPreviewPermanentError() throws Exception { initCloudProviderWithVideo(Arrays.asList(Pair.create(null, CLOUD_ID1))); launchPreviewMultiple(/* count */ 1); @@ -268,7 +268,6 @@ public class RemoteVideoPreviewTest extends PhotoPickerBaseTest { } @Test - @Ignore("Test have changed after Android U CTS cut") public void testVideoPreviewRetriableError() throws Exception { initCloudProviderWithVideo(Arrays.asList(Pair.create(null, CLOUD_ID1))); final int surfaceId = 0; diff --git a/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerUiUtils.java b/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerUiUtils.java index 2bbe69ea7b4..89d2f54f89c 100644 --- a/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerUiUtils.java +++ b/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerUiUtils.java @@ -23,6 +23,7 @@ import android.text.format.DateUtils; import androidx.annotation.NonNull; 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; @@ -181,4 +182,22 @@ public class PhotoPickerUiUtils { uiObject.click(); uiDevice.waitForIdle(); } + + /** + * Verifies whether the selected tab is the one with the provided title + */ + public static boolean isSelectedTabTitle( + @NonNull String tabTitle, @NonNull String tabResourceId, UiDevice device) + throws UiObjectNotFoundException { + final UiObject tabLayout = findObject(tabResourceId, device); + final UiObject tab = tabLayout.getChild(new UiSelector().textContains(tabTitle)); + return tab.isSelected(); + } + + /** + * Returns the UI object corresponding to the specified resourceId + */ + public static UiObject findObject(@NonNull String resourceId, UiDevice device) { + return device.findObject(new UiSelector().resourceIdMatches(resourceId)); + } } diff --git a/tests/PhotoPicker/src/android/photopicker/cts/util/ResultsAssertionsUtils.java b/tests/PhotoPicker/src/android/photopicker/cts/util/ResultsAssertionsUtils.java index 2f346770215..9c14650a43f 100644 --- a/tests/PhotoPicker/src/android/photopicker/cts/util/ResultsAssertionsUtils.java +++ b/tests/PhotoPicker/src/android/photopicker/cts/util/ResultsAssertionsUtils.java @@ -53,13 +53,17 @@ import java.util.Map; public class ResultsAssertionsUtils { private static final String TAG = "PhotoPickerTestAssertions"; - public static void assertPickerUriFormat(Uri uri, int expectedUserId) { + public static void assertPickerUriFormat(String action, Uri uri, int expectedUserId) { // content://media/picker/<user-id>/<media-id> final int userId = Integer.parseInt(uri.getPathSegments().get(1)); assertThat(userId).isEqualTo(expectedUserId); final String auth = uri.getPathSegments().get(0); - assertThat(auth).isEqualTo("picker"); + if (action.equalsIgnoreCase(Intent.ACTION_GET_CONTENT)) { + assertThat(auth).isEqualTo("picker_get_content"); + } else { + assertThat(auth).isEqualTo("picker"); + } } public static void assertPersistedGrant(Uri uri, ContentResolver resolver) { diff --git a/tests/PhotoPicker/src/android/photopicker/cts/util/UiAssertionUtils.java b/tests/PhotoPicker/src/android/photopicker/cts/util/UiAssertionUtils.java index 4d1e35b4655..0dcfc9efabb 100644 --- a/tests/PhotoPicker/src/android/photopicker/cts/util/UiAssertionUtils.java +++ b/tests/PhotoPicker/src/android/photopicker/cts/util/UiAssertionUtils.java @@ -16,10 +16,14 @@ package android.photopicker.cts.util; +import static android.photopicker.cts.util.PhotoPickerUiUtils.REGEX_PACKAGE_NAME; import static android.photopicker.cts.util.PhotoPickerUiUtils.SHORT_TIMEOUT; import static com.google.common.truth.Truth.assertThat; +import android.provider.MediaStore; + +import androidx.test.uiautomator.UiDevice; import androidx.test.uiautomator.UiObject; import androidx.test.uiautomator.UiSelector; @@ -27,6 +31,10 @@ import androidx.test.uiautomator.UiSelector; * Photo Picker Utility methods for PhotoPicker UI assertions. */ public class UiAssertionUtils { + + private static final String PICKER_TAB_LAYOUT_RESOURCE_ID = + REGEX_PACKAGE_NAME + ":id/tab_layout"; + /** * Verifies PhotoPicker UI is shown. */ @@ -53,4 +61,24 @@ public class UiAssertionUtils { } assertThat(new UiObject(new UiSelector().text("Albums")).exists()).isTrue(); } + + + /** + * Verifies PhotoPicker UI based on the launch option set in the intent + */ + public static void assertThatShowsPickerUi( + String mimeTypeFilter, int launchPickerTab, UiDevice device) throws Exception { + + assertThatShowsPickerUi(mimeTypeFilter); + + if (launchPickerTab == MediaStore.PICK_IMAGES_TAB_ALBUMS) { + // Picker launches with Albums tab + PhotoPickerUiUtils.isSelectedTabTitle( + "Albums", PICKER_TAB_LAYOUT_RESOURCE_ID, device); + } else if (launchPickerTab == MediaStore.PICK_IMAGES_TAB_IMAGES) { + // Picker launches with Photos tab + PhotoPickerUiUtils.isSelectedTabTitle( + "Photos", PICKER_TAB_LAYOUT_RESOURCE_ID, device); + } + } } diff --git a/tests/appsearch/Android.bp b/tests/appsearch/Android.bp index ed646f7112a..b8a34a571c5 100644 --- a/tests/appsearch/Android.bp +++ b/tests/appsearch/Android.bp @@ -34,6 +34,7 @@ android_test { "cts", "general-tests", "mts-appsearch", + "mcts-appsearch", ], data: [ ":CtsAppSearchTestHelperA", diff --git a/tests/autofillservice/src/android/autofillservice/cts/dropdown/AuthenticationTest.java b/tests/autofillservice/src/android/autofillservice/cts/dropdown/AuthenticationTest.java index 4a6bf6c2d83..bd3f859950c 100644 --- a/tests/autofillservice/src/android/autofillservice/cts/dropdown/AuthenticationTest.java +++ b/tests/autofillservice/src/android/autofillservice/cts/dropdown/AuthenticationTest.java @@ -498,14 +498,6 @@ public class AuthenticationTest extends AbstractLoginActivityTestCase { mActivity.onUsername((v) -> v.setText("du")); mUiBot.assertDatasets("DS1", "DS2"); mActivity.onUsername((v) -> v.setText("dud")); - mUiBot.assertDatasets("DS1", "DS2"); - mActivity.onUsername((v) -> v.setText("dude")); - mUiBot.assertDatasets("DS1", "DS2"); - mActivity.onUsername((v) -> v.setText("dude,")); - mUiBot.assertDatasets("DS2"); - - // Now delete the char and assert 2 are shown again... - mActivity.onUsername((v) -> v.setText("dude")); final UiObject2 picker = mUiBot.assertDatasets("DS1", "DS2"); // ...and select it this time diff --git a/tests/autofillservice/src/android/autofillservice/cts/dropdown/FillEventHistoryTest.java b/tests/autofillservice/src/android/autofillservice/cts/dropdown/FillEventHistoryTest.java index 8a7f91c288d..c9642292393 100644 --- a/tests/autofillservice/src/android/autofillservice/cts/dropdown/FillEventHistoryTest.java +++ b/tests/autofillservice/src/android/autofillservice/cts/dropdown/FillEventHistoryTest.java @@ -124,18 +124,18 @@ public class FillEventHistoryTest extends FillEventHistoryCommonTestCase { sReplier.addResponse(new CannedFillResponse.Builder().addDataset( new CannedDataset.Builder() - .setField(ID_USERNAME, "username1") - .setField(ID_PASSWORD, "password1") + .setField(ID_USERNAME, "ab1") + .setField(ID_PASSWORD, "ab1") .setPresentation(createPresentation("dataset1")) .build()) .addDataset(new CannedDataset.Builder() - .setField(ID_USERNAME, "username2") - .setField(ID_PASSWORD, "password2") + .setField(ID_USERNAME, "ab2") + .setField(ID_PASSWORD, "ab2") .setPresentation(createPresentation("dataset2")) .build()) .setFillResponseFlags(FillResponse.FLAG_TRACK_CONTEXT_COMMITED) .build()); - mActivity.expectAutoFill("username1", "password1"); + mActivity.expectAutoFill("ab1", "ab1"); // Trigger autofill on username mActivity.onUsername(View::requestFocus); @@ -153,10 +153,10 @@ public class FillEventHistoryTest extends FillEventHistoryCommonTestCase { } // Finish the context by login in - mActivity.onUsername((v) -> v.setText("USERNAME")); - mActivity.onPassword((v) -> v.setText("USERNAME")); + mActivity.onUsername((v) -> v.setText("AB")); + mActivity.onPassword((v) -> v.setText("AB")); - final String expectedMessage = getWelcomeMessage("USERNAME"); + final String expectedMessage = getWelcomeMessage("AB"); final String actualMessage = mActivity.tapLogin(); assertWithMessage("Wrong welcome msg").that(actualMessage).isEqualTo(expectedMessage); mUiBot.assertSaveNotShowing(SAVE_DATA_TYPE_PASSWORD); @@ -368,19 +368,19 @@ public class FillEventHistoryTest extends FillEventHistoryCommonTestCase { sReplier.addResponse(new CannedFillResponse.Builder().addDataset( new CannedDataset.Builder() .setId("id1") - .setField(ID_USERNAME, "username1") - .setField(ID_PASSWORD, "password1") + .setField(ID_USERNAME, "ab1") + .setField(ID_PASSWORD, "ab1") .setPresentation(createPresentation("dataset1")) .build()) .addDataset(new CannedDataset.Builder() .setId("id2") - .setField(ID_USERNAME, "username2") - .setField(ID_PASSWORD, "password2") + .setField(ID_USERNAME, "ab2") + .setField(ID_PASSWORD, "ab2") .setPresentation(createPresentation("dataset2")) .build()) .setFillResponseFlags(FillResponse.FLAG_TRACK_CONTEXT_COMMITED) .build()); - mActivity.expectAutoFill("username1", "password1"); + mActivity.expectAutoFill("ab1", "ab1"); // Trigger autofill on username mActivity.onUsername(View::requestFocus); @@ -398,10 +398,10 @@ public class FillEventHistoryTest extends FillEventHistoryCommonTestCase { } // Finish the context by login in - mActivity.onUsername((v) -> v.setText("USERNAME")); - mActivity.onPassword((v) -> v.setText("USERNAME")); + mActivity.onUsername((v) -> v.setText("AB")); + mActivity.onPassword((v) -> v.setText("AB")); - final String expectedMessage = getWelcomeMessage("USERNAME"); + final String expectedMessage = getWelcomeMessage("AB"); final String actualMessage = mActivity.tapLogin(); assertWithMessage("Wrong welcome msg").that(actualMessage).isEqualTo(expectedMessage); mUiBot.assertSaveNotShowing(SAVE_DATA_TYPE_PASSWORD); @@ -612,13 +612,13 @@ public class FillEventHistoryTest extends FillEventHistoryCommonTestCase { sReplier.addResponse(new CannedFillResponse.Builder().addDataset( new CannedDataset.Builder() .setId("id1") - .setField(ID_USERNAME, "username") - .setField(ID_PASSWORD, "username") + .setField(ID_USERNAME, "abc") + .setField(ID_PASSWORD, "abc") .setPresentation(createPresentation("dataset1")) .build()) .setFillResponseFlags(FillResponse.FLAG_TRACK_CONTEXT_COMMITED) .build()); - mActivity.expectAutoFill("username", "username"); + mActivity.expectAutoFill("abc", "abc"); // Trigger autofill on username mActivity.onUsername(View::requestFocus); @@ -634,15 +634,15 @@ public class FillEventHistoryTest extends FillEventHistoryCommonTestCase { assertFillEventForDatasetSelected(events.get(1), "id1", UI_TYPE_MENU); } - // Change the fields to different values from0 datasets - mActivity.onUsername((v) -> v.setText("USERNAME")); - mActivity.onPassword((v) -> v.setText("USERNAME")); + // Change the fields to different values from original datasets + mActivity.onUsername((v) -> v.setText("ABC")); + mActivity.onPassword((v) -> v.setText("ABC")); // Then change back to dataset values - mActivity.onUsername((v) -> v.setText("username")); - mActivity.onPassword((v) -> v.setText("username")); + mActivity.onUsername((v) -> v.setText("abc")); + mActivity.onPassword((v) -> v.setText("abc")); - final String expectedMessage = getWelcomeMessage("username"); + final String expectedMessage = getWelcomeMessage("abc"); final String actualMessage = mActivity.tapLogin(); assertWithMessage("Wrong welcome msg").that(actualMessage).isEqualTo(expectedMessage); mUiBot.assertSaveNotShowing(SAVE_DATA_TYPE_PASSWORD); diff --git a/tests/autofillservice/src/android/autofillservice/cts/dropdown/LoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/dropdown/LoginActivityTest.java index 15fc1ed2af4..d76e3ebb832 100644 --- a/tests/autofillservice/src/android/autofillservice/cts/dropdown/LoginActivityTest.java +++ b/tests/autofillservice/src/android/autofillservice/cts/dropdown/LoginActivityTest.java @@ -2429,11 +2429,11 @@ public class LoginActivityTest extends LoginActivityCommonTestCase { */ // Set expectations. sReplier.addResponse(new CannedDataset.Builder() - .setField(ID_USERNAME, "dude") + .setField(ID_USERNAME, "dud") .setField(ID_PASSWORD, "sweet") .setPresentation(createPresentation("The Dude")) .build()); - mActivity.expectAutoFill("dude", "sweet"); + mActivity.expectAutoFill("dud", "sweet"); // Trigger auto-fill. requestFocusOnUsername(); @@ -2469,7 +2469,7 @@ public class LoginActivityTest extends LoginActivityCommonTestCase { // Assert request. final FillRequest fillRequest2 = sReplier.getNextFillRequest(); assertHasFlags(fillRequest2.flags, FLAG_MANUAL_REQUEST); - assertValue(fillRequest2.structure, ID_USERNAME, "dude"); + assertValue(fillRequest2.structure, ID_USERNAME, "dud"); assertTextIsSanitized(fillRequest2.structure, ID_PASSWORD); // Select it. @@ -2490,11 +2490,11 @@ public class LoginActivityTest extends LoginActivityCommonTestCase { */ // Set expectations. sReplier.addResponse(new CannedDataset.Builder() - .setField(ID_USERNAME, "dude") + .setField(ID_USERNAME, "dud") .setField(ID_PASSWORD, "sweet") .setPresentation(createPresentation("The Dude")) .build()); - mActivity.expectAutoFill("dude", "sweet"); + mActivity.expectAutoFill("dud", "sweet"); // Trigger auto-fill. mActivity.forceAutofillOnUsername(); @@ -2530,7 +2530,7 @@ public class LoginActivityTest extends LoginActivityCommonTestCase { // Assert request. final FillRequest fillRequest2 = sReplier.getNextFillRequest(); assertHasFlags(fillRequest2.flags, FLAG_MANUAL_REQUEST); - assertValue(fillRequest2.structure, ID_USERNAME, "dude"); + assertValue(fillRequest2.structure, ID_USERNAME, "dud"); assertTextIsSanitized(fillRequest2.structure, ID_PASSWORD); // Select it. diff --git a/tests/backup/Android.bp b/tests/backup/Android.bp index 26ec960a17d..56ab8185973 100644 --- a/tests/backup/Android.bp +++ b/tests/backup/Android.bp @@ -44,6 +44,7 @@ android_test { "cts", "general-tests", "mts-permission", + "mcts-permission", ], sdk_version: "test_current", data: [ diff --git a/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java b/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java index 414033342bd..c37792aa9ff 100644 --- a/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java +++ b/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java @@ -2805,6 +2805,8 @@ public class CaptureRequestTest extends Camera2SurfaceViewTestCase { " Preview size is " + previewSize + ", repeating is " + repeating); } requestBuilder.set(CaptureRequest.SCALER_CROP_REGION, cropRegions[i]); + requestBuilder.set(CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE, + CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_OFF); requests[i] = requestBuilder.build(); if (VERBOSE) { Log.v(TAG, "submit crop region " + cropRegions[i]); @@ -2951,6 +2953,8 @@ public class CaptureRequestTest extends Camera2SurfaceViewTestCase { } requestBuilder.set(CaptureRequest.CONTROL_ZOOM_RATIO, zoomFactor); requestBuilder.set(CaptureRequest.SCALER_CROP_REGION, defaultCropRegion); + requestBuilder.set(CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE, + CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_OFF); CaptureRequest request = requestBuilder.build(); for (int j = 0; j < captureSubmitRepeat; ++j) { mSession.capture(request, listener, mHandler); @@ -3194,6 +3198,8 @@ public class CaptureRequestTest extends Camera2SurfaceViewTestCase { Size maxPreviewSize = mOrderedPreviewSizes.get(0); CaptureRequest.Builder requestBuilder = mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); + requestBuilder.set(CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE, + CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_OFF); for (Capability cap : extendedSceneModeCaps) { int mode = cap.getMode(); @@ -3282,10 +3288,9 @@ public class CaptureRequestTest extends Camera2SurfaceViewTestCase { } numFrames++; } - assertTrue("Autoframing state didn't converge within " + kMaxNumFrames - + " frames", numFrames < kMaxNumFrames); - if (expectedZoomRatio == 0.0f) { + if (autoframingState == CameraMetadata.CONTROL_AUTOFRAMING_STATE_CONVERGED + && expectedZoomRatio == 0.0f) { expectedZoomRatio = resultZoomRatio; } } else { @@ -3297,12 +3302,16 @@ public class CaptureRequestTest extends Camera2SurfaceViewTestCase { verifyCaptureResultForKey(CaptureResult.CONTROL_AUTOFRAMING, mode, listener, NUM_FRAMES_VERIFIED); - mCollector.expectTrue(String.format( - "Zoom Ratio in Capture Request does not match the expected zoom" - + "ratio in Capture Result (expected = %f, actual = %f)", - expectedZoomRatio, resultZoomRatio), - Math.abs(expectedZoomRatio - resultZoomRatio) / expectedZoomRatio - <= zoomErrorMargin); + // If autoframing was OFF, or the framing state CONVERGED, the zoom ratio in result + // should be within the margin of error. + if (autoframingState != CameraMetadata.CONTROL_AUTOFRAMING_STATE_FRAMING) { + mCollector.expectTrue(String.format( + "Zoom Ratio in Capture Request does not match the expected zoom" + + "ratio in Capture Result (expected = %f, actual = %f)", + expectedZoomRatio, resultZoomRatio), + Math.abs(expectedZoomRatio - resultZoomRatio) / expectedZoomRatio + <= zoomErrorMargin); + } } } } diff --git a/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java b/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java index ca5d18c5669..48d1580e52b 100644 --- a/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java +++ b/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java @@ -1032,6 +1032,8 @@ public class PerformanceTest { // Start viewfinder with settings override set and the starting zoom ratio, // and wait for some number of frames. CaptureRequest.Builder previewBuilder = configurePreviewOutputs(id); + previewBuilder.set(CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE, + CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_OFF); previewBuilder.set(CaptureRequest.CONTROL_SETTINGS_OVERRIDE, CameraMetadata.CONTROL_SETTINGS_OVERRIDE_ZOOM); previewBuilder.set(CaptureRequest.CONTROL_ZOOM_RATIO, startRatio); diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/AccountManagementTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/AccountManagementTest.java index 3cadf2a0d4e..7816f4c1dce 100644 --- a/tests/devicepolicy/src/android/devicepolicy/cts/AccountManagementTest.java +++ b/tests/devicepolicy/src/android/devicepolicy/cts/AccountManagementTest.java @@ -71,6 +71,7 @@ import com.android.bedstead.remotedpc.RemotePolicyManager; import org.junit.Assume; 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; @@ -614,6 +615,7 @@ public final class AccountManagementTest { } } + @Ignore("b/312605194 Ignore until test failure is root caused") @Postsubmit(reason = "new test") @PolicyAppliesTest(policy = AccountManagement.class) @ApiTest(apis = {"android.app.admin.DevicePolicyManager#setAccountManagementDisabled", diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/LockTaskTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/LockTaskTest.java index d16d726c691..1584bf79160 100644 --- a/tests/devicepolicy/src/android/devicepolicy/cts/LockTaskTest.java +++ b/tests/devicepolicy/src/android/devicepolicy/cts/LockTaskTest.java @@ -33,6 +33,7 @@ import static android.content.Intent.ACTION_DIAL; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.pm.PackageManager.FEATURE_TELEPHONY; +import static android.content.pm.PackageManager.FEATURE_TELEPHONY_CALLING; import static android.devicepolicy.cts.utils.PolicyEngineUtils.FINANCED_DEVICE_CONTROLLER_ROLE; import static com.android.bedstead.harrier.annotations.enterprise.MostImportantCoexistenceTest.LESS_IMPORTANT; @@ -998,7 +999,7 @@ public final class LockTaskTest { } @PolicyAppliesTest(policy = LockTaskFinance.class) - @RequireFeature(FEATURE_TELEPHONY) + @RequireFeature(FEATURE_TELEPHONY_CALLING) @Postsubmit(reason = "b/181993922 automatically marked flaky") // Tests that the default dialer doesn't crash or otherwise misbehave in lock task mode public void launchDefaultDialerInLockTaskMode_launches() { diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/ScreenCaptureDisabledTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/ScreenCaptureDisabledTest.java index 0e9903ed980..dfba1815eab 100644 --- a/tests/devicepolicy/src/android/devicepolicy/cts/ScreenCaptureDisabledTest.java +++ b/tests/devicepolicy/src/android/devicepolicy/cts/ScreenCaptureDisabledTest.java @@ -594,11 +594,18 @@ public final class ScreenCaptureDisabledTest { // as there could be notifications in the top part and white line(navigation bar) at bottom // which are included in the screenshot and are not redacted(black). It's not perfect, but // seems best option to avoid any flakiness at this point. - int[] pixels = new int[width * (height / 2)]; + int len = width * (height / 2); + int[] pixels = new int[len]; screenshot.getPixels(pixels, 0, width, 0, height / 4, width, height / 2); - for (int pixel : pixels) { - if (!(pixel == Color.BLACK || (pixel == Color.TRANSPARENT && isAutomotive()))) { + for (int i = 0; i < len; ++i) { + // Skip some pixels from the right to accommodate for the edge panel(present on + // some devices) which will not be redacted in the screenshot. + if ((i % width) /* X-position */ > (width - 34)) { + // skipping edge panel + continue; + } + if (!(pixels[i] == Color.BLACK || (pixels[i] == Color.TRANSPARENT && isAutomotive()))) { return false; } } diff --git a/tests/framework/base/windowmanager/src/android/server/wm/ActivityVisibilityTests.java b/tests/framework/base/windowmanager/src/android/server/wm/ActivityVisibilityTests.java index c255eab0198..069ad28c1e5 100644 --- a/tests/framework/base/windowmanager/src/android/server/wm/ActivityVisibilityTests.java +++ b/tests/framework/base/windowmanager/src/android/server/wm/ActivityVisibilityTests.java @@ -58,6 +58,7 @@ import static android.window.DisplayAreaOrganizer.FEATURE_UNDEFINED; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assume.assumeTrue; +import static org.junit.Assume.assumeFalse; import android.content.ComponentName; import android.platform.test.annotations.Presubmit; @@ -749,7 +750,7 @@ public class ActivityVisibilityTests extends ActivityManagerTestBase { @Test public void testTurnScreenOnSingleTask() { assumeTrue(supportsLockScreen()); - + assumeFalse(isCar() && supportsMultiDisplay()); final LockScreenSession lockScreenSession = createManagedLockScreenSession(); lockScreenSession.sleepDevice(); separateTestJournal(); diff --git a/tests/framework/base/windowmanager/src/android/server/wm/BlurTests.java b/tests/framework/base/windowmanager/src/android/server/wm/BlurTests.java index 5f0f9fbead9..5c49a60e1d4 100644 --- a/tests/framework/base/windowmanager/src/android/server/wm/BlurTests.java +++ b/tests/framework/base/windowmanager/src/android/server/wm/BlurTests.java @@ -71,6 +71,11 @@ public class BlurTests extends WindowManagerTestBase { Settings.Global::getInt, Settings.Global::putInt, 0); + private final TestRule mDisableTransitionAnimationRule = SettingsSession.overrideForTest( + Settings.Global.getUriFor(Settings.Global.TRANSITION_ANIMATION_SCALE), + Settings.Global::getFloat, + Settings.Global::putFloat, + 0f); private final ActivityTestRule<BackgroundActivity> mBackgroundActivity = new ActivityTestRule<>(BackgroundActivity.class); @@ -78,6 +83,7 @@ public class BlurTests extends WindowManagerTestBase { @Rule public final TestRule methodRules = RuleChain.outerRule(mDumpOnFailure) .around(mEnableBlurRule) + .around(mDisableTransitionAnimationRule) .around(mBackgroundActivity); @Before diff --git a/tests/framework/base/windowmanager/src/android/server/wm/StartActivityTests.java b/tests/framework/base/windowmanager/src/android/server/wm/StartActivityTests.java index 83f04b89fce..bd241e3a0ca 100644 --- a/tests/framework/base/windowmanager/src/android/server/wm/StartActivityTests.java +++ b/tests/framework/base/windowmanager/src/android/server/wm/StartActivityTests.java @@ -315,10 +315,9 @@ public class StartActivityTests extends ActivityManagerTestBase { if (useShellPermission) { waitAndAssertResumedActivity(BROADCAST_RECEIVER_ACTIVITY, "Activity should be started and resumed"); - if (type == ACTIVITY_TYPE_HOME && isAutomotive(mContext) - && hasSplitscreenMultitaskingFeature(mContext)) { - // For automotive devices with splitscreen multitasking, home activity might - // not be in front of the stack, hence, check for its visibility instead. + if (type == ACTIVITY_TYPE_HOME && isAutomotive(mContext)) { + // For automotive devices, home activity might not be in front of the stack, + // hence, check for its visibility instead. mWmState.assertHomeActivityVisible(/* visible= */ true); } else { mWmState.assertFrontStackActivityType( diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java b/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java index b6fd395fd87..c3ce3b44649 100644 --- a/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java +++ b/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java @@ -871,7 +871,7 @@ public class WindowManagerState { public int getRootTaskIdByActivity(ComponentName activityName) { final Task rootTask = getRootTaskByActivity(activityName); - return (rootTask == null) ? INVALID_TASK_ID : rootTask.mTaskId; + return (rootTask == null) ? INVALID_TASK_ID : rootTask.mRootTaskId; } public Task getTaskByActivity(ComponentName activityName) { diff --git a/tests/input/res/raw/test_keyboard_register.json b/tests/input/res/raw/test_keyboard_register.json index 044ea0df1ba..c5d7a089c50 100644 --- a/tests/input/res/raw/test_keyboard_register.json +++ b/tests/input/res/raw/test_keyboard_register.json @@ -8,8 +8,8 @@ "bus": "usb", "configuration":[ {"type": 100, "data": [1]}, // UI_SET_EVBIT : EV_KEY - // UI_SET_KEYBIT : KEY_Q, KEY_W, KEY_E, KEY_A, KEY_B, KEY_C, KEY_ALT_LEFT, KEY_GRAVE, + // UI_SET_KEYBIT : KEY_Q, KEY_W, KEY_E, KEY_A, KEY_B, KEY_C, KEY_ALT_LEFT, KEY_ESC, // KEY_META_LEFT, KEY_DEL, KEY_DPAD_LEFT - {"type": 101, "data": [16, 17, 18, 30, 48, 46, 56, 41, 125, 14, 105]} + {"type": 101, "data": [16, 17, 18, 30, 48, 46, 56, 1, 125, 14, 105]} ] } diff --git a/tests/input/src/android/input/cts/BackKeyShortcutsTest.kt b/tests/input/src/android/input/cts/BackKeyShortcutsTest.kt index 91f352c1449..7f7eac519f0 100644 --- a/tests/input/src/android/input/cts/BackKeyShortcutsTest.kt +++ b/tests/input/src/android/input/cts/BackKeyShortcutsTest.kt @@ -55,10 +55,10 @@ private fun injectKeyUp(device: UinputDevice, scanCode: Int) { class BackKeyShortcutsTest { companion object { - const val KEY_META_LEFT = 125 - const val KEY_GRAVE = 41 - const val KEY_DEL = 14 - const val KEY_DPAD_LEFT = 105 + const val KEY_LEFTMETA = 125 + const val KEY_ESC = 1 + const val KEY_BACKSPACE = 14 + const val KEY_LEFT = 105 } private val instrumentation = InstrumentationRegistry.getInstrumentation() @@ -102,11 +102,11 @@ class BackKeyShortcutsTest { PollingCheck.waitFor { inputManager.getInputDevice(keyboardDevice.deviceId) != null } activity.assertNoEvents() - for (scanCode in intArrayOf(KEY_GRAVE, KEY_DEL, KEY_DPAD_LEFT)) { - injectKeyDown(keyboardDevice, KEY_META_LEFT) + for (scanCode in intArrayOf(KEY_BACKSPACE, KEY_LEFT)) { + injectKeyDown(keyboardDevice, KEY_LEFTMETA) injectKeyDown(keyboardDevice, scanCode) injectKeyUp(keyboardDevice, scanCode) - injectKeyUp(keyboardDevice, KEY_META_LEFT) + injectKeyUp(keyboardDevice, KEY_LEFTMETA) assertReceivedEventsCorrectlyMapped(2, KeyEvent.KEYCODE_BACK) } diff --git a/tests/input/src/android/input/cts/MultiTouchTest.kt b/tests/input/src/android/input/cts/MultiTouchTest.kt index aa493f90f40..db47fefba4a 100644 --- a/tests/input/src/android/input/cts/MultiTouchTest.kt +++ b/tests/input/src/android/input/cts/MultiTouchTest.kt @@ -16,6 +16,7 @@ package android.input.cts import android.app.ActivityOptions +import android.content.ComponentName import android.content.Intent import android.content.pm.ActivityInfo import android.graphics.PointF @@ -38,6 +39,8 @@ class MultiTouchTest { private val instrumentation = InstrumentationRegistry.getInstrumentation() private lateinit var verifier: EventVerifier private val touchInjector = TouchInjector(instrumentation) + private val activityName = + ComponentName(instrumentation.targetContext, CaptureEventActivity::class.java) @JvmField @Parameterized.Parameter(0) @@ -54,7 +57,7 @@ class MultiTouchTest { fun setUp() { val bundle = ActivityOptions.makeBasic().setLaunchDisplayId(0).toBundle() val intent = Intent(Intent.ACTION_VIEW) - .setClass(instrumentation.targetContext, CaptureEventActivity::class.java) + .setComponent(activityName) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK) .putExtra(CaptureEventActivity.EXTRA_FIXED_ORIENTATION, orientation) .putExtra(CaptureEventActivity.EXTRA_WINDOW_FLAGS, flags) @@ -64,7 +67,10 @@ class MultiTouchTest { PollingCheck.waitFor { activity.hasWindowFocus() } verifier = EventVerifier(activity::getInputEvent) - WindowManagerStateHelper().waitForAppTransitionIdleOnDisplay(DEFAULT_DISPLAY) + val wmState = WindowManagerStateHelper() + wmState.waitForAppTransitionIdleOnDisplay(DEFAULT_DISPLAY) + wmState.waitForActivityOrientation(activityName, orientation) + instrumentation.uiAutomation.syncInputTransactions() instrumentation.waitForIdleSync() } diff --git a/tests/jdwp/runner/host-side/Android.bp b/tests/jdwp/runner/host-side/Android.bp index 4786c2f4829..4492693221d 100644 --- a/tests/jdwp/runner/host-side/Android.bp +++ b/tests/jdwp/runner/host-side/Android.bp @@ -39,5 +39,8 @@ java_test_host { "cts", "general-tests", "mts-art", + "mcts-art", + "mts-conscrypt", + "mcts-conscrypt", ], } diff --git a/tests/libcore/jsr166/Android.bp b/tests/libcore/jsr166/Android.bp index 9ffff7787ce..eb6e582fa95 100644 --- a/tests/libcore/jsr166/Android.bp +++ b/tests/libcore/jsr166/Android.bp @@ -40,6 +40,7 @@ android_test { "cts", "general-tests", "mts-art", + "mcts-art", ], host_required: ["cts-dalvik-host-test-runner"], } diff --git a/tests/libcore/luni/Android.bp b/tests/libcore/luni/Android.bp index e60d895cfcb..ba84aea2c15 100644 --- a/tests/libcore/luni/Android.bp +++ b/tests/libcore/luni/Android.bp @@ -62,5 +62,6 @@ android_test { "mts-art", "general-tests", "automotive-general-tests", + "mcts-art", ], } diff --git a/tests/libcore/ojluni/Android.bp b/tests/libcore/ojluni/Android.bp index 221d497fbef..fa07690a220 100644 --- a/tests/libcore/ojluni/Android.bp +++ b/tests/libcore/ojluni/Android.bp @@ -47,6 +47,7 @@ android_test { "cts", "general-tests", "mts-art", + "mcts-art", ], data: [ ":CtsLibcoreTestRunner", diff --git a/tests/libcore/okhttp/Android.bp b/tests/libcore/okhttp/Android.bp index 25fe13b1856..ad7cf593e78 100644 --- a/tests/libcore/okhttp/Android.bp +++ b/tests/libcore/okhttp/Android.bp @@ -51,6 +51,7 @@ android_test { "cts", "general-tests", "mts-conscrypt", + "mcts-conscrypt", ], host_required: ["cts-dalvik-host-test-runner"], test_config: "CtsLibcoreOkHttpTestCases.xml" diff --git a/tests/libcore/wycheproof-bc/Android.bp b/tests/libcore/wycheproof-bc/Android.bp index a7b90af55d4..97eb795c0b5 100644 --- a/tests/libcore/wycheproof-bc/Android.bp +++ b/tests/libcore/wycheproof-bc/Android.bp @@ -49,5 +49,6 @@ android_test { "cts", "general-tests", "mts-art", + "mcts-art", ], } diff --git a/tests/media/Android.bp b/tests/media/Android.bp index 57d76a683d0..0f7d0231d75 100644 --- a/tests/media/Android.bp +++ b/tests/media/Android.bp @@ -48,6 +48,7 @@ android_test { "cts", "general-tests", "mts-media", + "mcts-media", ], min_sdk_version: "29", } diff --git a/tests/media/common/src/android/mediav2/common/cts/CodecTestBase.java b/tests/media/common/src/android/mediav2/common/cts/CodecTestBase.java index dc17b8d99f4..4c022f047e2 100644 --- a/tests/media/common/src/android/mediav2/common/cts/CodecTestBase.java +++ b/tests/media/common/src/android/mediav2/common/cts/CodecTestBase.java @@ -746,7 +746,6 @@ public abstract class CodecTestBase { if (needVideo) { list.add(MediaFormat.MIMETYPE_VIDEO_AVC); list.add(MediaFormat.MIMETYPE_VIDEO_MPEG4); - list.add(MediaFormat.MIMETYPE_VIDEO_H263); list.add(MediaFormat.MIMETYPE_VIDEO_VP8); list.add(MediaFormat.MIMETYPE_VIDEO_VP9); } diff --git a/tests/mediapc/src/android/mediapc/cts/CodecTranscoderTestBase.java b/tests/mediapc/src/android/mediapc/cts/CodecTranscoderTestBase.java index cfd1b5d9749..d3317f865fe 100644 --- a/tests/mediapc/src/android/mediapc/cts/CodecTranscoderTestBase.java +++ b/tests/mediapc/src/android/mediapc/cts/CodecTranscoderTestBase.java @@ -360,6 +360,7 @@ public class CodecTranscoderTestBase { if (mUseHighBitDepth) { encoderFormat.setInteger(MediaFormat.KEY_PROFILE, Objects.requireNonNull(PROFILE_HLG_MAP.get(mMime))[0]); + encoderFormat.setInteger(MediaFormat.KEY_LEVEL, 1); } return encoderFormat; } diff --git a/tests/ondevicepersonalization/Android.bp b/tests/ondevicepersonalization/Android.bp index 738effe86b1..5509c26ab91 100644 --- a/tests/ondevicepersonalization/Android.bp +++ b/tests/ondevicepersonalization/Android.bp @@ -27,6 +27,7 @@ android_test { "cts", "general-tests", "mts-ondevicepersonalization", + "mcts-ondevicepersonalization", ], libs: [ "android.test.runner", diff --git a/tests/signature/api-check/src/java/android/signature/cts/api/HiddenApiTest.java b/tests/signature/api-check/src/java/android/signature/cts/api/HiddenApiTest.java index 5fae541f68c..442ce2c4f91 100644 --- a/tests/signature/api-check/src/java/android/signature/cts/api/HiddenApiTest.java +++ b/tests/signature/api-check/src/java/android/signature/cts/api/HiddenApiTest.java @@ -32,6 +32,7 @@ import java.util.HashSet; import java.util.Set; import java.util.function.Predicate; import org.junit.Test; +import org.junit.Ignore; /** * Checks that it is not possible to access hidden APIs. @@ -77,11 +78,13 @@ public class HiddenApiTest extends AbstractApiTest { } @Test + @Ignore("b/301075649") public void testSignatureFieldsThroughReflection() { doTestSignature(FIELD_FILTER, /* reflection= */ true, /* jni= */ false); } @Test + @Ignore("b/301075649") public void testSignatureFieldsThroughJni() { doTestSignature(FIELD_FILTER, /* reflection= */ false, /* jni= */ true); } diff --git a/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java b/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java index 4b7e402e164..e938f816b81 100644 --- a/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java +++ b/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java @@ -31,6 +31,7 @@ import java.util.function.Predicate; import java.util.function.Supplier; import java.util.stream.Collectors; import org.junit.Test; +import org.junit.Ignore; /** * Performs the signature check via a JUnit test. @@ -90,6 +91,7 @@ public class SignatureTest extends AbstractSignatureTest { * <p>Will check the entire API, and then report the complete list of failures</p> */ @Test(timeout = 600000) + @Ignore("b/301075649") public void testRuntimeCompatibilityWithCurrentApi() { runWithTestResultObserver(mResultObserver -> { ApiComplianceChecker complianceChecker = diff --git a/tests/signature/api-check/system-annotation/src/java/android/signature/cts/api/AnnotationTest.java b/tests/signature/api-check/system-annotation/src/java/android/signature/cts/api/AnnotationTest.java index e6d5b060e0f..71f8f649fc4 100644 --- a/tests/signature/api-check/system-annotation/src/java/android/signature/cts/api/AnnotationTest.java +++ b/tests/signature/api-check/system-annotation/src/java/android/signature/cts/api/AnnotationTest.java @@ -32,6 +32,7 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.function.Predicate; +import org.junit.Ignore; import org.junit.Test; /** @@ -65,6 +66,7 @@ public class AnnotationTest extends AbstractApiTest { * android.annotation.SystemApi) match the API definition. */ @Test + @Ignore("b/301075649") public void testAnnotation() { AnnotationChecker.ResultFilter filter = new AnnotationChecker.ResultFilter() { @Override diff --git a/tests/storageaccess/Android.bp b/tests/storageaccess/Android.bp index f2acdc22171..9a83b3ff2e0 100644 --- a/tests/storageaccess/Android.bp +++ b/tests/storageaccess/Android.bp @@ -46,5 +46,6 @@ android_test { "cts", "general-tests", "mts-documentsui", + "mcts-documentsui", ], } diff --git a/tests/tests/appop2/Android.bp b/tests/tests/appop2/Android.bp index 55a30b91be0..0630728cce4 100644 --- a/tests/tests/appop2/Android.bp +++ b/tests/tests/appop2/Android.bp @@ -33,6 +33,7 @@ android_test { "cts", "general-tests", "mts-permission", + "mcts-permission", "vts10", ], data: [ diff --git a/tests/tests/attributionsource/Android.bp b/tests/tests/attributionsource/Android.bp index ea09ec5bf48..09724ed7b5f 100644 --- a/tests/tests/attributionsource/Android.bp +++ b/tests/tests/attributionsource/Android.bp @@ -39,5 +39,6 @@ android_test { "cts", "general-tests", "mts-permission", + "mcts-permission", ], } diff --git a/tests/tests/bionic/Android.bp b/tests/tests/bionic/Android.bp index c6bc68c1f9d..72019b8c0c9 100644 --- a/tests/tests/bionic/Android.bp +++ b/tests/tests/bionic/Android.bp @@ -57,6 +57,7 @@ cc_test { "cts", "general-tests", "mts-mainline-infra", + "mcts-mainline-infra", ], data_bins: [ diff --git a/tests/tests/content/Android.bp b/tests/tests/content/Android.bp index 714ebeea741..2f48f9292af 100644 --- a/tests/tests/content/Android.bp +++ b/tests/tests/content/Android.bp @@ -154,6 +154,7 @@ android_test { "cts", "general-tests", "mts-documentsui", + "mcts-documentsui", ], min_sdk_version: "29", replace_max_sdk_version_placeholder: "current", diff --git a/tests/tests/content/emptytestapp/AndroidManifestLongUsesPermissionName.xml b/tests/tests/content/emptytestapp/AndroidManifestLongUsesPermissionName.xml index 25071b834fa..be38b74cc36 100644 --- a/tests/tests/content/emptytestapp/AndroidManifestLongUsesPermissionName.xml +++ b/tests/tests/content/emptytestapp/AndroidManifestLongUsesPermissionName.xml @@ -18,6 +18,6 @@ package="android.content.cts.emptytestapp.longusespermission"> <!-- Test that apks with a long name in <uses-permission> could not be installed successfully. The maximum size of the name is 512. --> - <uses-permission android:name="p05Ok3DDwKRRaaJTglSJ1b8CApMKVpqhs8MJioRQcDEslzBIFS8ArsT8IwByiTC1ArGiA3bi49pGwKDVzYJEluxHNJukCM7xamCByVrtGo0r93eVa3tPriVkCYe01Vxrmg9tkWThStdLAbgBOT4tNI3pP6NHAsiSie4CfrCWkc5IloeCYKBp05Ok3DDwKRRaaJTglSJ1b8CApMKVpqhs8MJioRQcDEslzBIFS8ArsT8IwByiTC1ArGiA3bi49pGwKDVzYJEluxHNJukCM7xamCByVrtGo0r93eVa3tPriVkCYe01Vxrmg9tkWThStdLAbgBOT4tNI3pP6NHAsiSie4CfrCWkc5IloeCY27jEBRNRG3ozwBsGr1sVIM9U0bVTI2TdyIyeRkZgW4JrJefwNIBAmCg4AzqXiCvG6JjqA0uTCWSFu2YqAVxVdiRKAay19k5VFlSaM7QW9uhvlrLQqsTW01ofFzxNDbp2QfIFHZR6rebKzKBz6byQFM0DYQnYMwFWXjWkMPNdqkRLykoFLyBup53G68k2n8w" /> + <uses-permission android:name="p05Ok3DDwKRRaaJTglSJ1b8CApMKVpqhs8MJioRQcDEslzBIFS8ArsT8IwByiTC1ArGiA3bi49pGwKDVzYJEluxHNJukCM7xamCByVrtGo0r93eVa3tPriVkCYe01Vxrmg9tkWThStdLAbgBOT4tNI3pP6NHAsiSie4CfrCWkc5IloeCYKBp05Ok3DDwKRRaaJTglSJ1b8CApMKVpqhs8MJioRQcDEslzBIFS8ArsT8IwByiTC1ArGiA3bi49pGwKDVzYJEluxHNJukCM7xamCByVrtGo0r93eVa3tPriVkCYe01Vxrmg9tkWThStdLAbgBOT4tNI3pP6NHAsiSie4CfrCWkc5IloeCY27jEBRNRG3ozwBsGr1sVIM9U0bVTI2TdyIyeRkZgW4JrJefwNIBAmCg4AzqXiCvG6JjqA0uTCWSFu2YqAVxVdiRKAay19k5VFlSaM7QW9uhvlrLQqsTW01ofFzxNDbp2QfIFHZR6rebKzKBz6byQFM0DYQnYMwFWXjWkMPNdqkRLykoFLyBup53G68k2n8wp05Ok3DDwKRRaaJTglSJ1b8CApMKVpqhs8MJioRQcDEslzBIFS8ArsT8IwByiTC1ArGiA3bi49pGwKDVzYJEluxHNJukCM7xamCByVrtGo0r93eVa3tPriVkCYe01Vxrmg9tkWThStdLAbgBOT4tNI3pP6NHAsiSie4CfrCWkc5IloeCYKBp05Ok3DDwKRRaaJTglSJ1b8CApMKVpqhs8MJioRQcDEslzBIFS8ArsT8IwByiTC1ArGiA3bi49pGwKDVzYJEluxHNJukCM7xamCByVrtGo0r93eVa3tPriVkCYe01Vxrmg9tkWThStdLAbgBOT4tNI3pP6NHAsiSie4CfrCWkc5IloeCY27jEBRNRG3ozwBsGr1sVIM9U0bVTI2TdyIyeRkZgW4JrJefwNIBAmCg4AzqXiCvG6JjqA0uTCWSFu2YqAVxVdiRKAay19k5VFlSaM7QW9uhvlrLQqsTW01ofFd" /> <application android:hasCode="false" android:label="Empty Test App" /> </manifest>
\ No newline at end of file diff --git a/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java b/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java index 89d6aed2e6d..7ffe9e91925 100644 --- a/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java +++ b/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java @@ -2075,13 +2075,14 @@ public class PackageManagerTest { @Test public void testInstall_withLongUsesPermissionName_fail() { - String expectedErrorCode = "INSTALL_PARSE_FAILED_MANIFEST_MALFORMED"; - String expectedErrorMessage = "The name in the <uses-permission> is greater than 512"; + String expectedErrorCode = "INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION"; + String expectedErrorMessage = + "String length limit exceeded for attribute in uses-permission"; String installResult = installPackageWithResult(LONG_USES_PERMISSION_NAME_APK); - assertThat(installResult.contains(expectedErrorCode)).isTrue(); - assertThat(installResult.contains(expectedErrorMessage)).isTrue(); + assertThat(installResult).contains(expectedErrorCode); + assertThat(installResult).contains(expectedErrorMessage); } private String installPackageWithResult(String apkPath) { diff --git a/tests/tests/deviceconfig/Android.bp b/tests/tests/deviceconfig/Android.bp index 8b90258733a..a4c86f0c571 100644 --- a/tests/tests/deviceconfig/Android.bp +++ b/tests/tests/deviceconfig/Android.bp @@ -26,6 +26,7 @@ android_test { "cts", "general-tests", "mts-configinfrastructure", + "mcts-configinfrastructure", ], libs: ["android.test.base"], static_libs: [ diff --git a/tests/tests/display/AndroidManifest.xml b/tests/tests/display/AndroidManifest.xml index e0f2481ee4e..9b895c51535 100644 --- a/tests/tests/display/AndroidManifest.xml +++ b/tests/tests/display/AndroidManifest.xml @@ -45,6 +45,7 @@ android:exported="true"/> <activity android:name=".HdrConversionTestActivity" /> <activity android:name=".SimpleActivity" /> + <activity android:name=".SimpleActivity2" /> </application> <!-- self-instrumenting test package. --> diff --git a/tests/tests/display/src/android/display/cts/DisplayEventTest.java b/tests/tests/display/src/android/display/cts/DisplayEventTest.java index 36339e54df1..7aeb777e775 100644 --- a/tests/tests/display/src/android/display/cts/DisplayEventTest.java +++ b/tests/tests/display/src/android/display/cts/DisplayEventTest.java @@ -379,11 +379,12 @@ public class DisplayEventTest { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); mInstrumentation.startActivitySync(intent); - // Launch Home to bring the test activity into cached mode - Intent home = new Intent(Intent.ACTION_MAIN); - home.addCategory(Intent.CATEGORY_HOME); - home.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - mContext.startActivity(home); + // Launch another activity to bring the test activity into cached mode + Intent intent2 = new Intent(Intent.ACTION_MAIN); + intent2.setClass(mContext, SimpleActivity2.class); + intent2.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + mInstrumentation.startActivitySync(intent2); + waitLatch(mLatchActivityCached); } diff --git a/tests/tests/display/src/android/display/cts/SimpleActivity2.java b/tests/tests/display/src/android/display/cts/SimpleActivity2.java new file mode 100644 index 00000000000..663c1b8ef0f --- /dev/null +++ b/tests/tests/display/src/android/display/cts/SimpleActivity2.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.display.cts; + +import android.app.Activity; + +/** + * An activity doing nothing + */ +public final class SimpleActivity2 extends Activity { } diff --git a/tests/tests/hardware/res/raw/sony_dualshock4_usb_register.json b/tests/tests/hardware/res/raw/sony_dualshock4_usb_register.json index db322d6ca37..67f0f921d5e 100644 --- a/tests/tests/hardware/res/raw/sony_dualshock4_usb_register.json +++ b/tests/tests/hardware/res/raw/sony_dualshock4_usb_register.json @@ -54,6 +54,11 @@ { "id": 0x81, "data": [0x81, 0x62, 0x97, 0xc9, 0x00, 0x00, 0x00] + }, + { + "id": 0x12, + "data": [0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00] } ] } diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java index b0d8026287f..553d99707f9 100644 --- a/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java +++ b/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java @@ -515,6 +515,7 @@ public class KeyAttestationTest { public void testEcAttestation_UniqueIdWorksWithCorrectPermission() throws Exception { assumeTrue("Device doesn't have secure lock screen", TestUtils.hasSecureLockScreen(getContext())); + assumeTrue("Device does not support attestation", TestUtils.isAttestationSupported()); String keystoreAlias = "test_key"; KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(keystoreAlias, PURPOSE_SIGN) diff --git a/tests/tests/libcoreapievolution/Android.bp b/tests/tests/libcoreapievolution/Android.bp index 954f3a25f40..b8b17998f30 100644 --- a/tests/tests/libcoreapievolution/Android.bp +++ b/tests/tests/libcoreapievolution/Android.bp @@ -33,5 +33,6 @@ android_test { "cts", "general-tests", "mts-art", + "mcts-art", ], } diff --git a/tests/tests/libcorefileio/Android.bp b/tests/tests/libcorefileio/Android.bp index b9db7d23290..5de87520e27 100644 --- a/tests/tests/libcorefileio/Android.bp +++ b/tests/tests/libcorefileio/Android.bp @@ -33,5 +33,6 @@ android_test { "cts", "general-tests", "mts-art", + "mcts-art", ], } diff --git a/tests/tests/libcorelegacy22/Android.bp b/tests/tests/libcorelegacy22/Android.bp index 98684b26a93..c46545657e3 100644 --- a/tests/tests/libcorelegacy22/Android.bp +++ b/tests/tests/libcorelegacy22/Android.bp @@ -27,5 +27,6 @@ android_test { "cts", "general-tests", "mts-art", + "mcts-art", ], } diff --git a/tests/tests/media/bettertogether/Android.bp b/tests/tests/media/bettertogether/Android.bp index 3c7a66b3436..fca197234e2 100644 --- a/tests/tests/media/bettertogether/Android.bp +++ b/tests/tests/media/bettertogether/Android.bp @@ -55,6 +55,7 @@ android_test { "cts", "general-tests", "mts-media", + "mcts-media", ], host_required: ["cts-dynamic-config"], min_sdk_version: "29", diff --git a/tests/tests/media/codec/Android.bp b/tests/tests/media/codec/Android.bp index ab6edbae9e4..3ccb2f2b14f 100644 --- a/tests/tests/media/codec/Android.bp +++ b/tests/tests/media/codec/Android.bp @@ -57,6 +57,7 @@ android_test { "cts", "general-tests", "mts-media", + "mcts-media", ], host_required: ["cts-dynamic-config"], min_sdk_version: "29", diff --git a/tests/tests/media/codec/src/android/media/codec/cts/DecodeEditEncodeTest.java b/tests/tests/media/codec/src/android/media/codec/cts/DecodeEditEncodeTest.java index 8b37ca22f11..e243665e7fb 100644 --- a/tests/tests/media/codec/src/android/media/codec/cts/DecodeEditEncodeTest.java +++ b/tests/tests/media/codec/src/android/media/codec/cts/DecodeEditEncodeTest.java @@ -34,6 +34,7 @@ import android.media.MediaFormat; import android.media.cts.InputSurface; import android.media.cts.OutputSurface; import android.media.cts.TestArgs; +import android.media.cts.TestUtils; import android.opengl.GLES20; import android.opengl.GLES30; import android.os.Build; @@ -230,6 +231,14 @@ public class DecodeEditEncodeTest { assumeTrue("Color conversion related tests are not valid on cuttlefish releases " + "through android T for format: " + format, IS_AFTER_T); } + // Pre Android U, this test only checked the 1st codec (which is usually a hardware codec) + // and software codecs exercised a problem in the underlying graphis code. + // So we will only run this for CTS mode or if we're on versions after Android T + // (where the graphics code is fixed) + if (TestUtils.isMtsMode()) { + assumeTrue("Color conversion related tests are skipped in MTS on releases " + + "through android T for format: " + format, IS_AFTER_T); + } } @Parameterized.Parameters(name = "{index}_{0}_{1}_{2}_{3}_{4}_{5}") diff --git a/tests/tests/media/codec/src/android/media/codec/cts/EncodeDecodeTest.java b/tests/tests/media/codec/src/android/media/codec/cts/EncodeDecodeTest.java index 4ee7455c079..94b3b653474 100644 --- a/tests/tests/media/codec/src/android/media/codec/cts/EncodeDecodeTest.java +++ b/tests/tests/media/codec/src/android/media/codec/cts/EncodeDecodeTest.java @@ -34,6 +34,7 @@ import android.media.cts.NdkMediaCodec; import android.media.cts.OutputSurface; import android.media.cts.SdkMediaCodec; import android.media.cts.TestArgs; +import android.media.cts.TestUtils; import android.opengl.GLES20; import android.os.Build; import android.platform.test.annotations.PlatinumTest; @@ -293,6 +294,15 @@ public class EncodeDecodeTest { assumeTrue("Color conversion related tests are not valid on cuttlefish releases " + "through android T", IS_AFTER_T); } + // Pre Android U, this test only checked the 1st codec (which is usually a hardware + // codec) and software codecs exercised a problem in the underlying graphis code. + // So we will only run this for CTS mode or if we're on versions after Android T + // (where the graphics code is fixed) + if (TestUtils.isMtsMode()) { + assumeTrue("Color conversion related tests are skipped in MTS on releases " + + "through android T", IS_AFTER_T); + } + SurfaceToSurfaceWrapper wrapper = new SurfaceToSurfaceWrapper(obj, persisent, useNdk); Thread th = new Thread(wrapper, "codec test"); 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 d34e4f433a9..98cefb217e1 100644 --- a/tests/tests/media/common/src/android/media/cts/CodecState.java +++ b/tests/tests/media/common/src/android/media/cts/CodecState.java @@ -449,6 +449,7 @@ public class CodecState { // yet, stopping the audio track now would result in getAudioTimeUs // returning 0 and prevent video samples from being presented. // We stop the audio track before the playback thread exits. + mAudioTrack.setEndOfStream(); return false; } diff --git a/tests/tests/media/common/src/android/media/cts/NonBlockingAudioTrack.java b/tests/tests/media/common/src/android/media/cts/NonBlockingAudioTrack.java index 6589cc568f0..17e92540f35 100644 --- a/tests/tests/media/common/src/android/media/cts/NonBlockingAudioTrack.java +++ b/tests/tests/media/common/src/android/media/cts/NonBlockingAudioTrack.java @@ -36,7 +36,9 @@ import java.util.concurrent.atomic.AtomicLong; public class NonBlockingAudioTrack { private static final String TAG = NonBlockingAudioTrack.class.getSimpleName(); - class QueueElement { + private static final long END_OF_STREAM_PTS = Long.MAX_VALUE; + + private static class QueueElement { ByteBuffer data; int size; long pts; @@ -130,6 +132,12 @@ public class NonBlockingAudioTrack { mAudioTrack.play(); } + public void setEndOfStream() { + QueueElement element = new QueueElement(); + element.pts = END_OF_STREAM_PTS; + mQueue.add(element); + } + public void stop() { if (mQueue.isEmpty()) { mAudioTrack.stop(); @@ -176,10 +184,30 @@ public class NonBlockingAudioTrack { break; } + if (element.pts == END_OF_STREAM_PTS) { + // For tunnel mode, when an audio PTS gap is encountered, silence is rendered + // during the gap. As such, it's necessary to fade down the audio to avoid a + // bad user experience. This necessitates that the Audio HAL holds onto the + // last audio frame and delays releasing it to the output device until the + // subsequent audio frame is seen so that it knows whether there's a PTS gap + // or not. When the end-of-stream is reached, this means that the last audio + // frame has not been rendered yet. So, in order to release the last audio + // frame, a signal must be sent to the Audio HAL so the last frame gets + // released. + int written = mAudioTrack.write(ByteBuffer.allocate(0), 0, + AudioTrack.WRITE_NON_BLOCKING, + END_OF_STREAM_PTS); + if (written < 0) { + throw new RuntimeException("AudioTrack.write failed (" + written + ")"); + } + mQueue.removeFirst(); + break; + } + int written = mAudioTrack.write(element.data, element.size, AudioTrack.WRITE_NON_BLOCKING, element.pts + mAudioOffsetNs.get()); if (written < 0) { - throw new RuntimeException("Audiotrack.write() failed."); + throw new RuntimeException("AudioTrack.write failed (" + written + ")"); } mTotalBytesWritten.addAndGet(written); diff --git a/tests/tests/media/decoder/Android.bp b/tests/tests/media/decoder/Android.bp index 410fb5b754a..208bb93b04f 100644 --- a/tests/tests/media/decoder/Android.bp +++ b/tests/tests/media/decoder/Android.bp @@ -87,6 +87,7 @@ android_test { "cts", "general-tests", "mts-media", + "mcts-media", ], host_required: ["cts-dynamic-config"], min_sdk_version: "29", diff --git a/tests/tests/media/decoder/src/android/media/decoder/cts/DecodeOnlyTest.java b/tests/tests/media/decoder/src/android/media/decoder/cts/DecodeOnlyTest.java index ac0c24ef0c2..1d120187a65 100644 --- a/tests/tests/media/decoder/src/android/media/decoder/cts/DecodeOnlyTest.java +++ b/tests/tests/media/decoder/src/android/media/decoder/cts/DecodeOnlyTest.java @@ -643,6 +643,7 @@ public class DecodeOnlyTest extends MediaTestBase { Thread.sleep(500); videoCodec.flush(); audioCodec.flush(); + audioTrack.flush(); videoAsyncHandler.clearBufferQueue(); // Frames at 7s of each file are not key frame, and there is non-zero key frame before it 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 cb88f684207..b29e4161c9a 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 @@ -3726,9 +3726,6 @@ public class DecoderTest extends MediaTestBase { // Allow the playback to advance past the PTS gap and back to normal operation Thread.sleep(500); - // Simulate the end of playback by pretending that we have no more audio data - mMediaCodecPlayer.stopDrainingAudioOutputBuffers(true); - // Sleep till framePosition stabilizes, i.e. playback is complete { long endOfPlayackTimeoutMs = 20000; @@ -3842,13 +3839,9 @@ public class DecoderTest extends MediaTestBase { Thread.sleep(200); mMediaCodecPlayer.stopDrainingAudioOutputBuffers(false); - // After 200 ms, simulate the end of playback by pretending that we have no more audio data - Thread.sleep(200); - mMediaCodecPlayer.stopDrainingAudioOutputBuffers(true); - // Sleep till framePosition stabilizes, i.e. playback is complete { - long endOfPlayackTimeoutMs = 3000; + long endOfPlayackTimeoutMs = 20000; long startTimeMs = System.currentTimeMillis(); AudioTimestamp previousTimestamp; do { diff --git a/tests/tests/media/drmframework/Android.bp b/tests/tests/media/drmframework/Android.bp index 5a66af1921c..87362379d2e 100644 --- a/tests/tests/media/drmframework/Android.bp +++ b/tests/tests/media/drmframework/Android.bp @@ -63,6 +63,7 @@ android_test { "cts", "general-tests", "mts-media", + "mcts-media", ], host_required: ["cts-dynamic-config"], min_sdk_version: "current", diff --git a/tests/tests/media/encoder/Android.bp b/tests/tests/media/encoder/Android.bp index cd860cc1d48..c7e2a1ae8f1 100644 --- a/tests/tests/media/encoder/Android.bp +++ b/tests/tests/media/encoder/Android.bp @@ -57,6 +57,7 @@ android_test { "cts", "general-tests", "mts-media", + "mcts-media", ], host_required: ["cts-dynamic-config"], min_sdk_version: "29", diff --git a/tests/tests/media/extractor/Android.bp b/tests/tests/media/extractor/Android.bp index fad256f4e02..943008e93f3 100644 --- a/tests/tests/media/extractor/Android.bp +++ b/tests/tests/media/extractor/Android.bp @@ -43,6 +43,7 @@ android_test { "cts", "general-tests", "mts-media", + "mcts-media", ], host_required: ["cts-dynamic-config"], min_sdk_version: "29", diff --git a/tests/tests/media/misc/Android.bp b/tests/tests/media/misc/Android.bp index feaabe47a4c..6aa9f401a84 100644 --- a/tests/tests/media/misc/Android.bp +++ b/tests/tests/media/misc/Android.bp @@ -106,6 +106,7 @@ android_test { "cts", "general-tests", "mts-media", + "mcts-media", ], host_required: ["cts-dynamic-config"], min_sdk_version: "29", diff --git a/tests/tests/media/muxer/Android.bp b/tests/tests/media/muxer/Android.bp index 85eab12543d..afe8d9201a7 100644 --- a/tests/tests/media/muxer/Android.bp +++ b/tests/tests/media/muxer/Android.bp @@ -73,6 +73,7 @@ android_test { "cts", "general-tests", "mts-media", + "mcts-media", ], host_required: ["cts-dynamic-config"], min_sdk_version: "29", diff --git a/tests/tests/media/player/Android.bp b/tests/tests/media/player/Android.bp index ecda2ff4f4b..5a6f185177b 100644 --- a/tests/tests/media/player/Android.bp +++ b/tests/tests/media/player/Android.bp @@ -55,6 +55,7 @@ android_test { "cts", "general-tests", "mts-media", + "mcts-media", ], host_required: ["cts-dynamic-config"], min_sdk_version: "29", diff --git a/tests/tests/media/projection/Android.bp b/tests/tests/media/projection/Android.bp index 584a31901f4..676942499fa 100644 --- a/tests/tests/media/projection/Android.bp +++ b/tests/tests/media/projection/Android.bp @@ -62,6 +62,7 @@ android_test { "cts", "general-tests", "mts-media", + "mcts-media", ], host_required: ["cts-dynamic-config"], min_sdk_version: "33", diff --git a/tests/tests/media/recorder/Android.bp b/tests/tests/media/recorder/Android.bp index 9e17567d8b8..9849ff20bc0 100644 --- a/tests/tests/media/recorder/Android.bp +++ b/tests/tests/media/recorder/Android.bp @@ -52,6 +52,7 @@ android_test { "cts", "general-tests", "mts-media", + "mcts-media", ], host_required: ["cts-dynamic-config"], min_sdk_version: "29", diff --git a/tests/tests/mediaparser/Android.bp b/tests/tests/mediaparser/Android.bp index d916d6198d2..bc6f6fbee3a 100644 --- a/tests/tests/mediaparser/Android.bp +++ b/tests/tests/mediaparser/Android.bp @@ -27,6 +27,7 @@ android_test { "cts", "general-tests", "mts-media", + "mcts-media", ], } diff --git a/tests/tests/mediastress/Android.bp b/tests/tests/mediastress/Android.bp index 48fe6a664be..2de946192a6 100644 --- a/tests/tests/mediastress/Android.bp +++ b/tests/tests/mediastress/Android.bp @@ -24,6 +24,7 @@ android_test { "cts", "general-tests", "mts-media", + "mcts-media", ], // Include both the 32 and 64 bit versions compile_multilib: "both", diff --git a/tests/tests/mediatranscoding/Android.bp b/tests/tests/mediatranscoding/Android.bp index 6a220a36fdb..341434c9c12 100644 --- a/tests/tests/mediatranscoding/Android.bp +++ b/tests/tests/mediatranscoding/Android.bp @@ -25,6 +25,7 @@ android_test { "cts", "general-tests", "mts-media", + "mcts-media", "mts", ], static_libs: [ diff --git a/tests/tests/neuralnetworks/Android.bp b/tests/tests/neuralnetworks/Android.bp index 00298e6cc0f..adb0f9fc98b 100644 --- a/tests/tests/neuralnetworks/Android.bp +++ b/tests/tests/neuralnetworks/Android.bp @@ -53,6 +53,7 @@ cc_test { "cts", "mts", "mts-neuralnetworks", + "mcts-neuralnetworks", ], test_config: "AndroidTestDevice.xml", }, diff --git a/tests/tests/neuralnetworks/benchmark/Android.bp b/tests/tests/neuralnetworks/benchmark/Android.bp index 60fb0eba874..c2804084434 100644 --- a/tests/tests/neuralnetworks/benchmark/Android.bp +++ b/tests/tests/neuralnetworks/benchmark/Android.bp @@ -28,6 +28,7 @@ android_test { "general-tests", "mts", "mts-neuralnetworks", + "mcts-neuralnetworks", ], static_libs: [ "androidx.test.rules", diff --git a/tests/tests/neuralnetworks/java_test/Android.bp b/tests/tests/neuralnetworks/java_test/Android.bp index cfa2782bfd5..84d257a36cf 100644 --- a/tests/tests/neuralnetworks/java_test/Android.bp +++ b/tests/tests/neuralnetworks/java_test/Android.bp @@ -36,6 +36,7 @@ android_test { "general-tests", "mts", "mts-neuralnetworks", + "mcts-neuralnetworks", ], sdk_version: "test_current", // Do not compress model data files. diff --git a/tests/tests/neuralnetworks/tflite_delegate/Android.bp b/tests/tests/neuralnetworks/tflite_delegate/Android.bp index 6acce1d74ed..67b2d9535fb 100644 --- a/tests/tests/neuralnetworks/tflite_delegate/Android.bp +++ b/tests/tests/neuralnetworks/tflite_delegate/Android.bp @@ -51,6 +51,7 @@ cc_test { "cts", "mts", "mts-neuralnetworks", + "mcts-neuralnetworks", "general-tests", ], sdk_version: "current", diff --git a/tests/tests/os/Android.bp b/tests/tests/os/Android.bp index fd7ff3a447d..b5e389e8c5d 100644 --- a/tests/tests/os/Android.bp +++ b/tests/tests/os/Android.bp @@ -62,6 +62,7 @@ android_test { "general-tests", "sts", "mts-documentsui", + "mcts-documentsui", ], sdk_version: "test_current", libs: [ diff --git a/tests/tests/packagewatchdog/Android.bp b/tests/tests/packagewatchdog/Android.bp index 46ec52d4480..72c9c52156e 100644 --- a/tests/tests/packagewatchdog/Android.bp +++ b/tests/tests/packagewatchdog/Android.bp @@ -26,7 +26,8 @@ android_test { "cts", "vts", "general-tests", - "mts-extservices" + "mts-extservices", + "mcts-extservices", ], libs: ["android.test.base"], static_libs: [ diff --git a/tests/tests/permission/Android.bp b/tests/tests/permission/Android.bp index 5a907d7b76a..5ca334444cb 100644 --- a/tests/tests/permission/Android.bp +++ b/tests/tests/permission/Android.bp @@ -30,6 +30,7 @@ android_test { "general-tests", "sts", "mts-permission", + "mcts-permission", ], // Include both the 32 and 64 bit versions compile_multilib: "both", diff --git a/tests/tests/permission/sdk28/Android.bp b/tests/tests/permission/sdk28/Android.bp index 3043c93298d..2bdffabe5bc 100644 --- a/tests/tests/permission/sdk28/Android.bp +++ b/tests/tests/permission/sdk28/Android.bp @@ -29,5 +29,6 @@ android_test { "cts", "general-tests", "mts-permission", + "mcts-permission", ], } diff --git a/tests/tests/permission/telephony/Android.bp b/tests/tests/permission/telephony/Android.bp index bbfe06c5580..5ded57ab35e 100644 --- a/tests/tests/permission/telephony/Android.bp +++ b/tests/tests/permission/telephony/Android.bp @@ -26,6 +26,7 @@ android_test { "cts", "general-tests", "mts-permission", + "mcts-permission", ], // Include both the 32 and 64 bit versions compile_multilib: "both", diff --git a/tests/tests/permissionmultiuser/Android.bp b/tests/tests/permissionmultiuser/Android.bp index f577c82e3f4..b86b022057c 100644 --- a/tests/tests/permissionmultiuser/Android.bp +++ b/tests/tests/permissionmultiuser/Android.bp @@ -43,5 +43,6 @@ android_test { "cts", "general-tests", "mts-permission", + "mcts-permission", ], } diff --git a/tests/tests/permissionpolicy/Android.bp b/tests/tests/permissionpolicy/Android.bp index 5a92e890a89..4fdc51b3faf 100644 --- a/tests/tests/permissionpolicy/Android.bp +++ b/tests/tests/permissionpolicy/Android.bp @@ -26,6 +26,7 @@ android_test { "cts", "general-tests", "mts-permission", + "mcts-permission", ], libs: ["android.test.base"], static_libs: [ diff --git a/tests/tests/provider/Android.bp b/tests/tests/provider/Android.bp index 285e3f5d0fd..31e28aafcff 100644 --- a/tests/tests/provider/Android.bp +++ b/tests/tests/provider/Android.bp @@ -14,6 +14,7 @@ android_test { "general-tests", "sts", "mts-documentsui", + "mcts-documentsui", ], libs: [ diff --git a/tests/tests/provider/preconditions/Android.bp b/tests/tests/provider/preconditions/Android.bp index d889df53bc0..485cc2e63cb 100644 --- a/tests/tests/provider/preconditions/Android.bp +++ b/tests/tests/provider/preconditions/Android.bp @@ -15,6 +15,7 @@ java_test_helper_library { "cts", "general-tests", "sts", + "mcts-documentsui", "mts-documentsui" ], host_supported: true, diff --git a/tests/tests/role/Android.bp b/tests/tests/role/Android.bp index ae1fdfd2111..a619ecdc679 100644 --- a/tests/tests/role/Android.bp +++ b/tests/tests/role/Android.bp @@ -38,6 +38,7 @@ android_test { "cts", "general-tests", "mts-permission", + "mcts-permission", ], data: [ diff --git a/tests/tests/systemui/AndroidManifest.xml b/tests/tests/systemui/AndroidManifest.xml index 3bcb78ef8c1..6fbb6825efb 100644 --- a/tests/tests/systemui/AndroidManifest.xml +++ b/tests/tests/systemui/AndroidManifest.xml @@ -39,7 +39,6 @@ android:screenOrientation="portrait"/> <activity android:name=".WindowInsetsActivity" android:theme="@android:style/Theme.Material" - android:screenOrientation="portrait" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN"/> diff --git a/tests/tests/systemui/src/android/systemui/cts/WindowInsetsBehaviorTests.java b/tests/tests/systemui/src/android/systemui/cts/WindowInsetsBehaviorTests.java index 681d94825d4..10e63597c76 100644 --- a/tests/tests/systemui/src/android/systemui/cts/WindowInsetsBehaviorTests.java +++ b/tests/tests/systemui/src/android/systemui/cts/WindowInsetsBehaviorTests.java @@ -25,6 +25,8 @@ import static android.view.View.SYSTEM_UI_CLEARABLE_FLAGS; import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN; import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; +import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; +import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; import static android.view.View.SYSTEM_UI_FLAG_VISIBLE; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; @@ -760,7 +762,8 @@ public class WindowInsetsBehaviorTests { final int swipeCount = 2; final boolean insideLimit = true; testSystemGestureExclusionLimit(swipeCount, insideLimit, SYSTEM_UI_FLAG_IMMERSIVE_STICKY - | SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_HIDE_NAVIGATION); + | SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_HIDE_NAVIGATION + | SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); assertEquals("Swipe must not be canceled.", 0, mActionCancelPoints.size()); assertEquals("Action up points.", swipeCount, mActionUpPoints.size()); @@ -775,7 +778,8 @@ public class WindowInsetsBehaviorTests { final int swipeCount = 2; final boolean insideLimit = false; testSystemGestureExclusionLimit(swipeCount, insideLimit, SYSTEM_UI_FLAG_IMMERSIVE_STICKY - | SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_HIDE_NAVIGATION); + | SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_HIDE_NAVIGATION + | SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); assertEquals("Swipe must not be canceled.", 0, mActionCancelPoints.size()); assertEquals("Action up points.", swipeCount, mActionUpPoints.size()); diff --git a/tests/tests/textclassifier/Android.bp b/tests/tests/textclassifier/Android.bp index bac5f6a24ff..6ab8811ba87 100644 --- a/tests/tests/textclassifier/Android.bp +++ b/tests/tests/textclassifier/Android.bp @@ -26,6 +26,7 @@ android_test { "cts", "general-tests", "mts-extservices", + "mcts-extservices", ], libs: ["android.test.base"], static_libs: [ diff --git a/tests/tests/textclassifier/src/android/view/textclassifier/cts/TextClassifierServiceSwapTest.java b/tests/tests/textclassifier/src/android/view/textclassifier/cts/TextClassifierServiceSwapTest.java index a732832acaa..2e91599a88c 100644 --- a/tests/tests/textclassifier/src/android/view/textclassifier/cts/TextClassifierServiceSwapTest.java +++ b/tests/tests/textclassifier/src/android/view/textclassifier/cts/TextClassifierServiceSwapTest.java @@ -47,6 +47,7 @@ import com.android.compatibility.common.util.BlockingBroadcastReceiver; import com.android.compatibility.common.util.RequiredServiceRule; import com.android.compatibility.common.util.SafeCleanerRule; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.RuleChain; @@ -66,6 +67,7 @@ import java.util.concurrent.CountDownLatch; * queries from clients in the same package. */ @RunWith(AndroidJUnit4.class) +@Ignore("b/318869191") public class TextClassifierServiceSwapTest { // TODO: Add more tests to verify all the TC APIs call between caller and TCS. private static final String TAG = "TextClassifierServiceSwapTest"; diff --git a/tests/tests/tv/src/android/media/tv/tuner/cts/TunerTest.java b/tests/tests/tv/src/android/media/tv/tuner/cts/TunerTest.java index 72093a961de..6f9a7e379ff 100644 --- a/tests/tests/tv/src/android/media/tv/tuner/cts/TunerTest.java +++ b/tests/tests/tv/src/android/media/tv/tuner/cts/TunerTest.java @@ -1936,6 +1936,13 @@ public class TunerTest { // connect CiCam to Frontend if (TunerVersionChecker.isHigherOrEqualVersionTo(TunerVersionChecker.TUNER_VERSION_1_1)) { // TODO: get real CiCam id from MediaCas + int res = tunerA.connectFrontendToCiCam(ciCamId); + // INVALID_LTS_ID means hal doesn't support CiCam + if (res == Tuner.INVALID_LTS_ID) { + // Resources cleanup before return + tunerA.close(); + return; + } assertEquals(Tuner.RESULT_SUCCESS, tunerA.connectFrontendToCiCam(ciCamId)); linkCiCamToFrontendSupported = true; } else { diff --git a/tests/tests/util/Android.bp b/tests/tests/util/Android.bp index 1c29b2133a0..3fd0ab591a4 100644 --- a/tests/tests/util/Android.bp +++ b/tests/tests/util/Android.bp @@ -24,6 +24,7 @@ android_test { "cts", "general-tests", "mts-statsd", + "mcts-statsd", ], libs: ["android.test.runner"], static_libs: [ diff --git a/tests/tests/webkit/assets/webkit/test_imageaccess.html b/tests/tests/webkit/assets/webkit/test_imageaccess.html index ce76c830eb5..c46c9f3965e 100644 --- a/tests/tests/webkit/assets/webkit/test_imageaccess.html +++ b/tests/tests/webkit/assets/webkit/test_imageaccess.html @@ -16,13 +16,13 @@ <html> <head> <title>TEST FAILED</title> - </head> - <body> - <img id='img' src="../images/tomato.png" onload="success()" /> - <script> + <script> function success() { document.title=document.getElementById('img').naturalHeight; } </script> + </head> + <body> + <img id='img' src="../images/tomato.png" onload="success()" /> </body> </html> diff --git a/tests/tests/widget/src/android/widget/cts/RemoteViewsFixedCollectionAdapterTest.java b/tests/tests/widget/src/android/widget/cts/RemoteViewsFixedCollectionAdapterTest.java index 408f3278980..a4c17c6faa6 100644 --- a/tests/tests/widget/src/android/widget/cts/RemoteViewsFixedCollectionAdapterTest.java +++ b/tests/tests/widget/src/android/widget/cts/RemoteViewsFixedCollectionAdapterTest.java @@ -474,8 +474,10 @@ public class RemoteViewsFixedCollectionAdapterTest { assertTrue(adapter.hasStableIds()); assertEquals(2, mListView.getChildCount()); - TextView textView0 = (TextView) mListView.getChildAt(0); - TextView textView1 = (TextView) mListView.getChildAt(1); + AppWidgetHostView child0 = (AppWidgetHostView) mListView.getChildAt(0); + AppWidgetHostView child1 = (AppWidgetHostView) mListView.getChildAt(1); + TextView textView0 = (TextView) child0.getChildAt(0); + TextView textView1 = (TextView) child1.getChildAt(0); assertEquals("Hello", textView0.getText()); assertEquals("World", textView1.getText()); } @@ -532,10 +534,13 @@ public class RemoteViewsFixedCollectionAdapterTest { assertTrue(adapter.hasStableIds()); assertEquals(3, listView.getChildCount()); - TextView textView0 = (TextView) listView.getChildAt(0); - TextView textView1 = (TextView) listView.getChildAt(1); + AppWidgetHostView child0 = (AppWidgetHostView) listView.getChildAt(0); + AppWidgetHostView child1 = (AppWidgetHostView) listView.getChildAt(1); + AppWidgetHostView child2 = (AppWidgetHostView) listView.getChildAt(2); + TextView textView0 = (TextView) child0.getChildAt(0); + TextView textView1 = (TextView) child1.getChildAt(0); CompoundButton checkBox2 = - (CompoundButton) ((ViewGroup) listView.getChildAt(2)).getChildAt(0); + (CompoundButton) ((ViewGroup) child2.getChildAt(0)).getChildAt(0); assertEquals("Hello", textView0.getText()); assertEquals("World", textView1.getText()); assertEquals("Checkbox", checkBox2.getText()); @@ -601,7 +606,8 @@ public class RemoteViewsFixedCollectionAdapterTest { runOnMainAndDrawSync(mActivityRule, listView, () -> mRemoteViews.reapply(mActivity, mView)); Adapter initialAdapter = listView.getAdapter(); - TextView initialFirstItemView = (TextView) listView.getChildAt(0); + AppWidgetHostView child0 = (AppWidgetHostView) listView.getChildAt(0); + TextView initialFirstItemView = (TextView) child0.getChildAt(0); int initialFirstItemViewType = initialAdapter.getItemViewType(0); items = new RemoteCollectionItems.Builder() @@ -616,8 +622,9 @@ public class RemoteViewsFixedCollectionAdapterTest { // layoutId should have been maintained (as 0) and the next view type assigned to the // checkbox layout. The view for the row should have been recycled without inflating a new // view. + AppWidgetHostView child1 = (AppWidgetHostView) listView.getChildAt(1); assertSame(initialAdapter, listView.getAdapter()); - assertSame(initialFirstItemView, listView.getChildAt(1)); + assertSame(initialFirstItemView, child1.getChildAt(0)); assertEquals(initialFirstItemViewType, listView.getAdapter().getItemViewType(1)); assertNotEquals(initialFirstItemViewType, listView.getAdapter().getItemViewType(0)); } @@ -634,7 +641,8 @@ public class RemoteViewsFixedCollectionAdapterTest { runOnMainAndDrawSync(mActivityRule, listView, () -> mRemoteViews.reapply(mActivity, mView)); Adapter initialAdapter = listView.getAdapter(); - TextView initialFirstItemView = (TextView) listView.getChildAt(0); + AppWidgetHostView child0 = (AppWidgetHostView) listView.getChildAt(0); + TextView initialFirstItemView = (TextView) child0.getChildAt(0); items = new RemoteCollectionItems.Builder() .addItem(8 /* id= */, new RemoteViews(PACKAGE_NAME, R.layout.checkbox_layout)) @@ -644,9 +652,10 @@ public class RemoteViewsFixedCollectionAdapterTest { runOnMainAndDrawSync(mActivityRule, listView, () -> mRemoteViews.reapply(mActivity, mView)); // The adapter should have been replaced, which is required when the view type increases. + AppWidgetHostView child1 = (AppWidgetHostView) listView.getChildAt(1); assertEquals(2, listView.getAdapter().getViewTypeCount()); assertNotSame(initialAdapter, listView.getAdapter()); - assertNotSame(initialFirstItemView, listView.getChildAt(1)); + assertNotSame(initialFirstItemView, child1.getChildAt(0)); } @Test @@ -663,7 +672,8 @@ public class RemoteViewsFixedCollectionAdapterTest { runOnMainAndDrawSync(mActivityRule, listView, () -> mRemoteViews.reapply(mActivity, mView)); Adapter initialAdapter = listView.getAdapter(); - TextView initialSecondItemView = (TextView) listView.getChildAt(1); + AppWidgetHostView child1 = (AppWidgetHostView) listView.getChildAt(1); + TextView initialSecondItemView = (TextView) child1.getChildAt(0); assertEquals(1, initialAdapter.getItemViewType(1)); items = new RemoteCollectionItems.Builder() @@ -675,9 +685,10 @@ public class RemoteViewsFixedCollectionAdapterTest { // The adapter should have been kept, and the second item should have maintained its view // type of 1 even though its now the only view type. + AppWidgetHostView child0 = (AppWidgetHostView) listView.getChildAt(0); assertEquals(2, listView.getAdapter().getViewTypeCount()); assertSame(initialAdapter, listView.getAdapter()); - assertSame(initialSecondItemView, listView.getChildAt(0)); + assertSame(initialSecondItemView, child0.getChildAt(0)); assertEquals(1, listView.getAdapter().getItemViewType(0)); } @@ -694,7 +705,8 @@ public class RemoteViewsFixedCollectionAdapterTest { runOnMainAndDrawSync(mActivityRule, listView, () -> mRemoteViews.reapply(mActivity, mView)); Adapter initialAdapter = listView.getAdapter(); - TextView initialSecondItemView = (TextView) listView.getChildAt(1); + AppWidgetHostView child1 = (AppWidgetHostView) listView.getChildAt(1); + TextView initialSecondItemView = (TextView) child1.getChildAt(0); assertEquals(1, initialAdapter.getItemViewType(1)); items = new RemoteCollectionItems.Builder() @@ -705,9 +717,10 @@ public class RemoteViewsFixedCollectionAdapterTest { // The adapter should have been kept, and kept its higher view count to allow for views to // be recycled. + AppWidgetHostView child0 = (AppWidgetHostView) listView.getChildAt(0); assertEquals(2, listView.getAdapter().getViewTypeCount()); assertSame(initialAdapter, listView.getAdapter()); - assertSame(initialSecondItemView, listView.getChildAt(0)); + assertSame(initialSecondItemView, child0.getChildAt(0)); assertEquals(1, listView.getAdapter().getItemViewType(0)); } @@ -755,10 +768,14 @@ public class RemoteViewsFixedCollectionAdapterTest { assertEquals(13, adapter.getItemId(3)); assertEquals(4, mGridView.getChildCount()); - TextView textView0 = (TextView) mGridView.getChildAt(0); - TextView textView1 = (TextView) mGridView.getChildAt(1); - TextView textView2 = (TextView) mGridView.getChildAt(2); - TextView textView3 = (TextView) mGridView.getChildAt(3); + AppWidgetHostView child0 = (AppWidgetHostView) mGridView.getChildAt(0); + AppWidgetHostView child1 = (AppWidgetHostView) mGridView.getChildAt(1); + AppWidgetHostView child2 = (AppWidgetHostView) mGridView.getChildAt(2); + AppWidgetHostView child3 = (AppWidgetHostView) mGridView.getChildAt(3); + TextView textView0 = (TextView) child0.getChildAt(0); + TextView textView1 = (TextView) child1.getChildAt(0); + TextView textView2 = (TextView) child2.getChildAt(0); + TextView textView3 = (TextView) child3.getChildAt(0); assertEquals("Hello", textView0.getText()); assertEquals("World", textView1.getText()); assertEquals("Hola", textView2.getText()); diff --git a/tests/tests/widget/src/android/widget/cts/TextViewTest.java b/tests/tests/widget/src/android/widget/cts/TextViewTest.java index bc4a2bbdcd1..66352e2f50c 100644 --- a/tests/tests/widget/src/android/widget/cts/TextViewTest.java +++ b/tests/tests/widget/src/android/widget/cts/TextViewTest.java @@ -5035,7 +5035,6 @@ public class TextViewTest { @UiThreadTest @Test public void testSetLineHeightInUnits() { - assertEquals(1f, mActivity.getResources().getConfiguration().fontScale, /* delta= */ 0.02f); mTextView = new TextView(mActivity); mTextView.setText("This is some random text"); diff --git a/tests/tests/wifi/Android.bp b/tests/tests/wifi/Android.bp index 2d2538209a7..f18b5f423fd 100644 --- a/tests/tests/wifi/Android.bp +++ b/tests/tests/wifi/Android.bp @@ -53,6 +53,8 @@ android_test { "general-tests", "mts-tethering", "mts-wifi", + "mcts-tethering", + "mcts-wifi", "sts", ], diff --git a/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java b/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java index 63bdc5c7545..ffe2080e62e 100644 --- a/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java @@ -204,6 +204,7 @@ public class WifiManagerTest extends WifiJUnit4TestBase { private static final int SCAN_TEST_WAIT_DURATION_MS = 15_000; private static final int TEST_WAIT_DURATION_MS = 10_000; private static final int WIFI_CONNECT_TIMEOUT_MILLIS = 30_000; + private static final int WIFI_OFF_ON_TIMEOUT_MILLIS = 5_000; private static final int WIFI_PNO_CONNECT_TIMEOUT_MILLIS = 90_000; private static final int WAIT_MSEC = 60; private static final int DURATION_SCREEN_TOGGLE = 2000; @@ -1149,26 +1150,32 @@ public class WifiManagerTest extends WifiJUnit4TestBase { if (!sWifiManager.isPortableHotspotSupported()) { return; } - boolean wifiEnabled = sWifiManager.isWifiEnabled(); - if (wifiEnabled) { - // Re-enabled Wi-Fi as shell for HalDeviceManager legacy LOHS behavior when there's no - // STA+AP concurrency. - ShellIdentityUtils.invokeWithShellPermissions(() -> sWifiManager.setWifiEnabled(false)); - PollingCheck.check("Wifi turn off failed!", 2_000, () -> !sWifiManager.isWifiEnabled()); - SystemUtil.runShellCommand("cmd wifi set-wifi-enabled enabled"); - PollingCheck.check("Wifi turn on failed!", 2_000, () -> sWifiManager.isWifiEnabled()); - } - TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot(); + runWithScanning(() -> { + boolean wifiEnabled = sWifiManager.isWifiEnabled(); + if (wifiEnabled) { + // Re-enabled Wi-Fi as shell for HalDeviceManager legacy LOHS behavior when there's + // no STA+AP concurrency. + ShellIdentityUtils.invokeWithShellPermissions(() -> + sWifiManager.setWifiEnabled(false)); + PollingCheck.check("Wifi turn off failed!", WIFI_OFF_ON_TIMEOUT_MILLIS, + () -> !sWifiManager.isWifiEnabled()); + SystemUtil.runShellCommand("cmd wifi set-wifi-enabled enabled"); + PollingCheck.check("Wifi turn on failed!", WIFI_OFF_ON_TIMEOUT_MILLIS, + () -> sWifiManager.isWifiEnabled()); + } + TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot(); - // add sleep to avoid calling stopLocalOnlyHotspot before TetherController initialization. - // TODO: remove this sleep as soon as b/124330089 is fixed. - Log.d(TAG, "Sleeping for 2 seconds"); - Thread.sleep(2000); + // add sleep to avoid calling stopLocalOnlyHotspot before TetherController + // initialization. + // TODO: remove this sleep as soon as b/124330089 is fixed. + Log.d(TAG, "Sleeping for 2 seconds"); + Thread.sleep(2000); - stopLocalOnlyHotspot(callback, wifiEnabled); + stopLocalOnlyHotspot(callback, wifiEnabled); - // wifi should either stay on, or come back on - assertEquals(wifiEnabled, sWifiManager.isWifiEnabled()); + // wifi should either stay on, or come back on + assertEquals(wifiEnabled, sWifiManager.isWifiEnabled()); + }, false); } /** @@ -1928,46 +1935,52 @@ public class WifiManagerTest extends WifiJUnit4TestBase { // check that softap mode is supported by the device assumeTrue(sWifiManager.isPortableHotspotSupported()); - boolean caughtException = false; + runWithScanning(() -> { + boolean caughtException = false; + boolean wifiEnabled = sWifiManager.isWifiEnabled(); + if (wifiEnabled) { + // Re-enabled Wi-Fi as shell for HalDeviceManager legacy LOHS behavior when there's + // no STA+AP concurrency. + ShellIdentityUtils.invokeWithShellPermissions(() -> + sWifiManager.setWifiEnabled(false)); + PollingCheck.check("Wifi turn off failed!", WIFI_OFF_ON_TIMEOUT_MILLIS, + () -> !sWifiManager.isWifiEnabled()); + SystemUtil.runShellCommand("cmd wifi set-wifi-enabled enabled"); + PollingCheck.check("Wifi turn on failed!", WIFI_OFF_ON_TIMEOUT_MILLIS, + () -> sWifiManager.isWifiEnabled()); + } + + TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot(); - boolean wifiEnabled = sWifiManager.isWifiEnabled(); - if (wifiEnabled) { - // Re-enabled Wi-Fi as shell for HalDeviceManager legacy LOHS behavior when there's no - // STA+AP concurrency. - ShellIdentityUtils.invokeWithShellPermissions(() -> sWifiManager.setWifiEnabled(false)); - PollingCheck.check("Wifi turn off failed!", 2_000, () -> !sWifiManager.isWifiEnabled()); - SystemUtil.runShellCommand("cmd wifi set-wifi-enabled enabled"); - PollingCheck.check("Wifi turn on failed!", 2_000, () -> sWifiManager.isWifiEnabled()); - } + // now make a second request - this should fail. + TestLocalOnlyHotspotCallback callback2 = new TestLocalOnlyHotspotCallback(mLock); + try { + sWifiManager.startLocalOnlyHotspot(callback2, null); + } catch (IllegalStateException e) { + Log.d(TAG, "Caught the IllegalStateException we expected: called startLOHS twice"); + caughtException = true; + } + if (!caughtException) { + // second start did not fail, should clean up the hotspot. - TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot(); + // add sleep to avoid calling stopLocalOnlyHotspot before TetherController + // initialization. + // TODO: remove this sleep as soon as b/124330089 is fixed. + Log.d(TAG, "Sleeping for 2 seconds"); + Thread.sleep(2000); - // now make a second request - this should fail. - TestLocalOnlyHotspotCallback callback2 = new TestLocalOnlyHotspotCallback(mLock); - try { - sWifiManager.startLocalOnlyHotspot(callback2, null); - } catch (IllegalStateException e) { - Log.d(TAG, "Caught the IllegalStateException we expected: called startLOHS twice"); - caughtException = true; - } - if (!caughtException) { - // second start did not fail, should clean up the hotspot. + stopLocalOnlyHotspot(callback2, wifiEnabled); + } + assertTrue(caughtException); - // add sleep to avoid calling stopLocalOnlyHotspot before TetherController initialization. + // add sleep to avoid calling stopLocalOnlyHotspot before TetherController + // initialization. // TODO: remove this sleep as soon as b/124330089 is fixed. Log.d(TAG, "Sleeping for 2 seconds"); Thread.sleep(2000); - stopLocalOnlyHotspot(callback2, wifiEnabled); - } - assertTrue(caughtException); - - // add sleep to avoid calling stopLocalOnlyHotspot before TetherController initialization. - // TODO: remove this sleep as soon as b/124330089 is fixed. - Log.d(TAG, "Sleeping for 2 seconds"); - Thread.sleep(2000); - - stopLocalOnlyHotspot(callback, wifiEnabled); + stopLocalOnlyHotspot(callback, wifiEnabled); + }, false); } private static class TestExecutor implements Executor { @@ -2914,7 +2927,8 @@ public class WifiManagerTest extends WifiJUnit4TestBase { return; } runWithScanning(() -> { - UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); + UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation() + .getUiAutomation(); TestExecutor executor = new TestExecutor(); TestSoftApCallback callback = new TestSoftApCallback(mLock); try { @@ -2978,7 +2992,8 @@ public class WifiManagerTest extends WifiJUnit4TestBase { return; } runWithScanning(() -> { - UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); + UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation() + .getUiAutomation(); TestExecutor executor = new TestExecutor(); TestSoftApCallback callback = new TestSoftApCallback(mLock); try { @@ -3007,7 +3022,8 @@ public class WifiManagerTest extends WifiJUnit4TestBase { .getSupportedChannelList(SoftApConfiguration.BAND_5GHZ)[0]); SoftApConfiguration testSoftApConfig = generateSoftApConfigBuilderWithSsid(TEST_SSID_UNQUOTED) - .setPassphrase(TEST_PASSPHRASE, SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) + .setPassphrase(TEST_PASSPHRASE, + SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) .setChannels(dual_channels) .build(); @@ -3666,29 +3682,32 @@ public class WifiManagerTest extends WifiJUnit4TestBase { // check that softap mode is supported by the device assumeTrue(sWifiManager.isPortableHotspotSupported()); - // Re-enabled Wi-Fi as shell for HalDeviceManager legacy LOHS behavior when there's no - // STA+AP concurrency. - ShellIdentityUtils.invokeWithShellPermissions(() -> sWifiManager.setWifiEnabled(false)); - PollingCheck.check("Wifi turn off failed!", 2_000, () -> !sWifiManager.isWifiEnabled()); - SystemUtil.runShellCommand("cmd wifi set-wifi-enabled enabled"); - PollingCheck.check("Wifi turn on failed!", 2_000, () -> sWifiManager.isWifiEnabled()); + runWithScanning(() -> { + // Re-enabled Wi-Fi as shell for HalDeviceManager legacy LOHS behavior when there's no + // STA+AP concurrency. + ShellIdentityUtils.invokeWithShellPermissions(() -> sWifiManager.setWifiEnabled(false)); + PollingCheck.check("Wifi turn off failed!", 2_000, () -> !sWifiManager.isWifiEnabled()); + SystemUtil.runShellCommand("cmd wifi set-wifi-enabled enabled"); + PollingCheck.check("Wifi turn on failed!", WIFI_OFF_ON_TIMEOUT_MILLIS, + () -> sWifiManager.isWifiEnabled()); - boolean isStaApConcurrencySupported = sWifiManager.isStaApConcurrencySupported(); - // start local only hotspot. - TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot(); - try { - if (isStaApConcurrencySupported) { - assertTrue(sWifiManager.isWifiEnabled()); - } else { - // no concurrency, wifi should be disabled. - assertFalse(sWifiManager.isWifiEnabled()); + boolean isStaApConcurrencySupported = sWifiManager.isStaApConcurrencySupported(); + // start local only hotspot. + TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot(); + try { + if (isStaApConcurrencySupported) { + assertTrue(sWifiManager.isWifiEnabled()); + } else { + // no concurrency, wifi should be disabled. + assertFalse(sWifiManager.isWifiEnabled()); + } + } finally { + // clean up local only hotspot no matter if assertion passed or failed + stopLocalOnlyHotspot(callback, true); } - } finally { - // clean up local only hotspot no matter if assertion passed or failed - stopLocalOnlyHotspot(callback, true); - } - assertTrue(sWifiManager.isWifiEnabled()); + assertTrue(sWifiManager.isWifiEnabled()); + }, false); } /** @@ -3777,7 +3796,7 @@ public class WifiManagerTest extends WifiJUnit4TestBase { boolean newState = !currState; sWifiManager.setScanAlwaysAvailable(newState); PollingCheck.check( - "Wifi settings toggle failed!", + "Wifi scanning toggle failed!", DURATION_SETTINGS_TOGGLE, () -> sWifiManager.isScanAlwaysAvailable() == newState); assertEquals(newState, sWifiManager.isScanAlwaysAvailable()); @@ -5168,43 +5187,63 @@ public class WifiManagerTest extends WifiJUnit4TestBase { // These below API's only work with privileged permissions (obtained via shell identity // for test) UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); - List<CoexUnsafeChannel> prevUnsafeChannels = null; + List<CoexUnsafeChannel> prevUnsafeChannels = new ArrayList<>(); int prevRestrictions = -1; try { uiAutomation.adoptShellPermissionIdentity(); - final TestCoexCallback callback = new TestCoexCallback(mLock); - final List<CoexUnsafeChannel> testUnsafeChannels = new ArrayList<>(); - testUnsafeChannels.add(new CoexUnsafeChannel(WIFI_BAND_24_GHZ, 6)); - final int testRestrictions = COEX_RESTRICTION_WIFI_DIRECT - | COEX_RESTRICTION_SOFTAP | COEX_RESTRICTION_WIFI_AWARE; synchronized (mLock) { try { + boolean defaultAlgoEnabled = false; + final TestCoexCallback callback = new TestCoexCallback(mLock); sWifiManager.registerCoexCallback(mExecutor, callback); + // Callback should be called after registering mLock.wait(TEST_WAIT_DURATION_MS); assertEquals(1, callback.getOnCoexUnsafeChannelChangedCount()); - // Store the previous coex channels and set new coex channels + + // Store the previous coex channels and try setting new coex channels 5 times. + // + // If the default algorithm is disabled, we'll get exactly 5 callbacks, and we + // can verify that the update channels match what we inputted. + // + // If the default algorithm is enabled, then the callbacks will trigger + // according to the algorithm, which may or may not trigger during the test. + // Thus we try 5 times and see if the callbacks match the number of tries, since + // it's highly unlikely that the default algorithm will update the channels + // exactly 5 times during the test. prevUnsafeChannels = callback.getCoexUnsafeChannels(); prevRestrictions = callback.getCoexRestrictions(); - sWifiManager.setCoexUnsafeChannels(testUnsafeChannels, testRestrictions); - mLock.wait(TEST_WAIT_DURATION_MS); - // Unregister callback and try setting again - sWifiManager.unregisterCoexCallback(callback); - sWifiManager.setCoexUnsafeChannels(testUnsafeChannels, testRestrictions); - // Callback should not be called here since it was unregistered. - mLock.wait(TEST_WAIT_DURATION_MS); + List<CoexUnsafeChannel> testChannels = null; + final int testRestrictions = COEX_RESTRICTION_WIFI_DIRECT + | COEX_RESTRICTION_SOFTAP | COEX_RESTRICTION_WIFI_AWARE; + for (int i = 0; i < 5; i++) { + testChannels = List.of(new CoexUnsafeChannel(WIFI_BAND_24_GHZ, 1 + i)); + sWifiManager.setCoexUnsafeChannels(testChannels, testRestrictions); + mLock.wait(TEST_WAIT_DURATION_MS); + if (callback.getOnCoexUnsafeChannelChangedCount() != i + 2) { + defaultAlgoEnabled = true; + break; + } + } + + if (!defaultAlgoEnabled) { + int currentCallbackCount = callback.getOnCoexUnsafeChannelChangedCount(); + assertEquals(testChannels, callback.getCoexUnsafeChannels()); + assertEquals(testRestrictions, callback.getCoexRestrictions()); + // Unregister callback and try setting again + sWifiManager.unregisterCoexCallback(callback); + sWifiManager.setCoexUnsafeChannels( + List.of(new CoexUnsafeChannel(WIFI_BAND_24_GHZ, 11)), + testRestrictions); + mLock.wait(TEST_WAIT_DURATION_MS); + // Callback should not be called here since it was unregistered. + assertThat(callback.getOnCoexUnsafeChannelChangedCount()) + .isEqualTo(currentCallbackCount); + } } catch (InterruptedException e) { fail("Thread interrupted unexpectedly while waiting on mLock"); } } - if (callback.getOnCoexUnsafeChannelChangedCount() == 2) { - // Default algorithm disabled, setter should set the getter values. - assertEquals(testUnsafeChannels, callback.getCoexUnsafeChannels()); - assertEquals(testRestrictions, callback.getCoexRestrictions()); - } else if (callback.getOnCoexUnsafeChannelChangedCount() != 1) { - fail("Coex callback called " + callback.mOnCoexUnsafeChannelChangedCount - + " times. Expected 0 or 1 calls." ); - } } finally { // Reset the previous unsafe channels if we overrode them. if (prevRestrictions != -1) { diff --git a/tools/cts-dynamic-config/Android.bp b/tools/cts-dynamic-config/Android.bp index 61f9e54ed17..c4cd2bd4b04 100644 --- a/tools/cts-dynamic-config/Android.bp +++ b/tools/cts-dynamic-config/Android.bp @@ -34,6 +34,7 @@ java_test_host { "cts", "general-tests", "mts-media", + "mcts-media", ], java_resources: [ ":cts-dynamic-config.dynamic", diff --git a/tools/cts-media-preparer-app/Android.bp b/tools/cts-media-preparer-app/Android.bp index 7fe2a66ad1e..3412c17f13b 100644 --- a/tools/cts-media-preparer-app/Android.bp +++ b/tools/cts-media-preparer-app/Android.bp @@ -35,6 +35,7 @@ android_test { "cts", "general-tests", "mts-media", + "mcts-media", ], sdk_version: "test_current", min_sdk_version: "29", diff --git a/tools/cts-tradefed/res/config/cts-known-failures.xml b/tools/cts-tradefed/res/config/cts-known-failures.xml index 5b881fd4119..52c1f879dd3 100644 --- a/tools/cts-tradefed/res/config/cts-known-failures.xml +++ b/tools/cts-tradefed/res/config/cts-known-failures.xml @@ -329,4 +329,21 @@ <!-- b/307489638 --> <option name="compatibility:exclude-filter" value="CtsTelephonyTestCases android.telephony.satellite.cts.SatelliteManagerTestOnMockService" /> + + <!-- b/312075535 --> + <option name="compatibility:exclude-filter" value="CtsAdServicesTopicsAppUpdateTests com.android.adservices.tests.cts.topics.appupdate.AppUpdateTest#testAppUpdate" /> + + <!-- b/305609163 --> + <option name="compatibility:exclude-filter" value="CtsSandboxedTopicsManagerTests com.android.tests.sandbox.topics.SandboxedTopicsManagerTest#loadSdkAndRunTopicsApi" /> + + <!-- b/310063797 --> + <option name="compatibility:exclude-filter" value="CtsAdServicesPermissionsNoPermEndToEndTests com.android.adservices.tests.permissions.PermissionsNoPermTest#testPermissionNotRequested_fledgeRemoveCustomAudienceRemoteInfoOverride" /> + <option name="compatibility:exclude-filter" value="CtsAdServicesPermissionsNoPermEndToEndTests com.android.adservices.tests.permissions.PermissionsNoPermTest#testPermissionNotRequested_fledgeResetAllAdSelectionConfigRemoteOverrides" /> + <option name="compatibility:exclude-filter" value="CtsAdServicesPermissionsNoPermEndToEndTests com.android.adservices.tests.permissions.PermissionsNoPermTest#testPermissionNotRequested_fledgeRemoveAdSelectionConfigRemoteInfo" /> + <option name="compatibility:exclude-filter" value="CtsAdServicesPermissionsNoPermEndToEndTests com.android.adservices.tests.permissions.PermissionsNoPermTest#testPermissionNotRequested_fledgeOverrideCustomAudienceRemoteInfo" /> + <option name="compatibility:exclude-filter" value="CtsAdServicesPermissionsNoPermEndToEndTests com.android.adservices.tests.permissions.PermissionsNoPermTest#testPermissionNotRequested_fledgeResetAllCustomAudienceOverrides" /> + <option name="compatibility:exclude-filter" value="CtsAdServicesPermissionsNoPermEndToEndTests com.android.adservices.tests.permissions.PermissionsNoPermTest#testPermissionNotRequested_fledgeOverrideAdSelectionConfigRemoteInfo" /> + + <!-- b/301216478 --> + <option name="compatibility:exclude-filter" value="CtsSandboxedFledgeManagerTests com.android.tests.sandbox.fledge.SandboxedFledgeManagerTest#loadSdkAndRunFledgeFlow" /> </configuration> diff --git a/tools/cts-tradefed/res/config/cts-on-gsi-on-r.xml b/tools/cts-tradefed/res/config/cts-on-gsi-on-r.xml index 64143b07ac9..d8e749bcc05 100644 --- a/tools/cts-tradefed/res/config/cts-on-gsi-on-r.xml +++ b/tools/cts-tradefed/res/config/cts-on-gsi-on-r.xml @@ -77,4 +77,13 @@ <!-- CtsSecurityHostTestCases: b/256140333 --> <option name="compatibility:exclude-filter" value="CtsSecurityHostTestCases android.security.cts.FileSystemPermissionTest" /> + + <!-- CtsMediaV2TestCases: b/298410971 --> + <option name="compatibility:exclude-filter" value="CtsMediaV2TestCases android.mediav2.cts.EncoderProfileLevelTest#testValidateProfileLevel" /> + + <!-- CtsMediaCodecTestCases: b/298483255 --> + <option name="compatibility:exclude-filter" value="CtsMediaCodecTestCases android.media.codec.cts.MediaCodecInstancesTest#testGetMaxSupportedInstances" /> + + <!-- CtsVideoCodecTestCases: b/302293100 --> + <option name="compatibility:exclude-filter" value="CtsVideoCodecTestCases android.videocodec.cts.VideoEncoderMultiResTest#testMultiRes" /> </configuration> diff --git a/tools/cts-tradefed/res/config/cts-on-gsi-on-s.xml b/tools/cts-tradefed/res/config/cts-on-gsi-on-s.xml index df3b5483846..3a115652a09 100644 --- a/tools/cts-tradefed/res/config/cts-on-gsi-on-s.xml +++ b/tools/cts-tradefed/res/config/cts-on-gsi-on-s.xml @@ -72,4 +72,7 @@ <!-- CtsMediaDecoderTestCases: b/284409693 --> <option name="compatibility:exclude-filter" value="CtsMediaDecoderTestCases android.media.decoder.cts.VideoDecoderPerfTest" /> + <!-- CtsMediaV2TestCases: b/298410971 --> + <option name="compatibility:exclude-filter" value="CtsMediaV2TestCases android.mediav2.cts.EncoderProfileLevelTest#testValidateProfileLevel" /> + </configuration> diff --git a/tools/cts-tradefed/res/config/cts-on-gsi-on-t.xml b/tools/cts-tradefed/res/config/cts-on-gsi-on-t.xml index 5f7ff35240e..702609e860a 100644 --- a/tools/cts-tradefed/res/config/cts-on-gsi-on-t.xml +++ b/tools/cts-tradefed/res/config/cts-on-gsi-on-t.xml @@ -51,6 +51,9 @@ <option name="compatibility:exclude-filter" value="CtsMediaMiscTestCases android.media.misc.cts.ResourceManagerTest#testAVCVideoCodecReclaimHighResolution" /> <option name="compatibility:exclude-filter" value="CtsMediaMiscTestCases android.media.misc.cts.ResourceManagerTest#testHEVCVideoCodecReclaimHighResolution" /> + <!-- CtsMediaV2TestCases: b/298410971 --> + <option name="compatibility:exclude-filter" value="CtsMediaV2TestCases android.mediav2.cts.EncoderProfileLevelTest#testValidateProfileLevel" /> + <!-- CtsVideoCodecTestCases: b/288527955 --> <option name="compatibility:exclude-filter" value="CtsVideoCodecTestCases android.videocodec.cts.VideoEncoderMinMaxTest" /> |