Loading services/core/java/android/os/UserManagerInternal.java +12 −13 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ import android.content.Context; import android.content.pm.UserInfo; import android.graphics.Bitmap; import com.android.server.pm.RestrictionsSet; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; Loading Loading @@ -57,21 +59,18 @@ public abstract class UserManagerInternal { * Called by {@link com.android.server.devicepolicy.DevicePolicyManagerService} to set * restrictions enforced by the user. * * @param originatingUserId user id of the user where the restriction originated. * @param restrictions a bundle of user restrictions. * @param restrictionOwnerType determines which admin {@code userId} corresponds to. * The admin can be either * {@link UserManagerInternal#OWNER_TYPE_DEVICE_OWNER}, * {@link UserManagerInternal#OWNER_TYPE_PROFILE_OWNER}, * {@link UserManagerInternal#OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE} * or {@link UserManagerInternal#OWNER_TYPE_NO_OWNER}. * If the admin is a DEVICE_OWNER or a PROFILE_OWNER_ORG_OWNED_DEVICE then * a restriction may be applied globally depending on which restriction it is, * otherwise it will be applied just on the current user. * @see OwnerType * @param originatingUserId user id of the user where the restrictions originated. * @param global a bundle of global user restrictions. Global restrictions are * restrictions that apply device-wide: to the managed profile, * primary profile and secondary users and any profile created in * any secondary user. * @param local a restriction set of local user restrictions. The key is the user * id of the user whom the restrictions are targeting. * @param isDeviceOwner whether {@code originatingUserId} corresponds to device owner * user id. */ public abstract void setDevicePolicyUserRestrictions(int originatingUserId, @Nullable Bundle restrictions, @OwnerType int restrictionOwnerType); @Nullable Bundle global, @Nullable RestrictionsSet local, boolean isDeviceOwner); /** * Returns the "base" user restrictions. Loading services/core/java/com/android/server/pm/UserManagerService.java +3 −24 Original line number Diff line number Diff line Loading @@ -1716,27 +1716,6 @@ public class UserManagerService extends IUserManager.Stub { } } private void setDevicePolicyUserRestrictionsInner(@UserIdInt int originatingUserId, @Nullable Bundle restrictions, @UserManagerInternal.OwnerType int restrictionOwnerType) { final Bundle global = new Bundle(); final Bundle local = new Bundle(); // Sort restrictions into local and global ensuring they don't overlap. UserRestrictionsUtils.sortToGlobalAndLocal(restrictions, restrictionOwnerType, global, local); boolean isDeviceOwner = restrictionOwnerType == UserManagerInternal.OWNER_TYPE_DEVICE_OWNER; RestrictionsSet localRestrictionsSet; if (UserRestrictionsUtils.isEmpty(local)) { localRestrictionsSet = new RestrictionsSet(); } else { localRestrictionsSet = new RestrictionsSet(originatingUserId, local); } setDevicePolicyUserRestrictionsInner(originatingUserId, global, localRestrictionsSet, isDeviceOwner); } /** * See {@link UserManagerInternal#setDevicePolicyUserRestrictions} */ Loading Loading @@ -4754,10 +4733,10 @@ public class UserManagerService extends IUserManager.Stub { private class LocalService extends UserManagerInternal { @Override public void setDevicePolicyUserRestrictions(@UserIdInt int originatingUserId, @Nullable Bundle restrictions, @OwnerType int restrictionOwnerType) { @NonNull Bundle global, @NonNull RestrictionsSet local, boolean isDeviceOwner) { UserManagerService.this.setDevicePolicyUserRestrictionsInner(originatingUserId, restrictions, restrictionOwnerType); global, local, isDeviceOwner); } @Override Loading services/core/java/com/android/server/pm/UserRestrictionsUtils.java +18 −24 Original line number Diff line number Diff line Loading @@ -232,6 +232,13 @@ public class UserRestrictionsUtils { UserManager.DISALLOW_UNMUTE_MICROPHONE ); /** * Special user restrictions that profile owner of an organization-owned managed profile can * set on the parent profile instance to apply them on the personal profile. */ private static final Set<String> PROFILE_OWNER_ORGANIZATION_OWNED_LOCAL_RESTRICTIONS = Sets.newArraySet(); /** * User restrictions that default to {@code true} for managed profile owners. * Loading Loading @@ -416,7 +423,8 @@ public class UserRestrictionsUtils { * @return true if a restriction is settable by profile owner of an organization owned device. */ public static boolean canProfileOwnerOfOrganizationOwnedDeviceChange(String restriction) { return PROFILE_OWNER_ORGANIZATION_OWNED_GLOBAL_RESTRICTIONS.contains(restriction); return PROFILE_OWNER_ORGANIZATION_OWNED_GLOBAL_RESTRICTIONS.contains(restriction) || PROFILE_OWNER_ORGANIZATION_OWNED_LOCAL_RESTRICTIONS.contains(restriction); } /** Loading @@ -426,32 +434,10 @@ public class UserRestrictionsUtils { return DEFAULT_ENABLED_FOR_MANAGED_PROFILES; } /** * Takes restrictions that can be set by device owner, and sort them into what should be applied * globally and what should be applied only on the current user. */ public static void sortToGlobalAndLocal(@Nullable Bundle in, @UserManagerInternal.OwnerType int restrictionOwnerType, @NonNull Bundle global, @NonNull Bundle local) { if (in == null || in.size() == 0) { return; } for (String key : in.keySet()) { if (!in.getBoolean(key)) { continue; } if (isGlobal(restrictionOwnerType, key)) { global.putBoolean(key, true); } else { local.putBoolean(key, true); } } } /** * Whether given user restriction should be enforced globally. */ private static boolean isGlobal(@UserManagerInternal.OwnerType int restrictionOwnerType, public static boolean isGlobal(@UserManagerInternal.OwnerType int restrictionOwnerType, String key) { return ((restrictionOwnerType == UserManagerInternal.OWNER_TYPE_DEVICE_OWNER) && ( PRIMARY_USER_ONLY_RESTRICTIONS.contains(key) || GLOBAL_RESTRICTIONS.contains(key))) Loading @@ -462,6 +448,14 @@ public class UserRestrictionsUtils { || DEVICE_OWNER_ONLY_RESTRICTIONS.contains(key); } /** * Whether given user restriction should be enforced locally. */ public static boolean isLocal(@UserManagerInternal.OwnerType int restrictionOwnerType, String key) { return !isGlobal(restrictionOwnerType, key); } /** * @return true if two Bundles contain the same user restriction. * A null bundle and an empty bundle are considered to be equal. Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +109 −82 Original line number Diff line number Diff line Loading @@ -87,6 +87,9 @@ import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE; import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES; import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; import static android.os.UserManagerInternal.OWNER_TYPE_DEVICE_OWNER; import static android.os.UserManagerInternal.OWNER_TYPE_PROFILE_OWNER; import static android.os.UserManagerInternal.OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE; import static android.provider.Settings.Global.PRIVATE_DNS_MODE; import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER; import static android.provider.Telephony.Carriers.DPC_URI; Loading Loading @@ -284,6 +287,7 @@ import com.android.server.SystemService; import com.android.server.devicepolicy.DevicePolicyManagerService.ActiveAdmin.TrustAgentInfo; import com.android.server.inputmethod.InputMethodManagerInternal; import com.android.server.net.NetworkPolicyManagerInternal; import com.android.server.pm.RestrictionsSet; import com.android.server.pm.UserRestrictionsUtils; import com.android.server.pm.parsing.pkg.AndroidPackage; import com.android.server.storage.DeviceStorageMonitorInternal; Loading Loading @@ -322,6 +326,7 @@ import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Function; import java.util.function.Predicate; /** * Implementation of the device policy APIs. Loading Loading @@ -1828,6 +1833,50 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { info = deviceAdminInfo; } Bundle addSyntheticRestrictions(Bundle restrictions) { if (disableCamera) { restrictions.putBoolean(UserManager.DISALLOW_CAMERA, true); } else { restrictions.remove(UserManager.DISALLOW_CAMERA); } return restrictions; } static Bundle removeDeprecatedRestrictions(Bundle restrictions) { for (String deprecatedRestriction: DEPRECATED_USER_RESTRICTIONS) { restrictions.remove(deprecatedRestriction); } return restrictions; } static Bundle filterRestrictions(Bundle restrictions, Predicate<String> filter) { Bundle result = new Bundle(); for (String key : restrictions.keySet()) { if (!restrictions.getBoolean(key)) { continue; } if (filter.test(key)) { result.putBoolean(key, true); } } return result; } Bundle getEffectiveRestrictions() { return addSyntheticRestrictions( removeDeprecatedRestrictions(ensureUserRestrictions())); } Bundle getLocalUserRestrictions(int adminType) { return filterRestrictions(getEffectiveRestrictions(), key -> UserRestrictionsUtils.isLocal(adminType, key)); } Bundle getGlobalUserRestrictions(int adminType) { return filterRestrictions(getEffectiveRestrictions(), key -> UserRestrictionsUtils.isGlobal(adminType, key)); } void dump(IndentingPrintWriter pw) { pw.print("uid="); pw.println(getUid()); pw.print("testOnlyAdmin="); Loading Loading @@ -2772,7 +2821,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED, 0, userId) != 0) { profileOwner.ensureUserRestrictions().putBoolean( UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, true); saveUserRestrictionsLocked(userId, /* parent = */ false); saveUserRestrictionsLocked(userId); mInjector.settingsSecurePutIntForUser( Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED, 0, userId); } Loading Loading @@ -2803,7 +2852,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } admin.defaultEnabledRestrictionsAlreadySet.addAll(restrictionsToSet); Slog.i(LOG_TAG, "Enabled the following restrictions by default: " + restrictionsToSet); saveUserRestrictionsLocked(userId, /* parent = */ false); saveUserRestrictionsLocked(userId); } } Loading Loading @@ -8222,9 +8271,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } // Tell the user manager that the restrictions have changed. final int affectedUserId = parent ? getProfileParentId(userHandle) : userHandle; pushUserRestrictions(affectedUserId); pushUserRestrictions(userHandle); final int affectedUserId = parent ? getProfileParentId(userHandle) : userHandle; if (SecurityLog.isLoggingEnabled()) { SecurityLog.writeEvent(SecurityLog.TAG_CAMERA_POLICY_SET, who.getPackageName(), userHandle, affectedUserId, disabled ? 1 : 0); Loading Loading @@ -10806,10 +10855,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { "Cannot use the parent instance in Device Owner mode"); } } else { if (!(UserRestrictionsUtils.canProfileOwnerChange(key, userHandle) || ( isProfileOwnerOfOrganizationOwnedDevice(activeAdmin) && parent && UserRestrictionsUtils.canProfileOwnerOfOrganizationOwnedDeviceChange( key)))) { boolean profileOwnerCanChangeOnItself = !parent && UserRestrictionsUtils.canProfileOwnerChange(key, userHandle); boolean orgOwnedProfileOwnerCanChangesGlobally = parent && isProfileOwnerOfOrganizationOwnedDevice(activeAdmin) && UserRestrictionsUtils .canProfileOwnerOfOrganizationOwnedDeviceChange(key); if (!profileOwnerCanChangeOnItself && !orgOwnedProfileOwnerCanChangesGlobally) { throw new SecurityException("Profile owner cannot set user restriction " + key); } } Loading @@ -10821,7 +10874,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } else { restrictions.remove(key); } saveUserRestrictionsLocked(userHandle, parent); saveUserRestrictionsLocked(userHandle); } final int eventId = enabledFromThisOwner ? DevicePolicyEnums.ADD_USER_RESTRICTION Loading @@ -10839,91 +10892,65 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } private void saveUserRestrictionsLocked(int userId, boolean parent) { private void saveUserRestrictionsLocked(int userId) { saveSettingsLocked(userId); pushUserRestrictions(parent ? getProfileParentId(userId) : userId); pushUserRestrictions(userId); sendChangedNotification(userId); } private void pushUserRestrictions(int userId) { /** * Pushes the user restrictions originating from a specific user. * * If called by the profile owner of an organization-owned device, the global and local * user restrictions will be an accumulation of the global user restrictions from the profile * owner active admin and its parent active admin. The key of the local user restrictions set * will be the target user id. */ private void pushUserRestrictions(int originatingUserId) { final Bundle global; final RestrictionsSet local = new RestrictionsSet(); final boolean isDeviceOwner; synchronized (getLockObject()) { final boolean isDeviceOwner = mOwners.isDeviceOwnerUserId(userId); Bundle userRestrictions = null; final int restrictionOwnerType; final int originatingUserId; isDeviceOwner = mOwners.isDeviceOwnerUserId(originatingUserId); if (isDeviceOwner) { final ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked(); if (deviceOwner == null) { return; // Shouldn't happen. } userRestrictions = addOrRemoveDisableCameraRestriction( deviceOwner.userRestrictions, deviceOwner); restrictionOwnerType = UserManagerInternal.OWNER_TYPE_DEVICE_OWNER; originatingUserId = deviceOwner.getUserHandle().getIdentifier(); global = deviceOwner.getGlobalUserRestrictions(OWNER_TYPE_DEVICE_OWNER); local.updateRestrictions(originatingUserId, deviceOwner.getLocalUserRestrictions( OWNER_TYPE_DEVICE_OWNER)); } else { final ActiveAdmin profileOwnerOfOrganizationOwnedDevice = getProfileOwnerOfOrganizationOwnedDeviceLocked(userId); // If profile owner of an organization owned device, the restrictions will be // pushed to the parent instance. if (profileOwnerOfOrganizationOwnedDevice != null && !isManagedProfile(userId)) { restrictionOwnerType = UserManagerInternal.OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE; final ActiveAdmin parent = profileOwnerOfOrganizationOwnedDevice .getParentActiveAdmin(); userRestrictions = parent.userRestrictions; userRestrictions = addOrRemoveDisableCameraRestriction(userRestrictions, parent); originatingUserId = profileOwnerOfOrganizationOwnedDevice.getUserHandle().getIdentifier(); } else { final ActiveAdmin profileOwner = getProfileOwnerAdminLocked(userId); if (profileOwner != null) { userRestrictions = profileOwner.userRestrictions; restrictionOwnerType = UserManagerInternal.OWNER_TYPE_PROFILE_OWNER; originatingUserId = profileOwner.getUserHandle().getIdentifier(); } else { restrictionOwnerType = UserManagerInternal.OWNER_TYPE_NO_OWNER; originatingUserId = userId; } userRestrictions = addOrRemoveDisableCameraRestriction( userRestrictions, userId); } } // Remove deprecated restrictions. for (String deprecatedRestriction: DEPRECATED_USER_RESTRICTIONS) { userRestrictions.remove(deprecatedRestriction); } mUserManagerInternal.setDevicePolicyUserRestrictions(originatingUserId, userRestrictions, restrictionOwnerType); } } private Bundle addOrRemoveDisableCameraRestriction(Bundle userRestrictions, ActiveAdmin admin) { if (userRestrictions == null) { userRestrictions = new Bundle(); } if (admin.disableCamera) { userRestrictions.putBoolean(UserManager.DISALLOW_CAMERA, true); } else { userRestrictions.remove(UserManager.DISALLOW_CAMERA); } return userRestrictions; } private Bundle addOrRemoveDisableCameraRestriction(Bundle userRestrictions, int userId) { if (userRestrictions == null) { userRestrictions = new Bundle(); } if (getCameraDisabled(/* who= */ null, userId, /* mergeDeviceOwnerRestriction= */ false)) { userRestrictions.putBoolean(UserManager.DISALLOW_CAMERA, true); } else { userRestrictions.remove(UserManager.DISALLOW_CAMERA); final ActiveAdmin profileOwner = getProfileOwnerAdminLocked(originatingUserId); if (profileOwner == null) { return; } return userRestrictions; global = profileOwner.getGlobalUserRestrictions(OWNER_TYPE_PROFILE_OWNER); local.updateRestrictions(originatingUserId, profileOwner.getLocalUserRestrictions( OWNER_TYPE_PROFILE_OWNER)); // Global (device-wide) and local user restrictions set by the profile owner of an // organization-owned device are stored in the parent ActiveAdmin instance. if (isProfileOwnerOfOrganizationOwnedDevice( profileOwner.getUserHandle().getIdentifier())) { // The global restrictions set on the parent ActiveAdmin instance need to be // merged with the global restrictions set on the profile owner ActiveAdmin // instance, since both are to be applied device-wide. UserRestrictionsUtils.merge(global, profileOwner.getParentActiveAdmin().getGlobalUserRestrictions( OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE)); // The local restrictions set on the parent ActiveAdmin instance are only to be // applied to the primary user. They therefore need to be added the local // restriction set with the primary user id as the key, in this case the // primary user id is the target user. local.updateRestrictions( getProfileParentId(profileOwner.getUserHandle().getIdentifier()), profileOwner.getParentActiveAdmin().getLocalUserRestrictions( OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE)); } } } mUserManagerInternal.setDevicePolicyUserRestrictions(originatingUserId, global, local, isDeviceOwner); } @Override Loading services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +55 −46 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
services/core/java/android/os/UserManagerInternal.java +12 −13 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ import android.content.Context; import android.content.pm.UserInfo; import android.graphics.Bitmap; import com.android.server.pm.RestrictionsSet; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; Loading Loading @@ -57,21 +59,18 @@ public abstract class UserManagerInternal { * Called by {@link com.android.server.devicepolicy.DevicePolicyManagerService} to set * restrictions enforced by the user. * * @param originatingUserId user id of the user where the restriction originated. * @param restrictions a bundle of user restrictions. * @param restrictionOwnerType determines which admin {@code userId} corresponds to. * The admin can be either * {@link UserManagerInternal#OWNER_TYPE_DEVICE_OWNER}, * {@link UserManagerInternal#OWNER_TYPE_PROFILE_OWNER}, * {@link UserManagerInternal#OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE} * or {@link UserManagerInternal#OWNER_TYPE_NO_OWNER}. * If the admin is a DEVICE_OWNER or a PROFILE_OWNER_ORG_OWNED_DEVICE then * a restriction may be applied globally depending on which restriction it is, * otherwise it will be applied just on the current user. * @see OwnerType * @param originatingUserId user id of the user where the restrictions originated. * @param global a bundle of global user restrictions. Global restrictions are * restrictions that apply device-wide: to the managed profile, * primary profile and secondary users and any profile created in * any secondary user. * @param local a restriction set of local user restrictions. The key is the user * id of the user whom the restrictions are targeting. * @param isDeviceOwner whether {@code originatingUserId} corresponds to device owner * user id. */ public abstract void setDevicePolicyUserRestrictions(int originatingUserId, @Nullable Bundle restrictions, @OwnerType int restrictionOwnerType); @Nullable Bundle global, @Nullable RestrictionsSet local, boolean isDeviceOwner); /** * Returns the "base" user restrictions. Loading
services/core/java/com/android/server/pm/UserManagerService.java +3 −24 Original line number Diff line number Diff line Loading @@ -1716,27 +1716,6 @@ public class UserManagerService extends IUserManager.Stub { } } private void setDevicePolicyUserRestrictionsInner(@UserIdInt int originatingUserId, @Nullable Bundle restrictions, @UserManagerInternal.OwnerType int restrictionOwnerType) { final Bundle global = new Bundle(); final Bundle local = new Bundle(); // Sort restrictions into local and global ensuring they don't overlap. UserRestrictionsUtils.sortToGlobalAndLocal(restrictions, restrictionOwnerType, global, local); boolean isDeviceOwner = restrictionOwnerType == UserManagerInternal.OWNER_TYPE_DEVICE_OWNER; RestrictionsSet localRestrictionsSet; if (UserRestrictionsUtils.isEmpty(local)) { localRestrictionsSet = new RestrictionsSet(); } else { localRestrictionsSet = new RestrictionsSet(originatingUserId, local); } setDevicePolicyUserRestrictionsInner(originatingUserId, global, localRestrictionsSet, isDeviceOwner); } /** * See {@link UserManagerInternal#setDevicePolicyUserRestrictions} */ Loading Loading @@ -4754,10 +4733,10 @@ public class UserManagerService extends IUserManager.Stub { private class LocalService extends UserManagerInternal { @Override public void setDevicePolicyUserRestrictions(@UserIdInt int originatingUserId, @Nullable Bundle restrictions, @OwnerType int restrictionOwnerType) { @NonNull Bundle global, @NonNull RestrictionsSet local, boolean isDeviceOwner) { UserManagerService.this.setDevicePolicyUserRestrictionsInner(originatingUserId, restrictions, restrictionOwnerType); global, local, isDeviceOwner); } @Override Loading
services/core/java/com/android/server/pm/UserRestrictionsUtils.java +18 −24 Original line number Diff line number Diff line Loading @@ -232,6 +232,13 @@ public class UserRestrictionsUtils { UserManager.DISALLOW_UNMUTE_MICROPHONE ); /** * Special user restrictions that profile owner of an organization-owned managed profile can * set on the parent profile instance to apply them on the personal profile. */ private static final Set<String> PROFILE_OWNER_ORGANIZATION_OWNED_LOCAL_RESTRICTIONS = Sets.newArraySet(); /** * User restrictions that default to {@code true} for managed profile owners. * Loading Loading @@ -416,7 +423,8 @@ public class UserRestrictionsUtils { * @return true if a restriction is settable by profile owner of an organization owned device. */ public static boolean canProfileOwnerOfOrganizationOwnedDeviceChange(String restriction) { return PROFILE_OWNER_ORGANIZATION_OWNED_GLOBAL_RESTRICTIONS.contains(restriction); return PROFILE_OWNER_ORGANIZATION_OWNED_GLOBAL_RESTRICTIONS.contains(restriction) || PROFILE_OWNER_ORGANIZATION_OWNED_LOCAL_RESTRICTIONS.contains(restriction); } /** Loading @@ -426,32 +434,10 @@ public class UserRestrictionsUtils { return DEFAULT_ENABLED_FOR_MANAGED_PROFILES; } /** * Takes restrictions that can be set by device owner, and sort them into what should be applied * globally and what should be applied only on the current user. */ public static void sortToGlobalAndLocal(@Nullable Bundle in, @UserManagerInternal.OwnerType int restrictionOwnerType, @NonNull Bundle global, @NonNull Bundle local) { if (in == null || in.size() == 0) { return; } for (String key : in.keySet()) { if (!in.getBoolean(key)) { continue; } if (isGlobal(restrictionOwnerType, key)) { global.putBoolean(key, true); } else { local.putBoolean(key, true); } } } /** * Whether given user restriction should be enforced globally. */ private static boolean isGlobal(@UserManagerInternal.OwnerType int restrictionOwnerType, public static boolean isGlobal(@UserManagerInternal.OwnerType int restrictionOwnerType, String key) { return ((restrictionOwnerType == UserManagerInternal.OWNER_TYPE_DEVICE_OWNER) && ( PRIMARY_USER_ONLY_RESTRICTIONS.contains(key) || GLOBAL_RESTRICTIONS.contains(key))) Loading @@ -462,6 +448,14 @@ public class UserRestrictionsUtils { || DEVICE_OWNER_ONLY_RESTRICTIONS.contains(key); } /** * Whether given user restriction should be enforced locally. */ public static boolean isLocal(@UserManagerInternal.OwnerType int restrictionOwnerType, String key) { return !isGlobal(restrictionOwnerType, key); } /** * @return true if two Bundles contain the same user restriction. * A null bundle and an empty bundle are considered to be equal. Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +109 −82 Original line number Diff line number Diff line Loading @@ -87,6 +87,9 @@ import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE; import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES; import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; import static android.os.UserManagerInternal.OWNER_TYPE_DEVICE_OWNER; import static android.os.UserManagerInternal.OWNER_TYPE_PROFILE_OWNER; import static android.os.UserManagerInternal.OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE; import static android.provider.Settings.Global.PRIVATE_DNS_MODE; import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER; import static android.provider.Telephony.Carriers.DPC_URI; Loading Loading @@ -284,6 +287,7 @@ import com.android.server.SystemService; import com.android.server.devicepolicy.DevicePolicyManagerService.ActiveAdmin.TrustAgentInfo; import com.android.server.inputmethod.InputMethodManagerInternal; import com.android.server.net.NetworkPolicyManagerInternal; import com.android.server.pm.RestrictionsSet; import com.android.server.pm.UserRestrictionsUtils; import com.android.server.pm.parsing.pkg.AndroidPackage; import com.android.server.storage.DeviceStorageMonitorInternal; Loading Loading @@ -322,6 +326,7 @@ import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Function; import java.util.function.Predicate; /** * Implementation of the device policy APIs. Loading Loading @@ -1828,6 +1833,50 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { info = deviceAdminInfo; } Bundle addSyntheticRestrictions(Bundle restrictions) { if (disableCamera) { restrictions.putBoolean(UserManager.DISALLOW_CAMERA, true); } else { restrictions.remove(UserManager.DISALLOW_CAMERA); } return restrictions; } static Bundle removeDeprecatedRestrictions(Bundle restrictions) { for (String deprecatedRestriction: DEPRECATED_USER_RESTRICTIONS) { restrictions.remove(deprecatedRestriction); } return restrictions; } static Bundle filterRestrictions(Bundle restrictions, Predicate<String> filter) { Bundle result = new Bundle(); for (String key : restrictions.keySet()) { if (!restrictions.getBoolean(key)) { continue; } if (filter.test(key)) { result.putBoolean(key, true); } } return result; } Bundle getEffectiveRestrictions() { return addSyntheticRestrictions( removeDeprecatedRestrictions(ensureUserRestrictions())); } Bundle getLocalUserRestrictions(int adminType) { return filterRestrictions(getEffectiveRestrictions(), key -> UserRestrictionsUtils.isLocal(adminType, key)); } Bundle getGlobalUserRestrictions(int adminType) { return filterRestrictions(getEffectiveRestrictions(), key -> UserRestrictionsUtils.isGlobal(adminType, key)); } void dump(IndentingPrintWriter pw) { pw.print("uid="); pw.println(getUid()); pw.print("testOnlyAdmin="); Loading Loading @@ -2772,7 +2821,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED, 0, userId) != 0) { profileOwner.ensureUserRestrictions().putBoolean( UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, true); saveUserRestrictionsLocked(userId, /* parent = */ false); saveUserRestrictionsLocked(userId); mInjector.settingsSecurePutIntForUser( Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED, 0, userId); } Loading Loading @@ -2803,7 +2852,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } admin.defaultEnabledRestrictionsAlreadySet.addAll(restrictionsToSet); Slog.i(LOG_TAG, "Enabled the following restrictions by default: " + restrictionsToSet); saveUserRestrictionsLocked(userId, /* parent = */ false); saveUserRestrictionsLocked(userId); } } Loading Loading @@ -8222,9 +8271,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } // Tell the user manager that the restrictions have changed. final int affectedUserId = parent ? getProfileParentId(userHandle) : userHandle; pushUserRestrictions(affectedUserId); pushUserRestrictions(userHandle); final int affectedUserId = parent ? getProfileParentId(userHandle) : userHandle; if (SecurityLog.isLoggingEnabled()) { SecurityLog.writeEvent(SecurityLog.TAG_CAMERA_POLICY_SET, who.getPackageName(), userHandle, affectedUserId, disabled ? 1 : 0); Loading Loading @@ -10806,10 +10855,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { "Cannot use the parent instance in Device Owner mode"); } } else { if (!(UserRestrictionsUtils.canProfileOwnerChange(key, userHandle) || ( isProfileOwnerOfOrganizationOwnedDevice(activeAdmin) && parent && UserRestrictionsUtils.canProfileOwnerOfOrganizationOwnedDeviceChange( key)))) { boolean profileOwnerCanChangeOnItself = !parent && UserRestrictionsUtils.canProfileOwnerChange(key, userHandle); boolean orgOwnedProfileOwnerCanChangesGlobally = parent && isProfileOwnerOfOrganizationOwnedDevice(activeAdmin) && UserRestrictionsUtils .canProfileOwnerOfOrganizationOwnedDeviceChange(key); if (!profileOwnerCanChangeOnItself && !orgOwnedProfileOwnerCanChangesGlobally) { throw new SecurityException("Profile owner cannot set user restriction " + key); } } Loading @@ -10821,7 +10874,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } else { restrictions.remove(key); } saveUserRestrictionsLocked(userHandle, parent); saveUserRestrictionsLocked(userHandle); } final int eventId = enabledFromThisOwner ? DevicePolicyEnums.ADD_USER_RESTRICTION Loading @@ -10839,91 +10892,65 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } private void saveUserRestrictionsLocked(int userId, boolean parent) { private void saveUserRestrictionsLocked(int userId) { saveSettingsLocked(userId); pushUserRestrictions(parent ? getProfileParentId(userId) : userId); pushUserRestrictions(userId); sendChangedNotification(userId); } private void pushUserRestrictions(int userId) { /** * Pushes the user restrictions originating from a specific user. * * If called by the profile owner of an organization-owned device, the global and local * user restrictions will be an accumulation of the global user restrictions from the profile * owner active admin and its parent active admin. The key of the local user restrictions set * will be the target user id. */ private void pushUserRestrictions(int originatingUserId) { final Bundle global; final RestrictionsSet local = new RestrictionsSet(); final boolean isDeviceOwner; synchronized (getLockObject()) { final boolean isDeviceOwner = mOwners.isDeviceOwnerUserId(userId); Bundle userRestrictions = null; final int restrictionOwnerType; final int originatingUserId; isDeviceOwner = mOwners.isDeviceOwnerUserId(originatingUserId); if (isDeviceOwner) { final ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked(); if (deviceOwner == null) { return; // Shouldn't happen. } userRestrictions = addOrRemoveDisableCameraRestriction( deviceOwner.userRestrictions, deviceOwner); restrictionOwnerType = UserManagerInternal.OWNER_TYPE_DEVICE_OWNER; originatingUserId = deviceOwner.getUserHandle().getIdentifier(); global = deviceOwner.getGlobalUserRestrictions(OWNER_TYPE_DEVICE_OWNER); local.updateRestrictions(originatingUserId, deviceOwner.getLocalUserRestrictions( OWNER_TYPE_DEVICE_OWNER)); } else { final ActiveAdmin profileOwnerOfOrganizationOwnedDevice = getProfileOwnerOfOrganizationOwnedDeviceLocked(userId); // If profile owner of an organization owned device, the restrictions will be // pushed to the parent instance. if (profileOwnerOfOrganizationOwnedDevice != null && !isManagedProfile(userId)) { restrictionOwnerType = UserManagerInternal.OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE; final ActiveAdmin parent = profileOwnerOfOrganizationOwnedDevice .getParentActiveAdmin(); userRestrictions = parent.userRestrictions; userRestrictions = addOrRemoveDisableCameraRestriction(userRestrictions, parent); originatingUserId = profileOwnerOfOrganizationOwnedDevice.getUserHandle().getIdentifier(); } else { final ActiveAdmin profileOwner = getProfileOwnerAdminLocked(userId); if (profileOwner != null) { userRestrictions = profileOwner.userRestrictions; restrictionOwnerType = UserManagerInternal.OWNER_TYPE_PROFILE_OWNER; originatingUserId = profileOwner.getUserHandle().getIdentifier(); } else { restrictionOwnerType = UserManagerInternal.OWNER_TYPE_NO_OWNER; originatingUserId = userId; } userRestrictions = addOrRemoveDisableCameraRestriction( userRestrictions, userId); } } // Remove deprecated restrictions. for (String deprecatedRestriction: DEPRECATED_USER_RESTRICTIONS) { userRestrictions.remove(deprecatedRestriction); } mUserManagerInternal.setDevicePolicyUserRestrictions(originatingUserId, userRestrictions, restrictionOwnerType); } } private Bundle addOrRemoveDisableCameraRestriction(Bundle userRestrictions, ActiveAdmin admin) { if (userRestrictions == null) { userRestrictions = new Bundle(); } if (admin.disableCamera) { userRestrictions.putBoolean(UserManager.DISALLOW_CAMERA, true); } else { userRestrictions.remove(UserManager.DISALLOW_CAMERA); } return userRestrictions; } private Bundle addOrRemoveDisableCameraRestriction(Bundle userRestrictions, int userId) { if (userRestrictions == null) { userRestrictions = new Bundle(); } if (getCameraDisabled(/* who= */ null, userId, /* mergeDeviceOwnerRestriction= */ false)) { userRestrictions.putBoolean(UserManager.DISALLOW_CAMERA, true); } else { userRestrictions.remove(UserManager.DISALLOW_CAMERA); final ActiveAdmin profileOwner = getProfileOwnerAdminLocked(originatingUserId); if (profileOwner == null) { return; } return userRestrictions; global = profileOwner.getGlobalUserRestrictions(OWNER_TYPE_PROFILE_OWNER); local.updateRestrictions(originatingUserId, profileOwner.getLocalUserRestrictions( OWNER_TYPE_PROFILE_OWNER)); // Global (device-wide) and local user restrictions set by the profile owner of an // organization-owned device are stored in the parent ActiveAdmin instance. if (isProfileOwnerOfOrganizationOwnedDevice( profileOwner.getUserHandle().getIdentifier())) { // The global restrictions set on the parent ActiveAdmin instance need to be // merged with the global restrictions set on the profile owner ActiveAdmin // instance, since both are to be applied device-wide. UserRestrictionsUtils.merge(global, profileOwner.getParentActiveAdmin().getGlobalUserRestrictions( OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE)); // The local restrictions set on the parent ActiveAdmin instance are only to be // applied to the primary user. They therefore need to be added the local // restriction set with the primary user id as the key, in this case the // primary user id is the target user. local.updateRestrictions( getProfileParentId(profileOwner.getUserHandle().getIdentifier()), profileOwner.getParentActiveAdmin().getLocalUserRestrictions( OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE)); } } } mUserManagerInternal.setDevicePolicyUserRestrictions(originatingUserId, global, local, isDeviceOwner); } @Override Loading
services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +55 −46 File changed.Preview size limit exceeded, changes collapsed. Show changes