summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--PermissionController/WEAR_OWNERS1
-rw-r--r--PermissionController/res/values-uk/strings.xml2
-rw-r--r--PermissionController/res/xml/roles.xml10
-rw-r--r--PermissionController/role-controller/java/com/android/role/controller/model/Permissions.java95
-rw-r--r--PermissionController/role-controller/java/com/android/role/controller/model/Role.java25
-rw-r--r--PermissionController/role-controller/java/com/android/role/controller/model/RoleParser.java17
-rw-r--r--PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/role/model/RoleParserTest.kt30
-rw-r--r--flags/flags.aconfig9
-rw-r--r--tests/cts/permission/AndroidManifest.xml3
-rw-r--r--tests/cts/permission/src/android/permission/cts/BackgroundPermissionsTest.java36
-rw-r--r--tests/cts/permission/src/android/permission/cts/DevicePermissionsTest.kt27
-rw-r--r--tests/cts/permission/src/android/permission/cts/PermissionUpdateListenerTest.java35
-rw-r--r--tests/cts/permissionmultidevice/AndroidManifest.xml2
-rw-r--r--tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/AppPermissionsTest.kt1
-rw-r--r--tests/cts/permissionui/src/android/permissionui/cts/PermissionReviewTapjackingTest.kt2
15 files changed, 137 insertions, 158 deletions
diff --git a/PermissionController/WEAR_OWNERS b/PermissionController/WEAR_OWNERS
index da9486f1c..c8fabba56 100644
--- a/PermissionController/WEAR_OWNERS
+++ b/PermissionController/WEAR_OWNERS
@@ -1,3 +1,4 @@
adsule@google.com
sadrul@google.com
youngjoonyang@google.com
+vigneshrsastra@google.com
diff --git a/PermissionController/res/values-uk/strings.xml b/PermissionController/res/values-uk/strings.xml
index 7d713e2ff..1bc0f759b 100644
--- a/PermissionController/res/values-uk/strings.xml
+++ b/PermissionController/res/values-uk/strings.xml
@@ -362,7 +362,7 @@
<string name="role_browser_request_title" msgid="2895200507835937192">"Зробити <xliff:g id="APP_NAME">%1$s</xliff:g> веб-переглядачем за умовчанням?"</string>
<string name="role_browser_request_description" msgid="5888803407905985941">"Дозволи не потрібні"</string>
<string name="role_dialer_label" msgid="1100224146343237968">"Дзвінки за умовчанням"</string>
- <string name="role_dialer_short_label" msgid="7186888549465352489">"Додаток для викликів"</string>
+ <string name="role_dialer_short_label" msgid="7186888549465352489">"Додаток для дзвінків"</string>
<string name="role_dialer_description" msgid="8768708633696539612">"Додатки, у яких можна здійснювати й приймати виклики на пристрої"</string>
<string name="role_dialer_request_title" msgid="5959618560705912058">"Чи має <xliff:g id="APP_NAME">%1$s</xliff:g> використовуватись як додаток для викликів за умовчанням?"</string>
<string name="role_dialer_request_description" msgid="6288839625724909320">"Цьому додатку буде надано дозволи \"Камера\", \"Контакти\", \"Мікрофон\", \"Телефон\" і \"SMS\""</string>
diff --git a/PermissionController/res/xml/roles.xml b/PermissionController/res/xml/roles.xml
index ba4e80cf2..b067c41b5 100644
--- a/PermissionController/res/xml/roles.xml
+++ b/PermissionController/res/xml/roles.xml
@@ -625,7 +625,6 @@
visible="false">
<permissions>
<!-- Used for CTS testing -->
- <permission name="android.permission.CREATE_VIRTUAL_DEVICE" minSdkVersion="33" />
<permission name="android.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE" />
<permission name="android.permission.ACCESS_AMBIENT_CONTEXT_EVENT" minSdkVersion="33"/>
<permission name="android.permission.PERFORM_IMS_SINGLE_REGISTRATION" />
@@ -642,8 +641,6 @@
minSdkVersion="33" />
<permission name="android.permission.MANAGE_SAFETY_CENTER"
minSdkVersion="33" />
- <permission name="android.permission.ADD_TRUSTED_DISPLAY" minSdkVersion="33" />
- <permission name="android.permission.ADD_ALWAYS_UNLOCKED_DISPLAY" minSdkVersion="33" />
<permission name="android.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE"
minSdkVersion="33" />
<permission name="android.permission.MANAGE_DEVICE_POLICY_ACCOUNT_MANAGEMENT"
@@ -1281,7 +1278,6 @@
name="android.app.role.SYSTEM_SUPERVISION"
defaultHolders="config_systemSupervision"
exclusive="true"
- ignoreDisabledSystemPackageWhenGranting="true"
minSdkVersion="33"
static="true"
systemOnly="true"
@@ -1630,6 +1626,12 @@
<permission-set name="location" />
<permission name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<permission name="android.permission.ACTIVITY_RECOGNITION" />
+ <permission
+ name="android.permission.health.READ_HEART_RATE"
+ featureFlag="android.permission.flags.Flags.replaceBodySensorPermissionEnabled" />
+ <permission
+ name="android.permission.health.READ_HEALTH_DATA_IN_BACKGROUND"
+ featureFlag="android.permission.flags.Flags.replaceBodySensorPermissionEnabled" />
</permissions>
</role>
diff --git a/PermissionController/role-controller/java/com/android/role/controller/model/Permissions.java b/PermissionController/role-controller/java/com/android/role/controller/model/Permissions.java
index 6de52ca42..ed21db7bb 100644
--- a/PermissionController/role-controller/java/com/android/role/controller/model/Permissions.java
+++ b/PermissionController/role-controller/java/com/android/role/controller/model/Permissions.java
@@ -51,11 +51,13 @@ public class Permissions {
private static final boolean DEBUG = false;
+ private static final Object sPermissionInfoLock = new Object();
+ private static final ArrayMap<String, Boolean> sIsRuntimePermission = new ArrayMap<>();
+ private static final ArrayMap<String, Boolean> sIsRestrictedPermission = new ArrayMap<>();
+
+ private static final Object sForegroundBackgroundPermissionMappingsLock = new Object();
private static ArrayMap<String, String> sForegroundToBackgroundPermission;
private static ArrayMap<String, List<String>> sBackgroundToForegroundPermissions;
- private static final Object sForegroundBackgroundPermissionMappingsLock = new Object();
-
- private static final ArrayMap<String, Boolean> sRestrictedPermissions = new ArrayMap<>();
/**
* Filter a list of permissions based on their SDK versions.
@@ -88,7 +90,7 @@ public class Permissions {
* @param permissions the list of permissions to be granted
* @param ignoreDisabledSystemPackage whether to ignore the requested permissions of a disabled
* system package (if this package is an updated system
- * package)
+ * package) when granting runtime permissions
* @param overrideUserSetAndFixed whether to override user set and fixed flags on the permission
* @param setGrantedByRole whether the permissions will be granted as granted-by-role
* @param setGrantedByDefault whether the permissions will be granted as granted-by-default
@@ -150,11 +152,13 @@ public class Permissions {
PackageInfo disabledSystemPackageInfo = getFactoryPackageInfoAsUser(packageName, user,
context);
if (disabledSystemPackageInfo != null) {
- if (ArrayUtils.isEmpty(disabledSystemPackageInfo.requestedPermissions)) {
- return false;
+ for (int i = permissionsToGrant.size() - 1; i >= 0; i--) {
+ String permission = permissionsToGrant.valueAt(i);
+ if (isRuntimePermission(permission, context) && !ArrayUtils.contains(
+ disabledSystemPackageInfo.requestedPermissions, permission)) {
+ permissionsToGrant.removeAt(i);
+ }
}
- CollectionUtils.retainAll(permissionsToGrant,
- disabledSystemPackageInfo.requestedPermissions);
if (permissionsToGrant.isEmpty()) {
return false;
}
@@ -702,6 +706,50 @@ public class Permissions {
return true;
}
+ private static boolean isRuntimePermission(@NonNull String permission,
+ @NonNull Context context) {
+ synchronized (sPermissionInfoLock) {
+ Boolean isRuntimePermission = sIsRuntimePermission.get(permission);
+ if (isRuntimePermission != null) {
+ return isRuntimePermission;
+ }
+ fetchPermissionInfoLocked(permission, context);
+ return sIsRuntimePermission.get(permission);
+ }
+ }
+
+ private static boolean isRestrictedPermission(@NonNull String permission,
+ @NonNull Context context) {
+ synchronized (sPermissionInfoLock) {
+ Boolean isRestrictedPermission = sIsRestrictedPermission.get(permission);
+ if (isRestrictedPermission != null) {
+ return isRestrictedPermission;
+ }
+ fetchPermissionInfoLocked(permission, context);
+ return sIsRestrictedPermission.get(permission);
+ }
+ }
+
+ private static void fetchPermissionInfoLocked(@NonNull String permission,
+ @NonNull Context context) {
+ PackageManager packageManager = context.getPackageManager();
+ PermissionInfo permissionInfo = null;
+ try {
+ permissionInfo = packageManager.getPermissionInfo(permission, 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(LOG_TAG, "Cannot get PermissionInfo for permission: " + permission);
+ }
+
+ // Don't expect that to be a transient error, so we can still cache the failed information.
+ boolean isRuntimePermission = permissionInfo != null
+ && permissionInfo.getProtection() == PermissionInfo.PROTECTION_DANGEROUS;
+ boolean isRestrictedPermission = permissionInfo != null
+ && (permissionInfo.flags & (PermissionInfo.FLAG_SOFT_RESTRICTED
+ | PermissionInfo.FLAG_HARD_RESTRICTED)) != 0;
+ sIsRuntimePermission.put(permission, isRuntimePermission);
+ sIsRestrictedPermission.put(permission, isRestrictedPermission);
+ }
+
private static boolean isForegroundPermission(@NonNull String permission,
@NonNull Context context) {
ensureForegroundBackgroundPermissionMappings(context);
@@ -732,40 +780,13 @@ public class Permissions {
synchronized (sForegroundBackgroundPermissionMappingsLock) {
if (sForegroundToBackgroundPermission == null
&& sBackgroundToForegroundPermissions == null) {
- createForegroundBackgroundPermissionMappings(context);
+ createForegroundBackgroundPermissionMappingsLocked(context);
}
}
}
- private static boolean isRestrictedPermission(@NonNull String permission,
+ private static void createForegroundBackgroundPermissionMappingsLocked(
@NonNull Context context) {
- synchronized (sRestrictedPermissions) {
- if (sRestrictedPermissions.containsKey(permission)) {
- return sRestrictedPermissions.get(permission);
- }
- }
-
- PackageManager packageManager = context.getPackageManager();
- PermissionInfo permissionInfo = null;
- try {
- permissionInfo = packageManager.getPermissionInfo(permission, 0);
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(LOG_TAG, "Cannot get PermissionInfo for permission: " + permission);
- }
-
- // Don't expect that to be a transient error, so we can still cache the failed information.
- boolean isRestrictedPermission = permissionInfo != null
- && (permissionInfo.flags & (PermissionInfo.FLAG_SOFT_RESTRICTED
- | PermissionInfo.FLAG_HARD_RESTRICTED)) != 0;
-
- synchronized (sRestrictedPermissions) {
- sRestrictedPermissions.put(permission, isRestrictedPermission);
- }
-
- return isRestrictedPermission;
- }
-
- private static void createForegroundBackgroundPermissionMappings(@NonNull Context context) {
List<String> permissions = new ArrayList<>();
sBackgroundToForegroundPermissions = new ArrayMap<>();
diff --git a/PermissionController/role-controller/java/com/android/role/controller/model/Role.java b/PermissionController/role-controller/java/com/android/role/controller/model/Role.java
index 942535b0f..2f2431ece 100644
--- a/PermissionController/role-controller/java/com/android/role/controller/model/Role.java
+++ b/PermissionController/role-controller/java/com/android/role/controller/model/Role.java
@@ -126,12 +126,6 @@ public class Role {
private final Supplier<Boolean> mFeatureFlag;
/**
- * Whether this role should ignore the requested permissions of a disabled system package when
- * granting.
- */
- private final boolean mIgnoreDisabledSystemPackageWhenGranting;
-
- /**
* The string resource for the label of this role.
*/
@StringRes
@@ -248,8 +242,7 @@ public class Role {
public Role(@NonNull String name, boolean allowBypassingQualification,
@Nullable RoleBehavior behavior, @Nullable String defaultHoldersResourceName,
@StringRes int descriptionResource, boolean exclusive, boolean fallBackToDefaultHolder,
- @Nullable Supplier<Boolean> featureFlag,
- boolean ignoreDisabledSystemPackageWhenGranting, @StringRes int labelResource,
+ @Nullable Supplier<Boolean> featureFlag, @StringRes int labelResource,
int maxSdkVersion, int minSdkVersion, boolean onlyGrantWhenAdded,
boolean overrideUserWhenGranting, @StringRes int requestDescriptionResource,
@StringRes int requestTitleResource, boolean requestable,
@@ -267,7 +260,6 @@ public class Role {
mExclusive = exclusive;
mFallBackToDefaultHolder = fallBackToDefaultHolder;
mFeatureFlag = featureFlag;
- mIgnoreDisabledSystemPackageWhenGranting = ignoreDisabledSystemPackageWhenGranting;
mLabelResource = labelResource;
mMaxSdkVersion = maxSdkVersion;
mMinSdkVersion = minSdkVersion;
@@ -314,13 +306,6 @@ public class Role {
return mFeatureFlag;
}
- /**
- * @see #mIgnoreDisabledSystemPackageWhenGranting
- */
- public boolean shouldIgnoreDisabledSystemPackageWhenGranting() {
- return mIgnoreDisabledSystemPackageWhenGranting;
- }
-
@StringRes
public int getLabelResource() {
return mLabelResource;
@@ -371,10 +356,6 @@ public class Role {
return mShowNone;
}
- public boolean isSystemOnly() {
- return mSystemOnly;
- }
-
public boolean isVisible() {
return mVisible;
}
@@ -840,7 +821,7 @@ public class Role {
boolean overrideUser, @NonNull UserHandle user, @NonNull Context context) {
boolean permissionOrAppOpChanged = Permissions.grantAsUser(packageName,
Permissions.filterBySdkVersionAsUser(mPermissions, user, context),
- mIgnoreDisabledSystemPackageWhenGranting, overrideUser, true, false, false,
+ SdkLevel.isAtLeastS() ? !mSystemOnly : true, overrideUser, true, false, false,
user, context);
List<String> appOpPermissionsToGrant =
@@ -1126,8 +1107,6 @@ public class Role {
+ ", mExclusive=" + mExclusive
+ ", mFallBackToDefaultHolder=" + mFallBackToDefaultHolder
+ ", mFeatureFlag=" + mFeatureFlag
- + ", mIgnoreDisabledSystemPackageWhenGranting="
- + mIgnoreDisabledSystemPackageWhenGranting
+ ", mLabelResource=" + mLabelResource
+ ", mMaxSdkVersion=" + mMaxSdkVersion
+ ", mMinSdkVersion=" + mMinSdkVersion
diff --git a/PermissionController/role-controller/java/com/android/role/controller/model/RoleParser.java b/PermissionController/role-controller/java/com/android/role/controller/model/RoleParser.java
index d4e5fa2d6..6d5cf69bd 100644
--- a/PermissionController/role-controller/java/com/android/role/controller/model/RoleParser.java
+++ b/PermissionController/role-controller/java/com/android/role/controller/model/RoleParser.java
@@ -19,12 +19,9 @@ package com.android.role.controller.model;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.PermissionInfo;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.os.Build;
-import android.os.Process;
import android.permission.flags.Flags;
import android.util.ArrayMap;
import android.util.Log;
@@ -94,8 +91,6 @@ public class RoleParser {
private static final String ATTRIBUTE_EXCLUSIVE = "exclusive";
private static final String ATTRIBUTE_FALL_BACK_TO_DEFAULT_HOLDER = "fallBackToDefaultHolder";
private static final String ATTRIBUTE_FEATURE_FLAG = "featureFlag";
- private static final String ATTRIBUTE_IGNORE_DISABLED_SYSTEM_PACKAGE_WHEN_GRANTING =
- "ignoreDisabledSystemPackageWhenGranting";
private static final String ATTRIBUTE_LABEL = "label";
private static final String ATTRIBUTE_MAX_SDK_VERSION = "maxSdkVersion";
private static final String ATTRIBUTE_MIN_SDK_VERSION = "minSdkVersion";
@@ -431,11 +426,6 @@ public class RoleParser {
Supplier<Boolean> featureFlag = getAttributeMethodValue(parser, ATTRIBUTE_FEATURE_FLAG,
boolean.class, sFeatureFlagFallback, TAG_ROLE);
- boolean systemOnly = getAttributeBooleanValue(parser, ATTRIBUTE_SYSTEM_ONLY, false);
- boolean ignoreDisabledSystemPackageWhenGranting = getAttributeBooleanValue(parser,
- ATTRIBUTE_IGNORE_DISABLED_SYSTEM_PACKAGE_WHEN_GRANTING,
- SdkLevel.isAtLeastS() ? !systemOnly : true);
-
int maxSdkVersion = getAttributeIntValue(parser, ATTRIBUTE_MAX_SDK_VERSION,
Build.VERSION_CODES.CUR_DEVELOPMENT);
int minSdkVersion = getAttributeIntValue(parser, ATTRIBUTE_MIN_SDK_VERSION,
@@ -494,6 +484,8 @@ public class RoleParser {
return null;
}
+ boolean systemOnly = getAttributeBooleanValue(parser, ATTRIBUTE_SYSTEM_ONLY, false);
+
String uiBehaviorName = getAttributeValue(parser, ATTRIBUTE_UI_BEHAVIOR);
List<RequiredComponent> requiredComponents = null;
@@ -575,9 +567,8 @@ public class RoleParser {
preferredActivities = Collections.emptyList();
}
return new Role(name, allowBypassingQualification, behavior, defaultHoldersResourceName,
- descriptionResource, exclusive, fallBackToDefaultHolder, featureFlag,
- ignoreDisabledSystemPackageWhenGranting, labelResource, maxSdkVersion,
- minSdkVersion, onlyGrantWhenAdded, overrideUserWhenGranting,
+ descriptionResource, exclusive, fallBackToDefaultHolder, featureFlag, labelResource,
+ maxSdkVersion, minSdkVersion, onlyGrantWhenAdded, overrideUserWhenGranting,
requestDescriptionResource, requestTitleResource, requestable,
searchKeywordsResource, shortLabelResource, showNone, statik, systemOnly, visible,
requiredComponents, permissions, appOpPermissions, appOps, preferredActivities,
diff --git a/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/role/model/RoleParserTest.kt b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/role/model/RoleParserTest.kt
index f1accb6e5..da1430c0a 100644
--- a/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/role/model/RoleParserTest.kt
+++ b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/role/model/RoleParserTest.kt
@@ -22,7 +22,6 @@ import android.content.pm.PermissionInfo
import android.os.Process
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.modules.utils.build.SdkLevel
import com.android.permissioncontroller.role.model.RoleParserInitializer
import com.android.role.controller.model.AppOp
import com.android.role.controller.model.Permission
@@ -75,7 +74,7 @@ class RoleParserTest {
fun validateRoles(permissionSets: Map<String, PermissionSet>, roles: Map<String, Role>) {
for (permissionSet in permissionSets.values) {
for (permission in permissionSet.permissions) {
- validatePermission(permission, false)
+ validatePermission(permission)
}
}
@@ -92,14 +91,7 @@ class RoleParserTest {
}
for (permission in role.permissions) {
- // Prevent system-only roles that ignore disabled system packages from
- // granting runtime permissions for now, since that may allow apps to update and
- // silently obtain a new runtime permission.
- val enforceNotRuntime =
- SdkLevel.isAtLeastS() &&
- role.isSystemOnly &&
- role.shouldIgnoreDisabledSystemPackageWhenGranting()
- validatePermission(permission, enforceNotRuntime)
+ validatePermission(permission)
}
for (appOp in role.appOps) {
@@ -119,22 +111,18 @@ class RoleParserTest {
}
}
- private fun validatePermission(permission: Permission, enforceNotRuntime: Boolean) {
+ private fun validatePermission(permission: Permission) {
if (!permission.isAvailableAsUser(Process.myUserHandle(), targetContext)) {
return
}
- validatePermission(permission.name, true, enforceNotRuntime)
+ validatePermission(permission.name, true)
}
private fun validatePermission(permissionName: String) {
- validatePermission(permissionName, false, false)
+ validatePermission(permissionName, false)
}
- private fun validatePermission(
- permissionName: String,
- enforceIsRuntimeOrRole: Boolean,
- enforceNotRuntime: Boolean,
- ) {
+ private fun validatePermission(permissionName: String, enforceIsRuntimeOrRole: Boolean) {
val isAutomotive = packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
// Skip validation for car permissions which may not be available on all build targets.
if (!isAutomotive && permissionName.startsWith("android.car")) {
@@ -157,12 +145,6 @@ class RoleParserTest {
"Permission is not a runtime or role permission: $permissionName"
}
}
-
- if (enforceNotRuntime) {
- require(permissionInfo.protection != PermissionInfo.PROTECTION_DANGEROUS) {
- "Permission is a runtime permission: $permissionName"
- }
- }
}
private fun validateAppOpPermission(appOpPermission: Permission) {
diff --git a/flags/flags.aconfig b/flags/flags.aconfig
index 5544300e8..5f3e84121 100644
--- a/flags/flags.aconfig
+++ b/flags/flags.aconfig
@@ -110,6 +110,15 @@ flag {
}
flag {
+ name: "cross_user_role_enabled"
+ is_exported: true
+ namespace: "permissions"
+ description: "This flag enables cross-user roles support and API"
+ bug: "367732307"
+ is_fixed_read_only: true
+}
+
+flag {
name: "permission_timeline_attribution_label_fix"
is_exported: true
namespace: "permissions"
diff --git a/tests/cts/permission/AndroidManifest.xml b/tests/cts/permission/AndroidManifest.xml
index 43fd97bb2..bb027b5f2 100644
--- a/tests/cts/permission/AndroidManifest.xml
+++ b/tests/cts/permission/AndroidManifest.xml
@@ -51,6 +51,9 @@
android:label="@string/perm_group_c"
android:name="android.permission.cts.groupC"/>
+ <!-- for android.permission.cts.DevicePermissionsTest -->
+ <uses-permission android:name="android.permission.CREATE_VIRTUAL_DEVICE"/>
+
<uses-permission android:name="android.permission.INJECT_EVENTS"/>
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
<application>
diff --git a/tests/cts/permission/src/android/permission/cts/BackgroundPermissionsTest.java b/tests/cts/permission/src/android/permission/cts/BackgroundPermissionsTest.java
index f3f47631c..fcdccd87a 100644
--- a/tests/cts/permission/src/android/permission/cts/BackgroundPermissionsTest.java
+++ b/tests/cts/permission/src/android/permission/cts/BackgroundPermissionsTest.java
@@ -24,6 +24,7 @@ import static android.app.AppOpsManager.MODE_FOREGROUND;
import static android.app.AppOpsManager.MODE_IGNORED;
import static android.content.pm.PermissionInfo.PROTECTION_DANGEROUS;
import static android.content.pm.PermissionInfo.PROTECTION_INTERNAL;
+import static android.health.connect.HealthPermissions.HEALTH_PERMISSION_GROUP;
import static android.permission.cts.PermissionUtils.getAppOp;
import static android.permission.cts.PermissionUtils.grantPermission;
import static android.permission.cts.PermissionUtils.install;
@@ -31,6 +32,7 @@ import static android.permission.cts.PermissionUtils.uninstallApp;
import static com.android.compatibility.common.util.SystemUtil.eventually;
+import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertNotEquals;
@@ -43,14 +45,21 @@ import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
+import android.os.Build;
+import android.permission.flags.Flags;
import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.util.ArrayMap;
import android.util.Log;
+import androidx.test.filters.SdkSuppress;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import org.junit.After;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -72,6 +81,9 @@ public class BackgroundPermissionsTest {
private static final UiAutomation sUiAutomation =
InstrumentationRegistry.getInstrumentation().getUiAutomation();
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+
@After
public void uninstallTestApp() {
uninstallApp(APP_PKG);
@@ -79,9 +91,25 @@ public class BackgroundPermissionsTest {
@Test
@AppModeFull(reason = "Instant apps cannot read properties of other packages")
- public void verifybackgroundPermissionsProperties() throws Exception {
+ public void verifyBackgroundPropertiesForPlatformPermissions() throws Exception {
+ verifyBackgroundPermissionsProperties("android");
+ }
+
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM,
+ codeName = "VanillaIceCream")
+ @RequiresFlagsEnabled({Flags.FLAG_REPLACE_BODY_SENSOR_PERMISSION_ENABLED})
+ @Test
+ @AppModeFull(reason = "Instant apps cannot read properties of other packages")
+ public void verifyBackgroundPropertiesForHealthPermissions() throws Exception {
+ String healthPackageName = sContext.getPackageManager().getPermissionGroupInfo(
+ HEALTH_PERMISSION_GROUP, /* flags= */ 0).packageName;
+ verifyBackgroundPermissionsProperties(healthPackageName);
+ }
+
+ private void verifyBackgroundPermissionsProperties(String packageName)
+ throws Exception {
PackageInfo pkg = sContext.getPackageManager().getPackageInfo(
- "android", PackageManager.GET_PERMISSIONS);
+ packageName, PackageManager.GET_PERMISSIONS);
ArrayMap<String, String> potentialBackgroundPermissionsToGroup = new ArrayMap<>();
int numPermissions = pkg.permissions.length;
@@ -97,11 +125,13 @@ public class BackgroundPermissionsTest {
}
}
+ int backgroundPermissionCount = 0;
for (int i = 0; i < numPermissions; i++) {
PermissionInfo permission = pkg.permissions[i];
String backgroundPermissionName = permission.backgroundPermission;
if (backgroundPermissionName != null) {
+ backgroundPermissionCount += 1;
Log.i(LOG_TAG, permission.name + "->" + backgroundPermissionName);
// foreground permissions must be dangerous
@@ -115,6 +145,8 @@ public class BackgroundPermissionsTest {
.containsKey(backgroundPermissionName));
}
}
+ // Tested packages must have at least one permission linked with a background permission.
+ assertThat(backgroundPermissionCount).isGreaterThan(0);
}
/**
diff --git a/tests/cts/permission/src/android/permission/cts/DevicePermissionsTest.kt b/tests/cts/permission/src/android/permission/cts/DevicePermissionsTest.kt
index dbda1f5e1..ff333c6a0 100644
--- a/tests/cts/permission/src/android/permission/cts/DevicePermissionsTest.kt
+++ b/tests/cts/permission/src/android/permission/cts/DevicePermissionsTest.kt
@@ -20,10 +20,8 @@ import android.Manifest
import android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
import android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE
import android.app.Instrumentation
-import android.companion.virtual.VirtualDeviceManager
import android.companion.virtual.VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT
import android.companion.virtual.VirtualDeviceManager.VirtualDevice
-import android.companion.virtual.VirtualDeviceParams
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager.FLAG_PERMISSION_ONE_TIME
@@ -40,17 +38,15 @@ import android.platform.test.annotations.AppModeFull
import android.platform.test.annotations.RequiresFlagsDisabled
import android.platform.test.annotations.RequiresFlagsEnabled
import android.platform.test.flag.junit.DeviceFlagsValueProvider
-import android.virtualdevice.cts.common.FakeAssociationRule
+import android.virtualdevice.cts.common.VirtualDeviceRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.compatibility.common.util.AdoptShellPermissionsRule
import com.android.compatibility.common.util.SystemUtil.eventually
import com.android.compatibility.common.util.SystemUtil.runShellCommandOrThrow
import com.android.compatibility.common.util.SystemUtil.waitForBroadcasts
import com.google.common.truth.Truth.assertThat
import org.junit.After
-import org.junit.Assume.assumeNotNull
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -69,13 +65,8 @@ class DevicePermissionsTest {
private lateinit var permissionManager: PermissionManager
- @get:Rule var mFakeAssociationRule = FakeAssociationRule()
-
@get:Rule
- val mAdoptShellPermissionsRule =
- AdoptShellPermissionsRule(
- instrumentation.uiAutomation,
- Manifest.permission.CREATE_VIRTUAL_DEVICE,
+ var mVirtualDeviceRule = VirtualDeviceRule.withAdditionalPermissions(
Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS,
Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
@@ -86,14 +77,7 @@ class DevicePermissionsTest {
@Before
fun setup() {
- val virtualDeviceManager =
- defaultDeviceContext.getSystemService(VirtualDeviceManager::class.java)
- assumeNotNull(virtualDeviceManager)
- virtualDevice =
- virtualDeviceManager!!.createVirtualDevice(
- mFakeAssociationRule.getAssociationInfo().getId(),
- VirtualDeviceParams.Builder().build()
- )
+ virtualDevice = mVirtualDeviceRule.createManagedVirtualDevice()
virtualDeviceContext = defaultDeviceContext.createDeviceContext(virtualDevice.deviceId)
permissionManager = virtualDeviceContext.getSystemService(PermissionManager::class.java)!!
persistentDeviceId = virtualDevice.persistentDeviceId!!
@@ -103,9 +87,6 @@ class DevicePermissionsTest {
@After
fun cleanup() {
runShellCommandOrThrow("pm uninstall $TEST_PACKAGE_NAME")
- if (this::virtualDevice.isInitialized) {
- virtualDevice.close()
- }
}
@RequiresFlagsEnabled(
@@ -226,7 +207,7 @@ class DevicePermissionsTest {
permissionManager.checkPermission(
deviceAwarePermission,
TEST_PACKAGE_NAME,
- VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT
+ PERSISTENT_DEVICE_ID_DEFAULT
)
)
.isEqualTo(PERMISSION_DENIED)
diff --git a/tests/cts/permission/src/android/permission/cts/PermissionUpdateListenerTest.java b/tests/cts/permission/src/android/permission/cts/PermissionUpdateListenerTest.java
index e9e71af20..4325ace79 100644
--- a/tests/cts/permission/src/android/permission/cts/PermissionUpdateListenerTest.java
+++ b/tests/cts/permission/src/android/permission/cts/PermissionUpdateListenerTest.java
@@ -22,10 +22,8 @@ import static com.android.compatibility.common.util.SystemUtil.runWithShellPermi
import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assume.assumeNotNull;
-
import android.companion.virtual.VirtualDeviceManager;
-import android.companion.virtual.VirtualDeviceParams;
+import android.companion.virtual.VirtualDeviceManager.VirtualDevice;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.OnPermissionsChangedListener;
@@ -34,12 +32,11 @@ import android.platform.test.annotations.AppModeFull;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
-import android.virtualdevice.cts.common.FakeAssociationRule;
+import android.virtualdevice.cts.common.VirtualDeviceRule;
import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner;
import androidx.test.platform.app.InstrumentationRegistry;
-import com.android.compatibility.common.util.AdoptShellPermissionsRule;
import com.android.compatibility.common.util.SystemUtil;
import org.junit.After;
@@ -71,15 +68,8 @@ public class PermissionUpdateListenerTest {
private int mTestAppUid;
- private VirtualDeviceManager mVirtualDeviceManager;
-
- @Rule
- public FakeAssociationRule mFakeAssociationRule = new FakeAssociationRule();
-
@Rule
- public AdoptShellPermissionsRule mAdoptShellPermissionsRule = new AdoptShellPermissionsRule(
- InstrumentationRegistry.getInstrumentation().getUiAutomation(),
- android.Manifest.permission.CREATE_VIRTUAL_DEVICE);
+ public VirtualDeviceRule mVirtualDeviceRule = VirtualDeviceRule.createDefault();
@Rule
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
@@ -92,7 +82,6 @@ public class PermissionUpdateListenerTest {
SystemUtil.waitForBroadcasts();
Thread.sleep(1000);
mTestAppUid = mPackageManager.getPackageUid(PACKAGE_NAME, 0);
- mVirtualDeviceManager = mDefaultContext.getSystemService(VirtualDeviceManager.class);
}
@After
@@ -127,11 +116,7 @@ public class PermissionUpdateListenerTest {
@RequiresFlagsEnabled({Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED,
Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED})
public void testVirtualDeviceGrantPermissionNotifyListener() throws InterruptedException {
- assumeNotNull(mVirtualDeviceManager);
- VirtualDeviceManager.VirtualDevice virtualDevice =
- mVirtualDeviceManager.createVirtualDevice(
- mFakeAssociationRule.getAssociationInfo().getId(),
- new VirtualDeviceParams.Builder().build());
+ VirtualDevice virtualDevice = mVirtualDeviceRule.createManagedVirtualDevice();
Context deviceContext = mDefaultContext.createDeviceContext(virtualDevice.getDeviceId());
testGrantPermissionNotifyListener(deviceContext, virtualDevice.getPersistentDeviceId());
}
@@ -172,11 +157,7 @@ public class PermissionUpdateListenerTest {
@RequiresFlagsEnabled({Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED,
Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED})
public void testVirtualDeviceRevokePermissionNotifyListener() throws InterruptedException {
- assumeNotNull(mVirtualDeviceManager);
- VirtualDeviceManager.VirtualDevice virtualDevice =
- mVirtualDeviceManager.createVirtualDevice(
- mFakeAssociationRule.getAssociationInfo().getId(),
- new VirtualDeviceParams.Builder().build());
+ VirtualDevice virtualDevice = mVirtualDeviceRule.createManagedVirtualDevice();
Context deviceContext = mDefaultContext.createDeviceContext(virtualDevice.getDeviceId());
testRevokePermissionNotifyListener(
deviceContext, virtualDevice.getPersistentDeviceId());
@@ -213,11 +194,7 @@ public class PermissionUpdateListenerTest {
@RequiresFlagsEnabled({Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED,
Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED})
public void testVirtualDeviceUpdatePermissionFlagsNotifyListener() throws InterruptedException {
- assumeNotNull(mVirtualDeviceManager);
- VirtualDeviceManager.VirtualDevice virtualDevice =
- mVirtualDeviceManager.createVirtualDevice(
- mFakeAssociationRule.getAssociationInfo().getId(),
- new VirtualDeviceParams.Builder().build());
+ VirtualDevice virtualDevice = mVirtualDeviceRule.createManagedVirtualDevice();
Context deviceContext = mDefaultContext.createDeviceContext(virtualDevice.getDeviceId());
testUpdatePermissionFlagsNotifyListener(
deviceContext, virtualDevice.getPersistentDeviceId());
diff --git a/tests/cts/permissionmultidevice/AndroidManifest.xml b/tests/cts/permissionmultidevice/AndroidManifest.xml
index 9bad85813..7d04d140e 100644
--- a/tests/cts/permissionmultidevice/AndroidManifest.xml
+++ b/tests/cts/permissionmultidevice/AndroidManifest.xml
@@ -24,6 +24,8 @@
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
+ <uses-permission android:name="android.permission.CREATE_VIRTUAL_DEVICE" />
+ <uses-permission android:name="android.permission.ADD_TRUSTED_DISPLAY" />
<application>
<uses-library android:name="android.test.runner" />
diff --git a/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/AppPermissionsTest.kt b/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/AppPermissionsTest.kt
index 4d166939a..ac5564e37 100644
--- a/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/AppPermissionsTest.kt
+++ b/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/AppPermissionsTest.kt
@@ -62,7 +62,6 @@ class AppPermissionsTest {
Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS,
Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
- Manifest.permission.CREATE_VIRTUAL_DEVICE
)
private lateinit var persistentDeviceId: String
diff --git a/tests/cts/permissionui/src/android/permissionui/cts/PermissionReviewTapjackingTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/PermissionReviewTapjackingTest.kt
index 14901eb2a..95050ab3e 100644
--- a/tests/cts/permissionui/src/android/permissionui/cts/PermissionReviewTapjackingTest.kt
+++ b/tests/cts/permissionui/src/android/permissionui/cts/PermissionReviewTapjackingTest.kt
@@ -44,7 +44,7 @@ class PermissionReviewTapjackingTest : BaseUsePermissionTest() {
installPackage(APP_APK_PATH_22)
installPackage(HELPER_APP_OVERLAY)
- Thread.sleep(1000)
+ SystemUtil.waitForBroadcasts()
SystemUtil.runShellCommandOrThrow(
"appops set $HELPER_PACKAGE_NAME android:system_alert_window allow"