diff options
Diffstat (limited to 'common/testutils/devicetests/com/android/testutils/TestPermissionUtil.kt')
-rw-r--r-- | common/testutils/devicetests/com/android/testutils/TestPermissionUtil.kt | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/common/testutils/devicetests/com/android/testutils/TestPermissionUtil.kt b/common/testutils/devicetests/com/android/testutils/TestPermissionUtil.kt index f557f186..a4dbd9ad 100644 --- a/common/testutils/devicetests/com/android/testutils/TestPermissionUtil.kt +++ b/common/testutils/devicetests/com/android/testutils/TestPermissionUtil.kt @@ -19,6 +19,7 @@ package com.android.testutils import androidx.test.platform.app.InstrumentationRegistry +import com.android.modules.utils.build.SdkLevel import com.android.testutils.ExceptionUtils.ThrowingRunnable import com.android.testutils.ExceptionUtils.ThrowingSupplier @@ -31,6 +32,23 @@ import com.android.testutils.ExceptionUtils.ThrowingSupplier */ fun <T> runAsShell(vararg permissions: String, task: () -> T): T { val autom = InstrumentationRegistry.getInstrumentation().uiAutomation + + // Calls to adoptShellPermissionIdentity do not nest, and dropShellPermissionIdentity drops all + // permissions. Thus, nesting calls will almost certainly cause test bugs, On S+, where we can + // detect this, refuse to do it. + // + // TODO: when R is deprecated, we could try to make this work instead. + // - Get the list of previously-adopted permissions. + // - Adopt the union of the previously-adopted and newly-requested permissions. + // - Run the task. + // - Adopt the previously-adopted permissions, dropping the ones just adopted. + // + // This would allow tests (and utility classes, such as the TestCarrierConfigReceiver attempted + // in aosp/2106007) to call runAsShell even within a test that has already adopted permissions. + if (SdkLevel.isAtLeastS() && !autom.getAdoptedShellPermissions().isNullOrEmpty()) { + throw IllegalStateException("adoptShellPermissionIdentity calls must not be nested") + } + autom.adoptShellPermissionIdentity(*permissions) try { return task() |