From ad3b2975574f916c14382628d50c710a78064746 Mon Sep 17 00:00:00 2001 From: Svet Ganov Date: Tue, 7 Jul 2015 22:49:17 -0700 Subject: [PATCH] Add an API for apps to query if a permisison is denied by policy. bug:22177216 Change-Id: I32227f55097fae997f33743fd1eee06cb18f47f1 --- api/current.txt | 2 ++ api/system-current.txt | 2 ++ .../app/ApplicationPackageManager.java | 9 ++++++++ .../android/content/pm/IPackageManager.aidl | 2 ++ .../android/content/pm/PackageManager.java | 17 +++++++++++++- .../server/pm/PackageManagerService.java | 22 +++++++++++++++++++ .../android/test/mock/MockPackageManager.java | 5 +++++ 7 files changed, 58 insertions(+), 1 deletion(-) diff --git a/api/current.txt b/api/current.txt index af9586756bce7..7da030374c565 100644 --- a/api/current.txt +++ b/api/current.txt @@ -9256,6 +9256,7 @@ package android.content.pm { method public abstract java.lang.CharSequence getUserBadgedLabel(java.lang.CharSequence, android.os.UserHandle); method public abstract android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo); method public abstract boolean hasSystemFeature(java.lang.String); + method public abstract boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String); method public abstract boolean isSafeMode(); method public abstract java.util.List queryBroadcastReceivers(android.content.Intent, int); method public abstract java.util.List queryContentProviders(java.lang.String, int, int); @@ -31805,6 +31806,7 @@ package android.test.mock { method public java.lang.CharSequence getUserBadgedLabel(java.lang.CharSequence, android.os.UserHandle); method public android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo); method public boolean hasSystemFeature(java.lang.String); + method public boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String); method public boolean isSafeMode(); method public java.util.List queryBroadcastReceivers(android.content.Intent, int); method public java.util.List queryContentProviders(java.lang.String, int, int); diff --git a/api/system-current.txt b/api/system-current.txt index 9fce166b2153a..4824573e19e3c 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -9540,6 +9540,7 @@ package android.content.pm { method public abstract android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo); method public abstract void grantRuntimePermission(java.lang.String, java.lang.String, android.os.UserHandle); method public abstract boolean hasSystemFeature(java.lang.String); + method public abstract boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String); method public abstract boolean isSafeMode(); method public abstract java.util.List queryBroadcastReceivers(android.content.Intent, int); method public abstract java.util.List queryContentProviders(java.lang.String, int, int); @@ -34091,6 +34092,7 @@ package android.test.mock { method public android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo); method public void grantRuntimePermission(java.lang.String, java.lang.String, android.os.UserHandle); method public boolean hasSystemFeature(java.lang.String); + method public boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String); method public boolean isSafeMode(); method public java.util.List queryBroadcastReceivers(android.content.Intent, int); method public java.util.List queryContentProviders(java.lang.String, int, int); diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index cb1e7aac0e196..1fb0b2af33664 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -420,6 +420,15 @@ final class ApplicationPackageManager extends PackageManager { } } + @Override + public boolean isPermissionRevokedByPolicy(String permName, String pkgName) { + try { + return mPM.isPermissionRevokedByPolicy(permName, pkgName, mContext.getUserId()); + } catch (RemoteException e) { + throw new RuntimeException("Package manager has died", e); + } + } + @Override public boolean addPermission(PermissionInfo info) { try { diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 2b83d86ce9f86..103ee29102457 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -506,4 +506,6 @@ interface IPackageManager { int getMountExternalMode(int uid); void grantDefaultPermissionsToEnabledCarrierApps(in String[] packageNames, int userId); + + boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId); } diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 49386f9e04803..3f582dfd4ffa0 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -2398,7 +2398,7 @@ public abstract class PackageManager { * Check whether a particular package has been granted a particular * permission. * - * @param permName The name of the permission you are checking for, + * @param permName The name of the permission you are checking for. * @param pkgName The name of the package you are checking against. * * @return If the package has the permission, PERMISSION_GRANTED is @@ -2411,6 +2411,21 @@ public abstract class PackageManager { @CheckResult public abstract int checkPermission(String permName, String pkgName); + /** + * Checks whether a particular permissions has been revoked for a + * package by policy. Typically the device owner or the profile owner + * may apply such a policy. The user cannot grant policy revoked + * permissions, hence the only way for an app to get such a permission + * is by a policy change. + * + * @param permName The name of the permission you are checking for. + * @param pkgName The name of the package you are checking against. + * + * @return Whether the permission is restricted by policy. + */ + @CheckResult + public abstract boolean isPermissionRevokedByPolicy(String permName, String pkgName); + /** * Add a new dynamic permission to the system. For this to work, your * package must have defined a permission tree through the diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 124214c84b5f2..7b018c755e91b 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -3137,6 +3137,28 @@ public class PackageManagerService extends IPackageManager.Stub { return PackageManager.PERMISSION_DENIED; } + @Override + public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) { + if (UserHandle.getCallingUserId() != userId) { + mContext.enforceCallingPermission( + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, + "isPermissionRevokedByPolicy for user " + userId); + } + + if (checkPermission(permission, packageName, userId) + == PackageManager.PERMISSION_GRANTED) { + return false; + } + + final long identity = Binder.clearCallingIdentity(); + try { + final int flags = getPermissionFlags(permission, packageName, userId); + return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0; + } finally { + Binder.restoreCallingIdentity(identity); + } + } + /** * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java index ac92dc0371c92..3df7bbc91e9b3 100644 --- a/test-runner/src/android/test/mock/MockPackageManager.java +++ b/test-runner/src/android/test/mock/MockPackageManager.java @@ -176,6 +176,11 @@ public class MockPackageManager extends PackageManager { throw new UnsupportedOperationException(); } + @Override + public boolean isPermissionRevokedByPolicy(String permName, String pkgName) { + throw new UnsupportedOperationException(); + } + @Override public boolean addPermission(PermissionInfo info) { throw new UnsupportedOperationException();