Loading core/java/android/app/admin/DevicePolicyManager.java +45 −0 Original line number Diff line number Diff line Loading @@ -4108,6 +4108,29 @@ public class DevicePolicyManager { return null; } /** * Called by the system to check if a specific accessibility service is disabled by admin. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. * @param packageName Accessibility service package name that needs to be checked. * @param userHandle user id the admin is running as. * @return true if the accessibility service is permitted, otherwise false. * * @hide */ public boolean isAccessibilityServicePermittedByAdmin(@NonNull ComponentName admin, @NonNull String packageName, int userHandle) { if (mService != null) { try { return mService.isAccessibilityServicePermittedByAdmin(admin, packageName, userHandle); } catch (RemoteException e) { Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e); } } return false; } /** * Returns the list of accessibility services permitted by the device or profiles * owners of this user. Loading Loading @@ -4187,6 +4210,28 @@ public class DevicePolicyManager { return null; } /** * Called by the system to check if a specific input method is disabled by admin. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. * @param packageName Input method package name that needs to be checked. * @param userHandle user id the admin is running as. * @return true if the input method is permitted, otherwise false. * * @hide */ public boolean isInputMethodPermittedByAdmin(@NonNull ComponentName admin, @NonNull String packageName, int userHandle) { if (mService != null) { try { return mService.isInputMethodPermittedByAdmin(admin, packageName, userHandle); } catch (RemoteException e) { Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e); } } return false; } /** * Returns the list of input methods permitted by the device or profiles * owners of the current user. (*Not* calling user, due to a limitation in InputMethodManager.) Loading core/java/android/app/admin/IDevicePolicyManager.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -174,10 +174,12 @@ interface IDevicePolicyManager { boolean setPermittedAccessibilityServices(in ComponentName admin,in List packageList); List getPermittedAccessibilityServices(in ComponentName admin); List getPermittedAccessibilityServicesForUser(int userId); boolean isAccessibilityServicePermittedByAdmin(in ComponentName admin, String packageName, int userId); boolean setPermittedInputMethods(in ComponentName admin,in List packageList); List getPermittedInputMethods(in ComponentName admin); List getPermittedInputMethodsForCurrentUser(); boolean isInputMethodPermittedByAdmin(in ComponentName admin, String packageName, int userId); boolean setApplicationHidden(in ComponentName admin, in String packageName, boolean hidden); boolean isApplicationHidden(in ComponentName admin, in String packageName); Loading packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java +152 −43 Original line number Diff line number Diff line Loading @@ -155,7 +155,7 @@ public class RestrictedLockUtils { for (UserInfo userInfo : um.getProfiles(userId)) { final List<ComponentName> admins = dpm.getActiveAdminsAsUser(userInfo.id); if (admins == null) { return null; continue; } final boolean isSeparateProfileChallengeEnabled = lockPatternUtils.isSeparateProfileChallengeEnabled(userInfo.id); Loading Loading @@ -209,16 +209,7 @@ public class RestrictedLockUtils { IPackageManager ipm = AppGlobals.getPackageManager(); try { if (ipm.getBlockUninstallForUser(packageName, userId)) { DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService( Context.DEVICE_POLICY_SERVICE); if (dpm == null) { return null; } ComponentName admin = dpm.getProfileOwner(); if (admin == null) { admin = dpm.getDeviceOwnerComponentOnCallingUser(); } return new EnforcedAdmin(admin, UserHandle.myUserId()); return getProfileOrDeviceOwner(context, userId); } } catch (RemoteException e) { // Nothing to do Loading @@ -238,7 +229,7 @@ public class RestrictedLockUtils { try { ApplicationInfo ai = ipm.getApplicationInfo(packageName, 0, userId); if (ai != null && ((ai.flags & ApplicationInfo.FLAG_SUSPENDED) != 0)) { return getProfileOrDeviceOwnerOnCallingUser(context); return getProfileOrDeviceOwner(context, userId); } } catch (RemoteException e) { // Nothing to do Loading @@ -246,6 +237,80 @@ public class RestrictedLockUtils { return null; } public static EnforcedAdmin checkIfInputMethodDisallowed(Context context, String packageName, int userId) { DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService( Context.DEVICE_POLICY_SERVICE); if (dpm == null) { return null; } EnforcedAdmin admin = getProfileOrDeviceOwner(context, userId); boolean permitted = true; if (admin != null) { permitted = dpm.isInputMethodPermittedByAdmin(admin.component, packageName, userId); } int managedProfileId = getManagedProfileId(context, userId); EnforcedAdmin profileAdmin = getProfileOrDeviceOwner(context, managedProfileId); boolean permittedByProfileAdmin = true; if (profileAdmin != null) { permittedByProfileAdmin = dpm.isInputMethodPermittedByAdmin(profileAdmin.component, packageName, managedProfileId); } if (!permitted && !permittedByProfileAdmin) { return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN; } else if (!permitted) { return admin; } else if (!permittedByProfileAdmin) { return profileAdmin; } return null; } public static EnforcedAdmin checkIfAccessibilityServiceDisallowed(Context context, String packageName, int userId) { DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService( Context.DEVICE_POLICY_SERVICE); if (dpm == null) { return null; } EnforcedAdmin admin = getProfileOrDeviceOwner(context, userId); boolean permitted = true; if (admin != null) { permitted = dpm.isAccessibilityServicePermittedByAdmin(admin.component, packageName, userId); } int managedProfileId = getManagedProfileId(context, userId); EnforcedAdmin profileAdmin = getProfileOrDeviceOwner(context, managedProfileId); boolean permittedByProfileAdmin = true; if (profileAdmin != null) { permittedByProfileAdmin = dpm.isAccessibilityServicePermittedByAdmin( profileAdmin.component, packageName, managedProfileId); } if (!permitted && !permittedByProfileAdmin) { return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN; } else if (!permitted) { return admin; } else if (!permittedByProfileAdmin) { return profileAdmin; } return null; } private static int getManagedProfileId(Context context, int userId) { UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); List<UserInfo> userProfiles = um.getProfiles(userId); for (UserInfo uInfo : userProfiles) { if (uInfo.id == userId) { continue; } if (uInfo.isManagedProfile()) { return uInfo.id; } } return UserHandle.USER_NULL; } /** * Check if account management for a specific type of account is disabled by admin. * Only a profile or device owner can disable account management. So, we check if account Loading @@ -255,7 +320,7 @@ public class RestrictedLockUtils { * or {@code null} if the account management is not disabled. */ public static EnforcedAdmin checkIfAccountManagementDisabled(Context context, String accountType) { String accountType, int userId) { if (accountType == null) { return null; } Loading @@ -265,7 +330,7 @@ public class RestrictedLockUtils { return null; } boolean isAccountTypeDisabled = false; String[] disabledTypes = dpm.getAccountTypesWithManagementDisabled(); String[] disabledTypes = dpm.getAccountTypesWithManagementDisabledAsUser(userId); for (String type : disabledTypes) { if (accountType.equals(type)) { isAccountTypeDisabled = true; Loading @@ -275,7 +340,7 @@ public class RestrictedLockUtils { if (!isAccountTypeDisabled) { return null; } return getProfileOrDeviceOwnerOnCallingUser(context); return getProfileOrDeviceOwner(context, userId); } /** Loading @@ -296,7 +361,7 @@ public class RestrictedLockUtils { } /** * Checks if an admin has enforced minimum password quality requirements on the device. * Checks if an admin has enforced minimum password quality requirements on the given user. * * @return EnforcedAdmin Object containing the enforced admin component and admin user details, * or {@code null} if no quality requirements are set. If the requirements are set by Loading @@ -304,35 +369,73 @@ public class RestrictedLockUtils { * {@link UserHandle#USER_NULL}. * */ public static EnforcedAdmin checkIfPasswordQualityIsSet(Context context) { public static EnforcedAdmin checkIfPasswordQualityIsSet(Context context, int userId) { final DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService( Context.DEVICE_POLICY_SERVICE); if (dpm == null) { return null; } boolean isDisabledByMultipleAdmins = false; ComponentName adminComponent = null; List<ComponentName> admins = dpm.getActiveAdmins(); int quality; if (admins != null) { LockPatternUtils lockPatternUtils = new LockPatternUtils(context); EnforcedAdmin enforcedAdmin = null; if (lockPatternUtils.isSeparateProfileChallengeEnabled(userId)) { // userId is managed profile and has a separate challenge, only consider // the admins in that user. final List<ComponentName> admins = dpm.getActiveAdminsAsUser(userId); if (admins == null) { return null; } for (ComponentName admin : admins) { quality = dpm.getPasswordQuality(admin); if (quality >= DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { if (adminComponent == null) { adminComponent = admin; if (dpm.getPasswordQuality(admin, userId) > DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { if (enforcedAdmin == null) { enforcedAdmin = new EnforcedAdmin(admin, userId); } else { isDisabledByMultipleAdmins = true; break; return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN; } } } } else { // Return all admins for this user and the profiles that are visible from this // user that do not use a separate work challenge. final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); for (UserInfo userInfo : um.getProfiles(userId)) { final List<ComponentName> admins = dpm.getActiveAdminsAsUser(userInfo.id); if (admins == null) { continue; } EnforcedAdmin enforcedAdmin = null; if (adminComponent != null) { if (!isDisabledByMultipleAdmins) { enforcedAdmin = new EnforcedAdmin(adminComponent, UserHandle.myUserId()); final boolean isSeparateProfileChallengeEnabled = lockPatternUtils.isSeparateProfileChallengeEnabled(userInfo.id); for (ComponentName admin : admins) { if (!isSeparateProfileChallengeEnabled) { if (dpm.getPasswordQuality(admin, userInfo.id) > DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { if (enforcedAdmin == null) { enforcedAdmin = new EnforcedAdmin(admin, userInfo.id); } else { return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN; } // This same admins could have set policies both on the managed profile // and on the parent. So, if the admin has set the policy on the // managed profile here, we don't need to further check if that admin // has set policy on the parent admin. continue; } } if (userInfo.isManagedProfile()) { // If userInfo.id is a managed profile, we also need to look at // the policies set on the parent. DevicePolicyManager parentDpm = dpm.getParentProfileInstance(userInfo); if (parentDpm.getPasswordQuality(admin, userInfo.id) > DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { if (enforcedAdmin == null) { enforcedAdmin = new EnforcedAdmin(admin, userInfo.id); } else { enforcedAdmin = new EnforcedAdmin(); return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN; } } } } } } return enforcedAdmin; Loading @@ -352,7 +455,8 @@ public class RestrictedLockUtils { EnforcedAdmin enforcedAdmin = null; final int userId = UserHandle.myUserId(); if (lockPatternUtils.isSeparateProfileChallengeEnabled(userId)) { // If the user has a separate challenge, only consider the admins in that user. // userId is managed profile and has a separate challenge, only consider // the admins in that user. final List<ComponentName> admins = dpm.getActiveAdminsAsUser(userId); if (admins == null) { return null; Loading @@ -373,7 +477,7 @@ public class RestrictedLockUtils { for (UserInfo userInfo : um.getProfiles(userId)) { final List<ComponentName> admins = dpm.getActiveAdminsAsUser(userInfo.id); if (admins == null) { return null; continue; } final boolean isSeparateProfileChallengeEnabled = lockPatternUtils.isSeparateProfileChallengeEnabled(userInfo.id); Loading Loading @@ -410,19 +514,24 @@ public class RestrictedLockUtils { return enforcedAdmin; } public static EnforcedAdmin getProfileOrDeviceOwnerOnCallingUser(Context context) { public static EnforcedAdmin getProfileOrDeviceOwner(Context context, int userId) { if (userId == UserHandle.USER_NULL) { return null; } final DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService( Context.DEVICE_POLICY_SERVICE); if (dpm == null) { return null; } ComponentName adminComponent = dpm.getDeviceOwnerComponentOnCallingUser(); ComponentName adminComponent = dpm.getProfileOwnerAsUser(userId); if (adminComponent != null) { return new EnforcedAdmin(adminComponent, UserHandle.myUserId()); return new EnforcedAdmin(adminComponent, userId); } adminComponent = dpm.getProfileOwner(); if (dpm.getDeviceOwnerUserId() == userId) { adminComponent = dpm.getDeviceOwnerComponentOnAnyUser(); if (adminComponent != null) { return new EnforcedAdmin(adminComponent, UserHandle.myUserId()); return new EnforcedAdmin(adminComponent, userId); } } return null; } Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +61 −15 Original line number Diff line number Diff line Loading @@ -4132,7 +4132,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { public void choosePrivateKeyAlias(final int uid, final Uri uri, final String alias, final IBinder response) { // Caller UID needs to be trusted, so we restrict this method to SYSTEM_UID callers. if (!UserHandle.isSameApp(mInjector.binderGetCallingUid(), Process.SYSTEM_UID)) { if (!isCallerWithSystemUid()) { return; } Loading Loading @@ -5860,8 +5860,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } mContext.enforceCallingOrSelfPermission( android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS, null); if (hasUserSetupCompleted(userHandle) && !UserHandle.isSameApp(callingUid, Process.SYSTEM_UID)) { if (hasUserSetupCompleted(userHandle) && !isCallerWithSystemUid()) { throw new IllegalStateException("Cannot set the profile owner on a user which is " + "already set-up"); } Loading Loading @@ -5921,8 +5920,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private void enforceManageUsers() { final int callingUid = mInjector.binderGetCallingUid(); if (!(UserHandle.isSameApp(callingUid, Process.SYSTEM_UID) || callingUid == Process.ROOT_UID)) { if (!(isCallerWithSystemUid() || callingUid == Process.ROOT_UID)) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); } } Loading @@ -5945,8 +5943,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (userHandle == UserHandle.getUserId(callingUid)) { return; } if (!(UserHandle.isSameApp(callingUid, Process.SYSTEM_UID) || callingUid == Process.ROOT_UID)) { if (!(isCallerWithSystemUid() || callingUid == Process.ROOT_UID)) { mContext.enforceCallingOrSelfPermission(permission, "Must be system or have " + permission + " permission"); } Loading @@ -5964,6 +5961,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } private boolean isCallerWithSystemUid() { return UserHandle.isSameApp(mInjector.binderGetCallingUid(), Process.SYSTEM_UID); } private int getProfileParentId(int userHandle) { final long ident = mInjector.binderClearCallingIdentity(); try { Loading Loading @@ -6248,7 +6249,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public ComponentName getRestrictionsProvider(int userHandle) { synchronized (this) { if (!UserHandle.isSameApp(mInjector.binderGetCallingUid(), Process.SYSTEM_UID)) { if (!isCallerWithSystemUid()) { throw new SecurityException("Only the system can query the permission provider"); } DevicePolicyData userData = getUserData(userHandle); Loading Loading @@ -6321,8 +6322,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { * permittedList or are a system app. */ private boolean checkPackagesInPermittedListOrSystem(List<String> enabledPackages, List<String> permittedList) { int userIdToCheck = UserHandle.getCallingUserId(); List<String> permittedList, int userIdToCheck) { long id = mInjector.binderClearCallingIdentity(); try { // If we have an enabled packages list for a managed profile the packages Loading Loading @@ -6389,7 +6389,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { for (AccessibilityServiceInfo service : enabledServices) { enabledPackages.add(service.getResolveInfo().serviceInfo.packageName); } if (!checkPackagesInPermittedListOrSystem(enabledPackages, packageList)) { if (!checkPackagesInPermittedListOrSystem(enabledPackages, packageList, userId)) { Slog.e(LOG_TAG, "Cannot set permitted accessibility services, " + "because it contains already enabled accesibility services."); return false; Loading Loading @@ -6481,6 +6482,28 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } @Override public boolean isAccessibilityServicePermittedByAdmin(ComponentName who, String packageName, int userHandle) { if (!mHasFeature) { return true; } Preconditions.checkNotNull(who, "ComponentName is null"); Preconditions.checkStringNotEmpty(packageName, "packageName is null"); if (!isCallerWithSystemUid()){ throw new SecurityException( "Only the system can query if an accessibility service is disabled by admin"); } synchronized (this) { ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle); if (admin.permittedAccessiblityServices == null) { return true; } return checkPackagesInPermittedListOrSystem(Arrays.asList(packageName), admin.permittedAccessiblityServices, userHandle); } } private boolean checkCallerIsCurrentUserOrProfile() { int callingUserId = UserHandle.getCallingUserId(); long token = mInjector.binderClearCallingIdentity(); Loading Loading @@ -6536,7 +6559,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { for (InputMethodInfo ime : enabledImes) { enabledPackages.add(ime.getPackageName()); } if (!checkPackagesInPermittedListOrSystem(enabledPackages, packageList)) { if (!checkPackagesInPermittedListOrSystem(enabledPackages, packageList, mInjector.binderGetCallingUserHandle().getIdentifier())) { Slog.e(LOG_TAG, "Cannot set permitted input methods, " + "because it contains already enabled input method."); return false; Loading Loading @@ -6628,6 +6652,28 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } @Override public boolean isInputMethodPermittedByAdmin(ComponentName who, String packageName, int userHandle) { if (!mHasFeature) { return true; } Preconditions.checkNotNull(who, "ComponentName is null"); Preconditions.checkStringNotEmpty(packageName, "packageName is null"); if (!isCallerWithSystemUid()) { throw new SecurityException( "Only the system can query if an input method is disabled by admin"); } synchronized (this) { ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle); if (admin.permittedInputMethods == null) { return true; } return checkPackagesInPermittedListOrSystem(Arrays.asList(packageName), admin.permittedInputMethods, userHandle); } } @Override public UserHandle createUser(ComponentName who, String name) { Preconditions.checkNotNull(who, "ComponentName is null"); Loading Loading @@ -7425,7 +7471,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public void notifyLockTaskModeChanged(boolean isEnabled, String pkg, int userHandle) { if (!UserHandle.isSameApp(mInjector.binderGetCallingUid(), Process.SYSTEM_UID)) { if (!isCallerWithSystemUid()) { throw new SecurityException("notifyLockTaskModeChanged can only be called by system"); } synchronized (this) { Loading Loading @@ -8180,7 +8226,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return null; } Preconditions.checkNotNull(who, "ComponentName is null"); if (!UserHandle.isSameApp(mInjector.binderGetCallingUid(), Process.SYSTEM_UID)) { if (!isCallerWithSystemUid()) { throw new SecurityException("Only the system can query support message for user"); } synchronized (this) { Loading @@ -8198,7 +8244,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return null; } Preconditions.checkNotNull(who, "ComponentName is null"); if (!UserHandle.isSameApp(mInjector.binderGetCallingUid(), Process.SYSTEM_UID)) { if (!isCallerWithSystemUid()) { throw new SecurityException("Only the system can query support message for user"); } synchronized (this) { Loading Loading
core/java/android/app/admin/DevicePolicyManager.java +45 −0 Original line number Diff line number Diff line Loading @@ -4108,6 +4108,29 @@ public class DevicePolicyManager { return null; } /** * Called by the system to check if a specific accessibility service is disabled by admin. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. * @param packageName Accessibility service package name that needs to be checked. * @param userHandle user id the admin is running as. * @return true if the accessibility service is permitted, otherwise false. * * @hide */ public boolean isAccessibilityServicePermittedByAdmin(@NonNull ComponentName admin, @NonNull String packageName, int userHandle) { if (mService != null) { try { return mService.isAccessibilityServicePermittedByAdmin(admin, packageName, userHandle); } catch (RemoteException e) { Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e); } } return false; } /** * Returns the list of accessibility services permitted by the device or profiles * owners of this user. Loading Loading @@ -4187,6 +4210,28 @@ public class DevicePolicyManager { return null; } /** * Called by the system to check if a specific input method is disabled by admin. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. * @param packageName Input method package name that needs to be checked. * @param userHandle user id the admin is running as. * @return true if the input method is permitted, otherwise false. * * @hide */ public boolean isInputMethodPermittedByAdmin(@NonNull ComponentName admin, @NonNull String packageName, int userHandle) { if (mService != null) { try { return mService.isInputMethodPermittedByAdmin(admin, packageName, userHandle); } catch (RemoteException e) { Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e); } } return false; } /** * Returns the list of input methods permitted by the device or profiles * owners of the current user. (*Not* calling user, due to a limitation in InputMethodManager.) Loading
core/java/android/app/admin/IDevicePolicyManager.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -174,10 +174,12 @@ interface IDevicePolicyManager { boolean setPermittedAccessibilityServices(in ComponentName admin,in List packageList); List getPermittedAccessibilityServices(in ComponentName admin); List getPermittedAccessibilityServicesForUser(int userId); boolean isAccessibilityServicePermittedByAdmin(in ComponentName admin, String packageName, int userId); boolean setPermittedInputMethods(in ComponentName admin,in List packageList); List getPermittedInputMethods(in ComponentName admin); List getPermittedInputMethodsForCurrentUser(); boolean isInputMethodPermittedByAdmin(in ComponentName admin, String packageName, int userId); boolean setApplicationHidden(in ComponentName admin, in String packageName, boolean hidden); boolean isApplicationHidden(in ComponentName admin, in String packageName); Loading
packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java +152 −43 Original line number Diff line number Diff line Loading @@ -155,7 +155,7 @@ public class RestrictedLockUtils { for (UserInfo userInfo : um.getProfiles(userId)) { final List<ComponentName> admins = dpm.getActiveAdminsAsUser(userInfo.id); if (admins == null) { return null; continue; } final boolean isSeparateProfileChallengeEnabled = lockPatternUtils.isSeparateProfileChallengeEnabled(userInfo.id); Loading Loading @@ -209,16 +209,7 @@ public class RestrictedLockUtils { IPackageManager ipm = AppGlobals.getPackageManager(); try { if (ipm.getBlockUninstallForUser(packageName, userId)) { DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService( Context.DEVICE_POLICY_SERVICE); if (dpm == null) { return null; } ComponentName admin = dpm.getProfileOwner(); if (admin == null) { admin = dpm.getDeviceOwnerComponentOnCallingUser(); } return new EnforcedAdmin(admin, UserHandle.myUserId()); return getProfileOrDeviceOwner(context, userId); } } catch (RemoteException e) { // Nothing to do Loading @@ -238,7 +229,7 @@ public class RestrictedLockUtils { try { ApplicationInfo ai = ipm.getApplicationInfo(packageName, 0, userId); if (ai != null && ((ai.flags & ApplicationInfo.FLAG_SUSPENDED) != 0)) { return getProfileOrDeviceOwnerOnCallingUser(context); return getProfileOrDeviceOwner(context, userId); } } catch (RemoteException e) { // Nothing to do Loading @@ -246,6 +237,80 @@ public class RestrictedLockUtils { return null; } public static EnforcedAdmin checkIfInputMethodDisallowed(Context context, String packageName, int userId) { DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService( Context.DEVICE_POLICY_SERVICE); if (dpm == null) { return null; } EnforcedAdmin admin = getProfileOrDeviceOwner(context, userId); boolean permitted = true; if (admin != null) { permitted = dpm.isInputMethodPermittedByAdmin(admin.component, packageName, userId); } int managedProfileId = getManagedProfileId(context, userId); EnforcedAdmin profileAdmin = getProfileOrDeviceOwner(context, managedProfileId); boolean permittedByProfileAdmin = true; if (profileAdmin != null) { permittedByProfileAdmin = dpm.isInputMethodPermittedByAdmin(profileAdmin.component, packageName, managedProfileId); } if (!permitted && !permittedByProfileAdmin) { return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN; } else if (!permitted) { return admin; } else if (!permittedByProfileAdmin) { return profileAdmin; } return null; } public static EnforcedAdmin checkIfAccessibilityServiceDisallowed(Context context, String packageName, int userId) { DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService( Context.DEVICE_POLICY_SERVICE); if (dpm == null) { return null; } EnforcedAdmin admin = getProfileOrDeviceOwner(context, userId); boolean permitted = true; if (admin != null) { permitted = dpm.isAccessibilityServicePermittedByAdmin(admin.component, packageName, userId); } int managedProfileId = getManagedProfileId(context, userId); EnforcedAdmin profileAdmin = getProfileOrDeviceOwner(context, managedProfileId); boolean permittedByProfileAdmin = true; if (profileAdmin != null) { permittedByProfileAdmin = dpm.isAccessibilityServicePermittedByAdmin( profileAdmin.component, packageName, managedProfileId); } if (!permitted && !permittedByProfileAdmin) { return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN; } else if (!permitted) { return admin; } else if (!permittedByProfileAdmin) { return profileAdmin; } return null; } private static int getManagedProfileId(Context context, int userId) { UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); List<UserInfo> userProfiles = um.getProfiles(userId); for (UserInfo uInfo : userProfiles) { if (uInfo.id == userId) { continue; } if (uInfo.isManagedProfile()) { return uInfo.id; } } return UserHandle.USER_NULL; } /** * Check if account management for a specific type of account is disabled by admin. * Only a profile or device owner can disable account management. So, we check if account Loading @@ -255,7 +320,7 @@ public class RestrictedLockUtils { * or {@code null} if the account management is not disabled. */ public static EnforcedAdmin checkIfAccountManagementDisabled(Context context, String accountType) { String accountType, int userId) { if (accountType == null) { return null; } Loading @@ -265,7 +330,7 @@ public class RestrictedLockUtils { return null; } boolean isAccountTypeDisabled = false; String[] disabledTypes = dpm.getAccountTypesWithManagementDisabled(); String[] disabledTypes = dpm.getAccountTypesWithManagementDisabledAsUser(userId); for (String type : disabledTypes) { if (accountType.equals(type)) { isAccountTypeDisabled = true; Loading @@ -275,7 +340,7 @@ public class RestrictedLockUtils { if (!isAccountTypeDisabled) { return null; } return getProfileOrDeviceOwnerOnCallingUser(context); return getProfileOrDeviceOwner(context, userId); } /** Loading @@ -296,7 +361,7 @@ public class RestrictedLockUtils { } /** * Checks if an admin has enforced minimum password quality requirements on the device. * Checks if an admin has enforced minimum password quality requirements on the given user. * * @return EnforcedAdmin Object containing the enforced admin component and admin user details, * or {@code null} if no quality requirements are set. If the requirements are set by Loading @@ -304,35 +369,73 @@ public class RestrictedLockUtils { * {@link UserHandle#USER_NULL}. * */ public static EnforcedAdmin checkIfPasswordQualityIsSet(Context context) { public static EnforcedAdmin checkIfPasswordQualityIsSet(Context context, int userId) { final DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService( Context.DEVICE_POLICY_SERVICE); if (dpm == null) { return null; } boolean isDisabledByMultipleAdmins = false; ComponentName adminComponent = null; List<ComponentName> admins = dpm.getActiveAdmins(); int quality; if (admins != null) { LockPatternUtils lockPatternUtils = new LockPatternUtils(context); EnforcedAdmin enforcedAdmin = null; if (lockPatternUtils.isSeparateProfileChallengeEnabled(userId)) { // userId is managed profile and has a separate challenge, only consider // the admins in that user. final List<ComponentName> admins = dpm.getActiveAdminsAsUser(userId); if (admins == null) { return null; } for (ComponentName admin : admins) { quality = dpm.getPasswordQuality(admin); if (quality >= DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { if (adminComponent == null) { adminComponent = admin; if (dpm.getPasswordQuality(admin, userId) > DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { if (enforcedAdmin == null) { enforcedAdmin = new EnforcedAdmin(admin, userId); } else { isDisabledByMultipleAdmins = true; break; return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN; } } } } else { // Return all admins for this user and the profiles that are visible from this // user that do not use a separate work challenge. final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); for (UserInfo userInfo : um.getProfiles(userId)) { final List<ComponentName> admins = dpm.getActiveAdminsAsUser(userInfo.id); if (admins == null) { continue; } EnforcedAdmin enforcedAdmin = null; if (adminComponent != null) { if (!isDisabledByMultipleAdmins) { enforcedAdmin = new EnforcedAdmin(adminComponent, UserHandle.myUserId()); final boolean isSeparateProfileChallengeEnabled = lockPatternUtils.isSeparateProfileChallengeEnabled(userInfo.id); for (ComponentName admin : admins) { if (!isSeparateProfileChallengeEnabled) { if (dpm.getPasswordQuality(admin, userInfo.id) > DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { if (enforcedAdmin == null) { enforcedAdmin = new EnforcedAdmin(admin, userInfo.id); } else { return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN; } // This same admins could have set policies both on the managed profile // and on the parent. So, if the admin has set the policy on the // managed profile here, we don't need to further check if that admin // has set policy on the parent admin. continue; } } if (userInfo.isManagedProfile()) { // If userInfo.id is a managed profile, we also need to look at // the policies set on the parent. DevicePolicyManager parentDpm = dpm.getParentProfileInstance(userInfo); if (parentDpm.getPasswordQuality(admin, userInfo.id) > DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { if (enforcedAdmin == null) { enforcedAdmin = new EnforcedAdmin(admin, userInfo.id); } else { enforcedAdmin = new EnforcedAdmin(); return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN; } } } } } } return enforcedAdmin; Loading @@ -352,7 +455,8 @@ public class RestrictedLockUtils { EnforcedAdmin enforcedAdmin = null; final int userId = UserHandle.myUserId(); if (lockPatternUtils.isSeparateProfileChallengeEnabled(userId)) { // If the user has a separate challenge, only consider the admins in that user. // userId is managed profile and has a separate challenge, only consider // the admins in that user. final List<ComponentName> admins = dpm.getActiveAdminsAsUser(userId); if (admins == null) { return null; Loading @@ -373,7 +477,7 @@ public class RestrictedLockUtils { for (UserInfo userInfo : um.getProfiles(userId)) { final List<ComponentName> admins = dpm.getActiveAdminsAsUser(userInfo.id); if (admins == null) { return null; continue; } final boolean isSeparateProfileChallengeEnabled = lockPatternUtils.isSeparateProfileChallengeEnabled(userInfo.id); Loading Loading @@ -410,19 +514,24 @@ public class RestrictedLockUtils { return enforcedAdmin; } public static EnforcedAdmin getProfileOrDeviceOwnerOnCallingUser(Context context) { public static EnforcedAdmin getProfileOrDeviceOwner(Context context, int userId) { if (userId == UserHandle.USER_NULL) { return null; } final DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService( Context.DEVICE_POLICY_SERVICE); if (dpm == null) { return null; } ComponentName adminComponent = dpm.getDeviceOwnerComponentOnCallingUser(); ComponentName adminComponent = dpm.getProfileOwnerAsUser(userId); if (adminComponent != null) { return new EnforcedAdmin(adminComponent, UserHandle.myUserId()); return new EnforcedAdmin(adminComponent, userId); } adminComponent = dpm.getProfileOwner(); if (dpm.getDeviceOwnerUserId() == userId) { adminComponent = dpm.getDeviceOwnerComponentOnAnyUser(); if (adminComponent != null) { return new EnforcedAdmin(adminComponent, UserHandle.myUserId()); return new EnforcedAdmin(adminComponent, userId); } } return null; } Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +61 −15 Original line number Diff line number Diff line Loading @@ -4132,7 +4132,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { public void choosePrivateKeyAlias(final int uid, final Uri uri, final String alias, final IBinder response) { // Caller UID needs to be trusted, so we restrict this method to SYSTEM_UID callers. if (!UserHandle.isSameApp(mInjector.binderGetCallingUid(), Process.SYSTEM_UID)) { if (!isCallerWithSystemUid()) { return; } Loading Loading @@ -5860,8 +5860,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } mContext.enforceCallingOrSelfPermission( android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS, null); if (hasUserSetupCompleted(userHandle) && !UserHandle.isSameApp(callingUid, Process.SYSTEM_UID)) { if (hasUserSetupCompleted(userHandle) && !isCallerWithSystemUid()) { throw new IllegalStateException("Cannot set the profile owner on a user which is " + "already set-up"); } Loading Loading @@ -5921,8 +5920,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private void enforceManageUsers() { final int callingUid = mInjector.binderGetCallingUid(); if (!(UserHandle.isSameApp(callingUid, Process.SYSTEM_UID) || callingUid == Process.ROOT_UID)) { if (!(isCallerWithSystemUid() || callingUid == Process.ROOT_UID)) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); } } Loading @@ -5945,8 +5943,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (userHandle == UserHandle.getUserId(callingUid)) { return; } if (!(UserHandle.isSameApp(callingUid, Process.SYSTEM_UID) || callingUid == Process.ROOT_UID)) { if (!(isCallerWithSystemUid() || callingUid == Process.ROOT_UID)) { mContext.enforceCallingOrSelfPermission(permission, "Must be system or have " + permission + " permission"); } Loading @@ -5964,6 +5961,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } private boolean isCallerWithSystemUid() { return UserHandle.isSameApp(mInjector.binderGetCallingUid(), Process.SYSTEM_UID); } private int getProfileParentId(int userHandle) { final long ident = mInjector.binderClearCallingIdentity(); try { Loading Loading @@ -6248,7 +6249,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public ComponentName getRestrictionsProvider(int userHandle) { synchronized (this) { if (!UserHandle.isSameApp(mInjector.binderGetCallingUid(), Process.SYSTEM_UID)) { if (!isCallerWithSystemUid()) { throw new SecurityException("Only the system can query the permission provider"); } DevicePolicyData userData = getUserData(userHandle); Loading Loading @@ -6321,8 +6322,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { * permittedList or are a system app. */ private boolean checkPackagesInPermittedListOrSystem(List<String> enabledPackages, List<String> permittedList) { int userIdToCheck = UserHandle.getCallingUserId(); List<String> permittedList, int userIdToCheck) { long id = mInjector.binderClearCallingIdentity(); try { // If we have an enabled packages list for a managed profile the packages Loading Loading @@ -6389,7 +6389,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { for (AccessibilityServiceInfo service : enabledServices) { enabledPackages.add(service.getResolveInfo().serviceInfo.packageName); } if (!checkPackagesInPermittedListOrSystem(enabledPackages, packageList)) { if (!checkPackagesInPermittedListOrSystem(enabledPackages, packageList, userId)) { Slog.e(LOG_TAG, "Cannot set permitted accessibility services, " + "because it contains already enabled accesibility services."); return false; Loading Loading @@ -6481,6 +6482,28 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } @Override public boolean isAccessibilityServicePermittedByAdmin(ComponentName who, String packageName, int userHandle) { if (!mHasFeature) { return true; } Preconditions.checkNotNull(who, "ComponentName is null"); Preconditions.checkStringNotEmpty(packageName, "packageName is null"); if (!isCallerWithSystemUid()){ throw new SecurityException( "Only the system can query if an accessibility service is disabled by admin"); } synchronized (this) { ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle); if (admin.permittedAccessiblityServices == null) { return true; } return checkPackagesInPermittedListOrSystem(Arrays.asList(packageName), admin.permittedAccessiblityServices, userHandle); } } private boolean checkCallerIsCurrentUserOrProfile() { int callingUserId = UserHandle.getCallingUserId(); long token = mInjector.binderClearCallingIdentity(); Loading Loading @@ -6536,7 +6559,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { for (InputMethodInfo ime : enabledImes) { enabledPackages.add(ime.getPackageName()); } if (!checkPackagesInPermittedListOrSystem(enabledPackages, packageList)) { if (!checkPackagesInPermittedListOrSystem(enabledPackages, packageList, mInjector.binderGetCallingUserHandle().getIdentifier())) { Slog.e(LOG_TAG, "Cannot set permitted input methods, " + "because it contains already enabled input method."); return false; Loading Loading @@ -6628,6 +6652,28 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } @Override public boolean isInputMethodPermittedByAdmin(ComponentName who, String packageName, int userHandle) { if (!mHasFeature) { return true; } Preconditions.checkNotNull(who, "ComponentName is null"); Preconditions.checkStringNotEmpty(packageName, "packageName is null"); if (!isCallerWithSystemUid()) { throw new SecurityException( "Only the system can query if an input method is disabled by admin"); } synchronized (this) { ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle); if (admin.permittedInputMethods == null) { return true; } return checkPackagesInPermittedListOrSystem(Arrays.asList(packageName), admin.permittedInputMethods, userHandle); } } @Override public UserHandle createUser(ComponentName who, String name) { Preconditions.checkNotNull(who, "ComponentName is null"); Loading Loading @@ -7425,7 +7471,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public void notifyLockTaskModeChanged(boolean isEnabled, String pkg, int userHandle) { if (!UserHandle.isSameApp(mInjector.binderGetCallingUid(), Process.SYSTEM_UID)) { if (!isCallerWithSystemUid()) { throw new SecurityException("notifyLockTaskModeChanged can only be called by system"); } synchronized (this) { Loading Loading @@ -8180,7 +8226,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return null; } Preconditions.checkNotNull(who, "ComponentName is null"); if (!UserHandle.isSameApp(mInjector.binderGetCallingUid(), Process.SYSTEM_UID)) { if (!isCallerWithSystemUid()) { throw new SecurityException("Only the system can query support message for user"); } synchronized (this) { Loading @@ -8198,7 +8244,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return null; } Preconditions.checkNotNull(who, "ComponentName is null"); if (!UserHandle.isSameApp(mInjector.binderGetCallingUid(), Process.SYSTEM_UID)) { if (!isCallerWithSystemUid()) { throw new SecurityException("Only the system can query support message for user"); } synchronized (this) { Loading