diff --git a/api/current.txt b/api/current.txt index 707df04062887..716735a66135d 100644 --- a/api/current.txt +++ b/api/current.txt @@ -12025,6 +12025,7 @@ package android.content.pm { method public boolean hasSigningCertificate(int, @NonNull byte[], int); method public abstract boolean hasSystemFeature(@NonNull String); method public abstract boolean hasSystemFeature(@NonNull String, int); + method public boolean isAutoRevokeWhitelisted(); method public boolean isDefaultApplicationIcon(@NonNull android.graphics.drawable.Drawable); method public boolean isDeviceUpgrading(); method public abstract boolean isInstantApp(); diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 87d33a9804383..bfaa2be6da6a7 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -3337,6 +3337,15 @@ public class ApplicationPackageManager extends PackageManager { } } + @Override + public boolean isAutoRevokeWhitelisted() { + try { + return mPM.isAutoRevokeWhitelisted(mContext.getPackageName()); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } + public void setMimeGroup(String mimeGroup, Set mimeTypes) { try { mPM.setMimeGroup(mContext.getPackageName(), mimeGroup, diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 8c3eef27dd580..0311120aebfbb 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -748,4 +748,6 @@ interface IPackageManager { void clearMimeGroup(String packageName, String group); List getMimeGroup(String packageName, String group); + + boolean isAutoRevokeWhitelisted(String packageName); } diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index b0964fa398a7f..3764734d033cd 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -7834,6 +7834,15 @@ public abstract class PackageManager { "sendDeviceCustomizationReadyBroadcast not implemented in subclass"); } + /** + * @return whether this package is whitelisted from having its runtime permission be + * auto-revoked if unused for an extended period of time. + */ + public boolean isAutoRevokeWhitelisted() { + throw new UnsupportedOperationException( + "isAutoRevokeWhitelisted not implemented in subclass"); + } + /** * Returns if the provided drawable represents the default activity icon provided by the system. * diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 61bf5f0b6dfd2..ca2e2406d14d9 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -24,6 +24,8 @@ import static android.Manifest.permission.READ_EXTERNAL_STORAGE; import static android.Manifest.permission.REQUEST_DELETE_PACKAGES; import static android.Manifest.permission.SET_HARMFUL_APP_WARNINGS; import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; +import static android.app.AppOpsManager.MODE_ALLOWED; +import static android.app.AppOpsManager.MODE_IGNORED; import static android.content.Intent.ACTION_MAIN; import static android.content.Intent.CATEGORY_DEFAULT; import static android.content.Intent.CATEGORY_HOME; @@ -24360,6 +24362,24 @@ public class PackageManagerService extends IPackageManager.Stub mCompilerStats.deletePackageStats(pkgName); } + @Override + public boolean isAutoRevokeWhitelisted(String packageName) { + int mode = mInjector.getAppOpsManager().checkOpNoThrow( + AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, + Binder.getCallingUid(), packageName); + if (mode == MODE_ALLOWED) { + return false; + } else if (mode == MODE_IGNORED) { + return true; + } else { + synchronized (mLock) { + boolean manifestWhitelisted = + mPackages.get(packageName).isAllowDontAutoRevokePermmissions(); + return manifestWhitelisted; + } + } + } + @Override public int getInstallReason(String packageName, int userId) { final int callingUid = Binder.getCallingUid();