diff options
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" |