Loading core/java/android/app/admin/DevicePolicyManagerInternal.java +9 −0 Original line number Diff line number Diff line Loading @@ -60,4 +60,13 @@ public abstract class DevicePolicyManagerInternal { */ public abstract void addOnCrossProfileWidgetProvidersChangeListener( OnCrossProfileWidgetProvidersChangeListener listener); /** * Checks if an app with given uid is an active device admin of its user and has the policy * specified. * @param uid App uid. * @param reqPolicy Required policy, for policies see {@link DevicePolicyManager}. * @return true if the uid is an active admin with the given policy. */ public abstract boolean isActiveAdminWithPolicy(int uid, int reqPolicy); } services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +65 −42 Original line number Diff line number Diff line Loading @@ -1140,70 +1140,85 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { ActiveAdmin getActiveAdminForCallerLocked(ComponentName who, int reqPolicy) throws SecurityException { final int callingUid = Binder.getCallingUid(); final int userHandle = UserHandle.getUserId(callingUid); final DevicePolicyData policy = getUserData(userHandle); List<ActiveAdmin> candidates = new ArrayList<ActiveAdmin>(); ActiveAdmin result = getActiveAdminWithPolicyForUidLocked(who, reqPolicy, callingUid); if (result != null) { return result; } if (who != null) { final int userId = UserHandle.getUserId(callingUid); final DevicePolicyData policy = getUserData(userId); ActiveAdmin admin = policy.mAdminMap.get(who); if (reqPolicy == DeviceAdminInfo.USES_POLICY_DEVICE_OWNER) { throw new SecurityException("Admin " + admin.info.getComponent() + " does not own the device"); } if (reqPolicy == DeviceAdminInfo.USES_POLICY_PROFILE_OWNER) { throw new SecurityException("Admin " + admin.info.getComponent() + " does not own the profile"); } throw new SecurityException("Admin " + admin.info.getComponent() + " did not specify uses-policy for: " + admin.info.getTagForPolicy(reqPolicy)); } else { throw new SecurityException("No active admin owned by uid " + Binder.getCallingUid() + " for policy #" + reqPolicy); } } // Build a list of admins for this uid matching the given ComponentName private ActiveAdmin getActiveAdminWithPolicyForUidLocked(ComponentName who, int reqPolicy, int uid) { // Try to find an admin which can use reqPolicy final int userId = UserHandle.getUserId(uid); final DevicePolicyData policy = getUserData(userId); if (who != null) { ActiveAdmin admin = policy.mAdminMap.get(who); if (admin == null) { throw new SecurityException("No active admin " + who); } if (admin.getUid() != callingUid) { if (admin.getUid() != uid) { throw new SecurityException("Admin " + who + " is not owned by uid " + Binder.getCallingUid()); } candidates.add(admin); if (isActiveAdminWithPolicyForUserLocked(admin, reqPolicy, userId)) { return admin; } } else { for (ActiveAdmin admin : policy.mAdminList) { if (admin.getUid() == callingUid) { candidates.add(admin); if (admin.getUid() == uid && isActiveAdminWithPolicyForUserLocked(admin, reqPolicy, userId)) { return admin; } } } // Try to find an admin which can use reqPolicy for (ActiveAdmin admin : candidates) { return null; } private boolean isActiveAdminWithPolicyForUserLocked(ActiveAdmin admin, int reqPolicy, int userId) { boolean ownsDevice = isDeviceOwner(admin.info.getPackageName()); boolean ownsProfile = (getProfileOwner(userHandle) != null && getProfileOwner(userHandle).getPackageName() boolean ownsProfile = (getProfileOwner(userId) != null && getProfileOwner(userId).getPackageName() .equals(admin.info.getPackageName())); boolean ownsInitialization = isDeviceInitializer(admin.info.getPackageName()) && !hasUserSetupCompleted(userHandle); && !hasUserSetupCompleted(userId); if (reqPolicy == DeviceAdminInfo.USES_POLICY_DEVICE_OWNER) { if (ownsDevice || (userHandle == UserHandle.USER_OWNER && ownsInitialization)) { return admin; if (ownsDevice || (userId == UserHandle.USER_OWNER && ownsInitialization)) { return true; } } else if (reqPolicy == DeviceAdminInfo.USES_POLICY_PROFILE_OWNER) { if (ownsDevice || ownsProfile || ownsInitialization) { return admin; return true; } } else { if (admin.info.usesPolicy(reqPolicy)) { return admin; } } } if (who != null) { if (reqPolicy == DeviceAdminInfo.USES_POLICY_DEVICE_OWNER) { throw new SecurityException("Admin " + candidates.get(0).info.getComponent() + " does not own the device"); } if (reqPolicy == DeviceAdminInfo.USES_POLICY_PROFILE_OWNER) { throw new SecurityException("Admin " + candidates.get(0).info.getComponent() + " does not own the profile"); return true; } throw new SecurityException("Admin " + candidates.get(0).info.getComponent() + " did not specify uses-policy for: " + candidates.get(0).info.getTagForPolicy(reqPolicy)); } else { throw new SecurityException("No active admin owned by uid " + Binder.getCallingUid() + " for policy #" + reqPolicy); } return false; } void sendAdminCommandLocked(ActiveAdmin admin, String action) { Loading Loading @@ -5702,6 +5717,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } @Override public boolean isActiveAdminWithPolicy(int uid, int reqPolicy) { final int userId = UserHandle.getUserId(uid); synchronized(DevicePolicyManagerService.this) { return getActiveAdminWithPolicyForUidLocked(null, reqPolicy, uid) != null; } } private void notifyCrossProfileProvidersChanged(int userId, List<String> packages) { final List<OnCrossProfileWidgetProvidersChangeListener> listeners; synchronized (DevicePolicyManagerService.this) { Loading Loading
core/java/android/app/admin/DevicePolicyManagerInternal.java +9 −0 Original line number Diff line number Diff line Loading @@ -60,4 +60,13 @@ public abstract class DevicePolicyManagerInternal { */ public abstract void addOnCrossProfileWidgetProvidersChangeListener( OnCrossProfileWidgetProvidersChangeListener listener); /** * Checks if an app with given uid is an active device admin of its user and has the policy * specified. * @param uid App uid. * @param reqPolicy Required policy, for policies see {@link DevicePolicyManager}. * @return true if the uid is an active admin with the given policy. */ public abstract boolean isActiveAdminWithPolicy(int uid, int reqPolicy); }
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +65 −42 Original line number Diff line number Diff line Loading @@ -1140,70 +1140,85 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { ActiveAdmin getActiveAdminForCallerLocked(ComponentName who, int reqPolicy) throws SecurityException { final int callingUid = Binder.getCallingUid(); final int userHandle = UserHandle.getUserId(callingUid); final DevicePolicyData policy = getUserData(userHandle); List<ActiveAdmin> candidates = new ArrayList<ActiveAdmin>(); ActiveAdmin result = getActiveAdminWithPolicyForUidLocked(who, reqPolicy, callingUid); if (result != null) { return result; } if (who != null) { final int userId = UserHandle.getUserId(callingUid); final DevicePolicyData policy = getUserData(userId); ActiveAdmin admin = policy.mAdminMap.get(who); if (reqPolicy == DeviceAdminInfo.USES_POLICY_DEVICE_OWNER) { throw new SecurityException("Admin " + admin.info.getComponent() + " does not own the device"); } if (reqPolicy == DeviceAdminInfo.USES_POLICY_PROFILE_OWNER) { throw new SecurityException("Admin " + admin.info.getComponent() + " does not own the profile"); } throw new SecurityException("Admin " + admin.info.getComponent() + " did not specify uses-policy for: " + admin.info.getTagForPolicy(reqPolicy)); } else { throw new SecurityException("No active admin owned by uid " + Binder.getCallingUid() + " for policy #" + reqPolicy); } } // Build a list of admins for this uid matching the given ComponentName private ActiveAdmin getActiveAdminWithPolicyForUidLocked(ComponentName who, int reqPolicy, int uid) { // Try to find an admin which can use reqPolicy final int userId = UserHandle.getUserId(uid); final DevicePolicyData policy = getUserData(userId); if (who != null) { ActiveAdmin admin = policy.mAdminMap.get(who); if (admin == null) { throw new SecurityException("No active admin " + who); } if (admin.getUid() != callingUid) { if (admin.getUid() != uid) { throw new SecurityException("Admin " + who + " is not owned by uid " + Binder.getCallingUid()); } candidates.add(admin); if (isActiveAdminWithPolicyForUserLocked(admin, reqPolicy, userId)) { return admin; } } else { for (ActiveAdmin admin : policy.mAdminList) { if (admin.getUid() == callingUid) { candidates.add(admin); if (admin.getUid() == uid && isActiveAdminWithPolicyForUserLocked(admin, reqPolicy, userId)) { return admin; } } } // Try to find an admin which can use reqPolicy for (ActiveAdmin admin : candidates) { return null; } private boolean isActiveAdminWithPolicyForUserLocked(ActiveAdmin admin, int reqPolicy, int userId) { boolean ownsDevice = isDeviceOwner(admin.info.getPackageName()); boolean ownsProfile = (getProfileOwner(userHandle) != null && getProfileOwner(userHandle).getPackageName() boolean ownsProfile = (getProfileOwner(userId) != null && getProfileOwner(userId).getPackageName() .equals(admin.info.getPackageName())); boolean ownsInitialization = isDeviceInitializer(admin.info.getPackageName()) && !hasUserSetupCompleted(userHandle); && !hasUserSetupCompleted(userId); if (reqPolicy == DeviceAdminInfo.USES_POLICY_DEVICE_OWNER) { if (ownsDevice || (userHandle == UserHandle.USER_OWNER && ownsInitialization)) { return admin; if (ownsDevice || (userId == UserHandle.USER_OWNER && ownsInitialization)) { return true; } } else if (reqPolicy == DeviceAdminInfo.USES_POLICY_PROFILE_OWNER) { if (ownsDevice || ownsProfile || ownsInitialization) { return admin; return true; } } else { if (admin.info.usesPolicy(reqPolicy)) { return admin; } } } if (who != null) { if (reqPolicy == DeviceAdminInfo.USES_POLICY_DEVICE_OWNER) { throw new SecurityException("Admin " + candidates.get(0).info.getComponent() + " does not own the device"); } if (reqPolicy == DeviceAdminInfo.USES_POLICY_PROFILE_OWNER) { throw new SecurityException("Admin " + candidates.get(0).info.getComponent() + " does not own the profile"); return true; } throw new SecurityException("Admin " + candidates.get(0).info.getComponent() + " did not specify uses-policy for: " + candidates.get(0).info.getTagForPolicy(reqPolicy)); } else { throw new SecurityException("No active admin owned by uid " + Binder.getCallingUid() + " for policy #" + reqPolicy); } return false; } void sendAdminCommandLocked(ActiveAdmin admin, String action) { Loading Loading @@ -5702,6 +5717,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } @Override public boolean isActiveAdminWithPolicy(int uid, int reqPolicy) { final int userId = UserHandle.getUserId(uid); synchronized(DevicePolicyManagerService.this) { return getActiveAdminWithPolicyForUidLocked(null, reqPolicy, uid) != null; } } private void notifyCrossProfileProvidersChanged(int userId, List<String> packages) { final List<OnCrossProfileWidgetProvidersChangeListener> listeners; synchronized (DevicePolicyManagerService.this) { Loading