diff options
| -rw-r--r-- | api/current.txt | 8 | ||||
| -rwxr-xr-x | api/system-current.txt | 2 | ||||
| -rw-r--r-- | core/java/android/content/pm/parsing/ParsingPackage.java | 6 | ||||
| -rw-r--r-- | core/java/android/content/pm/parsing/ParsingPackageImpl.java | 28 | ||||
| -rw-r--r-- | core/java/android/content/pm/parsing/ParsingPackageRead.java | 6 | ||||
| -rw-r--r-- | core/java/android/content/pm/parsing/ParsingPackageUtils.java | 2 | ||||
| -rw-r--r-- | core/java/android/permission/IPermissionManager.aidl | 4 | ||||
| -rw-r--r-- | core/java/android/permission/PermissionManager.java | 42 | ||||
| -rw-r--r-- | core/java/com/android/internal/util/CollectionUtils.java | 23 | ||||
| -rw-r--r-- | core/res/res/values/attrs_manifest.xml | 13 | ||||
| -rw-r--r-- | core/res/res/values/public.xml | 2 | ||||
| -rw-r--r-- | services/core/java/com/android/server/pm/permission/PermissionManagerService.java | 30 |
12 files changed, 155 insertions, 11 deletions
diff --git a/api/current.txt b/api/current.txt index 1b7f6e56667d..8657d13b6b3f 100644 --- a/api/current.txt +++ b/api/current.txt @@ -290,6 +290,7 @@ package android { field public static final int allowAudioPlaybackCapture = 16844289; // 0x1010601 field public static final int allowBackup = 16843392; // 0x1010280 field public static final int allowClearUserData = 16842757; // 0x1010005 + field public static final int allowDontAutoRevokePermissions = 16844309; // 0x1010615 field public static final int allowEmbedded = 16843765; // 0x10103f5 field public static final int allowNativeHeapPointerTagging = 16844307; // 0x1010613 field public static final int allowParallelSyncs = 16843570; // 0x1010332 @@ -572,7 +573,7 @@ package android { field public static final int elevation = 16843840; // 0x1010440 field public static final int ellipsize = 16842923; // 0x10100ab field public static final int ems = 16843096; // 0x1010158 - field public static final int enableGwpAsan = 16844310; // 0x1010616 + field public static final int enableGwpAsan = 16844312; // 0x1010618 field public static final int enableVrMode = 16844069; // 0x1010525 field public static final int enabled = 16842766; // 0x101000e field public static final int end = 16843996; // 0x10104dc @@ -954,7 +955,7 @@ package android { field public static final int mediaRouteButtonStyle = 16843693; // 0x10103ad field public static final int mediaRouteTypes = 16843694; // 0x10103ae field public static final int menuCategory = 16843230; // 0x10101de - field public static final int mimeGroup = 16844309; // 0x1010615 + field public static final int mimeGroup = 16844311; // 0x1010617 field public static final int mimeType = 16842790; // 0x1010026 field public static final int min = 16844089; // 0x1010539 field public static final int minAspectRatio = 16844187; // 0x101059b @@ -1083,7 +1084,7 @@ package android { field public static final int preferenceScreenStyle = 16842891; // 0x101008b field public static final int preferenceStyle = 16842894; // 0x101008e field public static final int presentationTheme = 16843712; // 0x10103c0 - field public static final int preserveLegacyExternalStorage = 16844308; // 0x1010614 + field public static final int preserveLegacyExternalStorage = 16844310; // 0x1010616 field public static final int previewImage = 16843482; // 0x10102da field public static final int primaryContentAlpha = 16844114; // 0x1010552 field public static final int priority = 16842780; // 0x101001c @@ -1140,6 +1141,7 @@ package android { field public static final int reqKeyboardType = 16843304; // 0x1010228 field public static final int reqNavigation = 16843306; // 0x101022a field public static final int reqTouchScreen = 16843303; // 0x1010227 + field public static final int requestDontAutoRevokePermissions = 16844308; // 0x1010614 field public static final int requestLegacyExternalStorage = 16844291; // 0x1010603 field public static final int requireDeviceUnlock = 16843756; // 0x10103ec field public static final int required = 16843406; // 0x101028e diff --git a/api/system-current.txt b/api/system-current.txt index c102e661d400..4222b781118d 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -8948,6 +8948,8 @@ package android.permission { } public final class PermissionManager { + method @NonNull @RequiresPermission(android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY) public java.util.Set<java.lang.String> getAutoRevokeExemptionGrantedPackages(); + method @NonNull @RequiresPermission(android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY) public java.util.Set<java.lang.String> getAutoRevokeExemptionRequestedPackages(); method @IntRange(from=0) @RequiresPermission(anyOf={android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY, android.Manifest.permission.UPGRADE_RUNTIME_PERMISSIONS}) public int getRuntimePermissionsVersion(); method @NonNull public java.util.List<android.permission.PermissionManager.SplitPermissionInfo> getSplitPermissions(); method @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS_TO_TELEPHONY_DEFAULTS) public void grantDefaultPermissionsToEnabledCarrierApps(@NonNull String[], @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); diff --git a/core/java/android/content/pm/parsing/ParsingPackage.java b/core/java/android/content/pm/parsing/ParsingPackage.java index a479b2e5b4d1..e59462423097 100644 --- a/core/java/android/content/pm/parsing/ParsingPackage.java +++ b/core/java/android/content/pm/parsing/ParsingPackage.java @@ -191,7 +191,11 @@ public interface ParsingPackage extends ParsingPackageRead { ParsingPackage setRequestLegacyExternalStorage(boolean requestLegacyExternalStorage); ParsingPackage setAllowNativeHeapPointerTagging(boolean allowNativeHeapPointerTagging); - + + ParsingPackage setDontAutoRevokePermissions(boolean dontAutoRevokePermissions); + + ParsingPackage setAllowDontAutoRevokePermissions(boolean allowDontAutoRevokePermissions); + ParsingPackage setPreserveLegacyExternalStorage(boolean preserveLegacyExternalStorage); ParsingPackage setRestoreAnyVersion(boolean restoreAnyVersion); diff --git a/core/java/android/content/pm/parsing/ParsingPackageImpl.java b/core/java/android/content/pm/parsing/ParsingPackageImpl.java index f6a415e5dc55..351763775091 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageImpl.java +++ b/core/java/android/content/pm/parsing/ParsingPackageImpl.java @@ -405,6 +405,8 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { private boolean hasFragileUserData; private boolean cantSaveState; private boolean allowNativeHeapPointerTagging; + private boolean dontAutoRevokePermissions; + private boolean allowDontAutoRevokePermissions; private boolean preserveLegacyExternalStorage; @Nullable @@ -1089,6 +1091,8 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { dest.writeBoolean(this.hasFragileUserData); dest.writeBoolean(this.cantSaveState); dest.writeBoolean(this.allowNativeHeapPointerTagging); + dest.writeBoolean(this.dontAutoRevokePermissions); + dest.writeBoolean(this.allowDontAutoRevokePermissions); dest.writeBoolean(this.preserveLegacyExternalStorage); dest.writeArraySet(this.mimeGroups); sForBoolean.parcel(this.enableGwpAsan, dest, flags); @@ -1247,6 +1251,8 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { this.hasFragileUserData = in.readBoolean(); this.cantSaveState = in.readBoolean(); this.allowNativeHeapPointerTagging = in.readBoolean(); + this.dontAutoRevokePermissions = in.readBoolean(); + this.allowDontAutoRevokePermissions = in.readBoolean(); this.preserveLegacyExternalStorage = in.readBoolean(); this.mimeGroups = (ArraySet<String>) in.readArraySet(boot); this.enableGwpAsan = sForBoolean.unparcel(in); @@ -2023,6 +2029,16 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { } @Override + public boolean isDontAutoRevokePermmissions() { + return dontAutoRevokePermissions; + } + + @Override + public boolean isAllowDontAutoRevokePermmissions() { + return allowDontAutoRevokePermissions; + } + + @Override public boolean hasPreserveLegacyExternalStorage() { return preserveLegacyExternalStorage; } @@ -2493,6 +2509,18 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { } @Override + public ParsingPackageImpl setDontAutoRevokePermissions(boolean value) { + dontAutoRevokePermissions = value; + return this; + } + + @Override + public ParsingPackageImpl setAllowDontAutoRevokePermissions(boolean value) { + allowDontAutoRevokePermissions = value; + return this; + } + + @Override public ParsingPackageImpl setPreserveLegacyExternalStorage(boolean value) { preserveLegacyExternalStorage = value; return this; diff --git a/core/java/android/content/pm/parsing/ParsingPackageRead.java b/core/java/android/content/pm/parsing/ParsingPackageRead.java index 61d7824c2cde..adc10c6fbd11 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageRead.java +++ b/core/java/android/content/pm/parsing/ParsingPackageRead.java @@ -771,6 +771,12 @@ public interface ParsingPackageRead extends Parcelable { /** @see ApplicationInfo#PRIVATE_FLAG_ALLOW_NATIVE_HEAP_POINTER_TAGGING */ boolean isAllowNativeHeapPointerTagging(); + /** @see ApplicationInfo#PRIVATE_FLAG2_DONT_AUTO_REVOKE_PERMISSIONS */ + boolean isDontAutoRevokePermmissions(); + + /** @see ApplicationInfo#PRIVATE_FLAG2_ALLOW_DONT_AUTO_REVOKE_PERMISSIONS */ + boolean isAllowDontAutoRevokePermmissions(); + boolean hasPreserveLegacyExternalStorage(); /** diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index 19da71c19737..2da86e2ed4c4 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -1817,6 +1817,8 @@ public class ParsingPackageUtils { .setUseEmbeddedDex(bool(false, R.styleable.AndroidManifestApplication_useEmbeddedDex, sa)) .setUsesNonSdkApi(bool(false, R.styleable.AndroidManifestApplication_usesNonSdkApi, sa)) .setVmSafeMode(bool(false, R.styleable.AndroidManifestApplication_vmSafeMode, sa)) + .setDontAutoRevokePermissions(bool(false, R.styleable.AndroidManifestApplication_requestDontAutoRevokePermissions, sa)) + .setAllowDontAutoRevokePermissions(bool(false, R.styleable.AndroidManifestApplication_allowDontAutoRevokePermissions, sa)) // targetSdkVersion gated .setAllowAudioPlaybackCapture(bool(targetSdk >= Build.VERSION_CODES.Q, R.styleable.AndroidManifestApplication_allowAudioPlaybackCapture, sa)) .setBaseHardwareAccelerated(bool(targetSdk >= Build.VERSION_CODES.ICE_CREAM_SANDWICH, R.styleable.AndroidManifestApplication_hardwareAccelerated, sa)) diff --git a/core/java/android/permission/IPermissionManager.aidl b/core/java/android/permission/IPermissionManager.aidl index 2615c98a6d5e..40acb7be797b 100644 --- a/core/java/android/permission/IPermissionManager.aidl +++ b/core/java/android/permission/IPermissionManager.aidl @@ -106,4 +106,8 @@ interface IPermissionManager { int importanceToResetTimer, int importanceToKeepSessionAlive); void stopOneTimePermissionSession(String packageName, int userId); + + List<String> getAutoRevokeExemptionRequestedPackages(int userId); + + List<String> getAutoRevokeExemptionGrantedPackages(int userId); } diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java index 0bd211d70e89..8308bb39d8c5 100644 --- a/core/java/android/permission/PermissionManager.java +++ b/core/java/android/permission/PermissionManager.java @@ -40,11 +40,13 @@ import android.os.UserHandle; import android.util.Slog; import com.android.internal.annotations.Immutable; +import com.android.internal.util.CollectionUtils; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.Set; import java.util.concurrent.Executor; import java.util.function.Consumer; @@ -299,6 +301,46 @@ public final class PermissionManager { } } + /** + * Gets the list of packages that have permissions that specified + * {@code requestDontAutoRevokePermissions=true} in their + * {@code application} manifest declaration. + * + * @return the list of packages for current user + * @hide + */ + @SystemApi + @NonNull + @RequiresPermission(Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY) + public Set<String> getAutoRevokeExemptionRequestedPackages() { + try { + return CollectionUtils.toSet(mPermissionManager.getAutoRevokeExemptionRequestedPackages( + mContext.getUser().getIdentifier())); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Gets the list of packages that have permissions that specified + * {@code allowDontAutoRevokePermissions=true} in their + * {@code application} manifest declaration. + * + * @return the list of packages for current user + * @hide + */ + @SystemApi + @NonNull + @RequiresPermission(Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY) + public Set<String> getAutoRevokeExemptionGrantedPackages() { + try { + return CollectionUtils.toSet(mPermissionManager.getAutoRevokeExemptionGrantedPackages( + mContext.getUser().getIdentifier())); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + private List<SplitPermissionInfo> splitPermissionInfoListToNonParcelableList( List<SplitPermissionInfoParcelable> parcelableList) { final int size = parcelableList.size(); diff --git a/core/java/com/android/internal/util/CollectionUtils.java b/core/java/com/android/internal/util/CollectionUtils.java index 9b2bcfbe89c7..488b18db66d6 100644 --- a/core/java/com/android/internal/util/CollectionUtils.java +++ b/core/java/com/android/internal/util/CollectionUtils.java @@ -16,6 +16,8 @@ package com.android.internal.util; +import static java.util.Collections.emptySet; + import android.annotation.NonNull; import android.annotation.Nullable; import android.util.ArrayMap; @@ -67,7 +69,7 @@ public class CollectionUtils { */ public static @NonNull <T> Set<T> filter(@Nullable Set<T> set, java.util.function.Predicate<? super T> predicate) { - if (set == null || set.size() == 0) return Collections.emptySet(); + if (set == null || set.size() == 0) return emptySet(); ArraySet<T> result = null; if (set instanceof ArraySet) { ArraySet<T> arraySet = (ArraySet<T>) set; @@ -123,7 +125,7 @@ public class CollectionUtils { */ public static @NonNull <I, O> Set<O> map(@Nullable Set<I> cur, Function<? super I, ? extends O> f) { - if (isEmpty(cur)) return Collections.emptySet(); + if (isEmpty(cur)) return emptySet(); ArraySet<O> result = new ArraySet<>(); if (cur instanceof ArraySet) { ArraySet<I> arraySet = (ArraySet<I>) cur; @@ -182,7 +184,7 @@ public class CollectionUtils { * @see Collections#emptySet */ public static @NonNull <T> Set<T> emptyIfNull(@Nullable Set<T> cur) { - return cur == null ? Collections.emptySet() : cur; + return cur == null ? emptySet() : cur; } /** @@ -325,9 +327,9 @@ public class CollectionUtils { */ public static @NonNull <T> Set<T> addAll(@Nullable Set<T> cur, @Nullable Collection<T> val) { if (isEmpty(val)) { - return cur != null ? cur : Collections.emptySet(); + return cur != null ? cur : emptySet(); } - if (cur == null || cur == Collections.emptySet()) { + if (cur == null || cur == emptySet()) { cur = new ArraySet<>(); } cur.addAll(val); @@ -338,7 +340,7 @@ public class CollectionUtils { * @see #add(List, Object) */ public static @NonNull <T> Set<T> add(@Nullable Set<T> cur, T val) { - if (cur == null || cur == Collections.emptySet()) { + if (cur == null || cur == emptySet()) { cur = new ArraySet<>(); } cur.add(val); @@ -390,7 +392,14 @@ public class CollectionUtils { * @return a list that will not be affected by mutations to the given original list. */ public static @NonNull <T> Set<T> copyOf(@Nullable Set<T> cur) { - return isEmpty(cur) ? Collections.emptySet() : new ArraySet<>(cur); + return isEmpty(cur) ? emptySet() : new ArraySet<>(cur); + } + + /** + * @return a {@link Set} representing the given collection. + */ + public static @NonNull <T> Set<T> toSet(@Nullable Collection<T> cur) { + return isEmpty(cur) ? emptySet() : new ArraySet<>(cur); } /** diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index ba939eaa638a..81ba98935b70 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -1831,6 +1831,19 @@ <attr name="enableGwpAsan" /> + <!-- If {@code true} allow requesting that its permissions don't get automatically + revoked when the app is unused for an extended amount of time. + + The default value is {@code false}. --> + <attr name="requestDontAutoRevokePermissions" format="boolean" /> + + <!-- If {@code true} its permissions shouldn't get automatically + revoked when the app is unused for an extended amount of time. + + This implies {@code requestDontAutoRevokePermissions=true} + + The default value is {@code false}. --> + <attr name="allowDontAutoRevokePermissions" format="boolean" /> </declare-styleable> <!-- The <code>feature</code> tag declares a feature. A feature is a logical part of an app. diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index a823e52b3595..553dbf836d82 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -3013,6 +3013,8 @@ <!-- @hide @SystemApi --> <public name="minExtensionVersion" /> <public name="allowNativeHeapPointerTagging" /> + <public name="requestDontAutoRevokePermissions" /> + <public name="allowDontAutoRevokePermissions" /> <public name="preserveLegacyExternalStorage" /> <public name="mimeGroup" /> <public name="enableGwpAsan" /> diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index 85da5593223b..5141191dd8b7 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -3093,6 +3093,36 @@ public class PermissionManagerService extends IPermissionManager.Stub { } } + @Override + public List<String> getAutoRevokeExemptionRequestedPackages(int userId) { + mContext.enforceCallingPermission(Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY, + "Must hold " + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY); + + List<String> result = new ArrayList<>(); + mPackageManagerInt.forEachInstalledPackage(pkg -> { + if (pkg.isDontAutoRevokePermmissions()) { + result.add(pkg.getPackageName()); + } + }, userId); + + return result; + } + + @Override + public List<String> getAutoRevokeExemptionGrantedPackages(int userId) { + mContext.enforceCallingPermission(Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY, + "Must hold " + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY); + + List<String> result = new ArrayList<>(); + mPackageManagerInt.forEachInstalledPackage(pkg -> { + if (pkg.isAllowDontAutoRevokePermmissions()) { + result.add(pkg.getPackageName()); + } + }, userId); + + return result; + } + private boolean isNewPlatformPermissionForPackage(String perm, AndroidPackage pkg) { boolean allowed = false; final int NP = PackageParser.NEW_PERMISSIONS.length; |