diff options
author | Amith Yamasani <yamasani@google.com> | 2015-04-29 00:16:59 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-04-29 00:17:00 +0000 |
commit | 7c97a3ddea62a3bd8a95ca51e7b172b209388815 (patch) | |
tree | 5090188b286cccf2ede51c0a2d19c6c87989d42c | |
parent | 1f1b88b22bf2d22a1074785132a976bb83a4a1d8 (diff) | |
parent | d49489b3af01c13d3b13af1cd04d53787185cc0a (diff) | |
download | frameworks_base-7c97a3ddea62a3bd8a95ca51e7b172b209388815.zip frameworks_base-7c97a3ddea62a3bd8a95ca51e7b172b209388815.tar.gz frameworks_base-7c97a3ddea62a3bd8a95ca51e7b172b209388815.tar.bz2 |
Merge "Permissions control via profile/device owner admin" into mnc-dev
-rw-r--r-- | api/current.txt | 6 | ||||
-rw-r--r-- | api/system-current.txt | 6 | ||||
-rw-r--r-- | core/java/android/app/admin/DevicePolicyManager.java | 72 | ||||
-rw-r--r-- | core/java/android/app/admin/IDevicePolicyManager.aidl | 5 | ||||
-rw-r--r-- | services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java | 64 |
5 files changed, 152 insertions, 1 deletions
diff --git a/api/current.txt b/api/current.txt index e886227..73829e6 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5730,6 +5730,7 @@ package android.app.admin { method public int getPasswordMinimumSymbols(android.content.ComponentName); method public int getPasswordMinimumUpperCase(android.content.ComponentName); method public int getPasswordQuality(android.content.ComponentName); + method public int getPermissionPolicy(android.content.ComponentName); method public java.util.List<java.lang.String> getPermittedAccessibilityServices(android.content.ComponentName); method public java.util.List<java.lang.String> getPermittedInputMethods(android.content.ComponentName); method public boolean getScreenCaptureDisabled(android.content.ComponentName); @@ -5782,6 +5783,8 @@ package android.app.admin { method public void setPasswordMinimumSymbols(android.content.ComponentName, int); method public void setPasswordMinimumUpperCase(android.content.ComponentName, int); method public void setPasswordQuality(android.content.ComponentName, int); + method public boolean setPermissionGranted(android.content.ComponentName, java.lang.String, java.lang.String, boolean); + method public void setPermissionPolicy(android.content.ComponentName, int); method public boolean setPermittedAccessibilityServices(android.content.ComponentName, java.util.List<java.lang.String>); method public boolean setPermittedInputMethods(android.content.ComponentName, java.util.List<java.lang.String>); method public void setPreferredSetupActivity(android.content.ComponentName, android.content.ComponentName); @@ -5870,6 +5873,9 @@ package android.app.admin { field public static final int PASSWORD_QUALITY_NUMERIC_COMPLEX = 196608; // 0x30000 field public static final int PASSWORD_QUALITY_SOMETHING = 65536; // 0x10000 field public static final int PASSWORD_QUALITY_UNSPECIFIED = 0; // 0x0 + field public static final int PERMISSION_POLICY_AUTO_DENY = 2; // 0x2 + field public static final int PERMISSION_POLICY_AUTO_GRANT = 1; // 0x1 + field public static final int PERMISSION_POLICY_PROMPT = 0; // 0x0 field public static final int RESET_PASSWORD_REQUIRE_ENTRY = 1; // 0x1 field public static final int WIPE_EXTERNAL_STORAGE = 1; // 0x1 field public static final int WIPE_RESET_PROTECTION_DATA = 2; // 0x2 diff --git a/api/system-current.txt b/api/system-current.txt index b9ad94b..d74bf6e 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -5827,6 +5827,7 @@ package android.app.admin { method public int getPasswordMinimumSymbols(android.content.ComponentName); method public int getPasswordMinimumUpperCase(android.content.ComponentName); method public int getPasswordQuality(android.content.ComponentName); + method public int getPermissionPolicy(android.content.ComponentName); method public java.util.List<java.lang.String> getPermittedAccessibilityServices(android.content.ComponentName); method public java.util.List<java.lang.String> getPermittedAccessibilityServices(int); method public java.util.List<java.lang.String> getPermittedInputMethods(android.content.ComponentName); @@ -5885,6 +5886,8 @@ package android.app.admin { method public void setPasswordMinimumSymbols(android.content.ComponentName, int); method public void setPasswordMinimumUpperCase(android.content.ComponentName, int); method public void setPasswordQuality(android.content.ComponentName, int); + method public boolean setPermissionGranted(android.content.ComponentName, java.lang.String, java.lang.String, boolean); + method public void setPermissionPolicy(android.content.ComponentName, int); method public boolean setPermittedAccessibilityServices(android.content.ComponentName, java.util.List<java.lang.String>); method public boolean setPermittedInputMethods(android.content.ComponentName, java.util.List<java.lang.String>); method public void setPreferredSetupActivity(android.content.ComponentName, android.content.ComponentName); @@ -5978,6 +5981,9 @@ package android.app.admin { field public static final int PASSWORD_QUALITY_NUMERIC_COMPLEX = 196608; // 0x30000 field public static final int PASSWORD_QUALITY_SOMETHING = 65536; // 0x10000 field public static final int PASSWORD_QUALITY_UNSPECIFIED = 0; // 0x0 + field public static final int PERMISSION_POLICY_AUTO_DENY = 2; // 0x2 + field public static final int PERMISSION_POLICY_AUTO_GRANT = 1; // 0x1 + field public static final int PERMISSION_POLICY_PROMPT = 0; // 0x0 field public static final int RESET_PASSWORD_REQUIRE_ENTRY = 1; // 0x1 field public static final int WIPE_EXTERNAL_STORAGE = 1; // 0x1 field public static final int WIPE_RESET_PROTECTION_DATA = 2; // 0x2 diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index ed814c3..cf9813f 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -807,6 +807,24 @@ public class DevicePolicyManager { public static final String ACTION_SYSTEM_UPDATE_POLICY_CHANGED = "android.app.action.SYSTEM_UPDATE_POLICY_CHANGED"; + /** + * Permission policy to prompt user for new permission requests for runtime permissions. + * Already granted or denied permissions are not affected by this. + */ + public static final int PERMISSION_POLICY_PROMPT = 0; + + /** + * Permission policy to always grant new permission requests for runtime permissions. + * Already granted or denied permissions are not affected by this. + */ + public static final int PERMISSION_POLICY_AUTO_GRANT = 1; + + /** + * Permission policy to always deny new permission requests for runtime permissions. + * Already granted or denied permissions are not affected by this. + */ + public static final int PERMISSION_POLICY_AUTO_DENY = 2; + /** * Return true if the given administrator component is currently @@ -4342,4 +4360,58 @@ public class DevicePolicyManager { Log.w(TAG, "Failed talking with device policy service", re); } } + + /** + * Called by profile or device owners to set the default response for future runtime permission + * requests by applications. The policy can allow for normal operation which prompts the + * user to grant a permission, or can allow automatic granting or denying of runtime + * permission requests by an application. This also applies to new permissions declared by app + * updates. + * @param admin Which profile or device owner this request is associated with. + * @param policy One of the policy constants {@link #PERMISSION_POLICY_PROMPT}, + * {@link #PERMISSION_POLICY_AUTO_GRANT} and {@link #PERMISSION_POLICY_AUTO_DENY}. + */ + public void setPermissionPolicy(ComponentName admin, int policy) { + try { + mService.setPermissionPolicy(admin, policy); + } catch (RemoteException re) { + Log.w(TAG, "Failed talking with device policy service", re); + } + } + + /** + * Returns the current runtime permission policy set by the device or profile owner. The + * default is {@link #PERMISSION_POLICY_PROMPT}. + * @param admin Which profile or device owner this request is associated with. + * @return the current policy for future permission requests. + */ + public int getPermissionPolicy(ComponentName admin) { + try { + return mService.getPermissionPolicy(admin); + } catch (RemoteException re) { + return PERMISSION_POLICY_PROMPT; + } + } + + /** + * Grants or revokes a runtime permission to a specific application so that the user + * does not have to be prompted. This might affect all permissions in a group that the + * runtime permission belongs to. This method can only be called by a profile or device + * owner. + * @param admin Which profile or device owner this request is associated with. + * @param packageName The application to grant or revoke a permission to. + * @param permission The permission to grant or revoke. + * @param granted Whether or not to grant the permission. If false, all permissions in the + * associated permission group will be denied. + * @return whether the permission was successfully granted or revoked + */ + public boolean setPermissionGranted(ComponentName admin, String packageName, + String permission, boolean granted) { + try { + return mService.setPermissionGranted(admin, packageName, permission, granted); + } catch (RemoteException re) { + Log.w(TAG, "Failed talking with device policy service", re); + return false; + } + } } diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index a678c51..833bc00 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -229,4 +229,9 @@ interface IDevicePolicyManager { boolean getDoNotAskCredentialsOnBoot(); void notifyPendingSystemUpdate(in long updateReceivedTime); + + void setPermissionPolicy(in ComponentName admin, int policy); + int getPermissionPolicy(in ComponentName admin); + boolean setPermissionGranted(in ComponentName admin, String packageName, String permission, + boolean granted); } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 31d7f74..1d00de9 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -182,6 +182,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private static final String ATTR_PERMISSION_PROVIDER = "permission-provider"; private static final String ATTR_SETUP_COMPLETE = "setup-complete"; private static final String ATTR_PREFERRED_SETUP_ACTIVITY = "setup-activity"; + private static final String ATTR_PERMISSION_POLICY = "permission-policy"; private static final String ATTR_DELEGATED_CERT_INSTALLER = "delegated-cert-installer"; @@ -300,6 +301,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { int mPasswordOwner = -1; long mLastMaximumTimeToLock = -1; boolean mUserSetupComplete = false; + int mPermissionPolicy; final HashMap<ComponentName, ActiveAdmin> mAdminMap = new HashMap<>(); final ArrayList<ActiveAdmin> mAdminList = new ArrayList<>(); @@ -1409,6 +1411,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { out.attribute(null, ATTR_SETUP_COMPLETE, Boolean.toString(true)); } + if (policy.mPermissionPolicy != DevicePolicyManager.PERMISSION_POLICY_PROMPT) { + out.attribute(null, ATTR_PERMISSION_POLICY, + Integer.toString(policy.mPermissionPolicy)); + } if (policy.mDelegatedCertInstallerPackage != null) { out.attribute(null, ATTR_DELEGATED_CERT_INSTALLER, policy.mDelegatedCertInstallerPackage); @@ -1537,6 +1543,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (userSetupComplete != null && Boolean.toString(true).equals(userSetupComplete)) { policy.mUserSetupComplete = true; } + String permissionPolicy = parser.getAttributeValue(null, ATTR_PERMISSION_POLICY); + if (!TextUtils.isEmpty(permissionPolicy)) { + policy.mPermissionPolicy = Integer.parseInt(permissionPolicy); + } policy.mDelegatedCertInstallerPackage = parser.getAttributeValue(null, ATTR_DELEGATED_CERT_INSTALLER); String preferredSetupActivity = @@ -4253,14 +4263,22 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return; } UserHandle callingUser = Binder.getCallingUserHandle(); + int userId = callingUser.getIdentifier(); // Check if this is the profile owner who is calling getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); synchronized (this) { + // Reset some of the profile-owner policies + DevicePolicyData policy = getUserData(userId); + policy.mPermissionPolicy = DevicePolicyManager.PERMISSION_POLICY_PROMPT; + policy.mDelegatedCertInstallerPackage = null; + policy.mStatusBarEnabledState = true; + saveSettingsLocked(userId); + long ident = Binder.clearCallingIdentity(); try { clearUserRestrictions(callingUser); if (mDeviceOwner != null) { - mDeviceOwner.removeProfileOwner(callingUser.getIdentifier()); + mDeviceOwner.removeProfileOwner(userId); mDeviceOwner.writeOwnerFile(); } } finally { @@ -6261,4 +6279,48 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } } + + @Override + public void setPermissionPolicy(ComponentName admin, int policy) throws RemoteException { + int userId = UserHandle.getCallingUserId(); + synchronized (this) { + getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); + DevicePolicyData userPolicy = getUserData(userId); + if (userPolicy.mPermissionPolicy != policy) { + userPolicy.mPermissionPolicy = policy; + saveSettingsLocked(userId); + } + } + } + + @Override + public int getPermissionPolicy(ComponentName admin) throws RemoteException { + int userId = UserHandle.getCallingUserId(); + synchronized (this) { + DevicePolicyData userPolicy = getUserData(userId); + return userPolicy.mPermissionPolicy; + } + } + + @Override + public boolean setPermissionGranted(ComponentName admin, String packageName, + String permission, boolean granted) throws RemoteException { + UserHandle user = Binder.getCallingUserHandle(); + synchronized (this) { + getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); + long ident = Binder.clearCallingIdentity(); + try { + if (granted) { + mContext.getPackageManager().grantPermission(packageName, permission, user); + } else { + mContext.getPackageManager().revokePermission(packageName, permission, user); + } + return true; + } catch (SecurityException se) { + return false; + } finally { + Binder.restoreCallingIdentity(ident); + } + } + } } |