diff options
66 files changed, 841 insertions, 475 deletions
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml index 7f230be42d1..0f53eb0e84d 100644 --- a/apps/CtsVerifier/AndroidManifest.xml +++ b/apps/CtsVerifier/AndroidManifest.xml @@ -2977,6 +2977,7 @@ <activity android:name=".camera.fov.PhotoCaptureActivity" + android:configChanges="orientation|screenSize" android:label="@string/camera_fov_calibration" android:exported="true" android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen" > @@ -3334,6 +3335,8 @@ <meta-data android:name="display_mode" android:value="multi_display_mode" /> <meta-data android:name="CddTest" android:value="3.8.3/H-0-4" /> + <meta-data android:name="test_excluded_features" + android:value="android.hardware.type.watch" /> </activity> <activity android:name=".notifications.NotificationFullScreenIntentVerifierActivity" @@ -3350,6 +3353,8 @@ <meta-data android:name="ApiTest" android:value="android.app.Notification.Builder#setFullScreenIntent| android.app.NotificationManager#notify" /> + <meta-data android:name="test_excluded_features" + android:value="android.hardware.type.watch" /> </activity> <activity android:name=".notifications.NotificationListenerVerifierActivity" diff --git a/apps/CtsVerifier/res/layout-watch/audio_headset_audio_activity.xml b/apps/CtsVerifier/res/layout-watch/audio_headset_audio_activity.xml deleted file mode 100644 index 39c9819167a..00000000000 --- a/apps/CtsVerifier/res/layout-watch/audio_headset_audio_activity.xml +++ /dev/null @@ -1,173 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2022 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<ScrollView - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:id="@+id/scrollView" - android:padding="29dp"> - - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical"> - - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical"> - - <!-- Has Headset Buttons --> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical"> - <TextView - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:text="@string/analog_headset_query" - android:id="@+id/analog_headset_query"/> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" > - <Button - android:id="@+id/headset_analog_port_yes" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_weight="0.5" - android:text="@string/audio_general_yes" /> - <Button - android:text="@string/audio_general_no" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_weight="0.5" - android:id="@+id/headset_analog_port_no"/> - </LinearLayout> - </LinearLayout> - - <!-- Device Connection --> - <TextView - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:id="@+id/headset_analog_plug_message"/> - <TextView - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:id="@+id/headset_analog_device_type"/> - <TextView - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:id="@+id/headset_analog_name"/> - - <!-- Player Controls --> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" > - <Button - android:text="@string/analog_headset_play" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_weight="0.5" - android:id="@+id/headset_analog_play"/> - <Button - android:text="@string/analog_headset_stop" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_weight="0.5" - android:id="@+id/headset_analog_stop"/> - </LinearLayout> - </LinearLayout> - - <!-- Playback Status --> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical"> - - <TextView - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:id="@+id/analog_headset_playback_status"/> - - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" > - <Button - android:text="@string/audio_general_yes" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_weight="0.5" - android:id="@+id/headset_analog_play_yes"/> - <Button - android:text="@string/audio_general_no" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_weight="0.5" - android:id="@+id/headset_analog_play_no"/> - </LinearLayout> - </LinearLayout> - - <!-- Keycodes --> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical"> - <TextView - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:id="@+id/analog_headset_keycodes_prompt"/> - <TextView - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:text="@string/analog_headset_keycodes_label" - android:id="@+id/headset_keycodes"/> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical" > - <TextView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/analog_headset_headsethook" - android:id="@+id/headset_keycode_headsethook"/> - <TextView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/analog_headset_volup" - android:id="@+id/headset_keycode_volume_up"/> - <TextView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/analog_headset_voldown" - android:id="@+id/headset_keycode_volume_down"/> - </LinearLayout> - </LinearLayout> - - <!-- Results --> - <TextView - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:id="@+id/headset_results" - android:textSize="20sp"/> - - <include layout="@layout/pass_fail_buttons" /> - - </LinearLayout> -</ScrollView> diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/ManifestTestListAdapter.java b/apps/CtsVerifier/src/com/android/cts/verifier/ManifestTestListAdapter.java index e0c94ae4562..869b92219d9 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/ManifestTestListAdapter.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/ManifestTestListAdapter.java @@ -687,6 +687,8 @@ public class ManifestTestListAdapter extends TestListAdapter { if (test.applicableFeatures == null || hasAnyFeature(test.applicableFeatures)) { // Add suffix in test name if the test is in the folded mode. test.testName = setTestNameSuffix(mode, test.testName); + // Remove suffix in test name if the test is in the unfolded mode. + test.testName = removeTestNameSuffix(mode, test.testName); filteredTests.add(test); } else { Log.d(LOG_TAG, "Skipping " + test.testName + " due to metadata filtering"); diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/fov/PhotoCaptureActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/fov/PhotoCaptureActivity.java index e27ae0a0f11..2259c3d6940 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/fov/PhotoCaptureActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/fov/PhotoCaptureActivity.java @@ -22,6 +22,7 @@ import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.content.res.Configuration; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.SurfaceTexture; @@ -271,6 +272,12 @@ public class PhotoCaptureActivity extends Activity } @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + this.recreate(); + } + + @Override public void onPictureTaken(byte[] data, Camera camera) { File pictureFile = getPictureFile(this); 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 b6abc3cd39d..3def4b07543 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/security/FingerprintBoundKeysTest.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/security/FingerprintBoundKeysTest.java @@ -346,7 +346,7 @@ public class FingerprintBoundKeysTest extends PassFailButtons.Activity { boolean tokenExpired = false; long startTime = System.currentTimeMillis(); while (((System.currentTimeMillis() - startTime) - < (AUTHENTICATION_DURATION_SECONDS * 1000)) + < ((AUTHENTICATION_DURATION_SECONDS + 1) * 1000)) && (!tokenExpired)) { try { Thread.sleep(1000); diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/BaseTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/BaseTestActivity.java index be7d9e30bc1..8c30ef11d90 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/BaseTestActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/BaseTestActivity.java @@ -17,6 +17,7 @@ package com.android.cts.verifier.wifi; import android.content.Context; +import android.content.pm.PackageManager; import android.os.Bundle; import android.os.Handler; import android.text.Editable; @@ -110,10 +111,18 @@ public abstract class BaseTestActivity extends PassFailButtons.Activity implemen getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } + private boolean isWear() { + return getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH); + } + + + @Override protected void onDestroy() { - mTestCase.stop(); - mWifiProgress.setVisibility(View.GONE); + if (!isWear()) { + mTestCase.stop(); + mWifiProgress.setVisibility(View.GONE); + } super.onDestroy(); } diff --git a/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesPreInstallOverrideTest.java b/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesPreInstallOverrideTest.java index e3d3d80baa0..7e857953367 100644 --- a/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesPreInstallOverrideTest.java +++ b/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesPreInstallOverrideTest.java @@ -31,6 +31,8 @@ public final class CompatChangesPreInstallOverrideTest extends CompatChangeGatin private static final String CTS_CHANGE_ID_NAME = "CTS_SYSTEM_API_CHANGEID"; private static final long CTS_CHANGE_ID = 149391281L; + private static final int WAIT_TIME_MS = 1_000; + @Override protected void setUp() throws Exception { uninstallPackage(TEST_PACKAGE, false); @@ -130,6 +132,9 @@ public final class CompatChangesPreInstallOverrideTest extends CompatChangeGatin } private Change getCtsChange() throws Exception { + // Data put by device_config app_compat_overrides need some time to update the data + // for dumpsys platform_compat so adding some sleep time + Thread.sleep(WAIT_TIME_MS); return getOnDeviceChangeIdConfig(CTS_CHANGE_ID); } } 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 3fbe4801d03..3b8a313adc6 100644 --- a/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesValidConfigTest.java +++ b/hostsidetests/appcompat/compatchanges/src/com/android/cts/appcompat/CompatChangesValidConfigTest.java @@ -91,6 +91,7 @@ public final class CompatChangesValidConfigTest extends CompatChangeGatingTestCa "OVERRIDE_MIN_ASPECT_RATIO_PORTRAIT_ONLY", "OVERRIDE_MIN_ASPECT_RATIO_LARGE", "OVERRIDE_MIN_ASPECT_RATIO_MEDIUM", + "OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA", "OVERRIDE_MIN_ASPECT_RATIO_TO_ALIGN_WITH_SPLIT_SCREEN", "IMPLICIT_INTENTS_ONLY_MATCH_EXPORTED_COMPONENTS", "BLOCK_MUTABLE_IMPLICIT_PENDING_INTENT", @@ -102,6 +103,7 @@ public final class CompatChangesValidConfigTest extends CompatChangeGatingTestCa "OVERRIDE_ANY_ORIENTATION_TO_USER", "OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION", "OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION", + "OVERRIDE_LAYOUT_IN_DISPLAY_CUTOUT_MODE", "OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA", "OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION", "OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH", diff --git a/hostsidetests/jvmti/base/host/src/android/jvmti/cts/JvmtiHostTest.java b/hostsidetests/jvmti/base/host/src/android/jvmti/cts/JvmtiHostTest.java index cecb6ed547a..881ab719a0d 100644 --- a/hostsidetests/jvmti/base/host/src/android/jvmti/cts/JvmtiHostTest.java +++ b/hostsidetests/jvmti/base/host/src/android/jvmti/cts/JvmtiHostTest.java @@ -128,7 +128,7 @@ public class JvmtiHostTest extends DeviceTestCase implements IBuildReceiver, IAb RemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(mTestPackageName, RUNNER, device.getIDevice()); // set a max deadline limit to avoid hanging forever - runner.setMaxTimeToOutputResponse(5, TimeUnit.MINUTES); + runner.setMaxTimeToOutputResponse(10, TimeUnit.MINUTES); AttachAgent aa = new AttachAgent(device, mTestPackageName, mTestApk); aa.prepare(); diff --git a/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/preferred/PreferredActivitiesTest.java b/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/preferred/PreferredActivitiesTest.java index dcdfdd010d0..f8120732325 100644 --- a/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/preferred/PreferredActivitiesTest.java +++ b/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/preferred/PreferredActivitiesTest.java @@ -37,6 +37,7 @@ import android.dynamicmime.testapp.BaseDynamicMimeTest; import android.dynamicmime.testapp.assertions.MimeGroupAssertions; import android.dynamicmime.testapp.commands.MimeGroupCommands; import android.dynamicmime.testapp.util.Utils; +import android.os.SystemClock; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.uiautomator.By; @@ -376,6 +377,7 @@ public class PreferredActivitiesTest extends BaseDynamicMimeTest { if (scrollable.exists()) { scrollable.scrollToBeginning(Integer.MAX_VALUE); scrollable.scrollIntoView(selector); + SystemClock.sleep(1000L); } } catch (UiObjectNotFoundException ignore) { throw new AssertionError("Scrollable view was lost."); diff --git a/hostsidetests/statsdatom/src/android/cts/statsdatom/users/UserInfoStatsTests.java b/hostsidetests/statsdatom/src/android/cts/statsdatom/users/UserInfoStatsTests.java index 6e584d44b49..85a2a7cafe3 100644 --- a/hostsidetests/statsdatom/src/android/cts/statsdatom/users/UserInfoStatsTests.java +++ b/hostsidetests/statsdatom/src/android/cts/statsdatom/users/UserInfoStatsTests.java @@ -39,6 +39,7 @@ public class UserInfoStatsTests extends DeviceTestCase implements IBuildReceiver public static final int ATOM_ID = 10152; protected IBuildInfo mCtsBuild; protected List<Integer> mUsersToRemove = new ArrayList(); + private int mInitialUser = 0; @Override protected void setUp() throws Exception { @@ -47,11 +48,12 @@ public class UserInfoStatsTests extends DeviceTestCase implements IBuildReceiver ConfigUtils.removeConfig(getDevice()); ReportUtils.clearReports(getDevice()); RunUtil.getDefault().sleep(WAIT_TIME_LONG); + mInitialUser = getDevice().getCurrentUser(); } @Override protected void tearDown() throws Exception { - getDevice().switchUser(0); + getDevice().switchUser(mInitialUser); for (Integer userId : mUsersToRemove) { getDevice().removeUser(userId); } diff --git a/hostsidetests/statsdatom/src/android/cts/statsdatom/users/UserStatsTests.java b/hostsidetests/statsdatom/src/android/cts/statsdatom/users/UserStatsTests.java index 28b1c067283..004f9bafe30 100644 --- a/hostsidetests/statsdatom/src/android/cts/statsdatom/users/UserStatsTests.java +++ b/hostsidetests/statsdatom/src/android/cts/statsdatom/users/UserStatsTests.java @@ -36,6 +36,7 @@ public abstract class UserStatsTests<T> extends DeviceTestCase implements IBuild protected IBuildInfo mCtsBuild; protected List<Integer> mUsersToRemove = new ArrayList(); protected int mAtomId; + private int mInitialUser = 0; public UserStatsTests(int atomId) { mAtomId = atomId; @@ -49,11 +50,12 @@ public abstract class UserStatsTests<T> extends DeviceTestCase implements IBuild ReportUtils.clearReports(getDevice()); RunUtil.getDefault().sleep(WAIT_TIME_LONG); getDevice().executeShellCommand("adb logcat -c"); + mInitialUser = getDevice().getCurrentUser(); } @Override protected void tearDown() throws Exception { - getDevice().switchUser(0); + getDevice().switchUser(mInitialUser); for (Integer userId : mUsersToRemove) { getDevice().removeUser(userId); } diff --git a/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java b/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java index 650370e3588..83cd6eed724 100644 --- a/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java +++ b/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java @@ -1401,9 +1401,9 @@ public class BlobStoreManagerTest { final long startTimeMs = System.currentTimeMillis(); final long blobId = commitBlob(blobData); assertThat(runShellCmd("cmd blob_store query-blob-existence -b " + blobId)).isEqualTo("1"); - final long commitDurationMs = System.currentTimeMillis() - startTimeMs; - SystemClock.sleep(Math.abs(expiryDurationMs - commitDurationMs)); + // Wait for the blob to expire + SystemClock.sleep(expiryDurationMs); assertThrows(SecurityException.class, () -> mBlobStoreManager.openBlob(blobData.getBlobHandle())); diff --git a/tests/accessibilityservice/AndroidManifest.xml b/tests/accessibilityservice/AndroidManifest.xml index 550c8e7d437..d3cb766b5b2 100644 --- a/tests/accessibilityservice/AndroidManifest.xml +++ b/tests/accessibilityservice/AndroidManifest.xml @@ -77,6 +77,7 @@ <activity android:label="@string/non_proxy_activity" android:name=".activities.NonProxyActivity" + android:windowSoftInputMode="stateHidden" android:screenOrientation="locked"/> <activity android:label="Full screen activity for gesture dispatch testing" @@ -89,6 +90,7 @@ <activity android:label="@string/accessibility_embedded_hierarchy_test_activity" android:name=".AccessibilityEmbeddedHierarchyTest$AccessibilityEmbeddedHierarchyActivity" + android:windowSoftInputMode="stateHidden" android:screenOrientation="locked"/> <activity android:label="@string/accessibility_drag_and_drop_test_activity" diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java index f737f88acb7..98641f20eb5 100644 --- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java +++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java @@ -28,6 +28,7 @@ import static android.accessibilityservice.cts.utils.ActivityLaunchUtils.findWin import static android.accessibilityservice.cts.utils.ActivityLaunchUtils.getActivityTitle; import static android.accessibilityservice.cts.utils.ActivityLaunchUtils.launchActivityAndWaitForItToBeOnscreen; import static android.accessibilityservice.cts.utils.AsyncUtils.DEFAULT_TIMEOUT_MS; +import static android.accessibilityservice.cts.utils.CtsTestUtils.isAutomotive; import static android.accessibilityservice.cts.utils.RunOnMainUtils.getOnMain; import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED; import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_CLICKED; @@ -44,6 +45,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static org.junit.Assume.assumeFalse; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; @@ -504,11 +506,8 @@ public class AccessibilityEndToEndTest extends StsExtraBusinessLogicTestCase { " - Watches have different notification system."); return; } - if (pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) { - Log.i(LOG_TAG, "Skipping: testTypeNotificationStateChangedAccessibilityEvent" + - " - Automotive handle notifications differently."); - return; - } + assumeFalse("Skipping - Automotive handle notifications differently.", + isAutomotive(sInstrumentation.getTargetContext())); String message = mActivity.getString(R.string.notification_message); @@ -1597,6 +1596,12 @@ public class AccessibilityEndToEndTest extends StsExtraBusinessLogicTestCase { @ApiTest(apis = { "android.view.accessibility.AccessibilityNodeInfo#setQueryFromAppProcessEnabled"}) public void testDirectAccessibilityConnection_UsesCurrentWindowSpec() throws Throwable { + if (isAutomotive(sInstrumentation.getTargetContext())) { + Log.i(LOG_TAG, "Skipping: testDirectAccessibilityConnection_UsesCurrentWindowSpec" + + " - Automotive does not support magnification."); + return; + } + // Store the initial bounds of the ANI. final View layoutView = mActivity.findViewById(R.id.buttonLayout); final AccessibilityNodeInfo layoutNode = layoutView.createAccessibilityNodeInfo(); @@ -1660,6 +1665,7 @@ public class AccessibilityEndToEndTest extends StsExtraBusinessLogicTestCase { @AsbSecurityTest(cveBugId = {243378132}) @Test public void testUninstallPackage_DisablesMultipleServices() throws Exception { + AccessibilityManager manager = mActivity.getSystemService(AccessibilityManager.class); final String apkPath = "/data/local/tmp/cts/content/CtsAccessibilityMultipleServicesApp.apk"; final String packageName = "foo.bar.multipleservices"; @@ -1674,15 +1680,21 @@ public class AccessibilityEndToEndTest extends StsExtraBusinessLogicTestCase { // Install the apk in this test method, instead of as part of the target preparer, to // allow repeated --iterations of the test. assertThat(ShellUtils.runShellCommand("pm install " + apkPath)).startsWith("Success"); + TestUtils.waitUntil( + "Failed to install services from " + apkPath, + (int) TIMEOUT_SERVICE_ENABLE / 1000, + () -> + manager.getInstalledAccessibilityServiceList().stream() + .filter(info -> info.getId().startsWith(packageName)) + .count() + == 2); // Enable the two services and wait until AccessibilityManager reports them as enabled. - final String servicesToEnable = getEnabledServicesSetting() + componentNameSeparator - + service1.flattenToShortString() + componentNameSeparator - + service2.flattenToShortString(); + final String servicesToEnable = service1.flattenToShortString() + + componentNameSeparator + service2.flattenToShortString(); ShellCommandBuilder.create(sInstrumentation) .putSecureSetting(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, servicesToEnable) - .putSecureSetting(Settings.Secure.ACCESSIBILITY_ENABLED, "1") .run(); TestUtils.waitUntil("Failed to enable 2 services from package " + packageName, (int) TIMEOUT_SERVICE_ENABLE / 1000, diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java index 6925f13b321..dcc72584a83 100644 --- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java +++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java @@ -18,6 +18,7 @@ import static android.accessibility.cts.common.InstrumentedAccessibilityService. import static android.accessibilityservice.cts.utils.ActivityLaunchUtils.launchActivityAndWaitForItToBeOnscreen; import static android.accessibilityservice.cts.utils.AsyncUtils.await; import static android.accessibilityservice.cts.utils.AsyncUtils.awaitCancellation; +import static android.accessibilityservice.cts.utils.CtsTestUtils.isAutomotive; import static android.accessibilityservice.cts.utils.GestureUtils.IS_ACTION_CANCEL; import static android.accessibilityservice.cts.utils.GestureUtils.IS_ACTION_DOWN; import static android.accessibilityservice.cts.utils.GestureUtils.IS_ACTION_MOVE; @@ -44,6 +45,7 @@ import static org.hamcrest.CoreMatchers.hasItem; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeFalse; import static java.util.concurrent.TimeUnit.MILLISECONDS; @@ -363,6 +365,8 @@ public class AccessibilityGestureDispatchTest { if (!mHasTouchScreen) { return; } + assumeFalse("Magnification is not supported on Automotive.", + isAutomotive(sInstrumentation.getTargetContext())); int displayId = mActivity.getWindow().getDecorView().getDisplay().getDisplayId(); if (displayId != Display.DEFAULT_DISPLAY) { diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityMagnificationTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityMagnificationTest.java index ccc60759094..f8600ea569d 100644 --- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityMagnificationTest.java +++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityMagnificationTest.java @@ -19,12 +19,14 @@ package android.accessibilityservice.cts; import static android.accessibilityservice.MagnificationConfig.MAGNIFICATION_MODE_FULLSCREEN; import static android.accessibilityservice.MagnificationConfig.MAGNIFICATION_MODE_WINDOW; import static android.accessibilityservice.cts.utils.ActivityLaunchUtils.launchActivityAndWaitForItToBeOnscreen; +import static android.accessibilityservice.cts.utils.CtsTestUtils.isAutomotive; import static android.content.pm.PackageManager.FEATURE_WINDOW_MAGNIFICATION; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeFalse; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyFloat; import static org.mockito.Mockito.eq; @@ -146,6 +148,8 @@ public class AccessibilityMagnificationTest { @Before public void setUp() throws Exception { mInstrumentation = InstrumentationRegistry.getInstrumentation(); + assumeFalse("Magnification is not supported on Automotive.", + isAutomotive(mInstrumentation.getTargetContext())); ShellCommandBuilder.create(sUiAutomation) .deleteSecureSetting(ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED) .run(); @@ -1231,9 +1235,7 @@ public class AccessibilityMagnificationTest { private static boolean isWindowModeSupported(Context context) { PackageManager pm = context.getPackageManager(); - // TODO(b/285201744): remove automotive check - boolean isAuto = pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); - return pm.hasSystemFeature(FEATURE_WINDOW_MAGNIFICATION) && !isAuto; + return pm.hasSystemFeature(FEATURE_WINDOW_MAGNIFICATION); } private static MagnificationConfig.Builder obtainConfigBuilder(MagnificationConfig config) { diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityVolumeTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityVolumeTest.java index eea01e28c20..e8ccb2445ff 100644 --- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityVolumeTest.java +++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityVolumeTest.java @@ -13,6 +13,7 @@ */ package android.accessibilityservice.cts; +import static android.accessibilityservice.cts.utils.CtsTestUtils.isAutomotive; import static android.content.Context.AUDIO_SERVICE; import static org.junit.Assert.assertEquals; @@ -75,8 +76,7 @@ public class AccessibilityVolumeTest { mSingleVolume = (pm != null) && (pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK) || pm.hasSystemFeature(PackageManager.FEATURE_TELEVISION)) || mAudioManager.isVolumeFixed(); - mIsPlatformAutomotive = (pm != null) - && (pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)); + mIsPlatformAutomotive = isAutomotive(mInstrumentation.getContext()); final int MIN = mAudioManager.getStreamMinVolume(AudioManager.STREAM_ACCESSIBILITY); final int MAX = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_ACCESSIBILITY); mFixedA11yVolume = (MIN == MAX); diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/FullScreenMagnificationGestureHandlerTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/FullScreenMagnificationGestureHandlerTest.java index e114da5d817..72bf47fcc09 100644 --- a/tests/accessibilityservice/src/android/accessibilityservice/cts/FullScreenMagnificationGestureHandlerTest.java +++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/FullScreenMagnificationGestureHandlerTest.java @@ -18,6 +18,7 @@ package android.accessibilityservice.cts; import static android.accessibilityservice.cts.utils.AsyncUtils.await; import static android.accessibilityservice.cts.utils.AsyncUtils.waitOn; +import static android.accessibilityservice.cts.utils.CtsTestUtils.isAutomotive; import static android.accessibilityservice.cts.utils.GestureUtils.add; import static android.accessibilityservice.cts.utils.GestureUtils.click; import static android.accessibilityservice.cts.utils.GestureUtils.dispatchGesture; @@ -39,6 +40,7 @@ import static android.view.MotionEvent.ACTION_UP; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeFalse; import android.accessibility.cts.common.AccessibilityDumpOnFailureRule; import android.accessibility.cts.common.InstrumentedAccessibilityService; @@ -119,6 +121,8 @@ public class FullScreenMagnificationGestureHandlerTest { mHasTouchscreen = pm.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN) || pm.hasSystemFeature(PackageManager.FEATURE_FAKETOUCH); if (!mHasTouchscreen) return; + assumeFalse("Magnification is not supported on Automotive.", + isAutomotive(mInstrumentation.getTargetContext())); // Backup and reset magnification settings. mOriginalIsMagnificationCapabilities = getSecureSettingInt( diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/CtsTestUtils.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/CtsTestUtils.java index b159c7d5e01..784a5ed7e07 100644 --- a/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/CtsTestUtils.java +++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/CtsTestUtils.java @@ -16,6 +16,8 @@ package android.accessibilityservice.cts.utils; +import android.content.Context; +import android.content.pm.PackageManager; import java.util.Optional; import java.util.function.Consumer; @@ -42,4 +44,10 @@ public class CtsTestUtils { public static <T> void runIfNotNull(T callee, Consumer<T> action) { Optional.ofNullable(callee).ifPresent(action); } + + /** Returns {@code true} if run on an Automotive device */ + public static boolean isAutomotive(Context context) { + PackageManager pm = context.getPackageManager(); + return pm != null && pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); + } } diff --git a/tests/atv/SettingsAPI/AndroidManifest.xml b/tests/atv/SettingsAPI/AndroidManifest.xml index 6cdb4472025..c1e0bf409db 100644 --- a/tests/atv/SettingsAPI/AndroidManifest.xml +++ b/tests/atv/SettingsAPI/AndroidManifest.xml @@ -17,7 +17,7 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.tv.settings.library.cts"> - <uses-sdk android:minSdkVersion="31" /> + <uses-sdk android:minSdkVersion="34" /> <application> <uses-library android:name="android.test.runner"/> </application> diff --git a/tests/autofillservice/AndroidTest.xml b/tests/autofillservice/AndroidTest.xml index 84bcda90232..1aeefbe3b54 100644 --- a/tests/autofillservice/AndroidTest.xml +++ b/tests/autofillservice/AndroidTest.xml @@ -22,6 +22,8 @@ <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <option name="config-descriptor:metadata" key="parameter" value="secondary_user_on_secondary_display" /> <option name="config-descriptor:metadata" key="parameter" value="run_on_sdk_sandbox" /> + <!-- See b/341605144. --> + <option name="hidden-api-checks" value="false" /> <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true" /> diff --git a/tests/camera/src/android/hardware/camera2/cts/HeifWriterTest.java b/tests/camera/src/android/hardware/camera2/cts/HeifWriterTest.java index f729cc7ef79..118e76fb6d6 100644 --- a/tests/camera/src/android/hardware/camera2/cts/HeifWriterTest.java +++ b/tests/camera/src/android/hardware/camera2/cts/HeifWriterTest.java @@ -114,6 +114,7 @@ public class HeifWriterTest extends Camera2AndroidTestCase { OutputConfiguration outConfig = null; Surface latestSurface = null; CaptureRequest.Builder reqStill = null; + SurfaceTexture preview = null; int width = sz.getWidth(); int height = sz.getHeight(); for (int cap = 0; cap < NUM_HEIC_CAPTURE_TESTED; cap++) { @@ -157,7 +158,7 @@ public class HeifWriterTest extends Camera2AndroidTestCase { new ArrayList<OutputConfiguration>(); configs.add(outConfig); - SurfaceTexture preview = new SurfaceTexture(/*random int*/ 1); + preview = new SurfaceTexture(/*random int*/ 1); Surface previewSurface = new Surface(preview); preview.setDefaultBufferSize(640, 480); configs.add(new OutputConfiguration(previewSurface)); @@ -209,6 +210,10 @@ public class HeifWriterTest extends Camera2AndroidTestCase { config.mRotation, config.mUseGrid, Math.min(numImages, config.mMaxNumImages)); } finally { + if (preview != null) { + preview.release(); + preview = null; + } if (heifWriter != null) { heifWriter.close(); heifWriter = null; diff --git a/tests/devicepolicy/AndroidTest.xml b/tests/devicepolicy/AndroidTest.xml index 4ff5e023c78..8f55bd1cb10 100644 --- a/tests/devicepolicy/AndroidTest.xml +++ b/tests/devicepolicy/AndroidTest.xml @@ -23,6 +23,8 @@ <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> <option name="config-descriptor:metadata" key="parameter" value="multiuser" /> <option name="config-descriptor:metadata" key="parameter" value="no_foldable_states" /> + <!-- See b/341807929. --> + <option name="hidden-api-checks" value="false" /> <target_preparer class="com.android.tradefed.targetprep.RunOnSystemUserTargetPreparer"/> <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/BluetoothTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/BluetoothTest.java index f4ebef323be..122b3575026 100644 --- a/tests/devicepolicy/src/android/devicepolicy/cts/BluetoothTest.java +++ b/tests/devicepolicy/src/android/devicepolicy/cts/BluetoothTest.java @@ -407,6 +407,8 @@ public final class BluetoothTest { @Postsubmit(reason = "new test") @ApiTest(apis = "android.os.UserManager#DISALLOW_BLUETOOTH_SHARING") public void share_disallowBluetoothAndSharingRestrictionsAreNotSet_canShare() { + Assume.assumeTrue("We can't test resolving if opp is disabled", OPP_ENABLED); + Poll.forValue("Opp Launcher Component Enabled", () -> TestApis.packages().activity(OPP_LAUNCHER_COMPONENT) .isEnabled(TestApis.users().system())) @@ -414,8 +416,6 @@ public final class BluetoothTest { .errorOnFail() .await(); - Assume.assumeTrue("We can't test resolving if opp is disabled", OPP_ENABLED); - List<ResolveInfo> resolveInfos = sPackageManager.queryIntentActivities( FILE_SHARING_INTENT, /* flags= */ 0); assertThat(resolveInfosContainsActivity(resolveInfos, OPP_LAUNCHER_COMPONENT)).isTrue(); @@ -426,6 +426,8 @@ public final class BluetoothTest { @Postsubmit(reason = "new test") @ApiTest(apis = "android.os.UserManager#DISALLOW_BLUETOOTH_SHARING") public void share_disallowBluetoothSharingRestrictionIsSet_canNotShare() { + Assume.assumeTrue("We can't test resolving if opp is disabled", OPP_ENABLED); + Poll.forValue("Opp Launcher Component Enabled", () -> TestApis.packages().activity(OPP_LAUNCHER_COMPONENT) .isEnabled(TestApis.users().system())) @@ -433,8 +435,6 @@ public final class BluetoothTest { .errorOnFail() .await(); - Assume.assumeTrue("We can't test resolving if opp is disabled", OPP_ENABLED); - List<ResolveInfo> resolveInfos = sPackageManager.queryIntentActivities( FILE_SHARING_INTENT, /* flags= */ 0); assertThat(resolveInfosContainsActivity(resolveInfos, OPP_LAUNCHER_COMPONENT)).isFalse(); @@ -483,6 +483,8 @@ public final class BluetoothTest { @ApiTest(apis = "android.os.UserManager#DISALLOW_BLUETOOTH") @RequireNotHeadlessSystemUserMode(reason = "b/276405672 bluetooth restriction not enforced on secondary users") public void share_disallowBluetoothRestrictionIsSet_canNotShare() { + Assume.assumeTrue("We can't test resolving if opp is disabled", OPP_ENABLED); + Poll.forValue("Opp Launcher Component Enabled", () -> TestApis.packages().activity(OPP_LAUNCHER_COMPONENT) .isEnabled(TestApis.users().system())) @@ -490,8 +492,6 @@ public final class BluetoothTest { .errorOnFail() .await(); - Assume.assumeTrue("We can't test resolving if opp is disabled", OPP_ENABLED); - List<ResolveInfo> resolveInfos = sPackageManager.queryIntentActivities( FILE_SHARING_INTENT, /* flags= */ 0); assertThat(resolveInfosContainsActivity(resolveInfos, OPP_LAUNCHER_COMPONENT)).isFalse(); diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/DefaultDialerApplicationTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/DefaultDialerApplicationTest.java index f6afbfa00f2..fe1d900d545 100644 --- a/tests/devicepolicy/src/android/devicepolicy/cts/DefaultDialerApplicationTest.java +++ b/tests/devicepolicy/src/android/devicepolicy/cts/DefaultDialerApplicationTest.java @@ -175,6 +175,6 @@ public final class DefaultDialerApplicationTest { throw new IllegalStateException( "Error setting default dialer application. Relevant logcat: " + logcat); } - }).timeout(Duration.ofMinutes(2)).runAndWrapException(); + }).timeout(Duration.ofMinutes(4)).runAndWrapException(); } } diff --git a/tests/devicestate/AndroidTest.xml b/tests/devicestate/AndroidTest.xml index ca0266c2485..0750e2aec10 100644 --- a/tests/devicestate/AndroidTest.xml +++ b/tests/devicestate/AndroidTest.xml @@ -22,6 +22,8 @@ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" /> <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> + <!-- See b/341613785. --> + <option name="hidden-api-checks" value="false" /> <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true" /> 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 069ad28c1e5..43803a3a43f 100644 --- a/tests/framework/base/windowmanager/src/android/server/wm/ActivityVisibilityTests.java +++ b/tests/framework/base/windowmanager/src/android/server/wm/ActivityVisibilityTests.java @@ -215,7 +215,7 @@ public class ActivityVisibilityTests extends ActivityManagerTestBase { // (b/308213530). // Wait for the existing TurnScreenOnActivity to finish and the home activity to be in // stopped state as the display is OFF. - if (supportsLockScreen()) { + if (!isDisplayOn(DEFAULT_DISPLAY)) { mWmState.waitForAllStoppedActivities(); } diff --git a/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlViewHostTests.java b/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlViewHostTests.java index ab34530b804..8a43f1c7c9d 100644 --- a/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlViewHostTests.java +++ b/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlViewHostTests.java @@ -901,50 +901,44 @@ public class SurfaceControlViewHostTests extends ActivityManagerTestBase impleme @Test public void testCanReplaceSurfacePackage() throws Throwable { // Create a surface view and wait for its surface to be created. - { - CountDownLatch surfaceCreated = new CountDownLatch(1); - mActivityRule.runOnUiThread(() -> { - final FrameLayout content = new FrameLayout(mActivity); - mSurfaceView = new SurfaceView(mActivity); - mSurfaceView.setZOrderOnTop(true); - content.addView(mSurfaceView, new FrameLayout.LayoutParams( - DEFAULT_SURFACE_VIEW_WIDTH, DEFAULT_SURFACE_VIEW_HEIGHT, - Gravity.LEFT | Gravity.TOP)); - mActivity.setContentView(content, new ViewGroup.LayoutParams( - DEFAULT_SURFACE_VIEW_WIDTH, DEFAULT_SURFACE_VIEW_HEIGHT)); - mSurfaceView.getHolder().addCallback(new SurfaceCreatedCallback(surfaceCreated)); - - // Create an embedded view without click handling. - mVr = new SurfaceControlViewHost(mActivity, mActivity.getDisplay(), - mSurfaceView.getHostToken()); - mEmbeddedView = new Button(mActivity); - mVr.setView(mEmbeddedView, mEmbeddedViewWidth, mEmbeddedViewHeight); + CountDownLatch surfaceCreated = new CountDownLatch(1); + mActivityRule.runOnUiThread(() -> { + final FrameLayout content = new FrameLayout(mActivity); + mSurfaceView = new SurfaceView(mActivity); + mSurfaceView.setZOrderOnTop(true); + content.addView(mSurfaceView, new FrameLayout.LayoutParams( + DEFAULT_SURFACE_VIEW_WIDTH, DEFAULT_SURFACE_VIEW_HEIGHT, + Gravity.LEFT | Gravity.TOP)); + mActivity.setContentView(content, new ViewGroup.LayoutParams( + DEFAULT_SURFACE_VIEW_WIDTH, DEFAULT_SURFACE_VIEW_HEIGHT)); + mSurfaceView.getHolder().addCallback(new SurfaceCreatedCallback(surfaceCreated)); - }); - surfaceCreated.await(); + // Create an embedded view without click handling. + mVr = new SurfaceControlViewHost(mActivity, mActivity.getDisplay(), + mSurfaceView.getHostToken()); + mEmbeddedView = new Button(mActivity); + mVr.setView(mEmbeddedView, mEmbeddedViewWidth, mEmbeddedViewHeight); mSurfaceView.setChildSurfacePackage(mVr.getSurfacePackage()); - mInstrumentation.waitForIdleSync(); - waitUntilEmbeddedViewDrawn(); - } - - { - CountDownLatch hostReady = new CountDownLatch(1); - // Create a second surface view and wait for its surface to be created. - mActivityRule.runOnUiThread(() -> { - // Create an embedded view. - mVr = new SurfaceControlViewHost(mActivity, mActivity.getDisplay(), - mSurfaceView.getHostToken()); - mEmbeddedView = new Button(mActivity); - mEmbeddedView.setOnClickListener((View v) -> mClicked = true); - mVr.setView(mEmbeddedView, mEmbeddedViewWidth, mEmbeddedViewHeight); - hostReady.countDown(); + }); + surfaceCreated.await(); + mInstrumentation.waitForIdleSync(); + waitUntilEmbeddedViewDrawn(); - }); - hostReady.await(); + CountDownLatch hostReady = new CountDownLatch(1); + // Create a second surface view and wait for its surface to be created. + mActivityRule.runOnUiThread(() -> { + // Create an embedded view. + mVr = new SurfaceControlViewHost(mActivity, mActivity.getDisplay(), + mSurfaceView.getHostToken()); + mEmbeddedView = new Button(mActivity); + mEmbeddedView.setOnClickListener((View v) -> mClicked = true); + mVr.setView(mEmbeddedView, mEmbeddedViewWidth, mEmbeddedViewHeight); + hostReady.countDown(); mSurfaceView.setChildSurfacePackage(mVr.getSurfacePackage()); - mInstrumentation.waitForIdleSync(); - waitUntilEmbeddedViewDrawn(); - } + }); + hostReady.await(); + mInstrumentation.waitForIdleSync(); + waitUntilEmbeddedViewDrawn(); // Check to see if the click went through - this only would happen if the surface package // was replaced diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsTestHelper.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsTestHelper.java index 14e2c9ce570..67b65e3cf52 100644 --- a/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsTestHelper.java +++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsTestHelper.java @@ -26,7 +26,6 @@ import static org.junit.Assert.assertTrue; import android.app.Activity; import android.content.Context; -import android.content.res.Resources; import android.graphics.Insets; import android.graphics.Point; import android.graphics.Rect; @@ -37,10 +36,6 @@ import android.view.WindowInsets; import android.view.WindowManager; import android.view.WindowMetrics; -import androidx.test.core.app.ApplicationProvider; - -import com.android.modules.utils.build.SdkLevel; - import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -191,24 +186,7 @@ public class WindowMetricsTestHelper { } private static int configExcludedInsetsTypes() { - // The device owners can choose to decouple the display cutout from the configuration app - // bounds to ensure a better experience. Return the legacy value if the decouple config is - // not set to true. - final int legacyNonDecorTypes = navigationBars() | displayCutout(); - if (!SdkLevel.isAtLeastU()) { - return legacyNonDecorTypes; - } - try { - final boolean isScreenSizeDecoupledFromStatusBarAndCutout = - ApplicationProvider.getApplicationContext().getResources().getBoolean( - Resources.getSystem().getIdentifier( - "config_decoupleStatusBarAndDisplayCutoutFromScreenSize", - "bool", "android")); - return isScreenSizeDecoupledFromStatusBarAndCutout - ? navigationBars() : legacyNonDecorTypes; - } catch (Resources.NotFoundException e) { - return legacyNonDecorTypes; - } + return navigationBars() | displayCutout(); } public static class OnLayoutChangeListener implements View.OnLayoutChangeListener { diff --git a/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java b/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java index 4002657570a..92f1b2e58a6 100644 --- a/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java +++ b/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java @@ -378,6 +378,9 @@ public final class MockIme extends InputMethodService { final boolean enabled = command.getExtras().getBoolean("enabled"); return getMemorizedOrCurrentInputConnection().reportFullscreenMode(enabled); } + case "getOnEvaluateFullscreenMode": { + return onEvaluateFullscreenMode(); + } case "performSpellCheck": { return getMemorizedOrCurrentInputConnection().performSpellCheck(); } diff --git a/tests/inputmethod/mockime/src/com/android/cts/mockime/MockImeSession.java b/tests/inputmethod/mockime/src/com/android/cts/mockime/MockImeSession.java index 07a5c64458c..fe9098eecda 100644 --- a/tests/inputmethod/mockime/src/com/android/cts/mockime/MockImeSession.java +++ b/tests/inputmethod/mockime/src/com/android/cts/mockime/MockImeSession.java @@ -1709,6 +1709,15 @@ public class MockImeSession implements AutoCloseable { } /** + * Calls and returns value of + * {@link android.inputmethodservice.InputMethodService#onEvaluateFullscreenMode}. + */ + @NonNull + public ImeCommand callGetOnEvaluateFullscreenMode() { + return callCommandInternal("getOnEvaluateFullscreenMode", new Bundle()); + } + + /** * Verifies {@code InputMethodService.getLayoutInflater().getContext()} is equal to * {@code InputMethodService.this}. * diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java index 4ef76ae632c..be8f17b7bb5 100644 --- a/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java +++ b/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java @@ -39,6 +39,7 @@ import static android.widget.PopupWindow.INPUT_METHOD_NOT_NEEDED; import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity; import static com.android.cts.mockime.ImeEventStreamTestUtils.editorMatcher; +import static com.android.cts.mockime.ImeEventStreamTestUtils.expectCommand; import static com.android.cts.mockime.ImeEventStreamTestUtils.expectEvent; import static com.android.cts.mockime.ImeEventStreamTestUtils.expectEventWithKeyValue; import static com.android.cts.mockime.ImeEventStreamTestUtils.hideSoftInputMatcher; @@ -1339,6 +1340,10 @@ public class KeyboardVisibilityControlTest extends EndToEndImeTestBase { expectImeInvisible(TIMEOUT); assertTrue("isActive() must return true if the View has IME focus", getOnMainSync(() -> imm.isActive(editText))); + assumeFalse("onEvaluateFullscreenMode() should be false for portrait", + expectCommand( + stream, imeSession.callGetOnEvaluateFullscreenMode(), TIMEOUT) + .getReturnBooleanValue()); // Call ShowSoftInput() implicitly assertTrue("showSoftInput must success if the View has IME focus", diff --git a/tests/signature/api-check/hidden-api-killswitch-sdklist/AndroidTest.xml b/tests/signature/api-check/hidden-api-killswitch-sdklist/AndroidTest.xml index bcd4bf950c3..bc43c36fab2 100644 --- a/tests/signature/api-check/hidden-api-killswitch-sdklist/AndroidTest.xml +++ b/tests/signature/api-check/hidden-api-killswitch-sdklist/AndroidTest.xml @@ -35,7 +35,7 @@ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" /> <option name="class" value="android.signature.cts.api.SdkListKillswitchTest" /> <option name="runtime-hint" value="60s" /> - <option name="shell-timeout" value="45m" /> + <option name="shell-timeout" value="65m" /> </test> <!-- Controller that will skip the module if a native bridge situation is detected --> diff --git a/tests/signature/api-check/hidden-api-killswitch-wildcard/AndroidTest.xml b/tests/signature/api-check/hidden-api-killswitch-wildcard/AndroidTest.xml index f971b5b6479..5ca9acd3948 100644 --- a/tests/signature/api-check/hidden-api-killswitch-wildcard/AndroidTest.xml +++ b/tests/signature/api-check/hidden-api-killswitch-wildcard/AndroidTest.xml @@ -35,7 +35,7 @@ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" /> <option name="class" value="android.signature.cts.api.WildcardKillswitchTest" /> <option name="runtime-hint" value="60s" /> - <option name="shell-timeout" value="45m" /> + <option name="shell-timeout" value="65m" /> </test> <!-- Controller that will skip the module if a native bridge situation is detected --> diff --git a/tests/tests/carrierapi/src/android/carrierapi/cts/BugreportManagerTest.java b/tests/tests/carrierapi/src/android/carrierapi/cts/BugreportManagerTest.java index ce8fdd7b094..86b684d5000 100644 --- a/tests/tests/carrierapi/src/android/carrierapi/cts/BugreportManagerTest.java +++ b/tests/tests/carrierapi/src/android/carrierapi/cts/BugreportManagerTest.java @@ -44,6 +44,7 @@ import androidx.test.uiautomator.Until; import com.android.compatibility.common.util.ApiTest; import com.android.compatibility.common.util.CddTest; import com.android.compatibility.common.util.PollingCheck; +import com.android.compatibility.common.util.UiAutomatorUtils2; import org.junit.After; import org.junit.Before; @@ -397,11 +398,21 @@ public class BugreportManagerTest extends BaseCarrierApiTest { switch (consentReply) { case ALLOW: Log.d(TAG, "Allow the consent dialog"); - replySelector = By.res("android", "button1"); + if (isWear()) { + replySelector = By.desc( + getContext().getResources().getString(android.R.string.ok)); + } else { + replySelector = By.res("android", "button1"); + } break; case DENY: Log.d(TAG, "Deny the consent dialog"); - replySelector = By.res("android", "button2"); + if (isWear()) { + replySelector = By.desc( + getContext().getResources().getString(android.R.string.cancel)); + } else { + replySelector = By.res("android", "button2"); + } break; case NONE_TIMEOUT: default: @@ -411,12 +422,16 @@ public class BugreportManagerTest extends BaseCarrierApiTest { } UiObject2 replyButton; - UiObject2 scrollable = - device.findObject(By.res("android:id/scrollView").scrollable(true)); - while ((replyButton = device.findObject(replySelector)) == null) { - // Need to scroll the screen to get to the buttons on some form factors - // (e.g. on a watch). - scrollable.scroll(Direction.DOWN, 100); + if (isWear()) { + replyButton = UiAutomatorUtils2.waitFindObject(replySelector); + } else { + UiObject2 scrollable = + device.findObject(By.res("android:id/scrollView").scrollable(true)); + while ((replyButton = device.findObject(replySelector)) == null) { + // Need to scroll the screen to get to the buttons on some form factors + // (e.g. on a watch). + scrollable.scroll(Direction.DOWN, 100); + } } assertWithMessage("The button of consent dialog is not found") diff --git a/tests/tests/database/src/android/database/cts/DatabaseUtilsTest.java b/tests/tests/database/src/android/database/cts/DatabaseUtilsTest.java index a35a6ac7c83..341adecbfd2 100644 --- a/tests/tests/database/src/android/database/cts/DatabaseUtilsTest.java +++ b/tests/tests/database/src/android/database/cts/DatabaseUtilsTest.java @@ -153,6 +153,7 @@ public class DatabaseUtilsTest extends AndroidTestCase { assertEquals(1, cursor.getCount()); cursor.moveToFirst(); assertEquals("Mike", cursor.getString(1)); + db.close(); getContext().deleteDatabase(dbName); } diff --git a/tests/tests/gameframerate/src/GameFrameRateCtsActivity.java b/tests/tests/gameframerate/src/GameFrameRateCtsActivity.java index f5687f9e70c..361052c47df 100644 --- a/tests/tests/gameframerate/src/GameFrameRateCtsActivity.java +++ b/tests/tests/gameframerate/src/GameFrameRateCtsActivity.java @@ -47,7 +47,7 @@ public class GameFrameRateCtsActivity extends Activity { private static final int PRECONDITION_WAIT_MAX_ATTEMPTS = 5; private static final long PRECONDITION_WAIT_TIMEOUT_NANOSECONDS = 20 * 1_000_000_000L; private static final long PRECONDITION_VIOLATION_WAIT_TIMEOUT_NANOSECONDS = 3 * 1_000_000_000L; - private static final float FRAME_RATE_TOLERANCE = 0.01f; + private static final float FRAME_RATE_TOLERANCE = 1.01f; private static final float FPS_TOLERANCE_FOR_FRAME_RATE_OVERRIDE = 5; private static final long FRAME_RATE_MIN_WAIT_TIME_NANOSECONDS = 1 * 1_000_000_000L; private static final long FRAME_RATE_MAX_WAIT_TIME_NANOSECONDS = 10 * 1_000_000_000L; diff --git a/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java b/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java index 6c7030725aa..f70ea7b1357 100644 --- a/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java +++ b/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java @@ -293,10 +293,7 @@ public class ImageDecoderTest { ImageDecoder.isMimeTypeSupported("image/avif")); try { - ImageDecoder.Source src = ImageDecoder - .createSource(getResources(), R.raw.avif_yuv_420_10bit); - assertNotNull(src); - Bitmap bm = ImageDecoder.decodeBitmap(src, (decoder, info, source) -> { + Bitmap bm = decodeUnscaledBitmap(R.raw.avif_yuv_420_10bit, (decoder, info, source) -> { decoder.setAllocator(ImageDecoder.ALLOCATOR_SOFTWARE); }); assertNotNull(bm); @@ -308,6 +305,23 @@ public class ImageDecoderTest { } } + private Bitmap decodeUnscaledBitmap( + int resId, ImageDecoder.OnHeaderDecodedListener listener) throws IOException { + // For tests which rely on ImageDecoder *not* scaling to account for density. + // Temporarily change the DisplayMetrics to prevent that scaling. + Resources res = getResources(); + final int originalDensity = res.getDisplayMetrics().densityDpi; + res.getDisplayMetrics().densityDpi = DisplayMetrics.DENSITY_DEFAULT; + + try { + ImageDecoder.Source src = ImageDecoder.createSource(res, resId); + assertNotNull(src); + return ImageDecoder.decodeBitmap(src, listener); + } finally { + res.getDisplayMetrics().densityDpi = originalDensity; + } + } + @Test @RequiresDevice public void testDecode10BitHeifWithLowRam() { @@ -347,7 +361,7 @@ public class ImageDecoderTest { R.raw.avif_yuv_420_10bit); assertNotNull(src); try { - Bitmap bm = ImageDecoder.decodeBitmap(src, (decoder, info, source) -> { + Bitmap bm = decodeUnscaledBitmap(R.raw.avif_yuv_420_10bit, (decoder, info, source) -> { decoder.setMemorySizePolicy(ImageDecoder.MEMORY_POLICY_LOW_RAM); decoder.setAllocator(ImageDecoder.ALLOCATOR_SOFTWARE); }); @@ -527,27 +541,18 @@ public class ImageDecoderTest { } } }; - Listener l = new Listener(); - // This test relies on ImageDecoder *not* scaling to account for density. - // Temporarily change the DisplayMetrics to prevent that scaling. - Resources res = getResources(); - final int originalDensity = res.getDisplayMetrics().densityDpi; - res.getDisplayMetrics().densityDpi = DisplayMetrics.DENSITY_DEFAULT; - ImageDecoder.Source src = ImageDecoder.createSource(res, record.resId); - assertNotNull(src); + Listener l = new Listener(); l.doCrop = doCrop; l.doScale = doScale; l.allocator = allocator; Bitmap bm = null; try { - bm = ImageDecoder.decodeBitmap(src, l); + bm = decodeUnscaledBitmap(record.resId, l); } catch (IOException e) { fail("Failed " + Utils.getAsResourceUri(record.resId) + " with exception " + e); - } finally { - res.getDisplayMetrics().densityDpi = originalDensity; } assertNotNull(bm); @@ -562,6 +567,7 @@ public class ImageDecoderTest { assertNotEquals(Bitmap.Config.HARDWARE, bm.getConfig()); if (!doScale && !doCrop) { + Resources res = getResources(); BitmapFactory.Options options = new BitmapFactory.Options(); options.inScaled = false; Bitmap reference = BitmapFactory.decodeResource(res, diff --git a/tests/tests/keystore/src/android/keystore/cts/ECDSASignatureTest.java b/tests/tests/keystore/src/android/keystore/cts/ECDSASignatureTest.java index e13f8da41e0..3e182aa5e31 100644 --- a/tests/tests/keystore/src/android/keystore/cts/ECDSASignatureTest.java +++ b/tests/tests/keystore/src/android/keystore/cts/ECDSASignatureTest.java @@ -79,6 +79,15 @@ public class ECDSASignatureTest { private void assertNONEwithECDSATruncatesInputToFieldSize(KeyPair keyPair) throws Exception { int keySizeBits = TestUtils.getKeySizeBits(keyPair.getPublic()); + if (keySizeBits == 521) { + // The message truncation for ECDSA P521 was broken on some old devices/chipsets for + // Keymaster implementations, as per the Bug 338340302. Therefore, this test is skipped + // on older devices with VSR <= 29. + if (TestUtils.getVendorApiLevel() <= 29) { + Log.i(TAG, "This test is skipped for the P521 curve on chipsets with VSR <= 29"); + return; + } + } byte[] message = new byte[(keySizeBits * 3) / 8]; for (int i = 0; i < message.length; i++) { message[i] = (byte) (i + 1); diff --git a/tests/tests/media/audio/src/android/media/audio/cts/AudioPlaybackConfigurationTest.java b/tests/tests/media/audio/src/android/media/audio/cts/AudioPlaybackConfigurationTest.java index 0c5e0895679..9a7b3bc65f0 100644 --- a/tests/tests/media/audio/src/android/media/audio/cts/AudioPlaybackConfigurationTest.java +++ b/tests/tests/media/audio/src/android/media/audio/cts/AudioPlaybackConfigurationTest.java @@ -493,6 +493,10 @@ public class AudioPlaybackConfigurationTest extends CtsAndroidTestCase { "android.media.AudioManager.AudioPlaybackCallback#isMuted", "android.media.AudioManager.AudioPlaybackCallback#getMutedBy"}) public void testAudioTrackMuteFromAppOpsNotification() throws Exception { + if (isWatch()) { + Log.w(TAG, "Skip testAudioTrackMuteFromAppOpsNotification for Wear"); + return; + } if (!isValidPlatform("testAudioTrackMuteFromAppOpsNotification")) return; if (hasAudioSilentProperty()) { Log.w(TAG, "Device has ro.audio.silent set, skipping " @@ -509,6 +513,10 @@ public class AudioPlaybackConfigurationTest extends CtsAndroidTestCase { "android.media.AudioManager.AudioPlaybackCallback#isMuted", "android.media.AudioManager.AudioPlaybackCallback#getMutedBy"}) public void testMediaPlayerMuteFromAppOpsNotification() throws Exception { + if (isWatch()) { + Log.w(TAG, "Skip testMediaPlayerMuteFromAppOpsNotification for Wear"); + return; + } if (!isValidPlatform("testMediaPlayerMuteFromAppOpsNotification")) return; if (hasAudioSilentProperty()) { Log.w(TAG, "Device has ro.audio.silent set, skipping " @@ -700,6 +708,9 @@ public class AudioPlaybackConfigurationTest extends CtsAndroidTestCase { assertTrue("onPlaybackConfigChanged play, format and device expected", callback.waitForCallbacks(3, TEST_TIMING_TOLERANCE_MS + PLAY_ROUTING_TIMING_TOLERANCE_MS)); + if (mAt != null) { + Thread.sleep(TEST_TIMING_TOLERANCE_MS + PLAY_ROUTING_TIMING_TOLERANCE_MS); + } } else { Thread.sleep(TEST_TIMING_TOLERANCE_MS + PLAY_ROUTING_TIMING_TOLERANCE_MS); } @@ -1022,4 +1033,8 @@ public class AudioPlaybackConfigurationTest extends CtsAndroidTestCase { } return true; } + + private boolean isWatch() { + return getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH); + } } diff --git a/tests/tests/media/audio/src/android/media/audio/cts/RoutingTest.java b/tests/tests/media/audio/src/android/media/audio/cts/RoutingTest.java index 660c97cbaff..f4ace49e12d 100644 --- a/tests/tests/media/audio/src/android/media/audio/cts/RoutingTest.java +++ b/tests/tests/media/audio/src/android/media/audio/cts/RoutingTest.java @@ -630,7 +630,12 @@ public class RoutingTest extends AndroidTestCase { assertNull(mediaPlayer.getPreferredDevice()); // resets to default + mediaPlayer.pause(); + //Wait for state to change before setPreferDevice + SystemClock.sleep(200); assertTrue(mediaPlayer.setPreferredDevice(null)); + mediaPlayer.start(); + assertTrue(mediaPlayer.isPlaying()); // test each device AudioDeviceInfo[] deviceList = mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS); @@ -639,12 +644,22 @@ public class RoutingTest extends AndroidTestCase { // Device with type as TYPE_TELEPHONY requires a privileged permission. continue; } + mediaPlayer.pause(); + //Wait for state to change before setPreferDevice + SystemClock.sleep(200); assertTrue(mediaPlayer.setPreferredDevice(deviceList[index])); + mediaPlayer.start(); + assertTrue(mediaPlayer.isPlaying()); assertTrue(mediaPlayer.getPreferredDevice() == deviceList[index]); } // Check defaults again + mediaPlayer.pause(); + //Wait for state to change before setPreferDevice + SystemClock.sleep(200); assertTrue(mediaPlayer.setPreferredDevice(null)); + mediaPlayer.start(); + assertTrue(mediaPlayer.isPlaying()); assertNull(mediaPlayer.getPreferredDevice()); mediaPlayer.stop(); @@ -737,7 +752,12 @@ public class RoutingTest extends AndroidTestCase { for (AudioDeviceInfo device : devices) { if (routedDevice.getId() != device.getId() && device.getType() != AudioDeviceInfo.TYPE_TELEPHONY) { + mediaPlayer.pause(); + //Wait for state to change before setPreferDevice + SystemClock.sleep(200); mediaPlayer.setPreferredDevice(device); + mediaPlayer.start(); + assertTrue(mediaPlayer.isPlaying()); listener.setCallExpected(true); listener.await(WAIT_ROUTING_CHANGE_TIME_MS); break; diff --git a/tests/tests/nfc/src/android/nfc/cts/NfcAdapterTest.java b/tests/tests/nfc/src/android/nfc/cts/NfcAdapterTest.java index 5453adb6447..55d70635614 100644 --- a/tests/tests/nfc/src/android/nfc/cts/NfcAdapterTest.java +++ b/tests/tests/nfc/src/android/nfc/cts/NfcAdapterTest.java @@ -5,13 +5,11 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.when; import static org.mockito.Mockito.doNothing; import android.app.Activity; import android.app.PendingIntent; -import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; @@ -20,9 +18,11 @@ import android.nfc.*; import android.nfc.tech.*; import android.os.Bundle; import android.os.RemoteException; -import androidx.test.core.app.ApplicationProvider; + import androidx.test.InstrumentationRegistry; +import androidx.test.core.app.ApplicationProvider; +import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -30,15 +30,15 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.mockito.internal.util.reflection.FieldReader; import org.mockito.internal.util.reflection.FieldSetter; import java.util.ArrayList; -import java.util.concurrent.Executor; -import java.util.HashMap; @RunWith(JUnit4.class) public class NfcAdapterTest { @Mock private INfcAdapter mService; + private INfcAdapter mSavedService; private Context mContext; private boolean supportsHardware() { @@ -47,10 +47,23 @@ public class NfcAdapterTest { } @Before - public void setUp() { + public void setUp() throws NoSuchFieldException { MockitoAnnotations.initMocks(this); mContext = InstrumentationRegistry.getContext(); assumeTrue(supportsHardware()); + // Backup the original service. It is being overridden + // when creating a mocked adapter. + NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext); + mSavedService = (INfcAdapter) ( + new FieldReader(adapter, adapter.getClass().getDeclaredField("sService")).read()); + } + + @After + public void tearDown() throws NoSuchFieldException { + // Restore the original service. + NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext); + FieldSetter.setField(adapter, + adapter.getClass().getDeclaredField("sService"), mSavedService); } @Test diff --git a/tests/tests/os/src/android/os/cts/SecurityFeaturesTest.java b/tests/tests/os/src/android/os/cts/SecurityFeaturesTest.java index 5958ad3fc53..c7c98d980c6 100644 --- a/tests/tests/os/src/android/os/cts/SecurityFeaturesTest.java +++ b/tests/tests/os/src/android/os/cts/SecurityFeaturesTest.java @@ -19,6 +19,7 @@ package android.os.cts; import static android.system.OsConstants.PR_GET_DUMPABLE; import android.os.Build; +import android.os.SystemProperties; import android.platform.test.annotations.AppModeFull; import android.platform.test.annotations.RestrictedBuildTest; import android.system.Os; @@ -50,7 +51,7 @@ public class SecurityFeaturesTest extends TestCase { } /** - * Verifies that prctl(PR_GET_DUMPABLE) == ro.debuggable + * Verifies prctl(PR_GET_DUMPABLE) * * When PR_SET_DUMPABLE is 0, an application will not generate a * coredump, and PTRACE_ATTACH is disallowed. It's a security best @@ -61,8 +62,8 @@ public class SecurityFeaturesTest extends TestCase { * By default, PR_SET_DUMPABLE is 0 for zygote spawned apps, except * in the following circumstances: * - * 1) ro.debuggable=1 (global debuggable enabled, i.e., userdebug or - * eng builds). + * 1) eng build or userdebug build when one of property "persist.debug.ptrace.enabled" + * and "persist.debug.dalvik.vm.jdwp.enabled" is set. * * 2) android:debuggable="true" in the manifest for an individual * application. @@ -73,15 +74,16 @@ public class SecurityFeaturesTest extends TestCase { * <meta-data android:name="com.android.graphics.injectLayers.enable" android:value="true"/> * in the application manifest. * - * For this test, neither #2, #3, nor #4 are true, so we expect ro.debuggable - * to exactly equal prctl(PR_GET_DUMPABLE). + * For this test, neither #2, #3, nor #4 are true, so we only test #1. */ @AppModeFull(reason = "Instant apps cannot access APIs") - @RestrictedBuildTest public void testPrctlDumpable() throws Exception { - boolean userBuild = "user".equals(Build.TYPE); + boolean userDebugBuild = "userdebug".equals(Build.TYPE); + boolean engBuild = "eng".equals(Build.TYPE); + boolean enablePtrace = SystemProperties.get("persist.debug.ptrace.enabled").equals("1"); + boolean enableJDWP = SystemProperties.get("persist.debug.dalvik.vm.jdwp.enabled").equals("1"); int prctl_dumpable = Os.prctl(PR_GET_DUMPABLE, 0, 0, 0, 0); - int expected = userBuild ? 0 : 1; + int expected = ((userDebugBuild && (enablePtrace || enableJDWP)) || engBuild) ? 1 : 0; assertEquals(expected, prctl_dumpable); } } diff --git a/tests/tests/os/src/android/os/storage/cts/StorageManagerTest.java b/tests/tests/os/src/android/os/storage/cts/StorageManagerTest.java index db1c05f144b..903446365ea 100644 --- a/tests/tests/os/src/android/os/storage/cts/StorageManagerTest.java +++ b/tests/tests/os/src/android/os/storage/cts/StorageManagerTest.java @@ -33,6 +33,7 @@ import static java.util.stream.Collectors.joining; import android.app.PendingIntent; import android.content.Context; +import android.content.pm.PackageManager; import android.content.res.Resources; import android.content.res.Resources.NotFoundException; import android.os.Environment; @@ -420,7 +421,14 @@ public class StorageManagerTest { mStorageManager.registerStorageVolumeCallback(mContext.getMainExecutor(), callback); InstrumentationRegistry.getInstrumentation().getUiAutomation() .executeShellCommand("sm unmount emulated;" + UserHandle.myUserId()); - assertTrue(unmounted.await(30, TimeUnit.SECONDS)); + if (isAutomotive(mContext)) { + // TODO(b/343167829): Remove this conditional casing once the delayed unmount + // operation is addressed for Auto. The 65 second duration is explained in + // b/331333384#comment48. + assertTrue(unmounted.await(65, TimeUnit.SECONDS)); + } else { + assertTrue(unmounted.await(30, TimeUnit.SECONDS)); + } // Now unregister and verify we don't hear future events mStorageManager.unregisterStorageVolumeCallback(callback); @@ -1084,6 +1092,11 @@ public class StorageManagerTest { } } + private boolean isAutomotive(Context context) { + PackageManager pm = context.getPackageManager(); + return pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); + } + @Test public void testComputeStorageCacheBytes() throws Exception { File mockFile = mock(File.class); diff --git a/tests/tests/packageinstaller/TEST_MAPPING b/tests/tests/packageinstaller/TEST_MAPPING index a17298a2077..205945a5b3b 100644 --- a/tests/tests/packageinstaller/TEST_MAPPING +++ b/tests/tests/packageinstaller/TEST_MAPPING @@ -1,4 +1,9 @@ { + "postsubmit": [ + { + "name": "CtsUserRestrictionTestCases" + } + ], "presubmit": [ { "name": "CtsAdminPackageInstallerTestCases" diff --git a/tests/tests/packageinstaller/userrestriction/Android.bp b/tests/tests/packageinstaller/userrestriction/Android.bp new file mode 100644 index 00000000000..df09a1ecbb5 --- /dev/null +++ b/tests/tests/packageinstaller/userrestriction/Android.bp @@ -0,0 +1,43 @@ +// Copyright (C) 2021 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// 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 { + name: "CtsUserRestrictionTestCases", + srcs: ["src/**/*.kt"], + static_libs: [ + "androidx.core_core", + "androidx.test.ext.junit", + "androidx.test.rules", + "androidx.test.runner", + "androidx.test.uiautomator_uiautomator", + "junit", + "kotlin-test", + "truth", + "Nene", + "Harrier", + "platform-test-annotations", + ], + platform_apis: true, + test_suites: [ + "cts", + "general-tests", + ], + data: [ + ":CtsEmptyTestApp", + ], +} diff --git a/tests/tests/packageinstaller/userrestriction/AndroidManifest.xml b/tests/tests/packageinstaller/userrestriction/AndroidManifest.xml new file mode 100644 index 00000000000..1f0fadabdc3 --- /dev/null +++ b/tests/tests/packageinstaller/userrestriction/AndroidManifest.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2018 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.packageinstaller.userrestriction.cts" > + + <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> + + <application android:label="Cts User Restriction Install Tests"> + <uses-library android:name="android.test.runner" /> + + <activity android:name="com.android.compatibility.common.util.FutureResultActivity" /> + + <provider android:authorities="android.packageinstaller.userrestriction.cts.fileprovider" + android:name="androidx.core.content.FileProvider" + android:grantUriPermissions="true"> + <meta-data + android:name="android.support.FILE_PROVIDER_PATHS" + android:resource="@xml/file_paths" /> + </provider> + </application> + + <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" + android:functionalTest="true" + android:targetPackage="android.packageinstaller.userrestriction.cts" + android:label="Install with User Restriction Tests"/> + +</manifest> diff --git a/tests/tests/packageinstaller/userrestriction/AndroidTest.xml b/tests/tests/packageinstaller/userrestriction/AndroidTest.xml new file mode 100644 index 00000000000..1f413561c5f --- /dev/null +++ b/tests/tests/packageinstaller/userrestriction/AndroidTest.xml @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2018 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. +--> + +<configuration description="Config for CTS Packageinstaller UserRestriction test cases"> + <option name="test-suite-tag" value="cts" /> + <option name="config-descriptor:metadata" key="component" value="packagemanager" /> + <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" /> + <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> + <option name="config-descriptor:metadata" key="parameter" value="no_foldable_states" /> + <option name="config-descriptor:metadata" key="parameter" value="multiuser" /> + + <!-- disable GPP UI --> + <target_preparer class="com.android.tradefed.targetprep.DeviceSetup"> + <option name="force-skip-system-props" value="true" /> + <option name="set-global-setting" key="verifier_engprod" value="1" /> + <option name="set-global-setting" key="verifier_verify_adb_installs" value="0" /> + <option name="restore-settings" value="true" /> + </target_preparer> + + <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> + <option name="cleanup-apks" value="true" /> + <option name="test-file-name" value="CtsUserRestrictionTestCases.apk" /> + </target_preparer> + + <target_preparer + class="com.android.compatibility.common.tradefed.targetprep.FilePusher"> + <option name="cleanup" value="true" /> + <option name="push" value="CtsEmptyTestApp.apk->/data/local/tmp/cts/packageinstaller/CtsEmptyTestApp.apk" /> + </target_preparer> + + <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"> + <option name="run-command" value="appops set android.packageinstaller.userrestriction.cts REQUEST_INSTALL_PACKAGES allow" /> + <option name="teardown-command" value="appops set android.packageinstaller.userrestriction.cts REQUEST_INSTALL_PACKAGES default" /> + <!-- Ensure the UI is ready and in an idle state before running tests --> + <option name="run-command" value="input keyevent KEYCODE_WAKEUP" /> + <option name="run-command" value="wm dismiss-keyguard" /> + <!-- Collapse notifications --> + <option name="run-command" value="cmd statusbar collapse" /> + <!-- dismiss all system dialogs before launch test --> + <option name="run-command" value="am broadcast -a android.intent.action.CLOSE_SYSTEM_DIALOGS" /> + </target_preparer> + + <!-- Do not remove this (b/277987631) --> + <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"> + <option name="force-root" value="false" /> + </target_preparer> + + <test class="com.android.tradefed.testtype.AndroidJUnitTest" > + <option name="package" value="android.packageinstaller.userrestriction.cts" /> + <option name="runtime-hint" value="1m" /> + <option name="exclude-annotation" value="com.android.bedstead.harrier.annotations.RequireRunOnWorkProfile" /> + <option name="exclude-annotation" value="com.android.bedstead.harrier.annotations.RequireRunOnSecondaryUser" /> + </test> + +</configuration> diff --git a/tests/tests/packageinstaller/userrestriction/res/xml/file_paths.xml b/tests/tests/packageinstaller/userrestriction/res/xml/file_paths.xml new file mode 100644 index 00000000000..80b7e2d5f4c --- /dev/null +++ b/tests/tests/packageinstaller/userrestriction/res/xml/file_paths.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2017 Google Inc. + + 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. +--> + +<paths xmlns:android="http://schemas.android.com/apk/res/android"> + <files-path name="apk" path="/" /> +</paths>
\ No newline at end of file diff --git a/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/UserRestrictionInstallTest.kt b/tests/tests/packageinstaller/userrestriction/src/android/packageinstaller/userrestriction/cts/UserRestrictionInstallTest.kt index 7eb7a6fc579..e6641ef5102 100644 --- a/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/UserRestrictionInstallTest.kt +++ b/tests/tests/packageinstaller/userrestriction/src/android/packageinstaller/userrestriction/cts/UserRestrictionInstallTest.kt @@ -1,11 +1,11 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * 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 + * https://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, @@ -14,10 +14,11 @@ * limitations under the License. */ -package android.packageinstaller.install.cts +package android.packageinstaller.userrestriction.cts import android.app.Activity import android.app.PendingIntent +import android.content.Context import android.content.Intent import android.content.pm.PackageInstaller.EXTRA_STATUS import android.content.pm.PackageInstaller.STATUS_FAILURE_INVALID @@ -25,9 +26,17 @@ import android.content.pm.PackageInstaller.STATUS_PENDING_USER_ACTION import android.content.pm.PackageInstaller.Session import android.content.pm.PackageInstaller.SessionParams import android.platform.test.annotations.AppModeFull +import android.util.Log import androidx.core.content.FileProvider +import androidx.test.InstrumentationRegistry +import androidx.test.rule.ActivityTestRule +import androidx.test.uiautomator.By +import androidx.test.uiautomator.BySelector +import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiObject +import androidx.test.uiautomator.UiObject2 import androidx.test.uiautomator.UiSelector +import androidx.test.uiautomator.Until import com.android.bedstead.harrier.BedsteadJUnit4 import com.android.bedstead.harrier.DeviceState import com.android.bedstead.harrier.UserType @@ -39,7 +48,7 @@ import com.android.bedstead.harrier.annotations.EnsureHasWorkProfile import com.android.bedstead.harrier.annotations.RequireRunOnWorkProfile import com.android.bedstead.harrier.annotations.enterprise.DevicePolicyRelevant import com.android.bedstead.nene.TestApis -import com.android.bedstead.nene.appops.CommonAppOps.OPSTR_REQUEST_INSTALL_PACKAGES +import android.app.AppOpsManager.OPSTR_REQUEST_INSTALL_PACKAGES import com.android.bedstead.nene.exceptions.AdbException import com.android.bedstead.nene.permissions.CommonPermissions.INTERACT_ACROSS_USERS_FULL import com.android.bedstead.nene.userrestrictions.CommonUserRestrictions.DISALLOW_DEBUGGING_FEATURES @@ -48,11 +57,15 @@ import com.android.bedstead.nene.users.UserReference import com.android.bedstead.nene.utils.ShellCommand import com.android.compatibility.common.util.ApiTest import com.android.compatibility.common.util.BlockingBroadcastReceiver +import com.android.compatibility.common.util.FutureResultActivity import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertWithMessage import java.io.File +import java.util.concurrent.CompletableFuture import java.util.concurrent.TimeUnit +import java.util.regex.Pattern import kotlin.test.assertFailsWith +import org.junit.Assert import org.junit.Assert.fail import org.junit.Before import org.junit.ClassRule @@ -62,17 +75,39 @@ import org.junit.runner.RunWith @RunWith(BedsteadJUnit4::class) @AppModeFull(reason = "DEVICE_POLICY_SERVICE is null in instant mode") -class UserRestrictionInstallTest : PackageInstallerTestBase() { - private val APP_INSTALL_ACTION = - "android.packageinstaller.install.cts.UserRestrictionInstallTest.action" +class UserRestrictionInstallTest { companion object { + const val INSTALL_BUTTON_ID = "button1" + const val CANCEL_BUTTON_ID = "button2" + + const val PACKAGE_INSTALLER_PACKAGE_NAME = "com.android.packageinstaller" + const val SYSTEM_PACKAGE_NAME = "android" + + const val TEST_APK_NAME = "CtsEmptyTestApp.apk" + const val TEST_APK_PACKAGE_NAME = "android.packageinstaller.emptytestapp.cts" + const val TEST_APK_LOCATION = "/data/local/tmp/cts/packageinstaller" + + const val CONTENT_AUTHORITY = "android.packageinstaller.userrestriction.cts.fileprovider" + const val APP_INSTALL_ACTION = "android.packageinstaller.userrestriction.cts.action" + + const val TIMEOUT = 60000L + @JvmField @ClassRule @Rule val sDeviceState = DeviceState() } + val TAG = UserRestrictionInstallTest::class.java.simpleName + + @get:Rule + val installDialogStarter = ActivityTestRule(FutureResultActivity::class.java) + + val context: Context = InstrumentationRegistry.getTargetContext() + val apkFile = File(context.filesDir, TEST_APK_NAME) + val uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) + @Before fun uninstallTestApp() { val cmd = ShellCommand.builder("pm uninstall") @@ -84,6 +119,11 @@ class UserRestrictionInstallTest : PackageInstallerTestBase() { } } + @Before + fun copyTestApk() { + File(TEST_APK_LOCATION, TEST_APK_NAME).copyTo(target = apkFile, overwrite = true) + } + @Test @ApiTest(apis = ["android.os.UserManager#DISALLOW_DEBUGGING_FEATURES"]) @DevicePolicyRelevant @@ -97,13 +137,15 @@ class UserRestrictionInstallTest : PackageInstallerTestBase() { installPackageViaAdb(apkPath = "$TEST_APK_LOCATION/$TEST_APK_NAME") assertWithMessage("Test app should be installed in initial user") - .that(TestApis.packages().find(TEST_APK_PACKAGE_NAME).installedOnUser(initialUser)) - .isTrue() + .that(TestApis.packages().find(TEST_APK_PACKAGE_NAME).installedOnUser(initialUser)) + .isTrue() - assertWithMessage("Test app shouldn't be installed in a work profile with " + - "$DISALLOW_DEBUGGING_FEATURES set") - .that(TestApis.packages().find(TEST_APK_PACKAGE_NAME).installedOnUser(workProfile)) - .isFalse() + assertWithMessage( + "Test app shouldn't be installed in a work profile with " + + "$DISALLOW_DEBUGGING_FEATURES set" + ) + .that(TestApis.packages().find(TEST_APK_PACKAGE_NAME).installedOnUser(workProfile)) + .isFalse() } @Test @@ -117,10 +159,12 @@ class UserRestrictionInstallTest : PackageInstallerTestBase() { installPackageViaAdb(apkPath = "$TEST_APK_LOCATION/$TEST_APK_NAME", user = workProfile) - assertWithMessage("Test app shouldn't be installed in a work profile with " + - "$DISALLOW_DEBUGGING_FEATURES set") - .that(TestApis.packages().find(TEST_APK_PACKAGE_NAME).installedOnUser(workProfile)) - .isFalse() + assertWithMessage( + "Test app shouldn't be installed in a work profile with " + + "$DISALLOW_DEBUGGING_FEATURES set" + ) + .that(TestApis.packages().find(TEST_APK_PACKAGE_NAME).installedOnUser(workProfile)) + .isFalse() } @Test @@ -138,7 +182,7 @@ class UserRestrictionInstallTest : PackageInstallerTestBase() { val result: Intent? = commitSessionAsUser(workProfile, session) assertThat(result).isNotNull() assertThat(result!!.getIntExtra(EXTRA_STATUS, STATUS_FAILURE_INVALID)) - .isEqualTo(STATUS_PENDING_USER_ACTION) + .isEqualTo(STATUS_PENDING_USER_ACTION) } finally { session.abandon() } @@ -153,7 +197,7 @@ class UserRestrictionInstallTest : PackageInstallerTestBase() { @RequireRunOnWorkProfile fun disallowDebuggingFeatures_intentInstallOnWorkProfile_installationSucceeds() { val context = TestApis.context().instrumentedContext() - val apkFile = File(context.filesDir, TEST_APK_NAME) + // val apkFile = File(context.filesDir, TEST_APK_NAME) val appInstallIntent = getAppInstallationIntent(apkFile) val installation = startInstallationViaIntent(appInstallIntent) @@ -168,8 +212,10 @@ class UserRestrictionInstallTest : PackageInstallerTestBase() { @DevicePolicyRelevant @EnsureHasWorkProfile @EnsureHasUserRestriction(value = DISALLOW_INSTALL_APPS, onUser = UserType.WORK_PROFILE) - @EnsureDoesNotHaveUserRestriction(value = DISALLOW_DEBUGGING_FEATURES, - onUser = UserType.WORK_PROFILE) + @EnsureDoesNotHaveUserRestriction( + value = DISALLOW_DEBUGGING_FEATURES, + onUser = UserType.WORK_PROFILE + ) fun disallowInstallApps_adbInstallOnAllUsers_installedOnUnrestrictedUser() { val initialUser = sDeviceState.initialUser() val workProfile = sDeviceState.workProfile() @@ -180,14 +226,17 @@ class UserRestrictionInstallTest : PackageInstallerTestBase() { it.packageName().equals(TEST_APK_PACKAGE_NAME) } assertWithMessage("Test app should be installed in initial user") - .that(targetPackage.size).isNotEqualTo(0) + .that(targetPackage.size) + .isNotEqualTo(0) targetPackage = TestApis.packages().installedForUser(workProfile).filter { it.packageName().equals(TEST_APK_PACKAGE_NAME) } - assertWithMessage("Test app shouldn't be installed in a work profile with " + - "$DISALLOW_INSTALL_APPS set") - .that(targetPackage.size).isEqualTo(0) + assertWithMessage( + "Test app shouldn't be installed in a work profile with $DISALLOW_INSTALL_APPS set" + ) + .that(targetPackage.size) + .isEqualTo(0) } @Test @@ -195,21 +244,27 @@ class UserRestrictionInstallTest : PackageInstallerTestBase() { @DevicePolicyRelevant @EnsureHasWorkProfile @EnsureHasUserRestriction(value = DISALLOW_INSTALL_APPS, onUser = UserType.WORK_PROFILE) - @EnsureDoesNotHaveUserRestriction(value = DISALLOW_DEBUGGING_FEATURES, - onUser = UserType.WORK_PROFILE) + @EnsureDoesNotHaveUserRestriction( + value = DISALLOW_DEBUGGING_FEATURES, + onUser = UserType.WORK_PROFILE + ) fun disallowInstallApps_adbInstallOnWorkProfile_fails() { val workProfile = sDeviceState.workProfile() - assertThat(TestApis.devicePolicy().userRestrictions(workProfile) - .isSet(DISALLOW_INSTALL_APPS)).isTrue() + assertThat( + TestApis.devicePolicy().userRestrictions(workProfile).isSet(DISALLOW_INSTALL_APPS) + ).isTrue() installPackageViaAdb(apkPath = "$TEST_APK_LOCATION/$TEST_APK_NAME", user = workProfile) val targetPackage = TestApis.packages().installedForUser(workProfile).filter { it.packageName().equals(TEST_APK_PACKAGE_NAME) } - assertWithMessage("Test app shouldn't be installed in a work profile with " + - "$DISALLOW_DEBUGGING_FEATURES set") - .that(targetPackage.size).isEqualTo(0) + assertWithMessage( + "Test app shouldn't be installed in a work profile with " + + "$DISALLOW_DEBUGGING_FEATURES set" + ) + .that(targetPackage.size) + .isEqualTo(0) } @Test @@ -217,8 +272,10 @@ class UserRestrictionInstallTest : PackageInstallerTestBase() { @DevicePolicyRelevant @EnsureHasWorkProfile @EnsureHasUserRestriction(value = DISALLOW_INSTALL_APPS, onUser = UserType.WORK_PROFILE) - @EnsureDoesNotHaveUserRestriction(value = DISALLOW_DEBUGGING_FEATURES, - onUser = UserType.WORK_PROFILE) + @EnsureDoesNotHaveUserRestriction( + value = DISALLOW_DEBUGGING_FEATURES, + onUser = UserType.WORK_PROFILE + ) @EnsureHasPermission(INTERACT_ACROSS_USERS_FULL) fun disallowInstallApps_sessionInstallOnWorkProfile_throwsException() { val workProfile = sDeviceState.workProfile() @@ -231,13 +288,15 @@ class UserRestrictionInstallTest : PackageInstallerTestBase() { @ApiTest(apis = ["android.os.UserManager#DISALLOW_INSTALL_APPS"]) @DevicePolicyRelevant @EnsureHasUserRestriction(value = DISALLOW_INSTALL_APPS, onUser = UserType.WORK_PROFILE) - @EnsureDoesNotHaveUserRestriction(value = DISALLOW_DEBUGGING_FEATURES, - onUser = UserType.WORK_PROFILE) + @EnsureDoesNotHaveUserRestriction( + value = DISALLOW_DEBUGGING_FEATURES, + onUser = UserType.WORK_PROFILE + ) @EnsureHasAppOp(OPSTR_REQUEST_INSTALL_PACKAGES) @RequireRunOnWorkProfile fun disallowInstallApps_intentInstallOnWorkProfile_installationFails() { val context = TestApis.context().instrumentedContext() - val apkFile = File(context.filesDir, TEST_APK_NAME) + // val apkFile = File(context.filesDir, TEST_APK_NAME) val appInstallIntent = getAppInstallationIntent(apkFile) val installation = startInstallationViaIntent(appInstallIntent) @@ -249,24 +308,30 @@ class UserRestrictionInstallTest : PackageInstallerTestBase() { // Install should have failed assertThat(installation.get(TIMEOUT, TimeUnit.MILLISECONDS)) - .isEqualTo(Activity.RESULT_CANCELED) + .isEqualTo(Activity.RESULT_CANCELED) } @Test - @ApiTest(apis = ["android.os.UserManager#DISALLOW_DEBUGGING_FEATURES", - "android.os.UserManager#DISALLOW_INSTALL_APPS"]) + @ApiTest( + apis = ["android.os.UserManager#DISALLOW_DEBUGGING_FEATURES", + "android.os.UserManager#DISALLOW_INSTALL_APPS"] + ) @DevicePolicyRelevant @EnsureHasWorkProfile - @EnsureDoesNotHaveUserRestriction(value = DISALLOW_DEBUGGING_FEATURES, - onUser = UserType.WORK_PROFILE) + @EnsureDoesNotHaveUserRestriction( + value = DISALLOW_DEBUGGING_FEATURES, + onUser = UserType.WORK_PROFILE + ) @EnsureDoesNotHaveUserRestriction(value = DISALLOW_INSTALL_APPS, onUser = UserType.WORK_PROFILE) fun unrestrictedWorkProfile_adbInstallOnAllUsers_installedOnAllUsers() { val initialUser = sDeviceState.initialUser() val workProfile = sDeviceState.workProfile() - assertThat(TestApis.devicePolicy().userRestrictions(workProfile) - .isSet(DISALLOW_DEBUGGING_FEATURES)).isFalse() - assertThat(TestApis.devicePolicy().userRestrictions(workProfile) - .isSet(DISALLOW_INSTALL_APPS)).isFalse() + assertThat( + TestApis.devicePolicy().userRestrictions(workProfile).isSet(DISALLOW_DEBUGGING_FEATURES) + ).isFalse() + assertThat( + TestApis.devicePolicy().userRestrictions(workProfile).isSet(DISALLOW_INSTALL_APPS) + ).isFalse() installPackageViaAdb(apkPath = "$TEST_APK_LOCATION/$TEST_APK_NAME") @@ -274,13 +339,22 @@ class UserRestrictionInstallTest : PackageInstallerTestBase() { it.packageName().equals(TEST_APK_PACKAGE_NAME) } assertWithMessage("Test app should be installed in initial user") - .that(targetPackage.size).isNotEqualTo(0) + .that(targetPackage.size) + .isNotEqualTo(0) targetPackage = TestApis.packages().installedForUser(workProfile).filter { it.packageName().equals(TEST_APK_PACKAGE_NAME) } assertWithMessage("Test app should be installed in work profile") - .that(targetPackage.size).isNotEqualTo(0) + .that(targetPackage.size) + .isNotEqualTo(0) + } + + /** + * Start an installation via an Intent + */ + private fun startInstallationViaIntent(intent: Intent): CompletableFuture<Int> { + return installDialogStarter.activity.startActivityForResult(intent) } private fun installPackageViaAdb(apkPath: String, user: UserReference? = null): String? { @@ -310,11 +384,11 @@ class UserRestrictionInstallTest : PackageInstallerTestBase() { } private fun writeSessionAsUser( - user: UserReference = sDeviceState.initialUser(), - session: Session + user: UserReference = sDeviceState.initialUser(), + session: Session ) { val context = TestApis.context().androidContextAsUser(user) - val apkFile = File(context.filesDir, TEST_APK_NAME) + // val apkFile = File(context.filesDir, TEST_APK_NAME) // Write data to session apkFile.inputStream().use { fileOnDisk -> session.openWrite(TEST_APK_NAME, 0, -1).use { sessionFile -> @@ -324,8 +398,8 @@ class UserRestrictionInstallTest : PackageInstallerTestBase() { } private fun commitSessionAsUser( - user: UserReference = sDeviceState.initialUser(), - session: Session + user: UserReference = sDeviceState.initialUser(), + session: Session ): Intent? { val context = TestApis.context().androidContextAsUser(user) val receiver: BlockingBroadcastReceiver = @@ -335,8 +409,11 @@ class UserRestrictionInstallTest : PackageInstallerTestBase() { val intent = Intent(APP_INSTALL_ACTION).setPackage(context.packageName) .addFlags(Intent.FLAG_RECEIVER_FOREGROUND) val pendingIntent = PendingIntent.getBroadcast( - context, 0 /* requestCode */, intent, - PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE) + context, + 0 /* requestCode */, + intent, + PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE + ) session.commit(pendingIntent.intentSender) @@ -351,4 +428,65 @@ class UserRestrictionInstallTest : PackageInstallerTestBase() { intent.putExtra(Intent.EXTRA_RETURN_RESULT, true) return intent } + + /** + * Click a button in the UI of the installer app + * + * @param resId The resource ID of the button to click + */ + fun clickInstallerUIButton(resId: String) { + clickInstallerUIButton(getBySelector(resId)) + } + + fun getBySelector(id: String): BySelector { + // Normally, we wouldn't need to look for buttons from 2 different packages. + // However, to fix b/297132020, AlertController was replaced with AlertDialog and shared + // to selective partners, leading to fragmentation in which button surfaces in an OEM's + // installer app. + return By.res( + Pattern.compile( + String.format( + "(?:^%s|^%s):id/%s", PACKAGE_INSTALLER_PACKAGE_NAME, SYSTEM_PACKAGE_NAME, id + ) + ) + ) + } + + /** + * Click a button in the UI of the installer app + * + * @param bySelector The bySelector of the button to click + */ + fun clickInstallerUIButton(bySelector: BySelector) { + var button: UiObject2? = null + val startTime = System.currentTimeMillis() + while (startTime + TIMEOUT > System.currentTimeMillis()) { + try { + button = uiDevice.wait(Until.findObject(bySelector), 1000) + if (button != null) { + Log.d( + TAG, + "Found bounds: ${button.getVisibleBounds()} of button $bySelector," + + " text: ${button.getText()}," + + " package: ${button.getApplicationPackage()}" + ) + button.click() + return + } else { + // Maybe the screen is small. Swipe down and attempt to click + swipeDown() + } + } catch (ignore: Throwable) { + } + } + Assert.fail("Failed to click the button: $bySelector") + } + + private fun swipeDown() { + // Perform a swipe from the center of the screen to the top of the screen. + // Higher the "steps" value, slower is the swipe + val centerX = uiDevice.displayWidth / 2 + val centerY = uiDevice.displayHeight / 2 + uiDevice.swipe(centerX, centerY, centerX, 0, 10) + } } diff --git a/tests/tests/permission3/src/android/permission3/cts/PermissionTest23.kt b/tests/tests/permission3/src/android/permission3/cts/PermissionTest23.kt index 4557d0c9df2..d8960da9651 100644 --- a/tests/tests/permission3/src/android/permission3/cts/PermissionTest23.kt +++ b/tests/tests/permission3/src/android/permission3/cts/PermissionTest23.kt @@ -113,6 +113,9 @@ class PermissionTest23 : BaseUsePermissionTest() { clickPermissionRequestAllowButton() } + // Wait for PermissionController's LiveData to catch up + Thread.sleep(5_000) + // Request the permission and do nothing // Expect the permission is granted requestAppPermissionsAndAssertResult(android.Manifest.permission.WRITE_CONTACTS to true) {} diff --git a/tests/tests/permission3/src/android/permission3/cts/PermissionTest30WithBluetooth.kt b/tests/tests/permission3/src/android/permission3/cts/PermissionTest30WithBluetooth.kt index fb2d7e9ab5f..02d07c7eb7b 100644 --- a/tests/tests/permission3/src/android/permission3/cts/PermissionTest30WithBluetooth.kt +++ b/tests/tests/permission3/src/android/permission3/cts/PermissionTest30WithBluetooth.kt @@ -57,9 +57,9 @@ class PermissionTest30WithBluetooth : BaseUsePermissionTest() { private val TEST_APP_PKG = "android.permission3.cts.usepermission" private lateinit var bluetoothAdapter: BluetoothAdapter - private var bluetoothAdapterWasEnabled: Boolean = false + private var bluetoothAdapterWasEnabled: Boolean? = null private val locationManager = context.getSystemService(LocationManager::class.java)!! - private var locationWasEnabled: Boolean = false + private var locationWasEnabled: Boolean? = null private enum class BluetoothScanResult { UNKNOWN, ERROR, EXCEPTION, EMPTY, FILTERED, FULL @@ -79,8 +79,10 @@ class PermissionTest30WithBluetooth : BaseUsePermissionTest() { assumeTrue(supportsBluetooth()) bluetoothAdapter = context.getSystemService(BluetoothManager::class.java).adapter bluetoothAdapterWasEnabled = bluetoothAdapter.isEnabled() - runWithShellPermissionIdentity { - assertTrue(BTAdapterUtils.enableAdapter(bluetoothAdapter, context)) + if (bluetoothAdapterWasEnabled == false) { + runWithShellPermissionIdentity { + assertTrue(BTAdapterUtils.enableAdapter(bluetoothAdapter, context)) + } } enableTestMode() } @@ -89,7 +91,7 @@ class PermissionTest30WithBluetooth : BaseUsePermissionTest() { fun enableLocation() { val userHandle: UserHandle = Process.myUserHandle() locationWasEnabled = locationManager.isLocationEnabledForUser(userHandle) - if (!locationWasEnabled) { + if (locationWasEnabled == false) { runWithShellPermissionIdentity { locationManager.setLocationEnabledForUser(true, userHandle) } @@ -100,7 +102,7 @@ class PermissionTest30WithBluetooth : BaseUsePermissionTest() { fun disableLocation() { val userHandle: UserHandle = Process.myUserHandle() - if (!locationWasEnabled) { + if (locationWasEnabled == false) { runWithShellPermissionIdentity { locationManager.setLocationEnabledForUser(false, userHandle) } @@ -111,7 +113,7 @@ class PermissionTest30WithBluetooth : BaseUsePermissionTest() { fun disableBluetooth() { assumeTrue(supportsBluetooth()) disableTestMode() - if (!bluetoothAdapterWasEnabled) { + if (bluetoothAdapterWasEnabled == false) { runWithShellPermissionIdentity { assertTrue(BTAdapterUtils.disableAdapter(bluetoothAdapter, context)) } diff --git a/tests/tests/persistentdataservice/AndroidTest.xml b/tests/tests/persistentdataservice/AndroidTest.xml index e47032f4d00..7d047fe4da7 100644 --- a/tests/tests/persistentdataservice/AndroidTest.xml +++ b/tests/tests/persistentdataservice/AndroidTest.xml @@ -22,6 +22,9 @@ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" /> <option name="config-descriptor:metadata" key="parameter" value="multi_abi" /> <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> + <!-- See b/341342803. --> + <option name="hidden-api-checks" value="false" /> + <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true" /> <option name="test-file-name" value="CtsPersistentDataBlockManagerTestCases.apk" /> diff --git a/tests/tests/preference/src/android/preference/cts/TestUtils.java b/tests/tests/preference/src/android/preference/cts/TestUtils.java index 2c3ed27c2af..f9968fa0bdf 100644 --- a/tests/tests/preference/src/android/preference/cts/TestUtils.java +++ b/tests/tests/preference/src/android/preference/cts/TestUtils.java @@ -70,7 +70,7 @@ public class TestUtils { // Only take a screenshot once the screen is stable enough. waitForIdle(); - Bitmap bt = mAutomation.takeScreenshot(); + Bitmap bt = mAutomation.takeScreenshot(mRule.getActivity().getWindow()); assertNotNull("Screenshot must not return null", bt); // Crop-out the status bar to avoid flakiness with changing notifications / time. diff --git a/tests/tests/security/src/android/security/cts/CertificateData.java b/tests/tests/security/src/android/security/cts/CertificateData.java index 08ff3c30cf7..0b976c2ac41 100644 --- a/tests/tests/security/src/android/security/cts/CertificateData.java +++ b/tests/tests/security/src/android/security/cts/CertificateData.java @@ -24,6 +24,12 @@ package android.security.cts; * to generate this file. */ class CertificateData { + static final String[] OPTIONAL_CERTIFICATE_DATA = { + "F4:27:86:EB:6E:B8:6D:88:31:67:02:FB:BA:66:A4:53:00:AA:7A:A6", + "D5:EC:8D:7B:4C:BA:79:F4:E7:E8:CB:9D:6B:AE:77:83:10:03:21:6A", + "D6:DA:A8:20:8D:09:D2:15:4D:24:B5:2F:CB:34:6E:B2:58:B2:8A:58", + }; + static final String[] CERTIFICATE_DATA = { "99:9A:64:C3:7F:F4:7D:9F:AB:95:F1:47:69:89:14:60:EE:C4:C3:C5", "D1:CB:CA:5D:B2:D5:2A:7F:69:3B:67:4D:E5:F0:5A:1D:0C:95:7D:F0", @@ -77,7 +83,6 @@ class CertificateData { "4C:DD:51:A3:D1:F5:20:32:14:B0:C6:C5:32:23:03:91:C7:46:42:6D", "0D:44:DD:8C:3C:8C:1A:1A:58:75:64:81:E9:0F:2E:2A:FF:B3:D2:6E", "CA:3A:FB:CF:12:40:36:4B:44:B2:16:20:88:80:48:39:19:93:7C:F7", - "F4:27:86:EB:6E:B8:6D:88:31:67:02:FB:BA:66:A4:53:00:AA:7A:A6", "5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25", "49:0A:75:74:DE:87:0A:47:FE:58:EE:F6:C7:6B:EB:C6:0B:12:40:99", "89:D4:83:03:4F:9E:9A:48:80:5F:72:37:D4:A9:A6:EF:CB:7C:1F:D1", @@ -159,7 +164,6 @@ class CertificateData { "5A:8C:EF:45:D7:A6:98:59:76:7A:8C:8B:44:96:B5:78:CF:47:4B:1A", "8D:A7:F9:65:EC:5E:FC:37:91:0F:1C:6E:59:FD:C1:CC:6A:6E:DE:16", "B1:2E:13:63:45:86:A4:6F:1A:B2:60:68:37:58:2D:C4:AC:FD:94:97", - "D5:EC:8D:7B:4C:BA:79:F4:E7:E8:CB:9D:6B:AE:77:83:10:03:21:6A", }; static final String[] WFA_CERTIFICATE_DATA = { diff --git a/tests/tests/security/src/android/security/cts/CertificateTest.java b/tests/tests/security/src/android/security/cts/CertificateTest.java index 75693383995..875d0aae2ab 100644 --- a/tests/tests/security/src/android/security/cts/CertificateTest.java +++ b/tests/tests/security/src/android/security/cts/CertificateTest.java @@ -97,8 +97,11 @@ public class CertificateTest { System.setProperty("system.certs.enabled", mApexCertsEnabled); Set<String> expectedCertificates = new HashSet<String>( Arrays.asList(CertificateData.CERTIFICATE_DATA)); + Set<String> optionalCertificates = new HashSet<String>( + Arrays.asList(CertificateData.OPTIONAL_CERTIFICATE_DATA)); Set<String> deviceCertificates = getDeviceCertificates(); deviceCertificates.removeAll(expectedCertificates); + deviceCertificates.removeAll(optionalCertificates); assertEquals("Unknown CA certificates", Collections.EMPTY_SET, deviceCertificates); } diff --git a/tests/tests/telecom/src/android/telecom/cts/ExtendedInCallServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/ExtendedInCallServiceTest.java index c241fc5aa64..1b58c681f68 100644 --- a/tests/tests/telecom/src/android/telecom/cts/ExtendedInCallServiceTest.java +++ b/tests/tests/telecom/src/android/telecom/cts/ExtendedInCallServiceTest.java @@ -41,6 +41,8 @@ import android.telecom.TelecomManager; import android.telecom.VideoProfile; import android.telephony.TelephonyManager; +import androidx.test.filters.FlakyTest; + import com.android.compatibility.common.util.FeatureUtil; import java.util.List; @@ -488,6 +490,7 @@ public class ExtendedInCallServiceTest extends BaseTelecomTestWithMockServices { } } + @FlakyTest public void testSwitchCallEndpoint() { if (!mShouldTestTelecom) { return; diff --git a/tests/tests/telephony/current/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java index 16bb603c654..f24024f0bf6 100644 --- a/tests/tests/telephony/current/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java +++ b/tests/tests/telephony/current/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java @@ -126,6 +126,10 @@ public class SmsUsageMonitorShortCodeTest { new ShortCodeTest("be", "6566", SMS_CATEGORY_PREMIUM_SHORT_CODE), new ShortCodeTest("be", "7777", SMS_CATEGORY_PREMIUM_SHORT_CODE), + new ShortCodeTest("bf", "35696", SMS_CATEGORY_NOT_SHORT_CODE), + new ShortCodeTest("bf", "3681", SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE), + new ShortCodeTest("bf", "3558", SMS_CATEGORY_FREE_SHORT_CODE), + new ShortCodeTest("bg", "112", SMS_CATEGORY_NOT_SHORT_CODE), new ShortCodeTest("bg", "116117", SMS_CATEGORY_FREE_SHORT_CODE), new ShortCodeTest("bg", "1234", SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE), @@ -349,10 +353,12 @@ public class SmsUsageMonitorShortCodeTest { new ShortCodeTest("il", "6688", SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE), new ShortCodeTest("il", "6681", SMS_CATEGORY_FREE_SHORT_CODE), - new ShortCodeTest("ir", "7007924", SMS_CATEGORY_NOT_SHORT_CODE), - new ShortCodeTest("ir", "700799", SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE), + new ShortCodeTest("ir", "300086178", SMS_CATEGORY_NOT_SHORT_CODE), + new ShortCodeTest("ir", "30008790",SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE), new ShortCodeTest("ir", "700792", SMS_CATEGORY_FREE_SHORT_CODE), new ShortCodeTest("ir", "700791", SMS_CATEGORY_FREE_SHORT_CODE), + new ShortCodeTest("ir", "100016", SMS_CATEGORY_FREE_SHORT_CODE), + new ShortCodeTest("ir", "30008360", SMS_CATEGORY_FREE_SHORT_CODE), new ShortCodeTest("it", "112", SMS_CATEGORY_NOT_SHORT_CODE), new ShortCodeTest("it", "116117", SMS_CATEGORY_FREE_SHORT_CODE), @@ -655,7 +661,7 @@ public class SmsUsageMonitorShortCodeTest { new ShortCodeTest("ye", "50824", SMS_CATEGORY_NOT_SHORT_CODE), new ShortCodeTest("ye", "5084", SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE), - new ShortCodeTest("ye", "5081", SMS_CATEGORY_FREE_SHORT_CODE), + new ShortCodeTest("ye", "5079", SMS_CATEGORY_FREE_SHORT_CODE), new ShortCodeTest("za", "330092", SMS_CATEGORY_NOT_SHORT_CODE), new ShortCodeTest("za", "33001", SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE), diff --git a/tests/tests/tv/src/android/media/tv/tuner/cts/TunerResourceTestService.java b/tests/tests/tv/src/android/media/tv/tuner/cts/TunerResourceTestService.java index e7145088bb3..93cdf000e15 100644 --- a/tests/tests/tv/src/android/media/tv/tuner/cts/TunerResourceTestService.java +++ b/tests/tests/tv/src/android/media/tv/tuner/cts/TunerResourceTestService.java @@ -69,6 +69,9 @@ public class TunerResourceTestService extends Service { mFeInfo = infos.get(frontendIndex); mFeSettings = TunerTest.createFrontendSettings(mFeInfo); + // apply target frontend only, for case when there are multiple instances in frontend type + mTuner.applyFrontend(mFeInfo); + // tune return mTuner.tune(mFeSettings); } 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 6a4ab4ec3a5..0d07786977f 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 @@ -24,6 +24,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.junit.Assume.assumeNotNull; +import static org.junit.Assume.assumeTrue; import android.content.ComponentName; import android.content.Context; @@ -1111,7 +1112,8 @@ public class TunerTest { return; } - assertEquals(lnb.setVoltage(Lnb.VOLTAGE_5V), Tuner.RESULT_SUCCESS); + int targetLnbVoltage = getTargetLnbVoltage(); + assertEquals(lnb.setVoltage(targetLnbVoltage), Tuner.RESULT_SUCCESS); assertEquals(lnb.setTone(Lnb.TONE_NONE), Tuner.RESULT_SUCCESS); assertEquals( lnb.setSatellitePosition(Lnb.POSITION_A), Tuner.RESULT_SUCCESS); @@ -1662,17 +1664,17 @@ public class TunerTest { assertFalse(ids.isEmpty()); int targetFrontendId = sTunerCtsConfiguration.getTargetFrontendId().intValueExact(); FrontendInfo info = mTuner.getFrontendInfoById(ids.get(targetFrontendId)); - FrontendSettings feSettings = createFrontendSettings(info); - // first tune with mTuner to acquire resource - int res = mTuner.tune(feSettings); + // first apply frontend with mTuner to acquire resource + int res = mTuner.applyFrontend(info); assertEquals(Tuner.RESULT_SUCCESS, res); assertNotNull(mTuner.getFrontendInfo()); - // now tune with a higher priority tuner to have mTuner's resource reclaimed + // now apply frontend with a higher priority tuner to have mTuner's resource reclaimed Tuner higherPrioTuner = new Tuner(mContext, null, 200); - res = higherPrioTuner.tune(feSettings); + res = higherPrioTuner.applyFrontend(info); assertEquals(Tuner.RESULT_SUCCESS, res); + assertNotNull(higherPrioTuner.getFrontendInfo()); higherPrioTuner.close(); @@ -1688,8 +1690,8 @@ public class TunerTest { FrontendInfo info = mTuner.getFrontendInfoById(ids.get(targetFrontendId)); FrontendSettings feSettings = createFrontendSettings(info); - // first tune with mTuner to acquire resource - int res = mTuner.tune(feSettings); + // first apply frontend with mTuner to acquire resource + int res = mTuner.applyFrontend(info); assertEquals(Tuner.RESULT_SUCCESS, res); assertNotNull(mTuner.getFrontendInfo()); @@ -1749,9 +1751,11 @@ public class TunerTest { tunerResourceTestServer = connection.getService(); // CASE1 - normal reclaim - // - // first tune with mTuner to acquire resource - int res = mTuner.tune(feSettings); + + // first apply frontend with mTuner to acquire resource + int res = mTuner.applyFrontend(info); + assertEquals(Tuner.RESULT_SUCCESS, res); + boolean tunerReclaimed = false; assertEquals(Tuner.RESULT_SUCCESS, res); assertNotNull(mTuner.getFrontendInfo()); @@ -1827,27 +1831,27 @@ public class TunerTest { @Test public void testShareFrontendFromTuner() throws Exception { - Tuner tuner100 = new Tuner(mContext, null, 100); - List<Integer> ids = tuner100.getFrontendIds(); + List<Integer> ids = mTuner.getFrontendIds(); assumeNotNull(ids); assertFalse(ids.isEmpty()); int targetFrontendId = sTunerCtsConfiguration.getTargetFrontendId().intValueExact(); - FrontendInfo info = tuner100.getFrontendInfoById(ids.get(targetFrontendId)); + FrontendInfo info = mTuner.getFrontendInfoById(ids.get(targetFrontendId)); FrontendSettings feSettings = createFrontendSettings(info); + int[] statusTypes = {1}; - boolean exceptionThrown = false; - int res; + boolean exceptionThrown; - // CASE1: check resource reclaim while sharee's priority < owner's priority - // let tuner100 share from tuner200 + Tuner tuner100 = new Tuner(mContext, null, 100); Tuner tuner200 = new Tuner(mContext, null, 200); - res = tuner200.tune(feSettings); - assertEquals(Tuner.RESULT_SUCCESS, res); + Tuner tuner300 = new Tuner(mContext, null, 300); - info = tuner200.getFrontendInfoById(ids.get(targetFrontendId)); - res = tuner200.tune(feSettings); + // CASE1: check resource reclaim while sharee's priority < owner's priority + + // apply target frontend only, for case when there are multiple instances in frontend type + int res = tuner200.applyFrontend(info); assertEquals(Tuner.RESULT_SUCCESS, res); + // let tuner100 share from tuner200 tuner100.shareFrontendFromTuner(tuner200); // call openFilter to trigger ITunerDemux.setFrontendDataSourceById() Filter f = tuner100.openFilter( @@ -1859,7 +1863,6 @@ public class TunerTest { TunerTestOnTuneEventListener cb200 = new TunerTestOnTuneEventListener(); // tune again on the owner - info = tuner200.getFrontendInfoById(ids.get(1)); tuner100.setOnTuneEventListener(getExecutor(), cb100); tuner200.setOnTuneEventListener(getExecutor(), cb200); res = tuner200.tune(feSettings); @@ -1870,8 +1873,7 @@ public class TunerTest { tuner200.clearOnTuneEventListener(); // now let the higher priority tuner steal the resource - Tuner tuner300 = new Tuner(mContext, null, 300); - res = tuner300.tune(feSettings); + res = tuner300.applyFrontend(info); assertEquals(Tuner.RESULT_SUCCESS, res); // confirm owner & sharee's resource gets reclaimed by confirming an exception is thrown @@ -1898,7 +1900,9 @@ public class TunerTest { // CASE2: check resource reclaim fail when sharee's priority > new requester tuner100 = new Tuner(mContext, null, 100); - res = tuner100.tune(feSettings); + + // apply target frontend only, for case when there are multiple instances in frontend type + res = tuner100.applyFrontend(info); assertEquals(Tuner.RESULT_SUCCESS, res); tuner300 = new Tuner(mContext, null, 300); @@ -1908,7 +1912,9 @@ public class TunerTest { assertNotNull(f); tuner200 = new Tuner(mContext, null, 200); - res = tuner200.tune(feSettings); + + // apply target frontend only, for case when there are multiple instances in frontend type + res = tuner200.applyFrontend(info); assertNotEquals(Tuner.RESULT_SUCCESS, res); // confirm the original tuner is still intact @@ -1926,13 +1932,15 @@ public class TunerTest { assertFalse(ids.isEmpty()); int targetFrontendId = sTunerCtsConfiguration.getTargetFrontendId().intValueExact(); FrontendInfo info = mTuner.getFrontendInfoById(ids.get(targetFrontendId)); - FrontendSettings feSettings = createFrontendSettings(info); + createFrontendSettings(info); // SCENARIO 1 - transfer and close the previous owner - // First create a tuner and tune() to acquire frontend resource + // First create a tuner and applyFrontend() to acquire frontend resource Tuner tunerA = new Tuner(mContext, null, 100); - int res = tunerA.tune(feSettings); + + // apply target frontend only, for case when there are multiple instances in frontend type + int res = tunerA.applyFrontend(info); assertEquals(Tuner.RESULT_SUCCESS, res); // Create another tuner and share frontend from tunerA @@ -1962,9 +1970,11 @@ public class TunerTest { // SCENARIO 2 - transfer and closeFrontend and tune on the previous owner - // First create a tuner and tune() to acquire frontend resource + // First create a tuner and applyFrontend() to acquire frontend resource tunerA = new Tuner(mContext, null, 200); - res = tunerA.tune(feSettings); + + // apply target frontend only, for case when there are multiple instances in frontend type + res = tunerA.applyFrontend(info); assertEquals(Tuner.RESULT_SUCCESS, res); // Create another tuner and share frontend from tunerA @@ -1981,7 +1991,9 @@ public class TunerTest { // Confirm tune works without going through Tuner.close() even after transferOwner() // The purpose isn't to get tunerB's frontend revoked, but doing so as singletuner // based test has wider coverage - res = tunerA.tune(feSettings); // this should reclaim tunerB + + // apply target frontend only, for case when there are multiple instances in frontend type + res = tunerA.applyFrontend(info); assertEquals(Tuner.RESULT_SUCCESS, res); // Confirm tuberB is revoked @@ -2071,8 +2083,9 @@ public class TunerTest { // Open Lnb and check the callback TunerTestLnbCallback lnbCB1 = new TunerTestLnbCallback(); Lnb lnbA = tunerA.openLnb(getExecutor(), lnbCB1); - assertNotNull(lnbA); - lnbA.setVoltage(Lnb.VOLTAGE_5V); + assumeTrue(lnbA != null); + int targetLnbVoltage = getTargetLnbVoltage(); + lnbA.setVoltage(targetLnbVoltage); lnbA.setTone(Lnb.TONE_CONTINUOUS); lnbA.sendDiseqcMessage(new byte[] {1, 2}); assertTrue(lnbCB1.getOnDiseqcMessageCalled()); @@ -2937,29 +2950,33 @@ public class TunerTest { int type = mTuner.getFrontendInfoById(ids.get(i)).getType(); if (TunerVersionChecker.isHigherOrEqualVersionTo( TunerVersionChecker.TUNER_VERSION_2_0)) { - int defaultMax = -1; + int defaultMax = mTuner.getMaxNumberOfFrontends(type); int status; - // Check default value - defaultMax = mTuner.getMaxNumberOfFrontends(type); - assertTrue(defaultMax > 0); - // Set to -1 - status = mTuner.setMaxNumberOfFrontends(type, -1); - assertEquals(Tuner.RESULT_INVALID_ARGUMENT, status); - // Set to defaultMax + 1 - status = mTuner.setMaxNumberOfFrontends(type, defaultMax + 1); - assertEquals(Tuner.RESULT_INVALID_ARGUMENT, status); - // Set to 0 - status = mTuner.setMaxNumberOfFrontends(type, 0); - assertEquals(Tuner.RESULT_SUCCESS, status); - // Check after set - int currentMax = -1; - currentMax = mTuner.getMaxNumberOfFrontends(type); - assertEquals(currentMax, 0); - // Reset to default - status = mTuner.setMaxNumberOfFrontends(type, defaultMax); - assertEquals(Tuner.RESULT_SUCCESS, status); - currentMax = mTuner.getMaxNumberOfFrontends(type); - assertEquals(defaultMax, currentMax); + // Use try block to ensure restoring the max Tuner + try { + // Check default value + assertTrue(defaultMax > 0); + // Set to -1 + status = mTuner.setMaxNumberOfFrontends(type, -1); + assertEquals(Tuner.RESULT_INVALID_ARGUMENT, status); + // Set to defaultMax + 1 + status = mTuner.setMaxNumberOfFrontends(type, defaultMax + 1); + assertEquals(Tuner.RESULT_INVALID_ARGUMENT, status); + // Set to 0 + status = mTuner.setMaxNumberOfFrontends(type, 0); + assertEquals(Tuner.RESULT_SUCCESS, status); + // Check after set + int currentMax = mTuner.getMaxNumberOfFrontends(type); + assertEquals(currentMax, 0); + } catch (Exception e) { + throw (e); + } finally { + // Reset to default + status = mTuner.setMaxNumberOfFrontends(type, defaultMax); + assertEquals(Tuner.RESULT_SUCCESS, status); + int currentMax = mTuner.getMaxNumberOfFrontends(type); + assertEquals(defaultMax, currentMax); + } } else { int defaultMax = mTuner.getMaxNumberOfFrontends(type); assertEquals(defaultMax, -1); @@ -2979,45 +2996,64 @@ public class TunerTest { assertEquals(Tuner.RESULT_SUCCESS, mTuner.tune(feSettings1)); assertNotNull(mTuner.getFrontendInfo()); - // validate that set max cannot be set to lower value than current usage - assertEquals(Tuner.RESULT_INVALID_ARGUMENT, + // Use try block to ensure restoring the max Tuner + try { + // validate that set max cannot be set to lower value than current usage + assertEquals(Tuner.RESULT_INVALID_ARGUMENT, mTuner.setMaxNumberOfFrontends(type1, 0)); - // validate max value is reflected in the tune behavior - mTuner.closeFrontend(); - assertEquals(Tuner.RESULT_SUCCESS, + // validate max value is reflected in the tune behavior + mTuner.closeFrontend(); + assertEquals(Tuner.RESULT_SUCCESS, mTuner.setMaxNumberOfFrontends(type1, 0)); - assertEquals(Tuner.RESULT_UNAVAILABLE, + assertEquals(Tuner.RESULT_UNAVAILABLE, mTuner.tune(feSettings1)); - assertEquals(Tuner.RESULT_SUCCESS, + assertEquals(Tuner.RESULT_SUCCESS, mTuner.setMaxNumberOfFrontends(type1, originalMax1)); - assertEquals(Tuner.RESULT_SUCCESS, mTuner.tune(feSettings1)); - assertNotNull(mTuner.getFrontendInfo()); - mTuner.closeFrontend(); + assertEquals(Tuner.RESULT_SUCCESS, mTuner.tune(feSettings1)); + assertNotNull(mTuner.getFrontendInfo()); + mTuner.closeFrontend(); + } catch (Exception e) { + throw(e); + } finally { + assertEquals(Tuner.RESULT_SUCCESS, + mTuner.setMaxNumberOfFrontends(type1, originalMax1)); + } } // validate max number on one frontend type has no impact on other if (ids.size() >= 2) { - FrontendInfo info2 = mTuner.getFrontendInfoById(ids.get(1)); - int type2 = info2.getType(); - int originalMax2 = mTuner.getMaxNumberOfFrontends(type2); - - assertEquals(Tuner.RESULT_SUCCESS, - mTuner.setMaxNumberOfFrontends(type2, 0)); - assertEquals(Tuner.RESULT_SUCCESS, - mTuner.tune(feSettings1)); - assertNotNull(mTuner.getFrontendInfo()); - - // set it back to the original max - assertEquals(Tuner.RESULT_SUCCESS, - mTuner.setMaxNumberOfFrontends(type2, originalMax2)); - mTuner.closeFrontend(); + int type2 = type1; + for (int i = 0; i < ids.size(); i++) { + FrontendInfo info2 = mTuner.getFrontendInfoById(ids.get(i)); + type2 = info2.getType(); + if (type1 != type2) break; + } + if (type1 != type2) { + int originalMax2 = mTuner.getMaxNumberOfFrontends(type2); + // Use try block to ensure restoring the max Tuner + try { + assertEquals(Tuner.RESULT_SUCCESS, + mTuner.setMaxNumberOfFrontends(type2, 0)); + assertEquals(Tuner.RESULT_SUCCESS, + mTuner.tune(feSettings1)); + assertNotNull(mTuner.getFrontendInfo()); + mTuner.closeFrontend(); + } catch (Exception e) { + throw (e); + } finally { + // set it back to the original max + assertEquals(Tuner.RESULT_SUCCESS, + mTuner.setMaxNumberOfFrontends(type2, originalMax2)); + } + } } } } + public static Filter createTsSectionFilter( Tuner tuner, Executor e, FilterCallback cb) { Filter f = tuner.openFilter(Filter.TYPE_TS, Filter.SUBTYPE_SECTION, 1000, e, cb); diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/SurfaceViewTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/SurfaceViewTests.java index a8697d24d3c..a5786f5919d 100644 --- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/SurfaceViewTests.java +++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/SurfaceViewTests.java @@ -119,10 +119,12 @@ public class SurfaceViewTests extends ActivityTestBase { a.start(); return a; } + private final Screenshotter mScreenshotter = testPositionInfo -> { - Bitmap source = getInstrumentation().getUiAutomation().takeScreenshot(); + Bitmap source = getInstrumentation().getUiAutomation().takeScreenshot( + getActivity().getWindow()); return Bitmap.createBitmap(source, - testPositionInfo.screenOffset.x, testPositionInfo.screenOffset.y, + testPositionInfo.surfaceOffset.x, testPositionInfo.surfaceOffset.y, TEST_WIDTH, TEST_HEIGHT); }; diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ActivityTestBase.java b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ActivityTestBase.java index a243bb3f9b0..fded51e9a65 100644 --- a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ActivityTestBase.java +++ b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ActivityTestBase.java @@ -180,16 +180,8 @@ public abstract class ActivityTestBase { */ public final Point surfaceOffset; - /** - * Position of capture area in screen space - use this offset for e.g. - * {@code getInstrumentation().getUiAutomation().takeScreenshot()}, - * since those screenshots are captured in screen space. - */ - public final Point screenOffset; - - public TestPositionInfo(Point surfaceOffset, Point screenOffset) { + public TestPositionInfo(Point surfaceOffset) { this.surfaceOffset = surfaceOffset; - this.screenOffset = screenOffset; } } diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/DrawActivity.kt b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/DrawActivity.kt index 110061d5cad..46abf1994e2 100644 --- a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/DrawActivity.kt +++ b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/DrawActivity.kt @@ -149,12 +149,8 @@ class DrawActivity : Activity() { val location = IntArray(2) mTestContainer.getLocationInWindow(location) val surfaceOffset = Point(location[0], location[1]) - mTestContainer.getLocationOnScreen(location) - val screenOffset = Point(location[0], location[1]) synchronized(mLock) { - mPositionInfo = ActivityTestBase.TestPositionInfo( - surfaceOffset, screenOffset - ) + mPositionInfo = ActivityTestBase.TestPositionInfo(surfaceOffset) mLock.notify() } } diff --git a/tests/videocodec/src/android/videocodec/cts/VideoEncoderMinMaxTest.java b/tests/videocodec/src/android/videocodec/cts/VideoEncoderMinMaxTest.java index 170b5a89e97..4653156b599 100644 --- a/tests/videocodec/src/android/videocodec/cts/VideoEncoderMinMaxTest.java +++ b/tests/videocodec/src/android/videocodec/cts/VideoEncoderMinMaxTest.java @@ -19,6 +19,7 @@ package android.videocodec.cts; import static android.media.MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CBR; import static android.media.MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_VBR; import static android.mediav2.common.cts.CodecTestBase.ComponentClass.HARDWARE; +import static android.mediav2.common.cts.CodecTestBase.VNDK_IS_BEFORE_U; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -290,6 +291,11 @@ public class VideoEncoderMinMaxTest extends VideoEncoderValidationTestBase { "android.media.MediaFormat#KEY_FRAME_RATE"}) @Test public void testMinMaxSupport() throws IOException, InterruptedException { + if (VNDK_IS_BEFORE_U) { + assumeTrue("Frame rate > 240 fps are limited to VNDK U and above.", + mEncCfgParams[0].mFrameRate <= 240); + } + MediaFormat format = mEncCfgParams[0].getFormat(); MediaCodecInfo info = getCodecInfo(mCodecName, mMediaType); assumeTrue(mCodecName + " does not support bitrate mode : " + bitRateModeToString( diff --git a/tools/cts-tradefed/res/config/cts-known-failures.xml b/tools/cts-tradefed/res/config/cts-known-failures.xml index ec2925756d3..17cad77586c 100644 --- a/tools/cts-tradefed/res/config/cts-known-failures.xml +++ b/tools/cts-tradefed/res/config/cts-known-failures.xml @@ -87,6 +87,9 @@ <!-- b/63916274 --> <option name="compatibility:exclude-filter" value="CtsTelecomTestCases android.telecom.cts.WiredHeadsetTest" /> + <!-- b/340793169 --> + <option name="compatibility:exclude-filter" value="CtsTelecomTestCases android.telecom.cts.ExtendedInCallServiceTest#testSwitchCallEndpoint" /> + <!-- b/62302163 --> <option name="compatibility:exclude-filter" value="CtsSecurityBulletinHostTestCases android.security.cts.Poc17_04#testPocCVE_2017_0564" /> |