summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--PermissionController/role-controller/java/com/android/role/controller/util/UserUtils.java3
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java33
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/utils/UserUtils.java2
-rw-r--r--PermissionController/src/com/android/permissioncontroller/safetycenter/service/SafetyCenterSearchIndexablesProvider.kt4
-rw-r--r--PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetySubpageEntryPreference.kt8
-rw-r--r--PermissionController/src/com/android/permissioncontroller/safetycenter/ui/StaticSafetyEntryPreference.java3
-rw-r--r--PermissionController/wear-permission-components/src/wear.permission.components/material2/Chip.kt2
-rw-r--r--PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionButton.kt1
-rw-r--r--tests/cts/permissionmultidevice/AccessRemoteDeviceCameraApp/AndroidManifest.xml1
-rw-r--r--tests/cts/permissionmultidevice/AccessRemoteDeviceCameraApp/src/android/permissionmultidevice/cts/accessremotedevicecamera/RequestPermissionActivity.kt18
-rw-r--r--tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/AppPermissionsTest.kt50
-rw-r--r--tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/DeviceAwarePermissionGrantTest.kt579
-rw-r--r--tests/cts/role/src/android/app/role/cts/RoleManagerTest.java1
13 files changed, 485 insertions, 220 deletions
diff --git a/PermissionController/role-controller/java/com/android/role/controller/util/UserUtils.java b/PermissionController/role-controller/java/com/android/role/controller/util/UserUtils.java
index 41233a23e..00ec67569 100644
--- a/PermissionController/role-controller/java/com/android/role/controller/util/UserUtils.java
+++ b/PermissionController/role-controller/java/com/android/role/controller/util/UserUtils.java
@@ -18,7 +18,6 @@ package com.android.role.controller.util;
import android.content.Context;
import android.os.Build;
-import android.os.Flags;
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
@@ -91,7 +90,7 @@ public final class UserUtils {
* allowed from Android V+ only, so this method will return false on Sdk levels below that.
*/
public static boolean isPrivateProfile(@NonNull UserHandle user, @NonNull Context context) {
- if (!SdkLevel.isAtLeastV() || !Flags.allowPrivateProfile()) {
+ if (!SdkLevel.isAtLeastV()) {
return false;
}
Context userContext = getUserContext(context, user);
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java
index 7573b571d..0dd07ffd0 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java
@@ -311,10 +311,8 @@ public class GrantPermissionsActivity extends SettingsActivity
PackageManager.EXTRA_REQUEST_PERMISSIONS_DEVICE_ID,
ContextCompat.DEVICE_ID_DEFAULT);
- if (mTargetDeviceId != ContextCompat.DEVICE_ID_DEFAULT) {
- mPackageManager = ContextCompat.createDeviceContext(this, mTargetDeviceId)
- .getPackageManager();
- }
+ mPackageManager = ContextCompat.createDeviceContext(this, mTargetDeviceId)
+ .getPackageManager();
// When the permission grant dialog is streamed to a virtual device, and when requested
// permissions include both device-aware permissions and non-device aware permissions,
@@ -337,21 +335,6 @@ public class GrantPermissionsActivity extends SettingsActivity
new Intent(this, PermissionDialogStreamingBlockedActivity.class));
return;
}
- } else if (mTargetDeviceId != ContextCompat.DEVICE_ID_DEFAULT) {
- // On the default device, when requested permissions are for a remote device,
- // filter out non-device aware permissions.
- for (int i = mRequestedPermissions.size() - 1; i >= 0; i--) {
- if (!MultiDeviceUtils.isPermissionDeviceAware(
- getApplicationContext(),
- mTargetDeviceId,
- mRequestedPermissions.get(i))) {
- Log.e(
- LOG_TAG,
- "non-device aware permission is requested for a remote device: "
- + mRequestedPermissions.get(i));
- mRequestedPermissions.remove(i);
- }
- }
}
}
@@ -740,7 +723,7 @@ public class GrantPermissionsActivity extends SettingsActivity
int dialogDisplayDeviceId = ContextCompat.getDeviceId(this);
boolean isMessageDeviceAware =
dialogDisplayDeviceId != ContextCompat.DEVICE_ID_DEFAULT
- || dialogDisplayDeviceId != mTargetDeviceId;
+ || dialogDisplayDeviceId != info.getDeviceId();
int messageId = getMessageId(info.getGroupName(), info.getPrompt(), isMessageDeviceAware);
CharSequence message =
@@ -1132,17 +1115,9 @@ public class GrantPermissionsActivity extends SettingsActivity
if ((mDelegated || (mViewModel != null && mViewModel.shouldReturnPermissionState()))
&& mTargetPackage != null) {
- PackageManager defaultDevicePackageManager = SdkLevel.isAtLeastV()
- && mTargetDeviceId != ContextCompat.DEVICE_ID_DEFAULT
- ? createDeviceContext(ContextCompat.DEVICE_ID_DEFAULT).getPackageManager()
- : mPackageManager;
- PackageManager targetDevicePackageManager = mPackageManager;
for (int i = 0; i < resultPermissions.length; i++) {
String permission = resultPermissions[i];
- PackageManager pm = MultiDeviceUtils.isPermissionDeviceAware(
- getApplicationContext(), mTargetDeviceId, permission)
- ? targetDevicePackageManager : defaultDevicePackageManager;
- grantResults[i] = pm.checkPermission(resultPermissions[i], mTargetPackage);
+ grantResults[i] = mPackageManager.checkPermission(permission, mTargetPackage);
}
} else {
grantResults = new int[0];
diff --git a/PermissionController/src/com/android/permissioncontroller/role/utils/UserUtils.java b/PermissionController/src/com/android/permissioncontroller/role/utils/UserUtils.java
index 4d778befb..10e8dd0e1 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/utils/UserUtils.java
+++ b/PermissionController/src/com/android/permissioncontroller/role/utils/UserUtils.java
@@ -139,7 +139,7 @@ public class UserUtils {
*/
private static boolean isPrivateProfile(@NonNull UserHandle userHandle,
@NonNull Context context) {
- if (!SdkLevel.isAtLeastV() || !android.os.Flags.allowPrivateProfile()) {
+ if (!SdkLevel.isAtLeastV()) {
return false;
}
Context userContext = context.createContextAsUser(userHandle, /* flags= */ 0);
diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/service/SafetyCenterSearchIndexablesProvider.kt b/PermissionController/src/com/android/permissioncontroller/safetycenter/service/SafetyCenterSearchIndexablesProvider.kt
index 8d7d96f99..307ef9cf6 100644
--- a/PermissionController/src/com/android/permissioncontroller/safetycenter/service/SafetyCenterSearchIndexablesProvider.kt
+++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/service/SafetyCenterSearchIndexablesProvider.kt
@@ -331,9 +331,7 @@ class SafetyCenterSearchIndexablesProvider : BaseSearchIndexablesProvider() {
get() = SafetyCenterIds.entryIdFromString(id)
private fun isPrivateProfileSupported(): Boolean {
- return SdkLevel.isAtLeastV() &&
- com.android.permission.flags.Flags.privateProfileSupported() &&
- android.os.Flags.allowPrivateProfile()
+ return SdkLevel.isAtLeastV() && com.android.permission.flags.Flags.privateProfileSupported()
}
companion object {
diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetySubpageEntryPreference.kt b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetySubpageEntryPreference.kt
index b89abde13..551f676f1 100644
--- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetySubpageEntryPreference.kt
+++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetySubpageEntryPreference.kt
@@ -49,7 +49,7 @@ class SafetySubpageEntryPreference(
context: Context,
private val launchTaskId: Int?,
private val entry: SafetyCenterEntry,
- private val viewModel: SafetyCenterViewModel
+ private val viewModel: SafetyCenterViewModel,
) : TwoTargetPreference(context), ComparablePreference {
init {
@@ -108,9 +108,7 @@ class SafetySubpageEntryPreference(
}
private fun isPrivateProfileSupported(): Boolean {
- return SdkLevel.isAtLeastV() &&
- com.android.permission.flags.Flags.privateProfileSupported() &&
- android.os.Flags.allowPrivateProfile()
+ return SdkLevel.isAtLeastV() && com.android.permission.flags.Flags.privateProfileSupported()
}
override fun onBindViewHolder(holder: PreferenceViewHolder) {
@@ -125,7 +123,7 @@ class SafetySubpageEntryPreference(
PendingIntentSender.send(iconAction.pendingIntent, launchTaskId)
viewModel.interactionLogger.recordForEntry(
Action.ENTRY_ICON_ACTION_CLICKED,
- entry
+ entry,
)
} catch (ex: Exception) {
Log.e(TAG, "Failed to execute icon action intent for $entry", ex)
diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/StaticSafetyEntryPreference.java b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/StaticSafetyEntryPreference.java
index 87d8744a8..0da8286f6 100644
--- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/StaticSafetyEntryPreference.java
+++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/StaticSafetyEntryPreference.java
@@ -98,8 +98,7 @@ public class StaticSafetyEntryPreference extends Preference implements Comparabl
private Boolean isPrivateProfileSupported() {
return SdkLevel.isAtLeastV()
- && com.android.permission.flags.Flags.privateProfileSupported()
- && android.os.Flags.allowPrivateProfile();
+ && com.android.permission.flags.Flags.privateProfileSupported();
}
@Override
diff --git a/PermissionController/wear-permission-components/src/wear.permission.components/material2/Chip.kt b/PermissionController/wear-permission-components/src/wear.permission.components/material2/Chip.kt
index 23074a06f..57fdbca03 100644
--- a/PermissionController/wear-permission-components/src/wear.permission.components/material2/Chip.kt
+++ b/PermissionController/wear-permission-components/src/wear.permission.components/material2/Chip.kt
@@ -205,7 +205,7 @@ fun Chip(
color = secondaryTextColor,
overflow = TextOverflow.Ellipsis,
maxLines = secondaryLabelMaxLines ?: 1,
- style = MaterialTheme.typography.caption2,
+ style = MaterialTheme.typography.caption2.copy(hyphens = Hyphens.Auto),
)
}
}
diff --git a/PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionButton.kt b/PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionButton.kt
index 5f1c8dd2c..320e58964 100644
--- a/PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionButton.kt
+++ b/PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionButton.kt
@@ -123,6 +123,7 @@ internal fun WearPermissionButtonInternal(
text = secondaryLabel,
modifier = Modifier.fillMaxWidth(),
maxLines = secondaryLabelMaxLines ?: LocalTextConfiguration.current.maxLines,
+ style = LocalTextStyle.current.copy(hyphens = Hyphens.Auto),
)
}
}
diff --git a/tests/cts/permissionmultidevice/AccessRemoteDeviceCameraApp/AndroidManifest.xml b/tests/cts/permissionmultidevice/AccessRemoteDeviceCameraApp/AndroidManifest.xml
index 211e415bd..c31bfdaf3 100644
--- a/tests/cts/permissionmultidevice/AccessRemoteDeviceCameraApp/AndroidManifest.xml
+++ b/tests/cts/permissionmultidevice/AccessRemoteDeviceCameraApp/AndroidManifest.xml
@@ -21,6 +21,7 @@
package="android.permissionmultidevice.cts.accessremotedevicecamera">
<uses-permission android:name="android.permission.CAMERA" />
+ <uses-permission android:name="android.permission.READ_CONTACTS" />
<application>
<activity android:name=".RequestPermissionActivity" android:exported="true" />
diff --git a/tests/cts/permissionmultidevice/AccessRemoteDeviceCameraApp/src/android/permissionmultidevice/cts/accessremotedevicecamera/RequestPermissionActivity.kt b/tests/cts/permissionmultidevice/AccessRemoteDeviceCameraApp/src/android/permissionmultidevice/cts/accessremotedevicecamera/RequestPermissionActivity.kt
index fa1d1f83c..33daa1253 100644
--- a/tests/cts/permissionmultidevice/AccessRemoteDeviceCameraApp/src/android/permissionmultidevice/cts/accessremotedevicecamera/RequestPermissionActivity.kt
+++ b/tests/cts/permissionmultidevice/AccessRemoteDeviceCameraApp/src/android/permissionmultidevice/cts/accessremotedevicecamera/RequestPermissionActivity.kt
@@ -16,7 +16,6 @@
package android.permissionmultidevice.cts.accessremotedevicecamera
-import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.Intent
@@ -33,17 +32,24 @@ class RequestPermissionActivity : Activity() {
val deviceId =
intent.getIntExtra(
PackageManager.EXTRA_REQUEST_PERMISSIONS_DEVICE_ID,
- Context.DEVICE_ID_DEFAULT
+ Context.DEVICE_ID_INVALID,
)
- requestPermissions(DEVICE_AWARE_PERMISSIONS, 1001, deviceId)
+ val permissions =
+ intent.getStringArrayExtra(PackageManager.EXTRA_REQUEST_PERMISSIONS_NAMES)!!
+
+ if (deviceId != Context.DEVICE_ID_INVALID) {
+ requestPermissions(permissions, 1001, deviceId)
+ } else {
+ requestPermissions(permissions, 1001)
+ }
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray,
- deviceId: Int
+ deviceId: Int,
) {
val resultReceiver =
intent.getParcelableExtra(Intent.EXTRA_RESULT_RECEIVER, RemoteCallback::class.java)
@@ -57,8 +63,4 @@ class RequestPermissionActivity : Activity() {
resultReceiver?.sendResult(result)
finish()
}
-
- companion object {
- private val DEVICE_AWARE_PERMISSIONS = arrayOf(Manifest.permission.CAMERA)
- }
}
diff --git a/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/AppPermissionsTest.kt b/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/AppPermissionsTest.kt
index 907917f6f..76c86df76 100644
--- a/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/AppPermissionsTest.kt
+++ b/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/AppPermissionsTest.kt
@@ -108,7 +108,7 @@ class AppPermissionsTest {
@RequiresFlagsEnabled(
Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED,
- Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED
+ Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED,
)
@Test
fun externalDevicePermissionGrantTest() {
@@ -123,7 +123,7 @@ class AppPermissionsTest {
verifyRadioButtonStates(
allowForegroundChecked = true,
askChecked = false,
- denyChecked = false
+ denyChecked = false,
)
UiAutomatorUtils2.getUiDevice().pressBack()
@@ -131,14 +131,14 @@ class AppPermissionsTest {
mapOf(
"Allowed" to listOf(externalDeviceCameraText),
"Ask every time" to emptyList(),
- "Not allowed" to listOf("Camera")
+ "Not allowed" to listOf("Camera", "Contacts"),
)
assertEquals(expectedGrantInfoMap, getGrantInfoMap())
}
@RequiresFlagsEnabled(
Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED,
- Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED
+ Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED,
)
@Test
fun externalDevicePermissionChangeToAskTest() {
@@ -153,7 +153,7 @@ class AppPermissionsTest {
@RequiresFlagsEnabled(
Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED,
- Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED
+ Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED,
)
@Test
fun externalDevicePermissionChangeToDenyTest() {
@@ -168,7 +168,7 @@ class AppPermissionsTest {
@RequiresFlagsEnabled(
Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED,
- Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED
+ Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED,
)
@Test
fun externalDevicePermissionChangeToAllowTest() {
@@ -180,7 +180,7 @@ class AppPermissionsTest {
verifyRadioButtonStates(
allowForegroundChecked = false,
askChecked = true,
- denyChecked = false
+ denyChecked = false,
)
clickAllowForegroundButton()
@@ -189,7 +189,7 @@ class AppPermissionsTest {
@RequiresFlagsEnabled(
Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED,
- Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED
+ Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED,
)
@Test
fun externalDevicePermissionNotDisplayedInitiallyTest() {
@@ -200,14 +200,14 @@ class AppPermissionsTest {
mapOf(
"Allowed" to emptyList(),
"Ask every time" to emptyList(),
- "Not allowed" to listOf("Camera")
+ "Not allowed" to listOf("Camera", "Contacts"),
)
assertEquals(expectedGrantInfoMap, getGrantInfoMap())
}
@RequiresFlagsEnabled(
Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED,
- Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED
+ Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED,
)
@Test
fun externalDevicePermissionStickyOnGrantTest() {
@@ -219,7 +219,7 @@ class AppPermissionsTest {
verifyRadioButtonStates(
allowForegroundChecked = true,
askChecked = false,
- denyChecked = false
+ denyChecked = false,
)
clickDenyButton()
@@ -232,7 +232,7 @@ class AppPermissionsTest {
mapOf(
"Allowed" to emptyList(),
"Ask every time" to emptyList(),
- "Not allowed" to listOf("Camera", externalDeviceCameraText)
+ "Not allowed" to listOf("Camera", externalDeviceCameraText, "Contacts"),
)
assertEquals(expectedGrantInfoMap, getGrantInfoMap())
}
@@ -243,7 +243,7 @@ class AppPermissionsTest {
verifyRadioButtonStates(
allowForegroundChecked = false,
askChecked = true,
- denyChecked = false
+ denyChecked = false,
)
UiAutomatorUtils2.getUiDevice().pressBack()
@@ -252,7 +252,7 @@ class AppPermissionsTest {
mapOf(
"Allowed" to emptyList(),
"Ask every time" to listOf(externalDeviceCameraText),
- "Not allowed" to listOf("Camera")
+ "Not allowed" to listOf("Camera", "Contacts"),
)
assertEquals(expectedGrantInfoMap, getGrantInfoMap())
@@ -270,7 +270,7 @@ class AppPermissionsTest {
verifyRadioButtonStates(
allowForegroundChecked = false,
askChecked = false,
- denyChecked = true
+ denyChecked = true,
)
UiAutomatorUtils2.getUiDevice().pressBack()
@@ -279,7 +279,7 @@ class AppPermissionsTest {
mapOf(
"Allowed" to emptyList(),
"Ask every time" to emptyList(),
- "Not allowed" to listOf("Camera", externalDeviceCameraText)
+ "Not allowed" to listOf("Camera", externalDeviceCameraText, "Contacts"),
)
assertEquals(expectedGrantInfoMap, getGrantInfoMap())
@@ -297,7 +297,7 @@ class AppPermissionsTest {
verifyRadioButtonStates(
allowForegroundChecked = true,
askChecked = false,
- denyChecked = false
+ denyChecked = false,
)
UiAutomatorUtils2.getUiDevice().pressBack()
@@ -306,7 +306,7 @@ class AppPermissionsTest {
mapOf(
"Allowed" to listOf(externalDeviceCameraText),
"Ask every time" to emptyList(),
- "Not allowed" to listOf("Camera")
+ "Not allowed" to listOf("Camera", "Contacts"),
)
assertEquals(expectedGrantInfoMap, getGrantInfoMap())
@@ -327,7 +327,7 @@ class AppPermissionsTest {
mapOf(
"Allowed" to mutableListOf<String>(),
"Ask every time" to mutableListOf(),
- "Not allowed" to mutableListOf()
+ "Not allowed" to mutableListOf(),
)
val outOfScopeTitles = setOf("Unused app settings", "Manage app if unused")
@@ -360,21 +360,21 @@ class AppPermissionsTest {
private fun verifyRadioButtonStates(
allowForegroundChecked: Boolean,
askChecked: Boolean,
- denyChecked: Boolean
+ denyChecked: Boolean,
) {
eventually {
assertEquals(
allowForegroundChecked,
UiAutomatorUtils2.waitFindObject(By.res(ALLOW_FOREGROUND_ONLY_RADIO_BUTTON))
- .isChecked
+ .isChecked,
)
assertEquals(
askChecked,
- UiAutomatorUtils2.waitFindObject(By.res(ASK_RADIO_BUTTON)).isChecked
+ UiAutomatorUtils2.waitFindObject(By.res(ASK_RADIO_BUTTON)).isChecked,
)
assertEquals(
denyChecked,
- UiAutomatorUtils2.waitFindObject(By.res(DENY_RADIO_BUTTON)).isChecked
+ UiAutomatorUtils2.waitFindObject(By.res(DENY_RADIO_BUTTON)).isChecked,
)
}
}
@@ -392,7 +392,7 @@ class AppPermissionsTest {
)
},
Until.newWindow(),
- NEW_WINDOW_TIMEOUT_MILLIS
+ NEW_WINDOW_TIMEOUT_MILLIS,
)
}
@@ -418,7 +418,7 @@ class AppPermissionsTest {
permissionManager.grantRuntimePermission(
APP_PACKAGE_NAME,
DEVICE_AWARE_PERMISSION,
- persistentDeviceId
+ persistentDeviceId,
)
private fun getPermState(): Map<String, PermissionManager.PermissionState> =
diff --git a/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/DeviceAwarePermissionGrantTest.kt b/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/DeviceAwarePermissionGrantTest.kt
index 5c7573a0b..e1068e19a 100644
--- a/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/DeviceAwarePermissionGrantTest.kt
+++ b/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/DeviceAwarePermissionGrantTest.kt
@@ -24,11 +24,11 @@ import android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_CUSTOM
import android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_DEFAULT
import android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_CAMERA
import android.content.ComponentName
+import android.content.Context
import android.content.Intent
import android.content.Intent.EXTRA_RESULT_RECEIVER
import android.content.pm.PackageManager
import android.content.pm.PackageManager.ACTION_REQUEST_PERMISSIONS
-import android.hardware.display.DisplayManager
import android.hardware.display.VirtualDisplay
import android.os.Build
import android.os.Bundle
@@ -41,7 +41,6 @@ import android.permissionmultidevice.cts.UiAutomatorUtils.click
import android.permissionmultidevice.cts.UiAutomatorUtils.findTextForView
import android.permissionmultidevice.cts.UiAutomatorUtils.waitFindObject
import android.platform.test.annotations.AppModeFull
-import android.platform.test.annotations.RequiresFlagsDisabled
import android.platform.test.annotations.RequiresFlagsEnabled
import android.provider.Settings
import android.view.Display
@@ -65,13 +64,19 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, codeName = "VanillaIceCream")
@AppModeFull(reason = "VirtualDeviceManager cannot be accessed by instant apps")
-class DeviceAwarePermissionGrantTest {
+@RequiresFlagsEnabled(
+ Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED,
+ Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED,
+ Flags.FLAG_ALLOW_HOST_PERMISSION_DIALOGS_ON_VIRTUAL_DEVICES,
+)
+open class DeviceAwarePermissionGrantTest {
private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
private val defaultDeviceContext = instrumentation.targetContext
+ private lateinit var defaultDeviceName: String
private lateinit var virtualDeviceManager: VirtualDeviceManager
private lateinit var virtualDevice: VirtualDeviceManager.VirtualDevice
private lateinit var virtualDisplay: VirtualDisplay
- private lateinit var deviceDisplayName: String
+ private lateinit var virtualDeviceName: String
private val permissionManager =
defaultDeviceContext.getSystemService(PermissionManager::class.java)!!
@@ -88,194 +93,449 @@ class DeviceAwarePermissionGrantTest {
installPackage(APP_APK_PATH_STREAMING)
virtualDeviceManager =
defaultDeviceContext.getSystemService(VirtualDeviceManager::class.java)!!
+
+ defaultDeviceName =
+ Settings.Global.getString(
+ defaultDeviceContext.contentResolver,
+ Settings.Global.DEVICE_NAME,
+ )
+ }
+
+ @After
+ fun cleanup() {
+ uninstallPackage(APP_PACKAGE_NAME, requireSuccess = false)
+ Thread.sleep(2000)
+ }
+
+ private fun createVirtualDevice(cameraPolicy: Int = DEVICE_POLICY_DEFAULT) {
virtualDevice =
virtualDeviceRule.createManagedVirtualDevice(
VirtualDeviceParams.Builder()
- .setDevicePolicy(POLICY_TYPE_CAMERA, DEVICE_POLICY_CUSTOM)
+ .setDevicePolicy(POLICY_TYPE_CAMERA, cameraPolicy)
.build()
)
-
- val displayConfigBuilder =
- VirtualDeviceRule.createDefaultVirtualDisplayConfigBuilder(
- DISPLAY_WIDTH,
- DISPLAY_HEIGHT,
- )
- .setFlags(
- DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC or
- DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED or
- DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY
- )
-
virtualDisplay =
- virtualDeviceRule.createManagedVirtualDisplay(virtualDevice, displayConfigBuilder)!!
- deviceDisplayName =
+ virtualDeviceRule.createManagedVirtualDisplay(
+ virtualDevice,
+ VirtualDeviceRule.createTrustedVirtualDisplayConfigBuilder(),
+ )!!
+ virtualDeviceName =
virtualDeviceManager.getVirtualDevice(virtualDevice.deviceId)!!.displayName.toString()
}
- @After
- fun cleanup() {
- uninstallPackage(APP_PACKAGE_NAME, requireSuccess = false)
- Thread.sleep(2000)
+ @Test
+ fun deviceAwarePermission_onHost_requestHostPermission() {
+ createVirtualDevice(cameraPolicy = DEVICE_POLICY_CUSTOM)
+ testMultiDevicePermissionGrant(
+ permission = Manifest.permission.CAMERA,
+ initialDefaultDevicePermission = false,
+ initialVirtualDevicePermission = false,
+ requestingFromDevice = DEVICE_ID_DEFAULT,
+ requestingForDevice = DEVICE_ID_DEFAULT,
+ dialogDeviceName = DEVICE_ID_INVALID,
+ expectPermissionGrantedOnDefaultDevice = true,
+ expectPermissionGrantedOnVirtualDevice = false,
+ )
}
- @RequiresFlagsEnabled(
- Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED,
- Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED,
- )
@Test
- fun onHostDevice_requestPermissionForHostDevice_shouldGrantPermission() {
- assertAppHasPermissionForDevice(DEVICE_ID_DEFAULT, false)
- assertAppHasPermissionForDevice(virtualDevice.deviceId, false)
+ fun deviceAwarePermission_onHost_withRemotePermission_requestHostPermission() {
+ createVirtualDevice(cameraPolicy = DEVICE_POLICY_CUSTOM)
+ testMultiDevicePermissionGrant(
+ permission = Manifest.permission.CAMERA,
+ initialDefaultDevicePermission = false,
+ initialVirtualDevicePermission = true,
+ requestingFromDevice = DEVICE_ID_DEFAULT,
+ requestingForDevice = DEVICE_ID_DEFAULT,
+ dialogDeviceName = DEVICE_ID_INVALID,
+ expectPermissionGrantedOnDefaultDevice = true,
+ expectPermissionGrantedOnVirtualDevice = true,
+ )
+ }
- testGrantPermissionForDevice(
- Display.DEFAULT_DISPLAY,
- DEVICE_ID_DEFAULT,
- false,
- "",
+ @Test
+ fun deviceAwarePermission_onHost_requestPermissionWithoutDeviceId() {
+ createVirtualDevice(cameraPolicy = DEVICE_POLICY_CUSTOM)
+ testMultiDevicePermissionGrant(
+ permission = Manifest.permission.CAMERA,
+ initialDefaultDevicePermission = false,
+ initialVirtualDevicePermission = false,
+ requestingFromDevice = DEVICE_ID_DEFAULT,
+ requestingForDevice = DEVICE_ID_INVALID,
+ dialogDeviceName = DEVICE_ID_INVALID,
expectPermissionGrantedOnDefaultDevice = true,
- expectPermissionGrantedOnRemoteDevice = false,
+ expectPermissionGrantedOnVirtualDevice = false,
)
}
- @RequiresFlagsEnabled(
- Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED,
- Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED,
- )
@Test
- fun onHostDevice_requestPermissionForRemoteDevice_shouldGrantPermission() {
- assertAppHasPermissionForDevice(DEVICE_ID_DEFAULT, false)
- assertAppHasPermissionForDevice(virtualDevice.deviceId, false)
+ fun deviceAwarePermission_onHost_withRemotePermission_requestPermissionWithoutDeviceId() {
+ createVirtualDevice(cameraPolicy = DEVICE_POLICY_CUSTOM)
+ testMultiDevicePermissionGrant(
+ permission = Manifest.permission.CAMERA,
+ initialDefaultDevicePermission = false,
+ initialVirtualDevicePermission = true,
+ requestingFromDevice = DEVICE_ID_DEFAULT,
+ requestingForDevice = DEVICE_ID_INVALID,
+ dialogDeviceName = DEVICE_ID_INVALID,
+ expectPermissionGrantedOnDefaultDevice = true,
+ expectPermissionGrantedOnVirtualDevice = true,
+ )
+ }
- testGrantPermissionForDevice(
- Display.DEFAULT_DISPLAY,
- virtualDevice.deviceId,
- true,
- deviceDisplayName,
+ @Test
+ fun deviceAwarePermission_onHost_requestRemotePermission() {
+ createVirtualDevice(cameraPolicy = DEVICE_POLICY_CUSTOM)
+ testMultiDevicePermissionGrant(
+ permission = Manifest.permission.CAMERA,
+ initialDefaultDevicePermission = false,
+ initialVirtualDevicePermission = false,
+ requestingFromDevice = DEVICE_ID_DEFAULT,
+ requestingForDevice = virtualDevice.deviceId,
+ dialogDeviceName = virtualDevice.deviceId,
expectPermissionGrantedOnDefaultDevice = false,
- expectPermissionGrantedOnRemoteDevice = true,
+ expectPermissionGrantedOnVirtualDevice = true,
)
}
@Test
- fun onHostDevice_requestPermissionForRemoteDeviceAfterPermissionGrantedToHostDevice() {
- instrumentation.uiAutomation.grantRuntimePermission(APP_PACKAGE_NAME, PERMISSION)
+ fun deviceAwarePermission_onHost_withHostPermission_requestRemotePermission() {
+ createVirtualDevice(cameraPolicy = DEVICE_POLICY_CUSTOM)
+ testMultiDevicePermissionGrant(
+ permission = Manifest.permission.CAMERA,
+ initialDefaultDevicePermission = true,
+ initialVirtualDevicePermission = false,
+ requestingFromDevice = DEVICE_ID_DEFAULT,
+ requestingForDevice = virtualDevice.deviceId,
+ dialogDeviceName = virtualDevice.deviceId,
+ expectPermissionGrantedOnDefaultDevice = true,
+ expectPermissionGrantedOnVirtualDevice = true,
+ )
+ }
- assertAppHasPermissionForDevice(DEVICE_ID_DEFAULT, true)
- assertAppHasPermissionForDevice(virtualDevice.deviceId, false)
+ @Test
+ fun deviceAwarePermission_onRemote_requestRemotePermission() {
+ createVirtualDevice(cameraPolicy = DEVICE_POLICY_CUSTOM)
+ testMultiDevicePermissionGrant(
+ permission = Manifest.permission.CAMERA,
+ initialDefaultDevicePermission = false,
+ initialVirtualDevicePermission = false,
+ requestingFromDevice = virtualDevice.deviceId,
+ requestingForDevice = virtualDevice.deviceId,
+ dialogDeviceName = virtualDevice.deviceId,
+ expectPermissionGrantedOnDefaultDevice = false,
+ expectPermissionGrantedOnVirtualDevice = true,
+ )
+ }
- testGrantPermissionForDevice(
- Display.DEFAULT_DISPLAY,
- virtualDevice.deviceId,
- true,
- deviceDisplayName,
+ @Test
+ fun deviceAwarePermission_onRemote_withHostPermission_requestRemotePermission() {
+ createVirtualDevice(cameraPolicy = DEVICE_POLICY_CUSTOM)
+ testMultiDevicePermissionGrant(
+ permission = Manifest.permission.CAMERA,
+ initialDefaultDevicePermission = true,
+ initialVirtualDevicePermission = false,
+ requestingFromDevice = virtualDevice.deviceId,
+ requestingForDevice = virtualDevice.deviceId,
+ dialogDeviceName = virtualDevice.deviceId,
expectPermissionGrantedOnDefaultDevice = true,
- expectPermissionGrantedOnRemoteDevice = true,
+ expectPermissionGrantedOnVirtualDevice = true,
)
}
@Test
- fun onHostDevice_requestPermissionForHostDeviceAfterPermissionGrantedToRemoteDevice() {
- permissionManager.grantRuntimePermission(
- APP_PACKAGE_NAME,
- PERMISSION,
- virtualDevice.persistentDeviceId!!,
+ fun deviceAwarePermission_onRemote_requestPermissionWithoutDeviceId() {
+ createVirtualDevice(cameraPolicy = DEVICE_POLICY_CUSTOM)
+ testMultiDevicePermissionGrant(
+ permission = Manifest.permission.CAMERA,
+ initialDefaultDevicePermission = false,
+ initialVirtualDevicePermission = false,
+ requestingFromDevice = virtualDevice.deviceId,
+ requestingForDevice = DEVICE_ID_INVALID,
+ dialogDeviceName = virtualDevice.deviceId,
+ expectPermissionGrantedOnDefaultDevice = false,
+ expectPermissionGrantedOnVirtualDevice = true,
)
+ }
- assertAppHasPermissionForDevice(DEVICE_ID_DEFAULT, false)
- assertAppHasPermissionForDevice(virtualDevice.deviceId, true)
+ @Test
+ fun deviceAwarePermission_onRemote_withHostPermission_requestPermissionWithoutDeviceId() {
+ createVirtualDevice(cameraPolicy = DEVICE_POLICY_CUSTOM)
+ testMultiDevicePermissionGrant(
+ permission = Manifest.permission.CAMERA,
+ initialDefaultDevicePermission = true,
+ initialVirtualDevicePermission = false,
+ requestingFromDevice = virtualDevice.deviceId,
+ requestingForDevice = DEVICE_ID_INVALID,
+ dialogDeviceName = virtualDevice.deviceId,
+ expectPermissionGrantedOnDefaultDevice = true,
+ expectPermissionGrantedOnVirtualDevice = true,
+ )
+ }
- testGrantPermissionForDevice(
- Display.DEFAULT_DISPLAY,
- DEVICE_ID_DEFAULT,
- false,
- "",
+ // TODO: Receives PERMISSION_DENIED but it's fine if remote permission is held??
+ @Test
+ fun deviceAwarePermission_onRemote_requestHostPermission() {
+ createVirtualDevice(cameraPolicy = DEVICE_POLICY_CUSTOM)
+ testMultiDevicePermissionGrant(
+ permission = Manifest.permission.CAMERA,
+ initialDefaultDevicePermission = false,
+ initialVirtualDevicePermission = false,
+ requestingFromDevice = virtualDevice.deviceId,
+ requestingForDevice = DEVICE_ID_DEFAULT,
+ dialogDeviceName = DEVICE_ID_DEFAULT,
expectPermissionGrantedOnDefaultDevice = true,
- expectPermissionGrantedOnRemoteDevice = true,
+ expectPermissionGrantedOnVirtualDevice = false,
)
}
- @RequiresFlagsEnabled(
- Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED,
- Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED,
- )
- @RequiresFlagsDisabled(Flags.FLAG_ALLOW_HOST_PERMISSION_DIALOGS_ON_VIRTUAL_DEVICES)
@Test
- fun onRemoteDevice_requestPermissionForHostDevice_shouldShowWarningDialog() {
- assertAppHasPermissionForDevice(DEVICE_ID_DEFAULT, false)
- assertAppHasPermissionForDevice(virtualDevice.deviceId, false)
+ fun deviceAwarePermission_onRemote_withRemotePermission_requestHostPermission() {
+ createVirtualDevice(cameraPolicy = DEVICE_POLICY_CUSTOM)
+ testMultiDevicePermissionGrant(
+ permission = Manifest.permission.CAMERA,
+ initialDefaultDevicePermission = false,
+ initialVirtualDevicePermission = true,
+ requestingFromDevice = virtualDevice.deviceId,
+ requestingForDevice = DEVICE_ID_DEFAULT,
+ dialogDeviceName = DEVICE_ID_DEFAULT,
+ expectPermissionGrantedOnDefaultDevice = true,
+ expectPermissionGrantedOnVirtualDevice = true,
+ )
+ }
- requestPermissionOnDevice(virtualDisplay.display.displayId, DEVICE_ID_DEFAULT)
+ @Test
+ fun deviceAwarePermissionWithoutCapability_onHost_requestHostPermission() {
+ createVirtualDevice(cameraPolicy = DEVICE_POLICY_DEFAULT)
+ testMultiDevicePermissionGrant(
+ permission = Manifest.permission.CAMERA,
+ initialDefaultDevicePermission = false,
+ initialVirtualDevicePermission = false,
+ requestingFromDevice = DEVICE_ID_DEFAULT,
+ requestingForDevice = DEVICE_ID_DEFAULT,
+ dialogDeviceName = DEVICE_ID_INVALID,
+ expectPermissionGrantedOnDefaultDevice = true,
+ expectPermissionGrantedOnVirtualDevice = true,
+ )
+ }
- val displayId = virtualDisplay.display.displayId
- waitFindObject(By.displayId(displayId).textContains("Permission request suppressed"))
+ @Test
+ fun deviceAwarePermissionWithoutCapability_onHost_requestPermissionWithoutDeviceId() {
+ createVirtualDevice(cameraPolicy = DEVICE_POLICY_DEFAULT)
+ testMultiDevicePermissionGrant(
+ permission = Manifest.permission.CAMERA,
+ initialDefaultDevicePermission = false,
+ initialVirtualDevicePermission = false,
+ requestingFromDevice = DEVICE_ID_DEFAULT,
+ requestingForDevice = DEVICE_ID_INVALID,
+ dialogDeviceName = DEVICE_ID_INVALID,
+ expectPermissionGrantedOnDefaultDevice = true,
+ expectPermissionGrantedOnVirtualDevice = true,
+ )
}
- @RequiresFlagsEnabled(
- Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED,
- Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED,
- Flags.FLAG_ALLOW_HOST_PERMISSION_DIALOGS_ON_VIRTUAL_DEVICES,
- )
- @SdkSuppress(minSdkVersion = Build.VERSION_CODES.BAKLAVA, codeName = "Baklava")
@Test
- fun onRemoteDevice_requestPermissionForHostDevice_shouldGrantPermission() {
- assertAppHasPermissionForDevice(DEVICE_ID_DEFAULT, false)
- assertAppHasPermissionForDevice(virtualDevice.deviceId, false)
- // Create a virtual device with default policy, so that camera permission request will
- // correspond to default device camera access.
- virtualDevice =
- virtualDeviceRule.createManagedVirtualDevice(
- VirtualDeviceParams.Builder()
- .setDevicePolicy(POLICY_TYPE_CAMERA, DEVICE_POLICY_DEFAULT)
- .build()
- )
- testGrantPermissionForDevice(
- virtualDisplay.display.displayId,
- virtualDevice.deviceId,
- true,
- Settings.Global.getString(
- defaultDeviceContext.contentResolver,
- Settings.Global.DEVICE_NAME,
- ),
+ fun deviceAwarePermissionWithoutCapability_onHost_requestRemotePermission() {
+ createVirtualDevice(cameraPolicy = DEVICE_POLICY_DEFAULT)
+ testMultiDevicePermissionGrant(
+ permission = Manifest.permission.CAMERA,
+ initialDefaultDevicePermission = false,
+ initialVirtualDevicePermission = false,
+ requestingFromDevice = DEVICE_ID_DEFAULT,
+ requestingForDevice = virtualDevice.deviceId,
+ dialogDeviceName = DEVICE_ID_INVALID,
expectPermissionGrantedOnDefaultDevice = true,
- expectPermissionGrantedOnRemoteDevice = false,
+ expectPermissionGrantedOnVirtualDevice = true,
)
}
- @RequiresFlagsEnabled(
- Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED,
- Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED,
- )
@Test
- fun onRemoteDevice_requestPermissionForRemoteDevice_shouldGrantPermission() {
- assertAppHasPermissionForDevice(DEVICE_ID_DEFAULT, false)
- assertAppHasPermissionForDevice(virtualDevice.deviceId, false)
+ fun deviceAwarePermissionWithoutCapability_onRemote_requestRemotePermission() {
+ createVirtualDevice(cameraPolicy = DEVICE_POLICY_DEFAULT)
+ testMultiDevicePermissionGrant(
+ permission = Manifest.permission.CAMERA,
+ initialDefaultDevicePermission = false,
+ initialVirtualDevicePermission = false,
+ requestingFromDevice = virtualDevice.deviceId,
+ requestingForDevice = virtualDevice.deviceId,
+ dialogDeviceName = DEVICE_ID_DEFAULT,
+ expectPermissionGrantedOnDefaultDevice = true,
+ expectPermissionGrantedOnVirtualDevice = true,
+ )
+ }
- testGrantPermissionForDevice(
- virtualDisplay.display.displayId,
- virtualDevice.deviceId,
- true,
- deviceDisplayName,
- expectPermissionGrantedOnDefaultDevice = false,
- expectPermissionGrantedOnRemoteDevice = true,
+ @Test
+ fun deviceAwarePermissionWithoutCapability_onRemote_requestPermissionWithoutDeviceId() {
+ createVirtualDevice(cameraPolicy = DEVICE_POLICY_DEFAULT)
+ testMultiDevicePermissionGrant(
+ permission = Manifest.permission.CAMERA,
+ initialDefaultDevicePermission = false,
+ initialVirtualDevicePermission = false,
+ requestingFromDevice = virtualDevice.deviceId,
+ requestingForDevice = DEVICE_ID_INVALID,
+ dialogDeviceName = DEVICE_ID_DEFAULT,
+ expectPermissionGrantedOnDefaultDevice = true,
+ expectPermissionGrantedOnVirtualDevice = true,
)
}
- private fun testGrantPermissionForDevice(
- displayId: Int,
- targetDeviceId: Int,
- showDeviceName: Boolean,
- expectedDeviceNameInDialog: String,
+ @Test
+ fun deviceAwarePermissionWithoutCapability_onRemote_requestHostPermission() {
+ createVirtualDevice(cameraPolicy = DEVICE_POLICY_DEFAULT)
+ testMultiDevicePermissionGrant(
+ permission = Manifest.permission.CAMERA,
+ initialDefaultDevicePermission = false,
+ initialVirtualDevicePermission = false,
+ requestingFromDevice = virtualDevice.deviceId,
+ requestingForDevice = DEVICE_ID_DEFAULT,
+ dialogDeviceName = DEVICE_ID_DEFAULT,
+ expectPermissionGrantedOnDefaultDevice = true,
+ expectPermissionGrantedOnVirtualDevice = true,
+ )
+ }
+
+ @Test
+ fun nonDeviceAwarePermission_onHost_requestHostPermission() {
+ createVirtualDevice()
+ testMultiDevicePermissionGrant(
+ permission = Manifest.permission.READ_CONTACTS,
+ initialDefaultDevicePermission = false,
+ initialVirtualDevicePermission = false,
+ requestingFromDevice = DEVICE_ID_DEFAULT,
+ requestingForDevice = DEVICE_ID_DEFAULT,
+ dialogDeviceName = DEVICE_ID_INVALID,
+ expectPermissionGrantedOnDefaultDevice = true,
+ expectPermissionGrantedOnVirtualDevice = true,
+ )
+ }
+
+ @Test
+ fun nonDeviceAwarePermission_onHost_requestPermissionWithoutDeviceId() {
+ createVirtualDevice()
+ testMultiDevicePermissionGrant(
+ permission = Manifest.permission.READ_CONTACTS,
+ initialDefaultDevicePermission = false,
+ initialVirtualDevicePermission = false,
+ requestingFromDevice = DEVICE_ID_DEFAULT,
+ requestingForDevice = DEVICE_ID_INVALID,
+ dialogDeviceName = DEVICE_ID_INVALID,
+ expectPermissionGrantedOnDefaultDevice = true,
+ expectPermissionGrantedOnVirtualDevice = true,
+ )
+ }
+
+ @Test
+ fun nonDeviceAwarePermission_onHost_requestRemotePermission() {
+ createVirtualDevice()
+ testMultiDevicePermissionGrant(
+ permission = Manifest.permission.READ_CONTACTS,
+ initialDefaultDevicePermission = false,
+ initialVirtualDevicePermission = false,
+ requestingFromDevice = DEVICE_ID_DEFAULT,
+ requestingForDevice = virtualDevice.deviceId,
+ dialogDeviceName = DEVICE_ID_INVALID,
+ expectPermissionGrantedOnDefaultDevice = true,
+ expectPermissionGrantedOnVirtualDevice = true,
+ )
+ }
+
+ @Test
+ fun nonDeviceAwarePermission_onRemote_requestRemotePermission() {
+ createVirtualDevice()
+ testMultiDevicePermissionGrant(
+ permission = Manifest.permission.READ_CONTACTS,
+ initialDefaultDevicePermission = false,
+ initialVirtualDevicePermission = false,
+ requestingFromDevice = virtualDevice.deviceId,
+ requestingForDevice = virtualDevice.deviceId,
+ dialogDeviceName = DEVICE_ID_DEFAULT,
+ expectPermissionGrantedOnDefaultDevice = true,
+ expectPermissionGrantedOnVirtualDevice = true,
+ )
+ }
+
+ @Test
+ fun nonDeviceAwarePermission_onRemote_requestPermissionWithoutDeviceId() {
+ createVirtualDevice()
+ testMultiDevicePermissionGrant(
+ permission = Manifest.permission.READ_CONTACTS,
+ initialDefaultDevicePermission = false,
+ initialVirtualDevicePermission = false,
+ requestingFromDevice = virtualDevice.deviceId,
+ requestingForDevice = DEVICE_ID_INVALID,
+ dialogDeviceName = DEVICE_ID_DEFAULT,
+ expectPermissionGrantedOnDefaultDevice = true,
+ expectPermissionGrantedOnVirtualDevice = true,
+ )
+ }
+
+ @Test
+ fun nonDeviceAwarePermission_onRemote_requestHostPermission() {
+ createVirtualDevice()
+ testMultiDevicePermissionGrant(
+ permission = Manifest.permission.READ_CONTACTS,
+ initialDefaultDevicePermission = false,
+ initialVirtualDevicePermission = false,
+ requestingFromDevice = virtualDevice.deviceId,
+ requestingForDevice = DEVICE_ID_DEFAULT,
+ dialogDeviceName = DEVICE_ID_DEFAULT,
+ expectPermissionGrantedOnDefaultDevice = true,
+ expectPermissionGrantedOnVirtualDevice = true,
+ )
+ }
+
+ private fun testMultiDevicePermissionGrant(
+ permission: String,
+ initialDefaultDevicePermission: Boolean,
+ initialVirtualDevicePermission: Boolean,
+ requestingFromDevice: Int,
+ requestingForDevice: Int,
+ dialogDeviceName: Int,
expectPermissionGrantedOnDefaultDevice: Boolean,
- expectPermissionGrantedOnRemoteDevice: Boolean,
+ expectPermissionGrantedOnVirtualDevice: Boolean,
) {
- val future = requestPermissionOnDevice(displayId, targetDeviceId)
+ if (initialDefaultDevicePermission) {
+ instrumentation.uiAutomation.grantRuntimePermission(APP_PACKAGE_NAME, permission)
+ }
+ if (initialVirtualDevicePermission) {
+ grantRuntimePermissionOnVirtualDevice(permission)
+ }
+ assertAppHasPermissionForDevice(
+ DEVICE_ID_DEFAULT,
+ permission,
+ initialDefaultDevicePermission,
+ )
+ assertAppHasPermissionForDevice(
+ virtualDevice.deviceId,
+ permission,
+ initialVirtualDevicePermission,
+ )
- if (showDeviceName) {
+ val displayId =
+ if (requestingFromDevice == DEVICE_ID_DEFAULT) {
+ Display.DEFAULT_DISPLAY
+ } else {
+ virtualDisplay.display.displayId
+ }
+
+ val future = requestPermissionOnDevice(displayId, requestingForDevice, permission)
+
+ if (dialogDeviceName != DEVICE_ID_INVALID) {
+ val expectedDeviceNameInDialog =
+ if (dialogDeviceName == DEVICE_ID_DEFAULT) {
+ defaultDeviceName
+ } else {
+ virtualDeviceName
+ }
assertPermissionMessageContainsDeviceName(displayId, expectedDeviceNameInDialog)
+ } else {
+ assertPermissionMessageDoesNotContainDeviceName(displayId)
}
// Click the allow button in the dialog to grant permission
- SystemUtil.eventually { click(By.displayId(displayId).res(ALLOW_BUTTON)) }
+ val allowButton =
+ if (permission == Manifest.permission.CAMERA) ALLOW_BUTTON_FOREGROUND else ALLOW_BUTTON
+ SystemUtil.eventually { click(By.displayId(displayId).res(allowButton)) }
// Validate permission grant result returned from callback
val grantPermissionResult = future.get(TIMEOUT, TimeUnit.MILLISECONDS)
@@ -284,34 +544,49 @@ class DeviceAwarePermissionGrantTest {
TestConstants.PERMISSION_RESULT_KEY_PERMISSIONS
)
)
- .isEqualTo(arrayOf(PERMISSION))
+ .isEqualTo(arrayOf(permission))
assertThat(
grantPermissionResult.getIntArray(TestConstants.PERMISSION_RESULT_KEY_GRANT_RESULTS)
)
.isEqualTo(arrayOf(PackageManager.PERMISSION_GRANTED).toIntArray())
+
+ val expectedPermissionResultDeviceId =
+ if (requestingForDevice == DEVICE_ID_INVALID) {
+ requestingFromDevice
+ } else {
+ requestingForDevice
+ }
assertThat(grantPermissionResult.getInt(TestConstants.PERMISSION_RESULT_KEY_DEVICE_ID))
- .isEqualTo(targetDeviceId)
+ .isEqualTo(expectedPermissionResultDeviceId)
// Validate whether permission is granted as expected
- assertAppHasPermissionForDevice(DEVICE_ID_DEFAULT, expectPermissionGrantedOnDefaultDevice)
+ assertAppHasPermissionForDevice(
+ DEVICE_ID_DEFAULT,
+ permission,
+ expectPermissionGrantedOnDefaultDevice,
+ )
assertAppHasPermissionForDevice(
virtualDevice.deviceId,
- expectPermissionGrantedOnRemoteDevice,
+ permission,
+ expectPermissionGrantedOnVirtualDevice,
)
}
private fun requestPermissionOnDevice(
displayId: Int,
targetDeviceId: Int,
+ permission: String,
): CompletableFuture<Bundle> {
val future = CompletableFuture<Bundle>()
val callback = RemoteCallback { result: Bundle? -> future.complete(result) }
+ val permissions = mutableListOf(permission).toTypedArray()
val intent =
Intent()
.setComponent(
ComponentName(APP_PACKAGE_NAME, "$APP_PACKAGE_NAME.RequestPermissionActivity")
)
.putExtra(PackageManager.EXTRA_REQUEST_PERMISSIONS_DEVICE_ID, targetDeviceId)
+ .putExtra(PackageManager.EXTRA_REQUEST_PERMISSIONS_NAMES, permissions)
.putExtra(EXTRA_RESULT_RECEIVER, callback)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
@@ -327,12 +602,23 @@ class DeviceAwarePermissionGrantTest {
assertThat(text).contains(deviceName)
}
- private fun assertAppHasPermissionForDevice(deviceId: Int, expectPermissionGranted: Boolean) {
+ private fun assertPermissionMessageDoesNotContainDeviceName(displayId: Int) {
+ waitFindObject(By.displayId(displayId).res(PERMISSION_MESSAGE_ID))
+ val text = findTextForView(By.displayId(displayId).res(PERMISSION_MESSAGE_ID))
+ assertThat(text).doesNotContain(virtualDeviceName)
+ assertThat(text).doesNotContain(defaultDeviceName)
+ }
+
+ private fun assertAppHasPermissionForDevice(
+ deviceId: Int,
+ permission: String,
+ expectPermissionGranted: Boolean,
+ ) {
val checkPermissionResult =
defaultDeviceContext
.createDeviceContext(deviceId)
.packageManager
- .checkPermission(PERMISSION, APP_PACKAGE_NAME)
+ .checkPermission(permission, APP_PACKAGE_NAME)
if (expectPermissionGranted) {
Assert.assertEquals(PackageManager.PERMISSION_GRANTED, checkPermissionResult)
@@ -347,18 +633,25 @@ class DeviceAwarePermissionGrantTest {
return intent.resolveActivity(defaultDeviceContext.packageManager)
}
+ private fun grantRuntimePermissionOnVirtualDevice(permission: String) {
+ permissionManager.grantRuntimePermission(
+ APP_PACKAGE_NAME,
+ permission,
+ virtualDevice.persistentDeviceId!!,
+ )
+ }
+
companion object {
const val APK_DIRECTORY = "/data/local/tmp/cts-permissionmultidevice"
const val APP_APK_PATH_STREAMING = "${APK_DIRECTORY}/CtsAccessRemoteDeviceCamera.apk"
const val APP_PACKAGE_NAME = "android.permissionmultidevice.cts.accessremotedevicecamera"
const val PERMISSION_MESSAGE_ID = "com.android.permissioncontroller:id/permission_message"
- const val ALLOW_BUTTON =
+ const val ALLOW_BUTTON_FOREGROUND =
"com.android.permissioncontroller:id/permission_allow_foreground_only_button"
- const val DEVICE_ID_DEFAULT = 0
+ const val ALLOW_BUTTON = "com.android.permissioncontroller:id/permission_allow_button"
+ const val DEVICE_ID_DEFAULT = Context.DEVICE_ID_DEFAULT
+ const val DEVICE_ID_INVALID = Context.DEVICE_ID_INVALID
const val PERSISTENT_DEVICE_ID_DEFAULT = VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT
- const val PERMISSION = Manifest.permission.CAMERA
const val TIMEOUT = 5000L
- private const val DISPLAY_HEIGHT = 1920
- private const val DISPLAY_WIDTH = 1080
}
}
diff --git a/tests/cts/role/src/android/app/role/cts/RoleManagerTest.java b/tests/cts/role/src/android/app/role/cts/RoleManagerTest.java
index 3bc3ff12b..e15614be2 100644
--- a/tests/cts/role/src/android/app/role/cts/RoleManagerTest.java
+++ b/tests/cts/role/src/android/app/role/cts/RoleManagerTest.java
@@ -878,7 +878,6 @@ public class RoleManagerTest {
}
@Test
- @RequiresFlagsEnabled(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE)
@EnsureHasPrivateProfile(installInstrumentedApp = OptionalBoolean.TRUE)
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM,
codeName = "VanillaIceCream")