diff options
-rw-r--r-- | api/current.txt | 8 | ||||
-rw-r--r-- | api/system-current.txt | 8 | ||||
-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, 154 insertions, 3 deletions
diff --git a/api/current.txt b/api/current.txt index 035b372..3bc0830 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5729,6 +5729,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); @@ -5781,6 +5782,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); @@ -5869,6 +5872,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 @@ -30433,7 +30439,6 @@ package android.telecom { public static abstract class InCallService.VideoCall { ctor public InCallService.VideoCall(); method public abstract void registerCallback(android.telecom.InCallService.VideoCall.Callback); - method public abstract void unregisterCallback(); method public abstract void requestCallDataUsage(); method public abstract void requestCameraCapabilities(); method public abstract void sendSessionModifyRequest(android.telecom.VideoProfile); @@ -30444,6 +30449,7 @@ package android.telecom { method public abstract void setPauseImage(java.lang.String); method public abstract void setPreviewSurface(android.view.Surface); method public abstract void setZoom(float); + method public abstract void unregisterCallback(); } public static abstract class InCallService.VideoCall.Callback { diff --git a/api/system-current.txt b/api/system-current.txt index e49ef9d..dd4225d 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -5828,6 +5828,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); @@ -5886,6 +5887,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); @@ -5979,6 +5982,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 @@ -32550,7 +32556,6 @@ package android.telecom { public static abstract class InCallService.VideoCall { ctor public InCallService.VideoCall(); method public abstract void registerCallback(android.telecom.InCallService.VideoCall.Callback); - method public abstract void unregisterCallback(); method public abstract void requestCallDataUsage(); method public abstract void requestCameraCapabilities(); method public abstract void sendSessionModifyRequest(android.telecom.VideoProfile); @@ -32561,6 +32566,7 @@ package android.telecom { method public abstract void setPauseImage(java.lang.String); method public abstract void setPreviewSurface(android.view.Surface); method public abstract void setZoom(float); + method public abstract void unregisterCallback(); } public static abstract class InCallService.VideoCall.Callback { 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); + } + } + } } |