Rework device policy user restrctions. am: 3ed359b5e9
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/21480344 Change-Id: Ia297b220cccc39a01aa9e30f6b6c5bc776335b0e Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -20,7 +20,9 @@ import android.annotation.NonNull;
|
|||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.annotation.UserIdInt;
|
import android.annotation.UserIdInt;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
|
import android.util.IntArray;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
@@ -37,9 +39,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data structure that contains the mapping of users to user restrictions (either the user
|
* Data structure that contains the mapping of users to user restrictions.
|
||||||
* restrictions that apply to them, or the user restrictions that they set, depending on the
|
|
||||||
* circumstances).
|
|
||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@@ -87,6 +87,24 @@ public class RestrictionsSet {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a particular restriction for all users.
|
||||||
|
*
|
||||||
|
* @return whether the restriction was removed or not.
|
||||||
|
*/
|
||||||
|
public boolean removeRestrictionsForAllUsers(String restriction) {
|
||||||
|
boolean removed = false;
|
||||||
|
for (int i = 0; i < mUserRestrictions.size(); i++) {
|
||||||
|
final Bundle restrictions = mUserRestrictions.valueAt(i);
|
||||||
|
|
||||||
|
if (UserRestrictionsUtils.contains(restrictions, restriction)) {
|
||||||
|
restrictions.remove(restriction);
|
||||||
|
removed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves a particular restriction from one restriction set to another, e.g. for all users.
|
* Moves a particular restriction from one restriction set to another, e.g. for all users.
|
||||||
*/
|
*/
|
||||||
@@ -139,22 +157,19 @@ public class RestrictionsSet {
|
|||||||
* @return list of enforcing users that enforce a particular restriction.
|
* @return list of enforcing users that enforce a particular restriction.
|
||||||
*/
|
*/
|
||||||
public @NonNull List<UserManager.EnforcingUser> getEnforcingUsers(String restriction,
|
public @NonNull List<UserManager.EnforcingUser> getEnforcingUsers(String restriction,
|
||||||
@UserIdInt int deviceOwnerUserId) {
|
@UserIdInt int userId) {
|
||||||
final List<UserManager.EnforcingUser> result = new ArrayList<>();
|
final List<UserManager.EnforcingUser> result = new ArrayList<>();
|
||||||
for (int i = 0; i < mUserRestrictions.size(); i++) {
|
if (getRestrictionsNonNull(userId).containsKey(restriction)) {
|
||||||
if (UserRestrictionsUtils.contains(mUserRestrictions.valueAt(i), restriction)) {
|
result.add(new UserManager.EnforcingUser(userId,
|
||||||
result.add(getEnforcingUser(mUserRestrictions.keyAt(i), deviceOwnerUserId));
|
UserManager.RESTRICTION_SOURCE_PROFILE_OWNER));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private UserManager.EnforcingUser getEnforcingUser(@UserIdInt int userId,
|
if (getRestrictionsNonNull(UserHandle.USER_ALL).containsKey(restriction)) {
|
||||||
@UserIdInt int deviceOwnerUserId) {
|
result.add(new UserManager.EnforcingUser(UserHandle.USER_ALL,
|
||||||
int source = deviceOwnerUserId == userId
|
UserManager.RESTRICTION_SOURCE_DEVICE_OWNER));
|
||||||
? UserManager.RESTRICTION_SOURCE_DEVICE_OWNER
|
}
|
||||||
: UserManager.RESTRICTION_SOURCE_PROFILE_OWNER;
|
|
||||||
return new UserManager.EnforcingUser(userId, source);
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -165,6 +180,11 @@ public class RestrictionsSet {
|
|||||||
return mUserRestrictions.get(userId);
|
return mUserRestrictions.get(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return list of user restrictions for a given user that is not null. */
|
||||||
|
public @NonNull Bundle getRestrictionsNonNull(@UserIdInt int userId) {
|
||||||
|
return UserRestrictionsUtils.nonNull(mUserRestrictions.get(userId));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a given user from the restrictions set, returning true if the user has non-empty
|
* Removes a given user from the restrictions set, returning true if the user has non-empty
|
||||||
* restrictions before removal.
|
* restrictions before removal.
|
||||||
@@ -236,6 +256,15 @@ public class RestrictionsSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return list of users in this restriction set. */
|
||||||
|
public IntArray getUserIds() {
|
||||||
|
IntArray userIds = new IntArray(mUserRestrictions.size());
|
||||||
|
for (int i = 0; i < mUserRestrictions.size(); i++) {
|
||||||
|
userIds.add(mUserRestrictions.keyAt(i));
|
||||||
|
}
|
||||||
|
return userIds;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean containsKey(@UserIdInt int userId) {
|
public boolean containsKey(@UserIdInt int userId) {
|
||||||
return mUserRestrictions.contains(userId);
|
return mUserRestrictions.contains(userId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,6 +141,18 @@ public abstract class UserManagerInternal {
|
|||||||
public abstract void setDevicePolicyUserRestrictions(int originatingUserId,
|
public abstract void setDevicePolicyUserRestrictions(int originatingUserId,
|
||||||
@Nullable Bundle global, @Nullable RestrictionsSet local, boolean isDeviceOwner);
|
@Nullable Bundle global, @Nullable RestrictionsSet local, boolean isDeviceOwner);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by {@link com.android.server.devicepolicy.DevicePolicyManagerService} to set a
|
||||||
|
* user restriction.
|
||||||
|
*
|
||||||
|
* @param userId user id to apply the restriction to. {@link com.android.os.UserHandle.USER_ALL}
|
||||||
|
* will apply the restriction to all users globally.
|
||||||
|
* @param key The key of the restriction.
|
||||||
|
* @param value The value of the restriction.
|
||||||
|
*/
|
||||||
|
public abstract void setUserRestriction(@UserIdInt int userId, @NonNull String key,
|
||||||
|
boolean value);
|
||||||
|
|
||||||
/** Return a user restriction. */
|
/** Return a user restriction. */
|
||||||
public abstract boolean getUserRestriction(int userId, String key);
|
public abstract boolean getUserRestriction(int userId, String key);
|
||||||
|
|
||||||
|
|||||||
@@ -457,30 +457,12 @@ public class UserManagerService extends IUserManager.Stub {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* User restrictions set by {@link com.android.server.devicepolicy.DevicePolicyManagerService}
|
* User restrictions set by {@link com.android.server.devicepolicy.DevicePolicyManagerService}
|
||||||
* that should be applied to all users, including guests. Only non-empty restriction bundles are
|
* for each user. Restrictions that apply to all users (global) are represented by
|
||||||
* stored.
|
* {@link com.android.os.UserHandle.USER_ALL}.
|
||||||
* The key is the user id of the user whom the restriction originated from.
|
|
||||||
*/
|
|
||||||
@GuardedBy("mRestrictionsLock")
|
|
||||||
private final RestrictionsSet mDevicePolicyGlobalUserRestrictions = new RestrictionsSet();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Id of the user that set global restrictions.
|
|
||||||
*/
|
|
||||||
@GuardedBy("mRestrictionsLock")
|
|
||||||
private int mDeviceOwnerUserId = UserHandle.USER_NULL;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* User restrictions set by {@link com.android.server.devicepolicy.DevicePolicyManagerService}
|
|
||||||
* for each user.
|
|
||||||
* The key is the user id of the user whom the restrictions are targeting.
|
* The key is the user id of the user whom the restrictions are targeting.
|
||||||
* The key inside the restrictionsSet is the user id of the user whom the restriction
|
|
||||||
* originated from.
|
|
||||||
* targetUserId -> originatingUserId -> restrictionBundle
|
|
||||||
*/
|
*/
|
||||||
@GuardedBy("mRestrictionsLock")
|
@GuardedBy("mRestrictionsLock")
|
||||||
private final SparseArray<RestrictionsSet> mDevicePolicyLocalUserRestrictions =
|
private final RestrictionsSet mDevicePolicyUserRestrictions = new RestrictionsSet();
|
||||||
new SparseArray<>();
|
|
||||||
|
|
||||||
@GuardedBy("mGuestRestrictions")
|
@GuardedBy("mGuestRestrictions")
|
||||||
private final Bundle mGuestRestrictions = new Bundle();
|
private final Bundle mGuestRestrictions = new Bundle();
|
||||||
@@ -2567,150 +2549,69 @@ public class UserManagerService extends IUserManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setUserRestrictionInner(int userId, @NonNull String key, boolean value) {
|
||||||
|
if (!UserRestrictionsUtils.isValidRestriction(key)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
synchronized (mRestrictionsLock) {
|
||||||
|
final Bundle newRestrictions = BundleUtils.clone(
|
||||||
|
mDevicePolicyUserRestrictions.getRestrictions(userId));
|
||||||
|
newRestrictions.putBoolean(key, value);
|
||||||
|
|
||||||
|
if (mDevicePolicyUserRestrictions.updateRestrictions(userId, newRestrictions)) {
|
||||||
|
if (userId == UserHandle.USER_ALL) {
|
||||||
|
applyUserRestrictionsForAllUsersLR();
|
||||||
|
} else {
|
||||||
|
applyUserRestrictionsLR(userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See {@link UserManagerInternal#setDevicePolicyUserRestrictions}
|
* See {@link UserManagerInternal#setDevicePolicyUserRestrictions}
|
||||||
*/
|
*/
|
||||||
private void setDevicePolicyUserRestrictionsInner(@UserIdInt int originatingUserId,
|
private void setDevicePolicyUserRestrictionsInner(@UserIdInt int originatingUserId,
|
||||||
@NonNull Bundle global, @NonNull RestrictionsSet local,
|
@NonNull Bundle global, @NonNull RestrictionsSet local,
|
||||||
boolean isDeviceOwner) {
|
boolean isDeviceOwner) {
|
||||||
boolean globalChanged, localChanged;
|
|
||||||
List<Integer> updatedLocalTargetUserIds;
|
|
||||||
synchronized (mRestrictionsLock) {
|
synchronized (mRestrictionsLock) {
|
||||||
// Update global and local restrictions if they were changed.
|
final IntArray updatedUserIds = mDevicePolicyUserRestrictions.getUserIds();
|
||||||
globalChanged = mDevicePolicyGlobalUserRestrictions
|
|
||||||
.updateRestrictions(originatingUserId, global);
|
|
||||||
updatedLocalTargetUserIds = getUpdatedTargetUserIdsFromLocalRestrictions(
|
|
||||||
originatingUserId, local);
|
|
||||||
localChanged = updateLocalRestrictionsForTargetUsersLR(originatingUserId, local,
|
|
||||||
updatedLocalTargetUserIds);
|
|
||||||
if (isDeviceOwner) {
|
|
||||||
// Remember the global restriction owner userId to be able to make a distinction
|
|
||||||
// in getUserRestrictionSource on who set local policies.
|
|
||||||
mDeviceOwnerUserId = originatingUserId;
|
|
||||||
} else {
|
|
||||||
if (mDeviceOwnerUserId == originatingUserId) {
|
|
||||||
// When profile owner sets restrictions it passes null global bundle and we
|
|
||||||
// reset global restriction owner userId.
|
|
||||||
// This means this user used to have DO, but now the DO is gone and the user
|
|
||||||
// instead has PO.
|
|
||||||
mDeviceOwnerUserId = UserHandle.USER_NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (DBG) {
|
|
||||||
Slog.d(LOG_TAG, "setDevicePolicyUserRestrictions: "
|
|
||||||
+ " originatingUserId=" + originatingUserId
|
|
||||||
+ " global=" + global + (globalChanged ? " (changed)" : "")
|
|
||||||
+ " local=" + local + (localChanged ? " (changed)" : "")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// Don't call them within the mRestrictionsLock.
|
|
||||||
synchronized (mPackagesLock) {
|
|
||||||
if (globalChanged || localChanged) {
|
|
||||||
if (updatedLocalTargetUserIds.size() == 1
|
|
||||||
&& updatedLocalTargetUserIds.contains(originatingUserId)) {
|
|
||||||
writeUserLP(getUserDataNoChecks(originatingUserId));
|
|
||||||
} else {
|
|
||||||
if (globalChanged) {
|
|
||||||
writeUserLP(getUserDataNoChecks(originatingUserId));
|
|
||||||
}
|
|
||||||
if (localChanged) {
|
|
||||||
for (int targetUserId : updatedLocalTargetUserIds) {
|
|
||||||
writeAllTargetUsersLP(targetUserId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (mRestrictionsLock) {
|
mCachedEffectiveUserRestrictions.removeAllRestrictions();
|
||||||
if (globalChanged) {
|
mDevicePolicyUserRestrictions.removeAllRestrictions();
|
||||||
applyUserRestrictionsForAllUsersLR();
|
|
||||||
} else if (localChanged) {
|
|
||||||
for (int targetUserId : updatedLocalTargetUserIds) {
|
|
||||||
applyUserRestrictionsLR(targetUserId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
mDevicePolicyUserRestrictions.updateRestrictions(UserHandle.USER_ALL, global);
|
||||||
* @return the list of updated target user ids in device policy local restrictions for a
|
|
||||||
* given originating user id.
|
|
||||||
*/
|
|
||||||
private List<Integer> getUpdatedTargetUserIdsFromLocalRestrictions(int originatingUserId,
|
|
||||||
@NonNull RestrictionsSet local) {
|
|
||||||
List<Integer> targetUserIds = new ArrayList<>();
|
|
||||||
// Update all the target user ids from the local restrictions set
|
|
||||||
for (int i = 0; i < local.size(); i++) {
|
|
||||||
targetUserIds.add(local.keyAt(i));
|
|
||||||
}
|
|
||||||
// Update the target user id from device policy local restrictions if the local
|
|
||||||
// restrictions set does not contain the target user id.
|
|
||||||
for (int i = 0; i < mDevicePolicyLocalUserRestrictions.size(); i++) {
|
|
||||||
int targetUserId = mDevicePolicyLocalUserRestrictions.keyAt(i);
|
|
||||||
RestrictionsSet restrictionsSet = mDevicePolicyLocalUserRestrictions.valueAt(i);
|
|
||||||
if (!local.containsKey(targetUserId)
|
|
||||||
&& restrictionsSet.containsKey(originatingUserId)) {
|
|
||||||
targetUserIds.add(targetUserId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return targetUserIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
final IntArray localUserIds = local.getUserIds();
|
||||||
* Update restrictions for all target users in the restriction set. If a target user does not
|
for (int i = 0; i < localUserIds.size(); i++) {
|
||||||
* exist in device policy local restrictions, remove the restrictions bundle for that target
|
final int userId = localUserIds.get(i);
|
||||||
* user originating from the specified originating user.
|
mDevicePolicyUserRestrictions.updateRestrictions(userId,
|
||||||
*/
|
local.getRestrictions(userId));
|
||||||
@GuardedBy("mRestrictionsLock")
|
updatedUserIds.add(userId);
|
||||||
private boolean updateLocalRestrictionsForTargetUsersLR(int originatingUserId,
|
|
||||||
RestrictionsSet local, List<Integer> updatedTargetUserIds) {
|
|
||||||
boolean changed = false;
|
|
||||||
for (int targetUserId : updatedTargetUserIds) {
|
|
||||||
Bundle restrictions = local.getRestrictions(targetUserId);
|
|
||||||
if (restrictions == null) {
|
|
||||||
restrictions = new Bundle();
|
|
||||||
}
|
}
|
||||||
if (getDevicePolicyLocalRestrictionsForTargetUserLR(targetUserId)
|
|
||||||
.updateRestrictions(originatingUserId, restrictions)) {
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
applyUserRestrictionsForAllUsersLR();
|
||||||
* A new restriction set is created if a restriction set does not already exist for a given
|
for (int i = 0; i < updatedUserIds.size(); i++) {
|
||||||
* target user.
|
applyUserRestrictionsLR(updatedUserIds.get(i));
|
||||||
*
|
}
|
||||||
* @return restrictions set for a given target user.
|
|
||||||
*/
|
|
||||||
@GuardedBy("mRestrictionsLock")
|
|
||||||
private @NonNull RestrictionsSet getDevicePolicyLocalRestrictionsForTargetUserLR(
|
|
||||||
int targetUserId) {
|
|
||||||
RestrictionsSet result = mDevicePolicyLocalUserRestrictions.get(targetUserId);
|
|
||||||
if (result == null) {
|
|
||||||
result = new RestrictionsSet();
|
|
||||||
mDevicePolicyLocalUserRestrictions.put(targetUserId, result);
|
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GuardedBy("mRestrictionsLock")
|
@GuardedBy("mRestrictionsLock")
|
||||||
private Bundle computeEffectiveUserRestrictionsLR(@UserIdInt int userId) {
|
private Bundle computeEffectiveUserRestrictionsLR(@UserIdInt int userId) {
|
||||||
final Bundle baseRestrictions =
|
final Bundle baseRestrictions = mBaseUserRestrictions.getRestrictionsNonNull(userId);
|
||||||
UserRestrictionsUtils.nonNull(mBaseUserRestrictions.getRestrictions(userId));
|
|
||||||
final Bundle global = mDevicePolicyGlobalUserRestrictions.mergeAll();
|
|
||||||
final RestrictionsSet local = getDevicePolicyLocalRestrictionsForTargetUserLR(userId);
|
|
||||||
|
|
||||||
if (BundleUtils.isEmpty(global) && local.isEmpty()) {
|
final Bundle global = mDevicePolicyUserRestrictions.getRestrictionsNonNull(
|
||||||
|
UserHandle.USER_ALL);
|
||||||
|
final Bundle local = mDevicePolicyUserRestrictions.getRestrictionsNonNull(userId);
|
||||||
|
|
||||||
|
if (global.isEmpty() && local.isEmpty()) {
|
||||||
// Common case first.
|
// Common case first.
|
||||||
return baseRestrictions;
|
return baseRestrictions;
|
||||||
}
|
}
|
||||||
final Bundle effective = BundleUtils.clone(baseRestrictions);
|
final Bundle effective = BundleUtils.clone(baseRestrictions);
|
||||||
UserRestrictionsUtils.merge(effective, global);
|
UserRestrictionsUtils.merge(effective, global);
|
||||||
UserRestrictionsUtils.merge(effective, local.mergeAll());
|
UserRestrictionsUtils.merge(effective, local);
|
||||||
|
|
||||||
return effective;
|
return effective;
|
||||||
}
|
}
|
||||||
@@ -2834,13 +2735,7 @@ public class UserManagerService extends IUserManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
synchronized (mRestrictionsLock) {
|
synchronized (mRestrictionsLock) {
|
||||||
// Check if it is set as a local restriction.
|
result.addAll(mDevicePolicyUserRestrictions.getEnforcingUsers(restrictionKey, userId));
|
||||||
result.addAll(getDevicePolicyLocalRestrictionsForTargetUserLR(userId).getEnforcingUsers(
|
|
||||||
restrictionKey, mDeviceOwnerUserId));
|
|
||||||
|
|
||||||
// Check if it is set as a global restriction.
|
|
||||||
result.addAll(mDevicePolicyGlobalUserRestrictions.getEnforcingUsers(restrictionKey,
|
|
||||||
mDeviceOwnerUserId));
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -2990,6 +2885,7 @@ public class UserManagerService extends IUserManager.Stub {
|
|||||||
@GuardedBy("mRestrictionsLock")
|
@GuardedBy("mRestrictionsLock")
|
||||||
private void applyUserRestrictionsLR(@UserIdInt int userId) {
|
private void applyUserRestrictionsLR(@UserIdInt int userId) {
|
||||||
updateUserRestrictionsInternalLR(null, userId);
|
updateUserRestrictionsInternalLR(null, userId);
|
||||||
|
scheduleWriteUser(getUserDataNoChecks(userId));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GuardedBy("mRestrictionsLock")
|
@GuardedBy("mRestrictionsLock")
|
||||||
@@ -3666,10 +3562,6 @@ public class UserManagerService extends IUserManager.Stub {
|
|||||||
parser.getAttributeInt(null, ATTR_USER_TYPE_VERSION, mUserTypeVersion);
|
parser.getAttributeInt(null, ATTR_USER_TYPE_VERSION, mUserTypeVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pre-O global user restriction were stored as a single bundle (as opposed to per-user
|
|
||||||
// currently), take care of it in case of upgrade.
|
|
||||||
Bundle oldDevicePolicyGlobalUserRestrictions = null;
|
|
||||||
|
|
||||||
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
||||||
if (type == XmlPullParser.START_TAG) {
|
if (type == XmlPullParser.START_TAG) {
|
||||||
final String name = parser.getName();
|
final String name = parser.getName();
|
||||||
@@ -3698,23 +3590,12 @@ public class UserManagerService extends IUserManager.Stub {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (name.equals(TAG_DEVICE_OWNER_USER_ID)
|
|
||||||
// Legacy name, should only be encountered when upgrading from pre-O.
|
|
||||||
|| name.equals(TAG_GLOBAL_RESTRICTION_OWNER_ID)) {
|
|
||||||
synchronized (mRestrictionsLock) {
|
|
||||||
mDeviceOwnerUserId =
|
|
||||||
parser.getAttributeInt(null, ATTR_ID, mDeviceOwnerUserId);
|
|
||||||
}
|
|
||||||
} else if (name.equals(TAG_DEVICE_POLICY_RESTRICTIONS)) {
|
|
||||||
// Should only happen when upgrading from pre-O (version < 7).
|
|
||||||
oldDevicePolicyGlobalUserRestrictions =
|
|
||||||
UserRestrictionsUtils.readRestrictions(parser);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateUserIds();
|
updateUserIds();
|
||||||
upgradeIfNecessaryLP(oldDevicePolicyGlobalUserRestrictions);
|
upgradeIfNecessaryLP();
|
||||||
} catch (IOException | XmlPullParserException e) {
|
} catch (IOException | XmlPullParserException e) {
|
||||||
fallbackToSingleUserLP();
|
fallbackToSingleUserLP();
|
||||||
} finally {
|
} finally {
|
||||||
@@ -3724,21 +3605,19 @@ public class UserManagerService extends IUserManager.Stub {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Upgrade steps between versions, either for fixing bugs or changing the data format.
|
* Upgrade steps between versions, either for fixing bugs or changing the data format.
|
||||||
* @param oldGlobalUserRestrictions Pre-O global device policy restrictions.
|
|
||||||
*/
|
*/
|
||||||
@GuardedBy({"mPackagesLock"})
|
@GuardedBy({"mPackagesLock"})
|
||||||
private void upgradeIfNecessaryLP(Bundle oldGlobalUserRestrictions) {
|
private void upgradeIfNecessaryLP() {
|
||||||
upgradeIfNecessaryLP(oldGlobalUserRestrictions, mUserVersion, mUserTypeVersion);
|
upgradeIfNecessaryLP(mUserVersion, mUserTypeVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Version of {@link #upgradeIfNecessaryLP(Bundle)} that takes in the userVersion for testing
|
* Version of {@link #upgradeIfNecessaryLP()} that takes in the userVersion for testing
|
||||||
* purposes. For non-tests, use {@link #upgradeIfNecessaryLP(Bundle)}.
|
* purposes. For non-tests, use {@link #upgradeIfNecessaryLP()}.
|
||||||
*/
|
*/
|
||||||
@GuardedBy({"mPackagesLock"})
|
@GuardedBy({"mPackagesLock"})
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void upgradeIfNecessaryLP(Bundle oldGlobalUserRestrictions, int userVersion,
|
void upgradeIfNecessaryLP(int userVersion, int userTypeVersion) {
|
||||||
int userTypeVersion) {
|
|
||||||
Slog.i(LOG_TAG, "Upgrading users from userVersion " + userVersion + " to " + USER_VERSION);
|
Slog.i(LOG_TAG, "Upgrading users from userVersion " + userVersion + " to " + USER_VERSION);
|
||||||
Set<Integer> userIdsToWrite = new ArraySet<>();
|
Set<Integer> userIdsToWrite = new ArraySet<>();
|
||||||
final int originalVersion = mUserVersion;
|
final int originalVersion = mUserVersion;
|
||||||
@@ -3792,16 +3671,11 @@ public class UserManagerService extends IUserManager.Stub {
|
|||||||
if (userVersion < 7) {
|
if (userVersion < 7) {
|
||||||
// Previously only one user could enforce global restrictions, now it is per-user.
|
// Previously only one user could enforce global restrictions, now it is per-user.
|
||||||
synchronized (mRestrictionsLock) {
|
synchronized (mRestrictionsLock) {
|
||||||
if (!BundleUtils.isEmpty(oldGlobalUserRestrictions)
|
if (mDevicePolicyUserRestrictions.removeRestrictionsForAllUsers(
|
||||||
&& mDeviceOwnerUserId != UserHandle.USER_NULL) {
|
UserManager.ENSURE_VERIFY_APPS)) {
|
||||||
mDevicePolicyGlobalUserRestrictions.updateRestrictions(
|
mDevicePolicyUserRestrictions.getRestrictionsNonNull(UserHandle.USER_ALL)
|
||||||
mDeviceOwnerUserId, oldGlobalUserRestrictions);
|
.putBoolean(UserManager.ENSURE_VERIFY_APPS, true);
|
||||||
}
|
}
|
||||||
// ENSURE_VERIFY_APPS is now enforced globally even if put by profile owner, so move
|
|
||||||
// it from local to global bundle for all users who set it.
|
|
||||||
UserRestrictionsUtils.moveRestriction(UserManager.ENSURE_VERIFY_APPS,
|
|
||||||
mDevicePolicyLocalUserRestrictions, mDevicePolicyGlobalUserRestrictions
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
// DISALLOW_CONFIG_WIFI was made a default guest restriction some time during version 6.
|
// DISALLOW_CONFIG_WIFI was made a default guest restriction some time during version 6.
|
||||||
final List<UserInfo> guestUsers = getGuestUsers();
|
final List<UserInfo> guestUsers = getGuestUsers();
|
||||||
@@ -4134,17 +4008,6 @@ public class UserManagerService extends IUserManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@GuardedBy({"mPackagesLock"})
|
|
||||||
private void writeAllTargetUsersLP(int originatingUserId) {
|
|
||||||
for (int i = 0; i < mDevicePolicyLocalUserRestrictions.size(); i++) {
|
|
||||||
int targetUserId = mDevicePolicyLocalUserRestrictions.keyAt(i);
|
|
||||||
RestrictionsSet restrictionsSet = mDevicePolicyLocalUserRestrictions.valueAt(i);
|
|
||||||
if (restrictionsSet.containsKey(originatingUserId)) {
|
|
||||||
writeUserLP(getUserDataNoChecks(targetUserId));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@GuardedBy({"mPackagesLock"})
|
@GuardedBy({"mPackagesLock"})
|
||||||
private void writeUserLP(UserData userData) {
|
private void writeUserLP(UserData userData) {
|
||||||
if (DBG) {
|
if (DBG) {
|
||||||
@@ -4231,11 +4094,14 @@ public class UserManagerService extends IUserManager.Stub {
|
|||||||
synchronized (mRestrictionsLock) {
|
synchronized (mRestrictionsLock) {
|
||||||
UserRestrictionsUtils.writeRestrictions(serializer,
|
UserRestrictionsUtils.writeRestrictions(serializer,
|
||||||
mBaseUserRestrictions.getRestrictions(userInfo.id), TAG_RESTRICTIONS);
|
mBaseUserRestrictions.getRestrictions(userInfo.id), TAG_RESTRICTIONS);
|
||||||
getDevicePolicyLocalRestrictionsForTargetUserLR(userInfo.id).writeRestrictions(
|
|
||||||
serializer, TAG_DEVICE_POLICY_LOCAL_RESTRICTIONS);
|
|
||||||
UserRestrictionsUtils.writeRestrictions(serializer,
|
UserRestrictionsUtils.writeRestrictions(serializer,
|
||||||
mDevicePolicyGlobalUserRestrictions.getRestrictions(userInfo.id),
|
mDevicePolicyUserRestrictions.getRestrictions(UserHandle.USER_ALL),
|
||||||
TAG_DEVICE_POLICY_GLOBAL_RESTRICTIONS);
|
TAG_DEVICE_POLICY_RESTRICTIONS);
|
||||||
|
|
||||||
|
UserRestrictionsUtils.writeRestrictions(serializer,
|
||||||
|
mDevicePolicyUserRestrictions.getRestrictions(userInfo.id),
|
||||||
|
TAG_DEVICE_POLICY_RESTRICTIONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userData.account != null) {
|
if (userData.account != null) {
|
||||||
@@ -4303,11 +4169,6 @@ public class UserManagerService extends IUserManager.Stub {
|
|||||||
.writeRestrictions(serializer, mGuestRestrictions, TAG_RESTRICTIONS);
|
.writeRestrictions(serializer, mGuestRestrictions, TAG_RESTRICTIONS);
|
||||||
}
|
}
|
||||||
serializer.endTag(null, TAG_GUEST_RESTRICTIONS);
|
serializer.endTag(null, TAG_GUEST_RESTRICTIONS);
|
||||||
serializer.startTag(null, TAG_DEVICE_OWNER_USER_ID);
|
|
||||||
synchronized (mRestrictionsLock) {
|
|
||||||
serializer.attributeInt(null, ATTR_ID, mDeviceOwnerUserId);
|
|
||||||
}
|
|
||||||
serializer.endTag(null, TAG_DEVICE_OWNER_USER_ID);
|
|
||||||
int[] userIdsToWrite;
|
int[] userIdsToWrite;
|
||||||
synchronized (mUsersLock) {
|
synchronized (mUsersLock) {
|
||||||
userIdsToWrite = new int[mUsers.size()];
|
userIdsToWrite = new int[mUsers.size()];
|
||||||
@@ -4379,7 +4240,7 @@ public class UserManagerService extends IUserManager.Stub {
|
|||||||
UserProperties userProperties = null;
|
UserProperties userProperties = null;
|
||||||
Bundle baseRestrictions = null;
|
Bundle baseRestrictions = null;
|
||||||
Bundle legacyLocalRestrictions = null;
|
Bundle legacyLocalRestrictions = null;
|
||||||
RestrictionsSet localRestrictions = null;
|
Bundle localRestrictions = null;
|
||||||
Bundle globalRestrictions = null;
|
Bundle globalRestrictions = null;
|
||||||
boolean ignorePrepareStorageErrors = true; // default is true for old users
|
boolean ignorePrepareStorageErrors = true; // default is true for old users
|
||||||
|
|
||||||
@@ -4445,8 +4306,7 @@ public class UserManagerService extends IUserManager.Stub {
|
|||||||
} else if (TAG_DEVICE_POLICY_RESTRICTIONS.equals(tag)) {
|
} else if (TAG_DEVICE_POLICY_RESTRICTIONS.equals(tag)) {
|
||||||
legacyLocalRestrictions = UserRestrictionsUtils.readRestrictions(parser);
|
legacyLocalRestrictions = UserRestrictionsUtils.readRestrictions(parser);
|
||||||
} else if (TAG_DEVICE_POLICY_LOCAL_RESTRICTIONS.equals(tag)) {
|
} else if (TAG_DEVICE_POLICY_LOCAL_RESTRICTIONS.equals(tag)) {
|
||||||
localRestrictions = RestrictionsSet.readRestrictions(parser,
|
localRestrictions = UserRestrictionsUtils.readRestrictions(parser);
|
||||||
TAG_DEVICE_POLICY_LOCAL_RESTRICTIONS);
|
|
||||||
} else if (TAG_DEVICE_POLICY_GLOBAL_RESTRICTIONS.equals(tag)) {
|
} else if (TAG_DEVICE_POLICY_GLOBAL_RESTRICTIONS.equals(tag)) {
|
||||||
globalRestrictions = UserRestrictionsUtils.readRestrictions(parser);
|
globalRestrictions = UserRestrictionsUtils.readRestrictions(parser);
|
||||||
} else if (TAG_ACCOUNT.equals(tag)) {
|
} else if (TAG_ACCOUNT.equals(tag)) {
|
||||||
@@ -4516,19 +4376,15 @@ public class UserManagerService extends IUserManager.Stub {
|
|||||||
mBaseUserRestrictions.updateRestrictions(id, baseRestrictions);
|
mBaseUserRestrictions.updateRestrictions(id, baseRestrictions);
|
||||||
}
|
}
|
||||||
if (localRestrictions != null) {
|
if (localRestrictions != null) {
|
||||||
mDevicePolicyLocalUserRestrictions.put(id, localRestrictions);
|
mDevicePolicyUserRestrictions.updateRestrictions(id, localRestrictions);
|
||||||
if (legacyLocalRestrictions != null) {
|
if (legacyLocalRestrictions != null) {
|
||||||
Slog.wtf(LOG_TAG, "Seeing both legacy and current local restrictions in xml");
|
Slog.wtf(LOG_TAG, "Seeing both legacy and current local restrictions in xml");
|
||||||
}
|
}
|
||||||
} else if (legacyLocalRestrictions != null) {
|
} else if (legacyLocalRestrictions != null) {
|
||||||
RestrictionsSet legacyLocalRestrictionsSet =
|
mDevicePolicyUserRestrictions.updateRestrictions(id, legacyLocalRestrictions);
|
||||||
legacyLocalRestrictions.isEmpty()
|
|
||||||
? new RestrictionsSet()
|
|
||||||
: new RestrictionsSet(id, legacyLocalRestrictions);
|
|
||||||
mDevicePolicyLocalUserRestrictions.put(id, legacyLocalRestrictionsSet);
|
|
||||||
}
|
}
|
||||||
if (globalRestrictions != null) {
|
if (globalRestrictions != null) {
|
||||||
mDevicePolicyGlobalUserRestrictions.updateRestrictions(id,
|
mDevicePolicyUserRestrictions.updateRestrictions(UserHandle.USER_ALL,
|
||||||
globalRestrictions);
|
globalRestrictions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5364,18 +5220,12 @@ public class UserManagerService extends IUserManager.Stub {
|
|||||||
}
|
}
|
||||||
} else if (atomTag == FrameworkStatsLog.MULTI_USER_INFO) {
|
} else if (atomTag == FrameworkStatsLog.MULTI_USER_INFO) {
|
||||||
if (UserManager.getMaxSupportedUsers() > 1) {
|
if (UserManager.getMaxSupportedUsers() > 1) {
|
||||||
int deviceOwnerUserId = UserHandle.USER_NULL;
|
|
||||||
|
|
||||||
synchronized (mRestrictionsLock) {
|
|
||||||
deviceOwnerUserId = mDeviceOwnerUserId;
|
|
||||||
}
|
|
||||||
|
|
||||||
data.add(FrameworkStatsLog.buildStatsEvent(FrameworkStatsLog.MULTI_USER_INFO,
|
data.add(FrameworkStatsLog.buildStatsEvent(FrameworkStatsLog.MULTI_USER_INFO,
|
||||||
UserManager.getMaxSupportedUsers(),
|
UserManager.getMaxSupportedUsers(),
|
||||||
isUserSwitcherEnabled(deviceOwnerUserId),
|
isUserSwitcherEnabled(UserHandle.USER_ALL),
|
||||||
UserManager.supportsMultipleUsers()
|
UserManager.supportsMultipleUsers()
|
||||||
&& !hasUserRestriction(UserManager.DISALLOW_ADD_USER,
|
&& !hasUserRestriction(UserManager.DISALLOW_ADD_USER,
|
||||||
deviceOwnerUserId)));
|
UserHandle.USER_ALL)));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Slogf.e(LOG_TAG, "Unexpected atom tag: %d", atomTag);
|
Slogf.e(LOG_TAG, "Unexpected atom tag: %d", atomTag);
|
||||||
@@ -5843,17 +5693,8 @@ public class UserManagerService extends IUserManager.Stub {
|
|||||||
mBaseUserRestrictions.remove(userId);
|
mBaseUserRestrictions.remove(userId);
|
||||||
mAppliedUserRestrictions.remove(userId);
|
mAppliedUserRestrictions.remove(userId);
|
||||||
mCachedEffectiveUserRestrictions.remove(userId);
|
mCachedEffectiveUserRestrictions.remove(userId);
|
||||||
// Remove local restrictions affecting user
|
// Remove restrictions affecting the user
|
||||||
mDevicePolicyLocalUserRestrictions.delete(userId);
|
if (mDevicePolicyUserRestrictions.remove(userId)) {
|
||||||
// Remove local restrictions set by user
|
|
||||||
boolean changed = false;
|
|
||||||
for (int i = 0; i < mDevicePolicyLocalUserRestrictions.size(); i++) {
|
|
||||||
int targetUserId = mDevicePolicyLocalUserRestrictions.keyAt(i);
|
|
||||||
changed |= getDevicePolicyLocalRestrictionsForTargetUserLR(targetUserId)
|
|
||||||
.remove(userId);
|
|
||||||
}
|
|
||||||
changed |= mDevicePolicyGlobalUserRestrictions.remove(userId);
|
|
||||||
if (changed) {
|
|
||||||
applyUserRestrictionsForAllUsersLR();
|
applyUserRestrictionsForAllUsersLR();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6587,10 +6428,12 @@ public class UserManagerService extends IUserManager.Stub {
|
|||||||
|
|
||||||
pw.println();
|
pw.println();
|
||||||
pw.println("Device properties:");
|
pw.println("Device properties:");
|
||||||
|
pw.println(" Device policy global restrictions:");
|
||||||
synchronized (mRestrictionsLock) {
|
synchronized (mRestrictionsLock) {
|
||||||
pw.println(" Device owner id:" + mDeviceOwnerUserId);
|
UserRestrictionsUtils.dumpRestrictions(
|
||||||
|
pw, " ",
|
||||||
|
mDevicePolicyUserRestrictions.getRestrictions(UserHandle.USER_ALL));
|
||||||
}
|
}
|
||||||
pw.println();
|
|
||||||
pw.println(" Guest restrictions:");
|
pw.println(" Guest restrictions:");
|
||||||
synchronized (mGuestRestrictions) {
|
synchronized (mGuestRestrictions) {
|
||||||
UserRestrictionsUtils.dumpRestrictions(pw, " ", mGuestRestrictions);
|
UserRestrictionsUtils.dumpRestrictions(pw, " ", mGuestRestrictions);
|
||||||
@@ -6768,13 +6611,10 @@ public class UserManagerService extends IUserManager.Stub {
|
|||||||
synchronized (mRestrictionsLock) {
|
synchronized (mRestrictionsLock) {
|
||||||
UserRestrictionsUtils.dumpRestrictions(
|
UserRestrictionsUtils.dumpRestrictions(
|
||||||
pw, " ", mBaseUserRestrictions.getRestrictions(userInfo.id));
|
pw, " ", mBaseUserRestrictions.getRestrictions(userInfo.id));
|
||||||
pw.println(" Device policy global restrictions:");
|
pw.println(" Device policy restrictions:");
|
||||||
UserRestrictionsUtils.dumpRestrictions(
|
UserRestrictionsUtils.dumpRestrictions(
|
||||||
pw, " ",
|
pw, " ",
|
||||||
mDevicePolicyGlobalUserRestrictions.getRestrictions(userInfo.id));
|
mDevicePolicyUserRestrictions.getRestrictions(userInfo.id));
|
||||||
pw.println(" Device policy local restrictions:");
|
|
||||||
getDevicePolicyLocalRestrictionsForTargetUserLR(
|
|
||||||
userInfo.id).dumpRestrictions(pw, " ");
|
|
||||||
pw.println(" Effective restrictions:");
|
pw.println(" Effective restrictions:");
|
||||||
UserRestrictionsUtils.dumpRestrictions(
|
UserRestrictionsUtils.dumpRestrictions(
|
||||||
pw, " ",
|
pw, " ",
|
||||||
@@ -6856,6 +6696,11 @@ public class UserManagerService extends IUserManager.Stub {
|
|||||||
global, local, isDeviceOwner);
|
global, local, isDeviceOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUserRestriction(int userId, @NonNull String key, boolean value) {
|
||||||
|
UserManagerService.this.setUserRestrictionInner(userId, key, value);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean getUserRestriction(@UserIdInt int userId, String key) {
|
public boolean getUserRestriction(@UserIdInt int userId, String key) {
|
||||||
return getUserRestrictions(userId).getBoolean(key);
|
return getUserRestrictions(userId).getBoolean(key);
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import android.platform.test.annotations.Presubmit;
|
|||||||
|
|
||||||
import androidx.test.runner.AndroidJUnit4;
|
import androidx.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
@@ -138,6 +139,7 @@ public class RestrictionsSetTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Ignore("b/268334580")
|
||||||
public void testGetEnforcingUsers_hasEnforcingUser() {
|
public void testGetEnforcingUsers_hasEnforcingUser() {
|
||||||
mRestrictionsSet.updateRestrictions(originatingUserId,
|
mRestrictionsSet.updateRestrictions(originatingUserId,
|
||||||
newRestrictions(UserManager.ENSURE_VERIFY_APPS));
|
newRestrictions(UserManager.ENSURE_VERIFY_APPS));
|
||||||
@@ -154,6 +156,7 @@ public class RestrictionsSetTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Ignore("b/268334580")
|
||||||
public void testGetEnforcingUsers_hasMultipleEnforcingUsers() {
|
public void testGetEnforcingUsers_hasMultipleEnforcingUsers() {
|
||||||
int originatingUserId2 = 10;
|
int originatingUserId2 = 10;
|
||||||
mRestrictionsSet.updateRestrictions(originatingUserId,
|
mRestrictionsSet.updateRestrictions(originatingUserId,
|
||||||
|
|||||||
@@ -230,7 +230,7 @@ public class UserManagerServiceUserInfoTest {
|
|||||||
mUserManagerService.putUserInfo(createUser(105, FLAG_SYSTEM | FLAG_FULL, null));
|
mUserManagerService.putUserInfo(createUser(105, FLAG_SYSTEM | FLAG_FULL, null));
|
||||||
mUserManagerService.putUserInfo(createUser(106, FLAG_DEMO | FLAG_FULL, null));
|
mUserManagerService.putUserInfo(createUser(106, FLAG_DEMO | FLAG_FULL, null));
|
||||||
|
|
||||||
mUserManagerService.upgradeIfNecessaryLP(null, versionToTest - 1, userTypeVersion);
|
mUserManagerService.upgradeIfNecessaryLP(versionToTest - 1, userTypeVersion);
|
||||||
|
|
||||||
assertTrue(mUserManagerService.isUserOfType(100, USER_TYPE_PROFILE_MANAGED));
|
assertTrue(mUserManagerService.isUserOfType(100, USER_TYPE_PROFILE_MANAGED));
|
||||||
assertTrue((mUserManagerService.getUserInfo(100).flags & FLAG_PROFILE) != 0);
|
assertTrue((mUserManagerService.getUserInfo(100).flags & FLAG_PROFILE) != 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user