diff options
author | 2023-08-22 13:40:37 -0700 | |
---|---|---|
committer | 2023-08-22 13:40:37 -0700 | |
commit | 58af55fec1f2c955f2fd80f63c4793eec61758a1 (patch) | |
tree | d98bb63dd4aac4229607a18bf748b7c15fa332f5 | |
parent | cbc0ac9a69d8d480f9cae67df2cea5d35e7a021d (diff) |
Replace waitForIdle in CtsPermissionUiTestCases
We call uiAutomation.waitForIdle in many places in our tests, including
after every click. In most cases, the motivation for doing this was to
wait for an activity to start or finish, or to finish navigating to
another screen in the same activity.
But, waitForIdle has been called "a source of problems", because of its
unreliability for actually doing what we're trying to use it for, and
often leads to unpredictable timeouts, especially when the device is
under high load.
The suggested way to address this is to use UiAutomator's "wait for
transitions" methods: UiDevice.performActionAndWait(...),
UiObject2.clickAndWait(...), etc. These methods wait for specific
accessibility events.
The general approach in this change was to:
1. Remove any redundant waitForIdle calls (i.e., multiple waitForIdle
calls in a row).
2. When opening a new window (i.e., bring a new activity to the
foreground or invoke navigation), wrap the action with
UiDevice.performActionAndWait(...). Then, any waitForIdle calls which
follow can safely be removed.
3. Each time we click anything, if that click is expected to open a new
window, use clickAndWait(Until.newWindow(), ...). Otherwise, simply
use click() and don't bother waiting for anything. Then, any
waitForIdle calls which follow can safely be removed.
4. In some cases, method arguments needed to be added (such as
"waitForWindowTransition") which tell the method whether it should
expect a new window event to occur or not after it occurs.
(After this, only a few waitForIdle calls remain. Either I haven't
been able to test those cases yet, or it's currently unclear how to
address them.)
Bug: 294875530
Test: atest CtsPermissionUiTestCases
Change-Id: I5b2a79dfa595a0291ccebd928873e93d1f12dec0
22 files changed, 373 insertions, 232 deletions
diff --git a/tests/cts/permissionui/src/android/permissionui/cts/AppDataSharingUpdatesTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/AppDataSharingUpdatesTest.kt index 6b7fe51f8..efdbea6d1 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/AppDataSharingUpdatesTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/AppDataSharingUpdatesTest.kt @@ -258,10 +258,8 @@ class AppDataSharingUpdatesTest : BaseUsePermissionTest() { try { findView(By.descContains(DATA_SHARING_UPDATES), true) findView(By.textContains(LEARN_ABOUT_DATA_SHARING), true) - waitForIdle() - click(By.textContains(LEARN_ABOUT_DATA_SHARING)) - waitForIdle() + clickAndWaitForWindowTransition(By.textContains(LEARN_ABOUT_DATA_SHARING)) eventually({assertHelpCenterLinkClickSuccessful()}, HELP_CENTER_TIMEOUT_MILLIS) } finally { @@ -297,9 +295,8 @@ class AppDataSharingUpdatesTest : BaseUsePermissionTest() { findView(By.descContains(DATA_SHARING_UPDATES), true) findView(By.textContains(UPDATES_IN_LAST_30_DAYS), true) findView(By.textContains(APP_PACKAGE_NAME_SUBSTRING), true) - waitForIdle() - click(By.textContains(APP_PACKAGE_NAME_SUBSTRING)) + clickAndWaitForWindowTransition(By.textContains(APP_PACKAGE_NAME_SUBSTRING)) findView(By.descContains(LOCATION_PERMISSION), true) findView(By.textContains(APP_PACKAGE_NAME), true) diff --git a/tests/cts/permissionui/src/android/permissionui/cts/BasePermissionTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/BasePermissionTest.kt index 5028384dc..a99357ba0 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/BasePermissionTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/BasePermissionTest.kt @@ -51,6 +51,7 @@ import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiObject2 import androidx.test.uiautomator.UiScrollable import androidx.test.uiautomator.UiSelector +import androidx.test.uiautomator.Until import com.android.compatibility.common.util.DisableAnimationRule import com.android.compatibility.common.util.FreezeRotationRule import com.android.compatibility.common.util.SystemUtil.runShellCommand @@ -86,6 +87,7 @@ abstract class BasePermissionTest { const val UNEXPECTED_TIMEOUT_MILLIS = 1000 const val TIMEOUT_MILLIS: Long = 20000 const val PACKAGE_INSTALLER_TIMEOUT = 60000L + const val NEW_WINDOW_TIMEOUT_MILLIS: Long = 20_000 @JvmStatic protected val instrumentation: Instrumentation = @@ -283,23 +285,19 @@ abstract class BasePermissionTest { } protected fun waitFindObject(selector: BySelector): UiObject2 { - waitForIdle() return findObjectWithRetry({ t -> UiAutomatorUtils2.waitFindObject(selector, t) })!! } protected fun waitFindObject(selector: BySelector, timeoutMillis: Long): UiObject2 { - waitForIdle() return findObjectWithRetry({ t -> UiAutomatorUtils2.waitFindObject(selector, t) }, timeoutMillis)!! } protected fun waitFindObjectOrNull(selector: BySelector): UiObject2? { - waitForIdle() return findObjectWithRetry({ t -> UiAutomatorUtils2.waitFindObjectOrNull(selector, t) }) } protected fun waitFindObjectOrNull(selector: BySelector, timeoutMillis: Long): UiObject2? { - waitForIdle() return findObjectWithRetry({ t -> UiAutomatorUtils2.waitFindObjectOrNull(selector, t) }, timeoutMillis) } @@ -308,7 +306,6 @@ abstract class BasePermissionTest { automatorMethod: (timeoutMillis: Long) -> UiObject2?, timeoutMillis: Long = 20_000L ): UiObject2? { - waitForIdle() val startTime = SystemClock.elapsedRealtime() return try { automatorMethod(timeoutMillis) @@ -323,7 +320,11 @@ abstract class BasePermissionTest { protected fun click(selector: BySelector, timeoutMillis: Long = 20_000) { waitFindObject(selector, timeoutMillis).click() - waitForIdle() + } + + protected fun clickAndWaitForWindowTransition(selector: BySelector, timeoutMillis: Long = 20_000) { + waitFindObject(selector, timeoutMillis) + .clickAndWait(Until.newWindow(), NEW_WINDOW_TIMEOUT_MILLIS) } protected fun findView(selector: BySelector, expected: Boolean) { @@ -374,12 +375,10 @@ abstract class BasePermissionTest { protected fun pressBack() { uiDevice.pressBack() - waitForIdle() } protected fun pressHome() { uiDevice.pressHome() - waitForIdle() } protected fun pressDPadDown() { diff --git a/tests/cts/permissionui/src/android/permissionui/cts/BaseUsePermissionTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/BaseUsePermissionTest.kt index ef5208c09..58165574b 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/BaseUsePermissionTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/BaseUsePermissionTest.kt @@ -44,6 +44,7 @@ import androidx.test.uiautomator.StaleObjectException import androidx.test.uiautomator.UiObjectNotFoundException import androidx.test.uiautomator.UiScrollable import androidx.test.uiautomator.UiSelector +import androidx.test.uiautomator.Until import com.android.compatibility.common.util.SystemUtil import com.android.compatibility.common.util.SystemUtil.callWithShellPermissionIdentity import com.android.compatibility.common.util.SystemUtil.eventually @@ -56,6 +57,7 @@ import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull import org.junit.Assert.assertTrue import org.junit.Before +import java.util.concurrent.CompletableFuture abstract class BaseUsePermissionTest : BasePermissionTest() { companion object { @@ -358,7 +360,6 @@ abstract class BaseUsePermissionTest : BasePermissionTest() { return } - waitForIdle() waitFindObjectOrNull(By.res("android:id/button1"), timeoutMillis)?.let { try { it.click() @@ -381,15 +382,16 @@ abstract class BaseUsePermissionTest : BasePermissionTest() { protected fun clickPermissionReviewContinue() { if (isAutomotive || isWatch) { - click(By.text(getPermissionControllerString("review_button_continue"))) + clickAndWaitForWindowTransition( + By.text(getPermissionControllerString("review_button_continue"))) } else { - click(By.res("com.android.permissioncontroller:id/continue_button")) + clickAndWaitForWindowTransition( + By.res("com.android.permissioncontroller:id/continue_button")) } } protected fun clickPermissionReviewContinueAndClearSdkWarning() { clickPermissionReviewContinue() - waitForIdle() clearTargetSdkWarning() } @@ -530,16 +532,15 @@ abstract class BaseUsePermissionTest : BasePermissionTest() { protected fun clickPermissionReviewCancel() { if (isAutomotive || isWatch) { - click(By.text(getPermissionControllerString("review_button_cancel"))) + clickAndWaitForWindowTransition(By.text(getPermissionControllerString("review_button_cancel"))) } else { - click(By.res("com.android.permissioncontroller:id/cancel_button")) + clickAndWaitForWindowTransition(By.res("com.android.permissioncontroller:id/cancel_button")) } } protected fun approvePermissionReview() { startAppActivityAndAssertResultCode(Activity.RESULT_OK) { clickPermissionReviewContinueAndClearSdkWarning() - waitForIdle() } } @@ -572,54 +573,70 @@ abstract class BaseUsePermissionTest : BasePermissionTest() { protected inline fun requestAppPermissionsForNoResult( vararg permissions: String?, - block: () -> Unit + crossinline block: () -> Unit ) { // Request the permissions - context.startActivity( - Intent().apply { - component = ComponentName( - APP_PACKAGE_NAME, "$APP_PACKAGE_NAME.RequestPermissionsActivity" - ) - putExtra("$APP_PACKAGE_NAME.PERMISSIONS", permissions) - addFlags(FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK) - } - ) - waitForIdle() + doAndWaitForWindowTransition { + context.startActivity( + Intent().apply { + component = ComponentName( + APP_PACKAGE_NAME, "$APP_PACKAGE_NAME.RequestPermissionsActivity" + ) + putExtra("$APP_PACKAGE_NAME.PERMISSIONS", permissions) + addFlags(FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK) + } + ) + } // Perform the post-request action block() } protected inline fun requestAppPermissions( - vararg permissions: String?, - askTwice: Boolean = false, - block: () -> Unit + vararg permissions: String?, + askTwice: Boolean = false, + waitForWindowTransition: Boolean = true, + crossinline block: () -> Unit ): Instrumentation.ActivityResult { // Request the permissions - val future = startActivityForFuture( - Intent().apply { - component = ComponentName( - APP_PACKAGE_NAME, "$APP_PACKAGE_NAME.RequestPermissionsActivity" - ) - putExtra("$APP_PACKAGE_NAME.PERMISSIONS", permissions) - putExtra("$APP_PACKAGE_NAME.ASK_TWICE", askTwice) - } - ) - waitForIdle() + lateinit var future: CompletableFuture<Instrumentation.ActivityResult> + doAndWaitForWindowTransition { + future = startActivityForFuture( + Intent().apply { + component = ComponentName( + APP_PACKAGE_NAME, "$APP_PACKAGE_NAME.RequestPermissionsActivity" + ) + putExtra("$APP_PACKAGE_NAME.PERMISSIONS", permissions) + putExtra("$APP_PACKAGE_NAME.ASK_TWICE", askTwice) + } + ) + } // Notification permission prompt is shown first, so get it out of the way clickNotificationPermissionRequestAllowButtonIfAvailable() // Perform the post-request action - block() + if (waitForWindowTransition) { + doAndWaitForWindowTransition { + block() + } + } else { + block() + } return future.get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS) } protected inline fun requestAppPermissionsAndAssertResult( - permissions: Array<out String?>, - permissionAndExpectedGrantResults: Array<out Pair<String?, Boolean>>, - askTwice: Boolean = false, - block: () -> Unit + permissions: Array<out String?>, + permissionAndExpectedGrantResults: Array<out Pair<String?, Boolean>>, + askTwice: Boolean = false, + waitForWindowTransition: Boolean = true, + crossinline block: () -> Unit ) { - val result = requestAppPermissions(*permissions, askTwice = askTwice, block = block) + val result = requestAppPermissions( + *permissions, + askTwice = askTwice, + waitForWindowTransition = waitForWindowTransition, + block = block + ) assertEquals(Activity.RESULT_OK, result.resultCode) val responseSize: Int = @@ -643,6 +660,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() { .map { it == PackageManager.PERMISSION_GRANTED } ) ) + permissionAndExpectedGrantResults.forEach { it.first?.let { permission -> assertAppHasPermission(permission, it.second) @@ -651,15 +669,29 @@ abstract class BaseUsePermissionTest : BasePermissionTest() { } protected inline fun requestAppPermissionsAndAssertResult( - vararg permissionAndExpectedGrantResults: Pair<String?, Boolean>, - askTwice: Boolean = false, - block: () -> Unit - ) = requestAppPermissionsAndAssertResult( - permissionAndExpectedGrantResults.map { it.first }.toTypedArray(), - permissionAndExpectedGrantResults, - askTwice, - block - ) + vararg permissionAndExpectedGrantResults: Pair<String?, Boolean>, + askTwice: Boolean = false, + waitForWindowTransition: Boolean = true, + crossinline block: () -> Unit + ) { + requestAppPermissionsAndAssertResult( + permissionAndExpectedGrantResults.map { it.first }.toTypedArray(), + permissionAndExpectedGrantResults, + askTwice, + waitForWindowTransition, + block + ) + } + + // Performs the requested action and returns, waiting for a new window transition if at least + // one has not already occurred while the action took place. + protected inline fun doAndWaitForWindowTransition( + crossinline block: () -> Unit + ) { + uiDevice.performActionAndWait({ + block() + }, Until.newWindow(), NEW_WINDOW_TIMEOUT_MILLIS) + } protected fun findPermissionRequestAllowButton(timeoutMillis: Long = 20000) { if (isAutomotive) { @@ -740,7 +772,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() { protected fun clickPermissionRequestAllowForegroundButton(timeoutMillis: Long = 10_000) { if (isAutomotive) { click(By.text( - getPermissionControllerString(ALLOW_FOREGROUND_BUTTON_TEXT)), timeoutMillis) + getPermissionControllerString(ALLOW_FOREGROUND_BUTTON_TEXT)), timeoutMillis) } else { click(By.res(ALLOW_FOREGROUND_BUTTON), timeoutMillis) } @@ -759,12 +791,10 @@ abstract class BaseUsePermissionTest : BasePermissionTest() { eventually({ clicksDenyInSettings() }, TIMEOUT_MILLIS * 2) - waitForIdle() pressBack() } protected fun clickPermissionRequestSettingsLink() { - waitForIdle() eventually { // UiObject2 doesn't expose CharSequence. val node = if (isAutomotive) { @@ -784,9 +814,10 @@ abstract class BaseUsePermissionTest : BasePermissionTest() { val text = node.text as Spanned val clickableSpan = text.getSpans(0, text.length, ClickableSpan::class.java)[0] // We could pass in null here in Java, but we need an instance in Kotlin. - clickableSpan.onClick(View(context)) + doAndWaitForWindowTransition { + clickableSpan.onClick(View(context)) + } } - waitForIdle() } protected fun clickPermissionRequestDenyAndDontAskAgainButton() { @@ -819,13 +850,11 @@ abstract class BaseUsePermissionTest : BasePermissionTest() { } protected fun clickPermissionRationaleContentInAppPermission() { - waitForIdle() - click(By.res(APP_PERMISSION_RATIONALE_CONTENT_VIEW)) + clickAndWaitForWindowTransition(By.res(APP_PERMISSION_RATIONALE_CONTENT_VIEW)) } protected fun clickPermissionRationaleViewInGrantDialog() { - waitForIdle() - click(By.res(GRANT_DIALOG_PERMISSION_RATIONALE_CONTAINER_VIEW)) + clickAndWaitForWindowTransition(By.res(GRANT_DIALOG_PERMISSION_RATIONALE_CONTAINER_VIEW)) } protected fun grantAppPermissionsByUi(vararg permissions: String) { @@ -863,23 +892,24 @@ abstract class BaseUsePermissionTest : BasePermissionTest() { eventually({ try { // Open the app details settings - context.startActivity( - Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { - data = Uri.fromParts("package", APP_PACKAGE_NAME, null) - addCategory(Intent.CATEGORY_DEFAULT) - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) - } - ) + doAndWaitForWindowTransition { + context.startActivity( + Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { + data = Uri.fromParts("package", APP_PACKAGE_NAME, null) + addCategory(Intent.CATEGORY_DEFAULT) + addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) + } + ) + } if (isTv) { - waitForIdle() pressDPadDown() pressDPadDown() pressDPadDown() pressDPadDown() } // Open the permissions UI - click(byTextRes(R.string.permissions).enabled(true)) + clickAndWaitForWindowTransition(byTextRes(R.string.permissions).enabled(true)) } catch (e: Exception) { pressBack() throw e @@ -907,32 +937,35 @@ abstract class BaseUsePermissionTest : BasePermissionTest() { navigateToAppPermissionSettings() val permissionLabel = getPermissionLabel(permission) if (isWatch) { - click(By.text(permissionLabel), 40_000) + clickAndWaitForWindowTransition(By.text(permissionLabel), 40_000) } else { clickPermissionControllerUi(By.text(permissionLabel)) } return } - - runWithShellPermissionIdentity { - context.startActivity( - Intent(Intent.ACTION_MANAGE_APP_PERMISSION).apply { - putExtra(Intent.EXTRA_PACKAGE_NAME, APP_PACKAGE_NAME) - putExtra(Intent.EXTRA_PERMISSION_NAME, permission) - putExtra(Intent.EXTRA_USER, Process.myUserHandle()) - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) - }) + doAndWaitForWindowTransition { + runWithShellPermissionIdentity { + context.startActivity( + Intent(Intent.ACTION_MANAGE_APP_PERMISSION).apply { + putExtra(Intent.EXTRA_PACKAGE_NAME, APP_PACKAGE_NAME) + putExtra(Intent.EXTRA_PERMISSION_NAME, permission) + putExtra(Intent.EXTRA_USER, Process.myUserHandle()) + addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) + }) + } } } /** Starts activity with intent [ACTION_REVIEW_APP_DATA_SHARING_UPDATES]. */ fun startAppDataSharingUpdatesActivity() { - runWithShellPermissionIdentity { - context.startActivity( + doAndWaitForWindowTransition { + runWithShellPermissionIdentity { + context.startActivity( Intent(ACTION_REVIEW_APP_DATA_SHARING_UPDATES).apply { addFlags(FLAG_ACTIVITY_NEW_TASK) }) + } } } @@ -964,15 +997,17 @@ abstract class BaseUsePermissionTest : BasePermissionTest() { clickPermissionControllerUi(By.text(permissionLabel)) } } else { - runWithShellPermissionIdentity { - context.startActivity( - Intent(Intent.ACTION_MANAGE_APP_PERMISSION).apply { - putExtra(Intent.EXTRA_PACKAGE_NAME, APP_PACKAGE_NAME) - putExtra(Intent.EXTRA_PERMISSION_NAME, permission) - putExtra(Intent.EXTRA_USER, Process.myUserHandle()) - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) - }) + doAndWaitForWindowTransition { + runWithShellPermissionIdentity { + context.startActivity( + Intent(Intent.ACTION_MANAGE_APP_PERMISSION).apply { + putExtra(Intent.EXTRA_PACKAGE_NAME, APP_PACKAGE_NAME) + putExtra(Intent.EXTRA_PERMISSION_NAME, permission) + putExtra(Intent.EXTRA_USER, Process.myUserHandle()) + addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) + }) + } } } @@ -1181,7 +1216,6 @@ abstract class BaseUsePermissionTest : BasePermissionTest() { ) } ) - waitForIdle() clickNotificationPermissionRequestAllowButtonIfAvailable() val result = future.get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS) assertEquals(Activity.RESULT_OK, result.resultCode) diff --git a/tests/cts/permissionui/src/android/permissionui/cts/CameraMicIndicatorsPermissionTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/CameraMicIndicatorsPermissionTest.kt index 11d3845ba..df099658f 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/CameraMicIndicatorsPermissionTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/CameraMicIndicatorsPermissionTest.kt @@ -568,17 +568,12 @@ class CameraMicIndicatorsPermissionTest : StsExtraBusinessLogicTestCase { private fun pressBack() { uiDevice.pressBack() - waitForIdle() } private fun pressHome() { uiDevice.pressHome() - waitForIdle() } - private fun waitForIdle() = - uiAutomation.waitForIdle(IDLE_TIMEOUT_MILLIS, TIMEOUT_MILLIS) - private fun changeSafetyCenterFlag(safetyCenterEnabled: String) { runWithShellPermissionIdentity { DeviceConfig.setProperty(DeviceConfig.NAMESPACE_PRIVACY, @@ -596,7 +591,6 @@ class CameraMicIndicatorsPermissionTest : StsExtraBusinessLogicTestCase { } protected fun waitFindObject(selector: BySelector): UiObject2? { - waitForIdle() return findObjectWithRetry({ t -> UiAutomatorUtils2.waitFindObject(selector, t) }) } @@ -604,7 +598,6 @@ class CameraMicIndicatorsPermissionTest : StsExtraBusinessLogicTestCase { automatorMethod: (timeoutMillis: Long) -> UiObject2?, timeoutMillis: Long = TIMEOUT_MILLIS ): UiObject2? { - waitForIdle() val startTime = SystemClock.elapsedRealtime() return try { automatorMethod(timeoutMillis) diff --git a/tests/cts/permissionui/src/android/permissionui/cts/LocationAccuracyTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/LocationAccuracyTest.kt index a904549b4..1a13d688f 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/LocationAccuracyTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/LocationAccuracyTest.kt @@ -145,7 +145,8 @@ class LocationAccuracyTest : BaseUsePermissionTest() { } assertAppHasPermission(ACCESS_FINE_LOCATION, false) requestAppPermissionsAndAssertResult( - ACCESS_FINE_LOCATION to true + ACCESS_FINE_LOCATION to true, + waitForWindowTransition = false ) { } } diff --git a/tests/cts/permissionui/src/android/permissionui/cts/LocationProviderInterceptDialogTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/LocationProviderInterceptDialogTest.kt index 15af9298a..b14603fd2 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/LocationProviderInterceptDialogTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/LocationProviderInterceptDialogTest.kt @@ -26,6 +26,7 @@ import android.permission.cts.PermissionUtils import android.platform.test.annotations.FlakyTest import androidx.test.filters.SdkSuppress import androidx.test.uiautomator.By +import androidx.test.uiautomator.Until import com.android.compatibility.common.util.AppOpsUtils import com.android.compatibility.common.util.CddTest import com.android.compatibility.common.util.SystemUtil @@ -63,7 +64,7 @@ class LocationProviderInterceptDialogTest : BaseUsePermissionTest() { @Test fun clickLocationPermission_showDialog_clickOk() { openPermissionScreenForApp() - click(By.text("Location")) + clickAndWaitForWindowTransition(By.text("Location")) findView( By.textContains("Location access can be modified from location settings"), true) @@ -73,11 +74,11 @@ class LocationProviderInterceptDialogTest : BaseUsePermissionTest() { @Test fun clickLocationPermission_showDialog_clickLocationAccess() { openPermissionScreenForApp() - click(By.text("Location")) + clickAndWaitForWindowTransition(By.text("Location")) findView( By.textContains("Location access can be modified from location settings"), true) - click(By.res(LOCATION_ACCESS_BUTTON_RES)) + clickAndWaitForWindowTransition(By.res(LOCATION_ACCESS_BUTTON_RES)) findView(By.res(USE_LOCATION_LABEL_ID), true) } @@ -90,16 +91,17 @@ class LocationProviderInterceptDialogTest : BaseUsePermissionTest() { private fun openPermissionScreenForApp() { restartPermissionController() - SystemUtil.runWithShellPermissionIdentity { - context.startActivity( - Intent(ACTION_MANAGE_APP_PERMISSIONS).apply { - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) - putExtra(EXTRA_PACKAGE_NAME, MIC_LOCATION_PROVIDER_APP_PACKAGE_NAME) - } - ) - } - waitForIdle() + uiDevice.performActionAndWait({ + SystemUtil.runWithShellPermissionIdentity { + context.startActivity( + Intent(ACTION_MANAGE_APP_PERMISSIONS).apply { + addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) + putExtra(EXTRA_PACKAGE_NAME, MIC_LOCATION_PROVIDER_APP_PACKAGE_NAME) + } + ) + } + }, Until.newWindow(), NEW_WINDOW_TIMEOUT_MILLIS) } private fun restartPermissionController() { diff --git a/tests/cts/permissionui/src/android/permissionui/cts/MediaPermissionTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/MediaPermissionTest.kt index 1dc21fcea..3258efa3a 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/MediaPermissionTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/MediaPermissionTest.kt @@ -111,7 +111,8 @@ class MediaPermissionTest : BaseUsePermissionTest() { installPackage(APP_APK_PATH_MEDIA_PERMISSION_33_WITH_STORAGE) requestAppPermissions( Manifest.permission.READ_EXTERNAL_STORAGE, - Manifest.permission.WRITE_EXTERNAL_STORAGE + Manifest.permission.WRITE_EXTERNAL_STORAGE, + waitForWindowTransition = false ) { } assertStorageAndMediaPermissionState(false) @@ -167,7 +168,8 @@ class MediaPermissionTest : BaseUsePermissionTest() { setRevokeWhenRequested("android.permission.READ_MEDIA_IMAGES") requestAppPermissionsAndAssertResult( - Manifest.permission.READ_EXTERNAL_STORAGE to true + Manifest.permission.READ_EXTERNAL_STORAGE to true, + waitForWindowTransition = false ) { // No dialog should appear } diff --git a/tests/cts/permissionui/src/android/permissionui/cts/MediaPermissionUpgradeTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/MediaPermissionUpgradeTest.kt index bed5c225f..17a7a8c5c 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/MediaPermissionUpgradeTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/MediaPermissionUpgradeTest.kt @@ -52,7 +52,8 @@ class MediaPermissionUpgradeTest : BaseUsePermissionTest() { requestAppPermissionsAndAssertResult( READ_MEDIA_AUDIO to true, READ_MEDIA_VIDEO to true, - READ_MEDIA_IMAGES to true + READ_MEDIA_IMAGES to true, + waitForWindowTransition = false ) { // Don't click any grant dialog buttons because no grant dialog should appear } diff --git a/tests/cts/permissionui/src/android/permissionui/cts/NotificationPermissionTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/NotificationPermissionTest.kt index f7dfbfdf5..33b01307b 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/NotificationPermissionTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/NotificationPermissionTest.kt @@ -32,6 +32,7 @@ import android.platform.test.annotations.FlakyTest import android.provider.Settings import androidx.test.filters.SdkSuppress import androidx.test.uiautomator.By +import androidx.test.uiautomator.Until import com.android.compatibility.common.util.SystemUtil import com.android.compatibility.common.util.SystemUtil.callWithShellPermissionIdentity import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity @@ -388,13 +389,14 @@ class NotificationPermissionTest : BaseUsePermissionTest() { val options = ActivityOptions.makeBasic() options.isEligibleForLegacyPermissionPrompt = isEligibleForPromptOption - context.startActivity(intent, options.toBundle()) + uiDevice.performActionAndWait({ + context.startActivity(intent, options.toBundle()) + }, Until.newWindow(), NEW_WINDOW_TIMEOUT_MILLIS) // Watch does not have app bar if (!isWatch) { waitFindObject(By.textContains(ACTIVITY_LABEL)) } - waitForIdle() } private fun assertDialogNotShowing(timeoutMillis: Long = EXPECTED_TIMEOUT_MS) { diff --git a/tests/cts/permissionui/src/android/permissionui/cts/PermissionDecisionsTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/PermissionDecisionsTest.kt index ad7da60ae..36c5f455a 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/PermissionDecisionsTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/PermissionDecisionsTest.kt @@ -23,6 +23,7 @@ import android.permission.PermissionManager import android.platform.test.annotations.FlakyTest import androidx.test.filters.SdkSuppress import androidx.test.uiautomator.By +import androidx.test.uiautomator.Until import com.android.compatibility.common.util.SystemUtil import org.junit.Assert.assertNull import org.junit.Assume.assumeTrue @@ -118,12 +119,14 @@ class PermissionDecisionsTest : BaseUsePermissionTest() { } private fun openPermissionDecisions() { - SystemUtil.runWithShellPermissionIdentity { - context.startActivity( - Intent(PermissionManager.ACTION_REVIEW_PERMISSION_DECISIONS).apply { - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - } - ) - } + uiDevice.performActionAndWait({ + SystemUtil.runWithShellPermissionIdentity { + context.startActivity( + Intent(PermissionManager.ACTION_REVIEW_PERMISSION_DECISIONS).apply { + addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + } + ) + } + }, Until.newWindow(), NEW_WINDOW_TIMEOUT_MILLIS) } } diff --git a/tests/cts/permissionui/src/android/permissionui/cts/PermissionGroupTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/PermissionGroupTest.kt index 6c2fe25e5..182fb4164 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/PermissionGroupTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/PermissionGroupTest.kt @@ -62,8 +62,11 @@ class PermissionGroupTest : BaseUsePermissionTest() { assertAppHasPermission(android.Manifest.permission.RECEIVE_SMS, true) // Request both permissions, and expect that SEND_SMS is granted - requestAppPermissionsAndAssertResult(android.Manifest.permission.RECEIVE_SMS to true, - android.Manifest.permission.SEND_SMS to true) { } + requestAppPermissionsAndAssertResult( + android.Manifest.permission.RECEIVE_SMS to true, + android.Manifest.permission.SEND_SMS to true, + waitForWindowTransition = false + ) { } assertAppHasPermission(android.Manifest.permission.SEND_SMS, true) } diff --git a/tests/cts/permissionui/src/android/permissionui/cts/PermissionRationalePermissionGrantDialogTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/PermissionRationalePermissionGrantDialogTest.kt index 06b4552f4..74f3d74ea 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/PermissionRationalePermissionGrantDialogTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/PermissionRationalePermissionGrantDialogTest.kt @@ -276,10 +276,8 @@ class PermissionRationalePermissionGrantDialogTest : BaseUsePermissionTest() { requestAppPermissionsForNoResult(ACCESS_FINE_LOCATION) { clickPermissionRationaleViewInGrantDialog() - waitForIdle() assertPermissionRationaleDialogIsVisible(true) pressBack() - waitForIdle() assertPermissionRationaleDialogIsVisible(false) assertPermissionRationaleContainerOnGrantDialogIsVisible(true) } diff --git a/tests/cts/permissionui/src/android/permissionui/cts/PermissionRationaleTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/PermissionRationaleTest.kt index cf080f745..feac46ec9 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/PermissionRationaleTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/PermissionRationaleTest.kt @@ -30,6 +30,7 @@ import android.util.Log import android.view.View import androidx.test.filters.SdkSuppress import androidx.test.uiautomator.By +import androidx.test.uiautomator.Until import com.android.compatibility.common.util.DeviceConfigStateChangerRule import com.android.compatibility.common.util.SystemUtil import com.android.compatibility.common.util.SystemUtil.eventually @@ -148,7 +149,7 @@ class PermissionRationaleTest : BaseUsePermissionTest() { clickHelpCenterLink() - eventually({assertHelpCenterLinkClickSuccessful()}, HELP_CENTER_TIMEOUT_MILLIS) + eventually({assertHelpCenterLinkClickSuccessful()}, NEW_WINDOW_TIMEOUT_MILLIS) } @Test @@ -235,9 +236,10 @@ class PermissionRationaleTest : BaseUsePermissionTest() { val text = node.text as Spanned val clickableSpan = text.getSpans(0, text.length, ClickableSpan::class.java)[0] // We could pass in null here in Java, but we need an instance in Kotlin. - clickableSpan.onClick(View(context)) + uiDevice.performActionAndWait({ + clickableSpan.onClick(View(context)) + }, Until.newWindow(), NEW_WINDOW_TIMEOUT_MILLIS) } - waitForIdle() } private fun clickHelpCenterLink() { @@ -252,9 +254,10 @@ class PermissionRationaleTest : BaseUsePermissionTest() { val text = node.text as Spanned val clickableSpan = text.getSpans(0, text.length, ClickableSpan::class.java)[0] // We could pass in null here in Java, but we need an instance in Kotlin. - clickableSpan.onClick(View(context)) + uiDevice.performActionAndWait({ + clickableSpan.onClick(View(context)) + }, Until.newWindow(), NEW_WINDOW_TIMEOUT_MILLIS) } - waitForIdle() } private fun clickSettingsLink() { @@ -269,9 +272,10 @@ class PermissionRationaleTest : BaseUsePermissionTest() { val text = node.text as Spanned val clickableSpan = text.getSpans(0, text.length, ClickableSpan::class.java)[0] // We could pass in null here in Java, but we need an instance in Kotlin. - clickableSpan.onClick(View(context)) + uiDevice.performActionAndWait({ + clickableSpan.onClick(View(context)) + }, Until.newWindow(), NEW_WINDOW_TIMEOUT_MILLIS) } - waitForIdle() } private fun clicksSettings_doesNothing_leaves() { @@ -391,6 +395,5 @@ class PermissionRationaleTest : BaseUsePermissionTest() { "com.android.permissioncontroller:id/settings_message" private const val HELP_CENTER_URL_ID = "data_sharing_help_center_link" - private const val HELP_CENTER_TIMEOUT_MILLIS: Long = 20000 } } diff --git a/tests/cts/permissionui/src/android/permissionui/cts/PermissionReviewTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/PermissionReviewTest.kt index 8e890b230..ea834210f 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/PermissionReviewTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/PermissionReviewTest.kt @@ -95,6 +95,7 @@ class PermissionReviewTest : BaseUsePermissionTest() { startAppActivityAndAssertResultCode(Activity.RESULT_OK) { // Deny clickPermissionControllerUi(By.text("Calendar")) + // Confirm deny click(By.res("android:id/button1")) diff --git a/tests/cts/permissionui/src/android/permissionui/cts/PermissionSplitTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/PermissionSplitTest.kt index bfd0e4bac..8319c1c68 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/PermissionSplitTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/PermissionSplitTest.kt @@ -83,12 +83,15 @@ class PermissionSplitTest : BaseUsePermissionTest() { assertAppHasPermission(android.Manifest.permission.ACCESS_BACKGROUND_LOCATION, false) requestAppPermissionsAndAssertResult( - android.Manifest.permission.ACCESS_FINE_LOCATION to true + android.Manifest.permission.ACCESS_FINE_LOCATION to true, + waitForWindowTransition = false ) { if (expectSplit) { clickPermissionRequestSettingsLinkAndAllowAlways() } else { - clickPermissionRequestAllowForegroundButton() + doAndWaitForWindowTransition { + clickPermissionRequestAllowForegroundButton() + } } } @@ -100,12 +103,15 @@ class PermissionSplitTest : BaseUsePermissionTest() { assertAppHasPermission(android.Manifest.permission.BODY_SENSORS_BACKGROUND, false) requestAppPermissionsAndAssertResult( - android.Manifest.permission.BODY_SENSORS to true + android.Manifest.permission.BODY_SENSORS to true, + waitForWindowTransition = false ) { if (expectSplit) { clickPermissionRequestSettingsLinkAndAllowAlways() } else { - clickPermissionRequestAllowForegroundButton() + doAndWaitForWindowTransition { + clickPermissionRequestAllowForegroundButton() + } } } diff --git a/tests/cts/permissionui/src/android/permissionui/cts/PermissionTest22.kt b/tests/cts/permissionui/src/android/permissionui/cts/PermissionTest22.kt index 6206a0300..a0db7eb7f 100755 --- a/tests/cts/permissionui/src/android/permissionui/cts/PermissionTest22.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/PermissionTest22.kt @@ -60,7 +60,8 @@ class PermissionTest22 : BaseUsePermissionTest() { // Request the permission and do nothing // Expect the permission is not granted requestAppPermissionsAndAssertResult( - arrayOf(android.Manifest.permission.SEND_SMS), emptyArray() + arrayOf(android.Manifest.permission.SEND_SMS), emptyArray(), + waitForWindowTransition = false ) {} } } diff --git a/tests/cts/permissionui/src/android/permissionui/cts/PermissionTest23.kt b/tests/cts/permissionui/src/android/permissionui/cts/PermissionTest23.kt index cc29fd328..a7a8a533c 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/PermissionTest23.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/PermissionTest23.kt @@ -116,7 +116,10 @@ class PermissionTest23 : BaseUsePermissionTest() { // Request the permission and do nothing // Expect the permission is granted - requestAppPermissionsAndAssertResult(android.Manifest.permission.WRITE_CONTACTS to true) {} + requestAppPermissionsAndAssertResult( + android.Manifest.permission.WRITE_CONTACTS to true, + waitForWindowTransition = false + ) {} } @Test @@ -136,7 +139,10 @@ class PermissionTest23 : BaseUsePermissionTest() { // Request the permission and do nothing // Expect the permission is not granted - requestAppPermissionsAndAssertResult(android.Manifest.permission.WRITE_CONTACTS to false) {} + requestAppPermissionsAndAssertResult( + android.Manifest.permission.WRITE_CONTACTS to false, + waitForWindowTransition = false + ) {} } @FlakyTest @@ -170,7 +176,6 @@ class PermissionTest23 : BaseUsePermissionTest() { askTwice = true ) { clickPermissionRequestDenyButton() - waitForIdle() denyPermissionRequestWithPrejudice() } @@ -197,7 +202,8 @@ class PermissionTest23 : BaseUsePermissionTest() { // Request the permission and do nothing // Expect the permission is not granted requestAppPermissionsAndAssertResult( - android.Manifest.permission.BIND_PRINT_SERVICE to false + android.Manifest.permission.BIND_PRINT_SERVICE to false, + waitForWindowTransition = false ) {} } @@ -208,7 +214,10 @@ class PermissionTest23 : BaseUsePermissionTest() { // Request the permission and do nothing // Expect the permission is not granted - requestAppPermissionsAndAssertResult(NON_EXISTENT_PERMISSION to false) {} + requestAppPermissionsAndAssertResult( + NON_EXISTENT_PERMISSION to false, + waitForWindowTransition = false + ) {} } @Test @@ -267,7 +276,11 @@ class PermissionTest23 : BaseUsePermissionTest() { val permissions: Array<String?> = arrayOf(null) val results: Array<Pair<String?, Boolean>> = arrayOf() // Go through normal grant flow - requestAppPermissionsAndAssertResult(permissions, results) {} + requestAppPermissionsAndAssertResult( + permissions, + results, + waitForWindowTransition = false + ) {} } @Test @@ -297,7 +310,10 @@ class PermissionTest23 : BaseUsePermissionTest() { fun testInvalidPermission() { // Request the permission and allow it // Expect the permission is not granted - requestAppPermissionsAndAssertResult(INVALID_PERMISSION to false) {} + requestAppPermissionsAndAssertResult( + INVALID_PERMISSION to false, + waitForWindowTransition = false + ) {} } @Test diff --git a/tests/cts/permissionui/src/android/permissionui/cts/PermissionTest29.kt b/tests/cts/permissionui/src/android/permissionui/cts/PermissionTest29.kt index 5e1b0d28f..2a9261163 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/PermissionTest29.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/PermissionTest29.kt @@ -48,7 +48,8 @@ class PermissionTest29 : BaseUsePermissionTest() { @Test fun testRequestOnlyBackgroundNotPossible() { requestAppPermissionsAndAssertResult( - android.Manifest.permission.ACCESS_BACKGROUND_LOCATION to false + android.Manifest.permission.ACCESS_BACKGROUND_LOCATION to false, + waitForWindowTransition = false ) {} assertAppHasPermission(android.Manifest.permission.ACCESS_BACKGROUND_LOCATION, false) @@ -58,7 +59,8 @@ class PermissionTest29 : BaseUsePermissionTest() { fun testRequestBoth() { requestAppPermissionsAndAssertResult( android.Manifest.permission.ACCESS_FINE_LOCATION to true, - android.Manifest.permission.ACCESS_BACKGROUND_LOCATION to true + android.Manifest.permission.ACCESS_BACKGROUND_LOCATION to true, + waitForWindowTransition = false ) { clickPermissionRequestSettingsLinkAndAllowAlways() } @@ -77,7 +79,8 @@ class PermissionTest29 : BaseUsePermissionTest() { // Step 2: request background only requestAppPermissionsAndAssertResult( - android.Manifest.permission.ACCESS_BACKGROUND_LOCATION to true + android.Manifest.permission.ACCESS_BACKGROUND_LOCATION to true, + waitForWindowTransition = false ) { clickPermissionRequestSettingsLinkAndAllowAlways() } @@ -98,7 +101,8 @@ class PermissionTest29 : BaseUsePermissionTest() { // Step 2: grant background requestAppPermissionsAndAssertResult( android.Manifest.permission.ACCESS_FINE_LOCATION to true, - android.Manifest.permission.ACCESS_BACKGROUND_LOCATION to true + android.Manifest.permission.ACCESS_BACKGROUND_LOCATION to true, + waitForWindowTransition = false ) { clickPermissionRequestSettingsLinkAndAllowAlways() } @@ -127,7 +131,8 @@ class PermissionTest29 : BaseUsePermissionTest() { // Step 3: All further requests should be denied automatically requestAppPermissionsAndAssertResult( android.Manifest.permission.ACCESS_FINE_LOCATION to false, - android.Manifest.permission.ACCESS_BACKGROUND_LOCATION to false + android.Manifest.permission.ACCESS_BACKGROUND_LOCATION to false, + waitForWindowTransition = false ) {} } @@ -138,27 +143,33 @@ class PermissionTest29 : BaseUsePermissionTest() { // Step 1: Request both, go to settings, do nothing requestAppPermissionsAndAssertResult( android.Manifest.permission.ACCESS_FINE_LOCATION to true, - android.Manifest.permission.ACCESS_BACKGROUND_LOCATION to false + android.Manifest.permission.ACCESS_BACKGROUND_LOCATION to false, + waitForWindowTransition = false ) { openSettingsThenDoNothingThenLeave() assertAppHasPermission(android.Manifest.permission.ACCESS_FINE_LOCATION, false) assertAppHasPermission(android.Manifest.permission.ACCESS_BACKGROUND_LOCATION, false) - clickPermissionRequestAllowForegroundButton() + doAndWaitForWindowTransition { + clickPermissionRequestAllowForegroundButton() + } } // Step 2: Upgrade foreground to background, go to settings, do nothing requestAppPermissionsAndAssertResult( android.Manifest.permission.ACCESS_FINE_LOCATION to true, - android.Manifest.permission.ACCESS_BACKGROUND_LOCATION to false + android.Manifest.permission.ACCESS_BACKGROUND_LOCATION to false, + waitForWindowTransition = false ) { openSettingsThenDoNothingThenLeave() assertAppHasPermission(android.Manifest.permission.ACCESS_FINE_LOCATION, true) assertAppHasPermission(android.Manifest.permission.ACCESS_BACKGROUND_LOCATION, false) - clickPermissionRequestNoUpgradeAndDontAskAgainButton() + doAndWaitForWindowTransition { + clickPermissionRequestNoUpgradeAndDontAskAgainButton() + } } } @@ -187,10 +198,10 @@ class PermissionTest29 : BaseUsePermissionTest() { requestAppPermissions( android.Manifest.permission.ACCESS_FINE_LOCATION, - android.Manifest.permission.ACCESS_BACKGROUND_LOCATION + android.Manifest.permission.ACCESS_BACKGROUND_LOCATION, + waitForWindowTransition = false ) { clickPermissionRequestSettingsLinkAndDeny() - waitForIdle() pressBack() } diff --git a/tests/cts/permissionui/src/android/permissionui/cts/PermissionTest30.kt b/tests/cts/permissionui/src/android/permissionui/cts/PermissionTest30.kt index bcf01265c..4555fb83c 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/PermissionTest30.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/PermissionTest30.kt @@ -38,8 +38,11 @@ class PermissionTest30 : BaseUsePermissionTest() { assertAppHasPermission(ACCESS_FINE_LOCATION, false) assertAppHasPermission(ACCESS_BACKGROUND_LOCATION, false) - requestAppPermissionsAndAssertResult(ACCESS_FINE_LOCATION to false, - ACCESS_BACKGROUND_LOCATION to false) { + requestAppPermissionsAndAssertResult( + ACCESS_FINE_LOCATION to false, + ACCESS_BACKGROUND_LOCATION to false, + waitForWindowTransition = false + ) { // Do nothing, should be automatically denied } } @@ -54,9 +57,11 @@ class PermissionTest30 : BaseUsePermissionTest() { clickPermissionRequestAllowForegroundButton() } - requestAppPermissionsAndAssertResult(ACCESS_BACKGROUND_LOCATION to true) { + requestAppPermissionsAndAssertResult( + ACCESS_BACKGROUND_LOCATION to true, + waitForWindowTransition = false + ) { clickAllowAlwaysInSettings() - waitForIdle() pressBack() } } @@ -76,7 +81,8 @@ class PermissionTest30 : BaseUsePermissionTest() { "accuracy options. Please update the system with " + "the latest (at least Oct, 2021) mainline modules.", locationAccuracyOptions) - return + // Close dialog + clickPermissionRequestDenyButton() } } } diff --git a/tests/cts/permissionui/src/android/permissionui/cts/PermissionUsageInfoTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/PermissionUsageInfoTest.kt index 7f61014cb..0e462e503 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/PermissionUsageInfoTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/PermissionUsageInfoTest.kt @@ -19,6 +19,7 @@ package android.permissionui.cts import android.content.Intent import android.platform.test.annotations.FlakyTest import androidx.test.uiautomator.By +import androidx.test.uiautomator.Until import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity import org.junit.Assume.assumeFalse import org.junit.Before @@ -43,14 +44,16 @@ class PermissionUsageInfoTest : BaseUsePermissionTest() { @Test fun testPermissionUsageInfo() { - runWithShellPermissionIdentity { - context.startActivity( - Intent(Intent.ACTION_MANAGE_APP_PERMISSIONS).apply { - putExtra(Intent.EXTRA_PACKAGE_NAME, APP_PACKAGE_NAME) - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - } - ) - } + uiDevice.performActionAndWait({ + runWithShellPermissionIdentity { + context.startActivity( + Intent(Intent.ACTION_MANAGE_APP_PERMISSIONS).apply { + putExtra(Intent.EXTRA_PACKAGE_NAME, APP_PACKAGE_NAME) + addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + } + ) + } + }, Until.newWindow(), NEW_WINDOW_TIMEOUT_MILLIS) click(By.res("com.android.permissioncontroller:id/icon")) } } diff --git a/tests/cts/permissionui/src/android/permissionui/cts/PhotoPickerPermissionTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/PhotoPickerPermissionTest.kt index df422acfb..b7d4f5dfb 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/PhotoPickerPermissionTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/PhotoPickerPermissionTest.kt @@ -130,8 +130,12 @@ class PhotoPickerPermissionTest : BaseUsePermissionTest() { installPackage(APP_APK_PATH_IMPLICIT_USER_SELECT_STORAGE) requestAppPermissionsAndAssertResult( arrayOf(READ_MEDIA_IMAGES, READ_MEDIA_VISUAL_USER_SELECTED), - arrayOf(READ_MEDIA_IMAGES to false, READ_MEDIA_VISUAL_USER_SELECTED to false)) { - click(By.res(SELECT_BUTTON)) + arrayOf(READ_MEDIA_IMAGES to false, READ_MEDIA_VISUAL_USER_SELECTED to false), + waitForWindowTransition = false + ) { + doAndWaitForWindowTransition { + click(By.res(SELECT_BUTTON)) + } findImageOrVideo(expected = true) uiDevice.pressBack() } @@ -142,9 +146,14 @@ class PhotoPickerPermissionTest : BaseUsePermissionTest() { @Test fun testImplicitUserSelectHasOneTimeGrantsWithoutAppOp() { installPackage(APP_APK_PATH_IMPLICIT_USER_SELECT_STORAGE) - requestAppPermissionsAndAssertResult(arrayOf(READ_MEDIA_IMAGES), - arrayOf(READ_MEDIA_IMAGES to true)) { - click(By.res(SELECT_BUTTON)) + requestAppPermissionsAndAssertResult( + arrayOf(READ_MEDIA_IMAGES), + arrayOf(READ_MEDIA_IMAGES to true), + waitForWindowTransition = false + ) { + doAndWaitForWindowTransition { + click(By.res(SELECT_BUTTON)) + } clickImageOrVideo() clickAllow() } @@ -175,7 +184,7 @@ class PhotoPickerPermissionTest : BaseUsePermissionTest() { assertAppHasPermission(READ_MEDIA_VISUAL_USER_SELECTED, true) } - requestAppPermissions(READ_MEDIA_IMAGES) { + requestAppPermissions(READ_MEDIA_IMAGES, waitForWindowTransition = false) { waitFindObject(By.res(DONT_SELECT_MORE_BUTTON)) uiDevice.pressBack() } @@ -186,8 +195,12 @@ class PhotoPickerPermissionTest : BaseUsePermissionTest() { installPackage(APP_APK_PATH_LATEST) requestAppPermissionsAndAssertResult( arrayOf(READ_MEDIA_IMAGES, READ_MEDIA_VISUAL_USER_SELECTED), - arrayOf(READ_MEDIA_IMAGES to false, READ_MEDIA_VISUAL_USER_SELECTED to true)) { - click(By.res(SELECT_BUTTON)) + arrayOf(READ_MEDIA_IMAGES to false, READ_MEDIA_VISUAL_USER_SELECTED to true), + waitForWindowTransition = false + ) { + doAndWaitForWindowTransition { + click(By.res(SELECT_BUTTON)) + } clickImageOrVideo() clickAllow() } @@ -199,21 +212,29 @@ class PhotoPickerPermissionTest : BaseUsePermissionTest() { @Test fun testNonImplicitAutomaticallyShowsPickerWhenUserFixed() { installPackage(APP_APK_PATH_LATEST) - requestAppPermissions(READ_MEDIA_IMAGES) { - click(By.res(SELECT_BUTTON)) + requestAppPermissions(READ_MEDIA_IMAGES, waitForWindowTransition = false) { + doAndWaitForWindowTransition { + click(By.res(SELECT_BUTTON)) + } clickImageOrVideo() - clickAllow() + doAndWaitForWindowTransition { + clickAllow() + } } - requestAppPermissions(READ_MEDIA_IMAGES) { - click(By.res(SELECT_BUTTON)) + requestAppPermissions(READ_MEDIA_IMAGES, waitForWindowTransition = false) { + doAndWaitForWindowTransition { + click(By.res(SELECT_BUTTON)) + } clickImageOrVideo() - clickAllow() + doAndWaitForWindowTransition { + clickAllow() + } } assertPermissionFlags(READ_MEDIA_VISUAL_USER_SELECTED, FLAG_PERMISSION_USER_FIXED to true) - requestAppPermissions(READ_MEDIA_IMAGES) { + requestAppPermissions(READ_MEDIA_IMAGES, waitForWindowTransition = false) { findImageOrVideo(expected = true) uiDevice.pressBack() } @@ -222,15 +243,19 @@ class PhotoPickerPermissionTest : BaseUsePermissionTest() { @Test fun testRequestedPermsFilterMediaType() { installPackage(APP_APK_PATH_LATEST) - requestAppPermissions(READ_MEDIA_IMAGES) { - click(By.res(SELECT_BUTTON)) + requestAppPermissions(READ_MEDIA_IMAGES, waitForWindowTransition = false) { + doAndWaitForWindowTransition { + click(By.res(SELECT_BUTTON)) + } findImageOrVideo(expected = true) findVideo(expected = false) uiDevice.pressBack() } - requestAppPermissions(READ_MEDIA_VIDEO) { - click(By.res(SELECT_BUTTON)) + requestAppPermissions(READ_MEDIA_VIDEO, waitForWindowTransition = false) { + doAndWaitForWindowTransition { + click(By.res(SELECT_BUTTON)) + } findVideo(expected = true) uiDevice.pressBack() } @@ -310,7 +335,7 @@ class PhotoPickerPermissionTest : BaseUsePermissionTest() { requestedPerms.contains(READ_MEDIA_VISUAL_USER_SELECTED)) } - requestAppPermissions(READ_MEDIA_IMAGES) { + requestAppPermissions(READ_MEDIA_IMAGES, waitForWindowTransition = false) { findView(By.res(SELECT_BUTTON), expected = false) pressBack() } @@ -322,11 +347,17 @@ class PhotoPickerPermissionTest : BaseUsePermissionTest() { @Test fun testAppCantRequestOnlyPartialStoragePerms() { installPackage(APP_APK_PATH_IMPLICIT_USER_SELECT_STORAGE) - requestAppPermissionsAndAssertResult(READ_MEDIA_VISUAL_USER_SELECTED to false) {} + requestAppPermissionsAndAssertResult( + READ_MEDIA_VISUAL_USER_SELECTED to false, + waitForWindowTransition = false + ) {} uninstallPackage(APP_PACKAGE_NAME) installPackage(APP_APK_PATH_LATEST) - requestAppPermissionsAndAssertResult(READ_MEDIA_VISUAL_USER_SELECTED to false, - ACCESS_MEDIA_LOCATION to false) {} + requestAppPermissionsAndAssertResult( + READ_MEDIA_VISUAL_USER_SELECTED to false, + ACCESS_MEDIA_LOCATION to false, + waitForWindowTransition = false + ) {} } @Test @@ -335,16 +366,25 @@ class PhotoPickerPermissionTest : BaseUsePermissionTest() { requestAppPermissions(ACCESS_MEDIA_LOCATION) { click(By.res(ALLOW_ALL_BUTTON)) } - requestAppPermissionsAndAssertResult(READ_MEDIA_IMAGES to true, - READ_MEDIA_VIDEO to true) {} + requestAppPermissionsAndAssertResult( + READ_MEDIA_IMAGES to true, + READ_MEDIA_VIDEO to true, + waitForWindowTransition = false + ) {} } @Test fun testExplicitAppCannotExpandAccessMediaLocation() { installPackage(APP_APK_PATH_LATEST) - requestAppPermissionsAndAssertResult(READ_MEDIA_IMAGES to false, - ACCESS_MEDIA_LOCATION to true, READ_MEDIA_VISUAL_USER_SELECTED to true) { - click(By.res(SELECT_BUTTON)) + requestAppPermissionsAndAssertResult( + READ_MEDIA_IMAGES to false, + ACCESS_MEDIA_LOCATION to true, + READ_MEDIA_VISUAL_USER_SELECTED to true, + waitForWindowTransition = false + ) { + doAndWaitForWindowTransition { + click(By.res(SELECT_BUTTON)) + } clickImageOrVideo() clickAllow() } @@ -356,8 +396,11 @@ class PhotoPickerPermissionTest : BaseUsePermissionTest() { @Test fun testExplicitAppCannotRequestOnlyPartialAccess() { installPackage(APP_APK_PATH_LATEST) - requestAppPermissionsAndAssertResult(ACCESS_MEDIA_LOCATION to false, - READ_MEDIA_VISUAL_USER_SELECTED to false) { + requestAppPermissionsAndAssertResult( + ACCESS_MEDIA_LOCATION to false, + READ_MEDIA_VISUAL_USER_SELECTED to false, + waitForWindowTransition = false + ) { findView(By.res(SELECT_BUTTON), expected = false) } } @@ -365,11 +408,18 @@ class PhotoPickerPermissionTest : BaseUsePermissionTest() { @Test fun testMorePhotosDialogShowsAfterClickingSelect() { installPackage(APP_APK_PATH_LATEST) - requestAppPermissionsAndAssertResult(READ_MEDIA_IMAGES to false, - ACCESS_MEDIA_LOCATION to true, READ_MEDIA_VISUAL_USER_SELECTED to true) { - click(By.res(SELECT_BUTTON)) + requestAppPermissionsAndAssertResult( + READ_MEDIA_IMAGES to false, + ACCESS_MEDIA_LOCATION to true, READ_MEDIA_VISUAL_USER_SELECTED to true, + waitForWindowTransition = false + ) { + doAndWaitForWindowTransition { + click(By.res(SELECT_BUTTON)) + } clickImageOrVideo() - clickAllow() + doAndWaitForWindowTransition { + clickAllow() + } } requestAppPermissions(READ_MEDIA_IMAGES, READ_MEDIA_VIDEO) { @@ -381,11 +431,18 @@ class PhotoPickerPermissionTest : BaseUsePermissionTest() { @Test fun testAMLNotGrantedIfNotRequested() { installPackage(APP_APK_PATH_LATEST) - requestAppPermissionsAndAssertResult(READ_MEDIA_IMAGES to false, - READ_MEDIA_VISUAL_USER_SELECTED to true) { - click(By.res(SELECT_BUTTON)) + requestAppPermissionsAndAssertResult( + READ_MEDIA_IMAGES to false, + READ_MEDIA_VISUAL_USER_SELECTED to true, + waitForWindowTransition = false + ) { + doAndWaitForWindowTransition { + click(By.res(SELECT_BUTTON)) + } clickImageOrVideo() - clickAllow() + doAndWaitForWindowTransition { + clickAllow() + } } assertAppHasPermission(ACCESS_MEDIA_LOCATION, false) } @@ -396,7 +453,6 @@ class PhotoPickerPermissionTest : BaseUsePermissionTest() { private fun clickAllow() { click(By.res(PhotoPickerUtils.getAllowId(context))) - waitForIdle() } private fun findImageOrVideo(expected: Boolean) { diff --git a/tests/cts/permissionui/src/android/permissionui/cts/ReviewAccessibilityServicesTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/ReviewAccessibilityServicesTest.kt index 86f294875..05cd6e497 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/ReviewAccessibilityServicesTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/ReviewAccessibilityServicesTest.kt @@ -31,6 +31,7 @@ import androidx.test.uiautomator.Configurator import androidx.test.uiautomator.StaleObjectException import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiObject2 +import androidx.test.uiautomator.Until import com.android.compatibility.common.util.SystemUtil import com.android.compatibility.common.util.UiAutomatorUtils2.waitFindObjectOrNull import java.util.regex.Pattern @@ -55,6 +56,7 @@ class ReviewAccessibilityServicesTest { companion object { private const val EXPECTED_TIMEOUT_MS = 500L + private const val NEW_WINDOW_TIMEOUT_MILLIS: Long = 20_000 } @get:Rule @@ -127,7 +129,6 @@ class ReviewAccessibilityServicesTest { accessibilityServiceRule.enableService() accessibilityServiceRule2.enableService() startAccessibilityActivity() - uiDevice.waitForIdle() findTestService2(true)!!.click() waitForSettingsButtonToDisappear() findTestService2(true) @@ -138,16 +139,18 @@ class ReviewAccessibilityServicesTest { val automan = InstrumentationRegistry.getInstrumentation() .getUiAutomation(UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES) - automan.adoptShellPermissionIdentity() - try { - context.startActivity( - Intent(Intent.ACTION_REVIEW_ACCESSIBILITY_SERVICES) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)) - } catch (e: Exception) { - throw RuntimeException("Caught exception", e) - } finally { - automan.dropShellPermissionIdentity() - } + uiDevice.performActionAndWait({ + automan.adoptShellPermissionIdentity() + try { + context.startActivity( + Intent(Intent.ACTION_REVIEW_ACCESSIBILITY_SERVICES) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)) + } catch (e: Exception) { + throw RuntimeException("Caught exception", e) + } finally { + automan.dropShellPermissionIdentity() + } + }, Until.newWindow(), NEW_WINDOW_TIMEOUT_MILLIS) } private fun findTestService(shouldBePresent: Boolean): UiObject2? { |