Loading core/java/android/app/admin/DevicePolicyManager.java +57 −1 Original line number Diff line number Diff line Loading @@ -11963,6 +11963,34 @@ public class DevicePolicyManager { } } /** * Adds a user restriction on {@code targetUser}, specified by the {@code key}. * * <p>Called by a system service only, meaning that the caller's UID must be equal to * {@link Process#SYSTEM_UID}. * * @param systemEntity The service entity that adds the restriction. A user restriction set by * a service entity can only be cleared by the same entity. This can be * just the calling package name, or any string of the caller's choice * can be used. * @param key The key of the restriction. * @param targetUser The user to add the restriction on. * @throws SecurityException if the caller is not a system service * * @hide */ public void addUserRestriction(@NonNull String systemEntity, @NonNull @UserManager.UserRestrictionKey String key, @UserIdInt int targetUser) { if (mService != null) { try { mService.setUserRestrictionForUser( systemEntity, key, /* enable= */ true, targetUser); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } /** * Called by a profile owner, device owner or a holder of any permission that is associated with * a user restriction to set a user restriction specified by the provided {@code key} globally Loading @@ -11971,7 +11999,7 @@ public class DevicePolicyManager { * <p>For a given user, a restriction will be set if it was applied globally or locally by any * admin. * * <p> The calling device admin must be a profile owner, device owner or or a holder of any * <p> The calling device admin must be a profile owner, device owner or a holder of any * permission that is associated with a user restriction; if it is not, a security * exception will be thrown. * Loading Loading @@ -12071,6 +12099,34 @@ public class DevicePolicyManager { } } /** * Clears a user restriction from {@code targetUser}, specified by the {@code key}. * * <p>Called by a system service only, meaning that the caller's UID must be equal to * {@link Process#SYSTEM_UID}. * * @param systemEntity The system entity that clears the restriction. A user restriction * set by a system entity can only be cleared by the same entity. This * can be just the calling package name, or any string of the caller's * choice can be used. * @param key The key of the restriction. * @param targetUser The user to clear the restriction from. * @throws SecurityException if the caller is not a system service * * @hide */ public void clearUserRestriction(@NonNull String systemEntity, @NonNull @UserManager.UserRestrictionKey String key, @UserIdInt int targetUser) { if (mService != null) { try { mService.setUserRestrictionForUser( systemEntity, key, /* enable= */ false, targetUser); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } /** * Called by an admin to get user restrictions set by themselves with * {@link #addUserRestriction(ComponentName, String)}. core/java/android/app/admin/IDevicePolicyManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -255,6 +255,7 @@ interface IDevicePolicyManager { ComponentName getRestrictionsProvider(int userHandle); void setUserRestriction(in ComponentName who, in String callerPackage, in String key, boolean enable, boolean parent); void setUserRestrictionForUser(in String systemEntity, in String key, boolean enable, int targetUser); void setUserRestrictionGlobally(in String callerPackage, in String key); Bundle getUserRestrictions(in ComponentName who, in String callerPackage, boolean parent); Bundle getUserRestrictionsGlobally(in String callerPackage); Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +28 −5 Original line number Diff line number Diff line Loading @@ -13634,7 +13634,28 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { setBackwardCompatibleUserRestriction( caller, admin, key, enabledFromThisOwner, parent); } logUserRestrictionCall(key, enabledFromThisOwner, parent, caller); logUserRestrictionCall(key, enabledFromThisOwner, parent, caller, affectedUserId); } @Override public void setUserRestrictionForUser( @NonNull String systemEntity, String key, boolean enabled, @UserIdInt int targetUser) { Objects.requireNonNull(systemEntity); CallerIdentity caller = getCallerIdentity(); if (caller.getUid() != Process.SYSTEM_UID) { throw new SecurityException("Only system services can call setUserRestrictionForUser" + " on a target user: " + targetUser); } if (VERBOSE_LOG) { Slogf.v(LOG_TAG, "Creating SystemEnforcingAdmin %s for calling package %s", systemEntity, caller.getPackageName()); } EnforcingAdmin admin = EnforcingAdmin.createSystemEnforcingAdmin(systemEntity); setLocalUserRestrictionInternal(admin, key, enabled, targetUser); logUserRestrictionCall(key, enabled, /* parent= */ false, caller, targetUser); } private void checkAdminCanSetRestriction(CallerIdentity caller, boolean parent, String key) { Loading Loading @@ -13755,7 +13776,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { setGlobalUserRestrictionInternal(admin, key, /* enabled= */ true); logUserRestrictionCall(key, /* enabled= */ true, /* parent= */ false, caller); logUserRestrictionCall(key, /* enabled= */ true, /* parent= */ false, caller, UserHandle.USER_ALL); } private void setLocalUserRestrictionInternal( EnforcingAdmin admin, String key, boolean enabled, int userId) { Loading Loading @@ -13791,7 +13813,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } private void logUserRestrictionCall( String key, boolean enabled, boolean parent, CallerIdentity caller) { String key, boolean enabled, boolean parent, CallerIdentity caller, int targetUserId) { final int eventId = enabled ? DevicePolicyEnums.ADD_USER_RESTRICTION : DevicePolicyEnums.REMOVE_USER_RESTRICTION; Loading @@ -13807,8 +13829,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { SecurityLog.writeEvent(eventTag, caller.getPackageName(), caller.getUserId(), key); } Slogf.i(LOG_TAG, "Changing user restriction %s to: %b caller: %s", key, enabled, caller.toString()); Slogf.i(LOG_TAG, "Changing user restriction %s on %s to: %b caller: %s", key, (targetUserId == UserHandle.USER_ALL ? "all users" : ("user " + targetUserId)), enabled, caller.toString()); } @Override services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java +70 −3 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import android.annotation.Nullable; import android.app.admin.Authority; import android.app.admin.DeviceAdminAuthority; import android.app.admin.DpcAuthority; import android.app.admin.PackagePermissionPolicyKey; import android.app.admin.RoleAuthority; import android.app.admin.UnknownAuthority; import android.content.ComponentName; Loading Loading @@ -57,23 +56,29 @@ final class EnforcingAdmin { static final String TAG = "EnforcingAdmin"; static final String ROLE_AUTHORITY_PREFIX = "role:"; static final String SYSTEM_AUTHORITY_PREFIX = "system:"; static final String DPC_AUTHORITY = "enterprise"; static final String DEVICE_ADMIN_AUTHORITY = "device_admin"; static final String DEFAULT_AUTHORITY = "default"; private static final String ATTR_PACKAGE_NAME = "package-name"; private static final String ATTR_SYSTEM_ENTITY = "system-entity"; private static final String ATTR_CLASS_NAME = "class-name"; private static final String ATTR_AUTHORITIES = "authorities"; private static final String ATTR_AUTHORITIES_SEPARATOR = ";"; private static final String ATTR_USER_ID = "user-id"; private static final String ATTR_IS_ROLE = "is-role"; private static final String ATTR_IS_SYSTEM = "is-system"; private final String mPackageName; // Name of the system entity. Only used when mIsSystemAuthority is true. private final String mSystemEntity; // This is needed for DPCs and active admins private final ComponentName mComponentName; private Set<String> mAuthorities; private final int mUserId; private final boolean mIsRoleAuthority; private final boolean mIsSystemAuthority; private final ActiveAdmin mActiveAdmin; static EnforcingAdmin createEnforcingAdmin(@NonNull String packageName, int userId, Loading Loading @@ -106,6 +111,11 @@ final class EnforcingAdmin { userId, activeAdmin); } static EnforcingAdmin createSystemEnforcingAdmin(@NonNull String systemEntity) { Objects.requireNonNull(systemEntity); return new EnforcingAdmin(systemEntity); } static EnforcingAdmin createEnforcingAdmin(android.app.admin.EnforcingAdmin admin) { Objects.requireNonNull(admin); Authority authority = admin.getAuthority(); Loading @@ -127,6 +137,7 @@ final class EnforcingAdmin { /* activeAdmin = */ null, /* isRoleAuthority = */ true); } // TODO(b/324899199): Consider supporting android.app.admin.SystemAuthority. return new EnforcingAdmin(admin.getPackageName(), admin.getComponentName(), Set.of(), admin.getUserHandle().getIdentifier(), /* activeAdmin = */ null); Loading Loading @@ -159,9 +170,11 @@ final class EnforcingAdmin { Objects.requireNonNull(packageName); Objects.requireNonNull(authorities); // Role authorities should not be using this constructor // Role/System authorities should not be using this constructor mIsRoleAuthority = false; mIsSystemAuthority = false; mPackageName = packageName; mSystemEntity = null; mComponentName = componentName; mAuthorities = new HashSet<>(authorities); mUserId = userId; Loading @@ -173,7 +186,9 @@ final class EnforcingAdmin { // Only role authorities use this constructor. mIsRoleAuthority = true; mIsSystemAuthority = false; mPackageName = packageName; mSystemEntity = null; mUserId = userId; mComponentName = null; // authorities will be loaded when needed Loading @@ -181,6 +196,21 @@ final class EnforcingAdmin { mActiveAdmin = activeAdmin; } /** Constructor for System authorities. */ private EnforcingAdmin(@NonNull String systemEntity) { Objects.requireNonNull(systemEntity); // Only system authorities use this constructor. mIsSystemAuthority = true; mIsRoleAuthority = false; mPackageName = null; mSystemEntity = systemEntity; mUserId = UserHandle.USER_SYSTEM; mComponentName = null; mAuthorities = getSystemAuthority(systemEntity); mActiveAdmin = null; } private EnforcingAdmin( String packageName, @Nullable ComponentName componentName, Set<String> authorities, int userId, @Nullable ActiveAdmin activeAdmin, boolean isRoleAuthority) { Loading @@ -188,7 +218,9 @@ final class EnforcingAdmin { Objects.requireNonNull(authorities); mIsRoleAuthority = isRoleAuthority; mIsSystemAuthority = false; mPackageName = packageName; mSystemEntity = null; mComponentName = componentName; mAuthorities = new HashSet<>(authorities); mUserId = userId; Loading @@ -204,6 +236,18 @@ final class EnforcingAdmin { return authorities.isEmpty() ? Set.of(DEFAULT_AUTHORITY) : authorities; } /** * Returns a set of authorities for system authority. * * <p>Note that a system authority enforcing admin has only one authority that has the package * name of the calling system service. Therefore, the returned set always contains one element. */ private static Set<String> getSystemAuthority(String systemEntity) { Set<String> authorities = new HashSet<>(); authorities.add(SYSTEM_AUTHORITY_PREFIX + systemEntity); return authorities; } // TODO(b/259042794): move this logic to RoleManagerLocal private static Set<String> getRoles(String packageName, int userId) { RoleManagerLocal roleManagerLocal = LocalManagerRegistry.getManager( Loading Loading @@ -264,6 +308,7 @@ final class EnforcingAdmin { } else if (mAuthorities.contains(DEVICE_ADMIN_AUTHORITY)) { authority = DeviceAdminAuthority.DEVICE_ADMIN_AUTHORITY; } else { // For now, System Authority returns UNKNOWN_AUTHORITY. authority = UnknownAuthority.UNKNOWN_AUTHORITY; } return new android.app.admin.EnforcingAdmin( Loading Loading @@ -291,8 +336,10 @@ final class EnforcingAdmin { if (o == null || getClass() != o.getClass()) return false; EnforcingAdmin other = (EnforcingAdmin) o; return Objects.equals(mPackageName, other.mPackageName) && Objects.equals(mSystemEntity, other.mSystemEntity) && Objects.equals(mComponentName, other.mComponentName) && Objects.equals(mIsRoleAuthority, other.mIsRoleAuthority) && (mIsSystemAuthority == other.mIsSystemAuthority) && hasMatchingAuthorities(this, other); } Loading @@ -307,6 +354,8 @@ final class EnforcingAdmin { public int hashCode() { if (mIsRoleAuthority) { return Objects.hash(mPackageName, mUserId); } else if (mIsSystemAuthority) { return Objects.hash(mSystemEntity); } else { return Objects.hash( mComponentName == null ? mPackageName : mComponentName, Loading @@ -318,8 +367,12 @@ final class EnforcingAdmin { void saveToXml(TypedXmlSerializer serializer) throws IOException { serializer.attribute(/* namespace= */ null, ATTR_PACKAGE_NAME, mPackageName); serializer.attributeBoolean(/* namespace= */ null, ATTR_IS_ROLE, mIsRoleAuthority); serializer.attributeBoolean(/* namespace= */ null, ATTR_IS_SYSTEM, mIsSystemAuthority); serializer.attributeInt(/* namespace= */ null, ATTR_USER_ID, mUserId); if (!mIsRoleAuthority) { if (mIsSystemAuthority) { serializer.attribute(/* namespace= */ null, ATTR_SYSTEM_ENTITY, mSystemEntity); } if (!mIsRoleAuthority && !mIsSystemAuthority) { if (mComponentName != null) { serializer.attribute( /* namespace= */ null, ATTR_CLASS_NAME, mComponentName.getClassName()); Loading @@ -336,7 +389,10 @@ final class EnforcingAdmin { static EnforcingAdmin readFromXml(TypedXmlPullParser parser) throws XmlPullParserException { String packageName = parser.getAttributeValue(/* namespace= */ null, ATTR_PACKAGE_NAME); String systemEntity = parser.getAttributeValue(/* namespace= */ null, ATTR_SYSTEM_ENTITY); boolean isRoleAuthority = parser.getAttributeBoolean(/* namespace= */ null, ATTR_IS_ROLE); boolean isSystemAuthority = parser.getAttributeBoolean( /* namespace= */ null, ATTR_IS_SYSTEM, /* defaultValue= */ false); String authoritiesStr = parser.getAttributeValue(/* namespace= */ null, ATTR_AUTHORITIES); int userId = parser.getAttributeInt(/* namespace= */ null, ATTR_USER_ID); Loading @@ -348,6 +404,13 @@ final class EnforcingAdmin { } // TODO(b/281697976): load active admin return new EnforcingAdmin(packageName, userId, null); } else if (isSystemAuthority) { if (systemEntity == null) { Slogf.wtf(TAG, "Error parsing EnforcingAdmin with SystemAuthority, " + "systemEntity is null."); return null; } return new EnforcingAdmin(systemEntity); } else { if (packageName == null || authoritiesStr == null) { Slogf.wtf(TAG, "Error parsing EnforcingAdmin, packageName is " Loading Loading @@ -381,6 +444,10 @@ final class EnforcingAdmin { sb.append(mUserId); sb.append(", mIsRoleAuthority= "); sb.append(mIsRoleAuthority); sb.append(", mIsSystemAuthority= "); sb.append(mIsSystemAuthority); sb.append(", mSystemEntity = "); sb.append(mSystemEntity); sb.append(" }"); return sb.toString(); } Loading Loading
core/java/android/app/admin/DevicePolicyManager.java +57 −1 Original line number Diff line number Diff line Loading @@ -11963,6 +11963,34 @@ public class DevicePolicyManager { } } /** * Adds a user restriction on {@code targetUser}, specified by the {@code key}. * * <p>Called by a system service only, meaning that the caller's UID must be equal to * {@link Process#SYSTEM_UID}. * * @param systemEntity The service entity that adds the restriction. A user restriction set by * a service entity can only be cleared by the same entity. This can be * just the calling package name, or any string of the caller's choice * can be used. * @param key The key of the restriction. * @param targetUser The user to add the restriction on. * @throws SecurityException if the caller is not a system service * * @hide */ public void addUserRestriction(@NonNull String systemEntity, @NonNull @UserManager.UserRestrictionKey String key, @UserIdInt int targetUser) { if (mService != null) { try { mService.setUserRestrictionForUser( systemEntity, key, /* enable= */ true, targetUser); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } /** * Called by a profile owner, device owner or a holder of any permission that is associated with * a user restriction to set a user restriction specified by the provided {@code key} globally Loading @@ -11971,7 +11999,7 @@ public class DevicePolicyManager { * <p>For a given user, a restriction will be set if it was applied globally or locally by any * admin. * * <p> The calling device admin must be a profile owner, device owner or or a holder of any * <p> The calling device admin must be a profile owner, device owner or a holder of any * permission that is associated with a user restriction; if it is not, a security * exception will be thrown. * Loading Loading @@ -12071,6 +12099,34 @@ public class DevicePolicyManager { } } /** * Clears a user restriction from {@code targetUser}, specified by the {@code key}. * * <p>Called by a system service only, meaning that the caller's UID must be equal to * {@link Process#SYSTEM_UID}. * * @param systemEntity The system entity that clears the restriction. A user restriction * set by a system entity can only be cleared by the same entity. This * can be just the calling package name, or any string of the caller's * choice can be used. * @param key The key of the restriction. * @param targetUser The user to clear the restriction from. * @throws SecurityException if the caller is not a system service * * @hide */ public void clearUserRestriction(@NonNull String systemEntity, @NonNull @UserManager.UserRestrictionKey String key, @UserIdInt int targetUser) { if (mService != null) { try { mService.setUserRestrictionForUser( systemEntity, key, /* enable= */ false, targetUser); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } /** * Called by an admin to get user restrictions set by themselves with * {@link #addUserRestriction(ComponentName, String)}.
core/java/android/app/admin/IDevicePolicyManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -255,6 +255,7 @@ interface IDevicePolicyManager { ComponentName getRestrictionsProvider(int userHandle); void setUserRestriction(in ComponentName who, in String callerPackage, in String key, boolean enable, boolean parent); void setUserRestrictionForUser(in String systemEntity, in String key, boolean enable, int targetUser); void setUserRestrictionGlobally(in String callerPackage, in String key); Bundle getUserRestrictions(in ComponentName who, in String callerPackage, boolean parent); Bundle getUserRestrictionsGlobally(in String callerPackage); Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +28 −5 Original line number Diff line number Diff line Loading @@ -13634,7 +13634,28 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { setBackwardCompatibleUserRestriction( caller, admin, key, enabledFromThisOwner, parent); } logUserRestrictionCall(key, enabledFromThisOwner, parent, caller); logUserRestrictionCall(key, enabledFromThisOwner, parent, caller, affectedUserId); } @Override public void setUserRestrictionForUser( @NonNull String systemEntity, String key, boolean enabled, @UserIdInt int targetUser) { Objects.requireNonNull(systemEntity); CallerIdentity caller = getCallerIdentity(); if (caller.getUid() != Process.SYSTEM_UID) { throw new SecurityException("Only system services can call setUserRestrictionForUser" + " on a target user: " + targetUser); } if (VERBOSE_LOG) { Slogf.v(LOG_TAG, "Creating SystemEnforcingAdmin %s for calling package %s", systemEntity, caller.getPackageName()); } EnforcingAdmin admin = EnforcingAdmin.createSystemEnforcingAdmin(systemEntity); setLocalUserRestrictionInternal(admin, key, enabled, targetUser); logUserRestrictionCall(key, enabled, /* parent= */ false, caller, targetUser); } private void checkAdminCanSetRestriction(CallerIdentity caller, boolean parent, String key) { Loading Loading @@ -13755,7 +13776,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { setGlobalUserRestrictionInternal(admin, key, /* enabled= */ true); logUserRestrictionCall(key, /* enabled= */ true, /* parent= */ false, caller); logUserRestrictionCall(key, /* enabled= */ true, /* parent= */ false, caller, UserHandle.USER_ALL); } private void setLocalUserRestrictionInternal( EnforcingAdmin admin, String key, boolean enabled, int userId) { Loading Loading @@ -13791,7 +13813,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } private void logUserRestrictionCall( String key, boolean enabled, boolean parent, CallerIdentity caller) { String key, boolean enabled, boolean parent, CallerIdentity caller, int targetUserId) { final int eventId = enabled ? DevicePolicyEnums.ADD_USER_RESTRICTION : DevicePolicyEnums.REMOVE_USER_RESTRICTION; Loading @@ -13807,8 +13829,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { SecurityLog.writeEvent(eventTag, caller.getPackageName(), caller.getUserId(), key); } Slogf.i(LOG_TAG, "Changing user restriction %s to: %b caller: %s", key, enabled, caller.toString()); Slogf.i(LOG_TAG, "Changing user restriction %s on %s to: %b caller: %s", key, (targetUserId == UserHandle.USER_ALL ? "all users" : ("user " + targetUserId)), enabled, caller.toString()); } @Override
services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java +70 −3 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import android.annotation.Nullable; import android.app.admin.Authority; import android.app.admin.DeviceAdminAuthority; import android.app.admin.DpcAuthority; import android.app.admin.PackagePermissionPolicyKey; import android.app.admin.RoleAuthority; import android.app.admin.UnknownAuthority; import android.content.ComponentName; Loading Loading @@ -57,23 +56,29 @@ final class EnforcingAdmin { static final String TAG = "EnforcingAdmin"; static final String ROLE_AUTHORITY_PREFIX = "role:"; static final String SYSTEM_AUTHORITY_PREFIX = "system:"; static final String DPC_AUTHORITY = "enterprise"; static final String DEVICE_ADMIN_AUTHORITY = "device_admin"; static final String DEFAULT_AUTHORITY = "default"; private static final String ATTR_PACKAGE_NAME = "package-name"; private static final String ATTR_SYSTEM_ENTITY = "system-entity"; private static final String ATTR_CLASS_NAME = "class-name"; private static final String ATTR_AUTHORITIES = "authorities"; private static final String ATTR_AUTHORITIES_SEPARATOR = ";"; private static final String ATTR_USER_ID = "user-id"; private static final String ATTR_IS_ROLE = "is-role"; private static final String ATTR_IS_SYSTEM = "is-system"; private final String mPackageName; // Name of the system entity. Only used when mIsSystemAuthority is true. private final String mSystemEntity; // This is needed for DPCs and active admins private final ComponentName mComponentName; private Set<String> mAuthorities; private final int mUserId; private final boolean mIsRoleAuthority; private final boolean mIsSystemAuthority; private final ActiveAdmin mActiveAdmin; static EnforcingAdmin createEnforcingAdmin(@NonNull String packageName, int userId, Loading Loading @@ -106,6 +111,11 @@ final class EnforcingAdmin { userId, activeAdmin); } static EnforcingAdmin createSystemEnforcingAdmin(@NonNull String systemEntity) { Objects.requireNonNull(systemEntity); return new EnforcingAdmin(systemEntity); } static EnforcingAdmin createEnforcingAdmin(android.app.admin.EnforcingAdmin admin) { Objects.requireNonNull(admin); Authority authority = admin.getAuthority(); Loading @@ -127,6 +137,7 @@ final class EnforcingAdmin { /* activeAdmin = */ null, /* isRoleAuthority = */ true); } // TODO(b/324899199): Consider supporting android.app.admin.SystemAuthority. return new EnforcingAdmin(admin.getPackageName(), admin.getComponentName(), Set.of(), admin.getUserHandle().getIdentifier(), /* activeAdmin = */ null); Loading Loading @@ -159,9 +170,11 @@ final class EnforcingAdmin { Objects.requireNonNull(packageName); Objects.requireNonNull(authorities); // Role authorities should not be using this constructor // Role/System authorities should not be using this constructor mIsRoleAuthority = false; mIsSystemAuthority = false; mPackageName = packageName; mSystemEntity = null; mComponentName = componentName; mAuthorities = new HashSet<>(authorities); mUserId = userId; Loading @@ -173,7 +186,9 @@ final class EnforcingAdmin { // Only role authorities use this constructor. mIsRoleAuthority = true; mIsSystemAuthority = false; mPackageName = packageName; mSystemEntity = null; mUserId = userId; mComponentName = null; // authorities will be loaded when needed Loading @@ -181,6 +196,21 @@ final class EnforcingAdmin { mActiveAdmin = activeAdmin; } /** Constructor for System authorities. */ private EnforcingAdmin(@NonNull String systemEntity) { Objects.requireNonNull(systemEntity); // Only system authorities use this constructor. mIsSystemAuthority = true; mIsRoleAuthority = false; mPackageName = null; mSystemEntity = systemEntity; mUserId = UserHandle.USER_SYSTEM; mComponentName = null; mAuthorities = getSystemAuthority(systemEntity); mActiveAdmin = null; } private EnforcingAdmin( String packageName, @Nullable ComponentName componentName, Set<String> authorities, int userId, @Nullable ActiveAdmin activeAdmin, boolean isRoleAuthority) { Loading @@ -188,7 +218,9 @@ final class EnforcingAdmin { Objects.requireNonNull(authorities); mIsRoleAuthority = isRoleAuthority; mIsSystemAuthority = false; mPackageName = packageName; mSystemEntity = null; mComponentName = componentName; mAuthorities = new HashSet<>(authorities); mUserId = userId; Loading @@ -204,6 +236,18 @@ final class EnforcingAdmin { return authorities.isEmpty() ? Set.of(DEFAULT_AUTHORITY) : authorities; } /** * Returns a set of authorities for system authority. * * <p>Note that a system authority enforcing admin has only one authority that has the package * name of the calling system service. Therefore, the returned set always contains one element. */ private static Set<String> getSystemAuthority(String systemEntity) { Set<String> authorities = new HashSet<>(); authorities.add(SYSTEM_AUTHORITY_PREFIX + systemEntity); return authorities; } // TODO(b/259042794): move this logic to RoleManagerLocal private static Set<String> getRoles(String packageName, int userId) { RoleManagerLocal roleManagerLocal = LocalManagerRegistry.getManager( Loading Loading @@ -264,6 +308,7 @@ final class EnforcingAdmin { } else if (mAuthorities.contains(DEVICE_ADMIN_AUTHORITY)) { authority = DeviceAdminAuthority.DEVICE_ADMIN_AUTHORITY; } else { // For now, System Authority returns UNKNOWN_AUTHORITY. authority = UnknownAuthority.UNKNOWN_AUTHORITY; } return new android.app.admin.EnforcingAdmin( Loading Loading @@ -291,8 +336,10 @@ final class EnforcingAdmin { if (o == null || getClass() != o.getClass()) return false; EnforcingAdmin other = (EnforcingAdmin) o; return Objects.equals(mPackageName, other.mPackageName) && Objects.equals(mSystemEntity, other.mSystemEntity) && Objects.equals(mComponentName, other.mComponentName) && Objects.equals(mIsRoleAuthority, other.mIsRoleAuthority) && (mIsSystemAuthority == other.mIsSystemAuthority) && hasMatchingAuthorities(this, other); } Loading @@ -307,6 +354,8 @@ final class EnforcingAdmin { public int hashCode() { if (mIsRoleAuthority) { return Objects.hash(mPackageName, mUserId); } else if (mIsSystemAuthority) { return Objects.hash(mSystemEntity); } else { return Objects.hash( mComponentName == null ? mPackageName : mComponentName, Loading @@ -318,8 +367,12 @@ final class EnforcingAdmin { void saveToXml(TypedXmlSerializer serializer) throws IOException { serializer.attribute(/* namespace= */ null, ATTR_PACKAGE_NAME, mPackageName); serializer.attributeBoolean(/* namespace= */ null, ATTR_IS_ROLE, mIsRoleAuthority); serializer.attributeBoolean(/* namespace= */ null, ATTR_IS_SYSTEM, mIsSystemAuthority); serializer.attributeInt(/* namespace= */ null, ATTR_USER_ID, mUserId); if (!mIsRoleAuthority) { if (mIsSystemAuthority) { serializer.attribute(/* namespace= */ null, ATTR_SYSTEM_ENTITY, mSystemEntity); } if (!mIsRoleAuthority && !mIsSystemAuthority) { if (mComponentName != null) { serializer.attribute( /* namespace= */ null, ATTR_CLASS_NAME, mComponentName.getClassName()); Loading @@ -336,7 +389,10 @@ final class EnforcingAdmin { static EnforcingAdmin readFromXml(TypedXmlPullParser parser) throws XmlPullParserException { String packageName = parser.getAttributeValue(/* namespace= */ null, ATTR_PACKAGE_NAME); String systemEntity = parser.getAttributeValue(/* namespace= */ null, ATTR_SYSTEM_ENTITY); boolean isRoleAuthority = parser.getAttributeBoolean(/* namespace= */ null, ATTR_IS_ROLE); boolean isSystemAuthority = parser.getAttributeBoolean( /* namespace= */ null, ATTR_IS_SYSTEM, /* defaultValue= */ false); String authoritiesStr = parser.getAttributeValue(/* namespace= */ null, ATTR_AUTHORITIES); int userId = parser.getAttributeInt(/* namespace= */ null, ATTR_USER_ID); Loading @@ -348,6 +404,13 @@ final class EnforcingAdmin { } // TODO(b/281697976): load active admin return new EnforcingAdmin(packageName, userId, null); } else if (isSystemAuthority) { if (systemEntity == null) { Slogf.wtf(TAG, "Error parsing EnforcingAdmin with SystemAuthority, " + "systemEntity is null."); return null; } return new EnforcingAdmin(systemEntity); } else { if (packageName == null || authoritiesStr == null) { Slogf.wtf(TAG, "Error parsing EnforcingAdmin, packageName is " Loading Loading @@ -381,6 +444,10 @@ final class EnforcingAdmin { sb.append(mUserId); sb.append(", mIsRoleAuthority= "); sb.append(mIsRoleAuthority); sb.append(", mIsSystemAuthority= "); sb.append(mIsSystemAuthority); sb.append(", mSystemEntity = "); sb.append(mSystemEntity); sb.append(" }"); return sb.toString(); } Loading