Merge "Make ENSURE_VERIFY_APPS global even when set by PO."
This commit is contained in:
@@ -32748,7 +32748,8 @@ package android.os {
|
||||
method public android.os.UserHandle getUserForSerialNumber(long);
|
||||
method public java.lang.String getUserName();
|
||||
method public java.util.List<android.os.UserHandle> getUserProfiles();
|
||||
method public int getUserRestrictionSource(java.lang.String, android.os.UserHandle);
|
||||
method public deprecated int getUserRestrictionSource(java.lang.String, android.os.UserHandle);
|
||||
method public java.util.List<android.os.UserManager.EnforcingUser> getUserRestrictionSources(java.lang.String, android.os.UserHandle);
|
||||
method public android.os.Bundle getUserRestrictions();
|
||||
method public android.os.Bundle getUserRestrictions(android.os.UserHandle);
|
||||
method public boolean hasUserRestriction(java.lang.String);
|
||||
@@ -32814,6 +32815,14 @@ package android.os {
|
||||
field public static final int USER_CREATION_FAILED_NO_MORE_USERS = 2; // 0x2
|
||||
}
|
||||
|
||||
public static final class UserManager.EnforcingUser implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public android.os.UserHandle getUserHandle();
|
||||
method public int getUserRestrictionSource();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<android.os.UserManager.EnforcingUser> CREATOR;
|
||||
}
|
||||
|
||||
public static abstract class UserManager.UserRestrictionSource implements java.lang.annotation.Annotation {
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ package android.os;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.PersistableBundle;
|
||||
import android.os.UserManager;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.content.IntentSender;
|
||||
import android.content.RestrictionEntry;
|
||||
@@ -61,6 +62,7 @@ interface IUserManager {
|
||||
int getUserSerialNumber(int userHandle);
|
||||
int getUserHandle(int userSerialNumber);
|
||||
int getUserRestrictionSource(String restrictionKey, int userHandle);
|
||||
List<UserManager.EnforcingUser> getUserRestrictionSources(String restrictionKey, int userHandle);
|
||||
Bundle getUserRestrictions(int userHandle);
|
||||
boolean hasBaseUserRestriction(String restrictionKey, int userHandle);
|
||||
boolean hasUserRestriction(in String restrictionKey, int userHandle);
|
||||
|
||||
20
core/java/android/os/UserManager.aidl
Normal file
20
core/java/android/os/UserManager.aidl
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
**
|
||||
** Copyright 2016, The Android Open Source Project
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
|
||||
package android.os;
|
||||
|
||||
parcelable UserManager.EnforcingUser;
|
||||
@@ -1187,7 +1187,9 @@ public class UserManager {
|
||||
* @return The source of user restriction. Any combination of {@link #RESTRICTION_NOT_SET},
|
||||
* {@link #RESTRICTION_SOURCE_SYSTEM}, {@link #RESTRICTION_SOURCE_DEVICE_OWNER}
|
||||
* and {@link #RESTRICTION_SOURCE_PROFILE_OWNER}
|
||||
* @deprecated use {@link #getUserRestrictionSources(String, int)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@SystemApi
|
||||
@UserRestrictionSource
|
||||
public int getUserRestrictionSource(String restrictionKey, UserHandle userHandle) {
|
||||
@@ -1198,6 +1200,25 @@ public class UserManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*
|
||||
* Returns a list of users who set a user restriction on a given user.
|
||||
* Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
|
||||
* @param restrictionKey the string key representing the restriction
|
||||
* @param userHandle the UserHandle of the user for whom to retrieve the restrictions.
|
||||
* @return a list of user ids enforcing this restriction.
|
||||
*/
|
||||
@SystemApi
|
||||
public List<EnforcingUser> getUserRestrictionSources(
|
||||
String restrictionKey, UserHandle userHandle) {
|
||||
try {
|
||||
return mService.getUserRestrictionSources(restrictionKey, userHandle.getIdentifier());
|
||||
} catch (RemoteException re) {
|
||||
throw re.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user-wide restrictions imposed on this user.
|
||||
* @return a Bundle containing all the restrictions.
|
||||
@@ -2310,8 +2331,8 @@ public class UserManager {
|
||||
* @hide
|
||||
* Checks if any uninitialized user has the specific seed account name and type.
|
||||
*
|
||||
* @param mAccountName The account name to check for
|
||||
* @param mAccountType The account type of the account to check for
|
||||
* @param accountName The account name to check for
|
||||
* @param accountType The account type of the account to check for
|
||||
* @return whether the seed account was found
|
||||
*/
|
||||
public boolean someUserHasSeedAccount(String accountName, String accountType) {
|
||||
@@ -2321,4 +2342,73 @@ public class UserManager {
|
||||
throw re.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* User that enforces a restriction.
|
||||
*
|
||||
* @see #getUserRestrictionSources(String, UserHandle)
|
||||
*/
|
||||
@SystemApi
|
||||
public static final class EnforcingUser implements Parcelable {
|
||||
private final @UserIdInt int userId;
|
||||
private final @UserRestrictionSource int userRestrictionSource;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public EnforcingUser(
|
||||
@UserIdInt int userId, @UserRestrictionSource int userRestrictionSource) {
|
||||
this.userId = userId;
|
||||
this.userRestrictionSource = userRestrictionSource;
|
||||
}
|
||||
|
||||
private EnforcingUser(Parcel in) {
|
||||
userId = in.readInt();
|
||||
userRestrictionSource = in.readInt();
|
||||
}
|
||||
|
||||
public static final Creator<EnforcingUser> CREATOR = new Creator<EnforcingUser>() {
|
||||
@Override
|
||||
public EnforcingUser createFromParcel(Parcel in) {
|
||||
return new EnforcingUser(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnforcingUser[] newArray(int size) {
|
||||
return new EnforcingUser[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(userId);
|
||||
dest.writeInt(userRestrictionSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an id of the enforcing user.
|
||||
*
|
||||
* <p> Will be UserHandle.USER_NULL when restriction is set by the system.
|
||||
*/
|
||||
public UserHandle getUserHandle() {
|
||||
return UserHandle.of(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the status of the enforcing user.
|
||||
*
|
||||
* <p> One of {@link #RESTRICTION_SOURCE_SYSTEM},
|
||||
* {@link #RESTRICTION_SOURCE_DEVICE_OWNER} and
|
||||
* {@link #RESTRICTION_SOURCE_PROFILE_OWNER}
|
||||
*/
|
||||
public @UserRestrictionSource int getUserRestrictionSource() {
|
||||
return userRestrictionSource;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package android.os;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.graphics.Bitmap;
|
||||
@@ -24,6 +23,10 @@ import android.graphics.Bitmap;
|
||||
* @hide Only for use within the system server.
|
||||
*/
|
||||
public abstract class UserManagerInternal {
|
||||
public static final int CAMERA_NOT_DISABLED = 0;
|
||||
public static final int CAMERA_DISABLED_LOCALLY = 1;
|
||||
public static final int CAMERA_DISABLED_GLOBALLY = 2;
|
||||
|
||||
public interface UserRestrictionsListener {
|
||||
/**
|
||||
* Called when a user restriction changes.
|
||||
@@ -36,18 +39,19 @@ public abstract class UserManagerInternal {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by {@link com.android.server.devicepolicy.DevicePolicyManagerService}
|
||||
* to set per-user as well as global user restrictions.
|
||||
* Called by {@link com.android.server.devicepolicy.DevicePolicyManagerService} to set
|
||||
* restrictions enforced by the user.
|
||||
*
|
||||
* @param userId target user id for the local restrictions.
|
||||
* @param localRestrictions per-user restrictions.
|
||||
* Caller must not change it once passed to this method.
|
||||
* @param globalRestrictions global restrictions set by DO. Must be null when PO changed user
|
||||
* restrictions, in which case global restrictions won't change.
|
||||
* Caller must not change it once passed to this method.
|
||||
* @param restrictions a bundle of user restrictions.
|
||||
* @param isDeviceOwner whether {@code userId} corresponds to device owner user id.
|
||||
* @param cameraRestrictionScope is camera disabled and if so what is the scope of restriction.
|
||||
* Should be one of {@link #CAMERA_NOT_DISABLED}, {@link #CAMERA_DISABLED_LOCALLY} or
|
||||
* {@link #CAMERA_DISABLED_GLOBALLY}
|
||||
*/
|
||||
public abstract void setDevicePolicyUserRestrictions(int userId,
|
||||
@NonNull Bundle localRestrictions, @Nullable Bundle globalRestrictions);
|
||||
public abstract void setDevicePolicyUserRestrictions(int userId, @Nullable Bundle restrictions,
|
||||
boolean isDeviceOwner, int cameraRestrictionScope);
|
||||
|
||||
/**
|
||||
* Returns the "base" user restrictions.
|
||||
*
|
||||
|
||||
@@ -67,6 +67,7 @@ import android.os.ShellCommand;
|
||||
import android.os.SystemProperties;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.os.UserManager.EnforcingUser;
|
||||
import android.os.UserManagerInternal;
|
||||
import android.os.UserManagerInternal.UserRestrictionsListener;
|
||||
import android.os.storage.StorageManager;
|
||||
@@ -118,6 +119,7 @@ import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -162,7 +164,11 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
private static final String TAG_USER = "user";
|
||||
private static final String TAG_RESTRICTIONS = "restrictions";
|
||||
private static final String TAG_DEVICE_POLICY_RESTRICTIONS = "device_policy_restrictions";
|
||||
private static final String TAG_DEVICE_POLICY_GLOBAL_RESTRICTIONS =
|
||||
"device_policy_global_restrictions";
|
||||
/** Legacy name for device owner id tag. */
|
||||
private static final String TAG_GLOBAL_RESTRICTION_OWNER_ID = "globalRestrictionOwnerUserId";
|
||||
private static final String TAG_DEVICE_OWNER_USER_ID = "deviceOwnerUserId";
|
||||
private static final String TAG_ENTRY = "entry";
|
||||
private static final String TAG_VALUE = "value";
|
||||
private static final String TAG_SEED_ACCOUNT_OPTIONS = "seedAccountOptions";
|
||||
@@ -202,7 +208,7 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
@VisibleForTesting
|
||||
static final int MAX_RECENTLY_REMOVED_IDS_SIZE = 100;
|
||||
|
||||
private static final int USER_VERSION = 6;
|
||||
private static final int USER_VERSION = 7;
|
||||
|
||||
private static final long EPOCH_PLUS_30_YEARS = 30L * 365 * 24 * 60 * 60 * 1000L; // ms
|
||||
|
||||
@@ -267,7 +273,7 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
|
||||
/**
|
||||
* User restrictions set via UserManager. This doesn't include restrictions set by
|
||||
* device owner / profile owners.
|
||||
* device owner / profile owners. Only non-empty restriction bundles are stored.
|
||||
*
|
||||
* DO NOT Change existing {@link Bundle} in it. When changing a restriction for a user,
|
||||
* a new {@link Bundle} should always be created and set. This is because a {@link Bundle}
|
||||
@@ -305,20 +311,21 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
|
||||
/**
|
||||
* User restrictions set by {@link com.android.server.devicepolicy.DevicePolicyManagerService}
|
||||
* that should be applied to all users, including guests.
|
||||
* that should be applied to all users, including guests. Only non-empty restriction bundles are
|
||||
* stored.
|
||||
*/
|
||||
@GuardedBy("mRestrictionsLock")
|
||||
private Bundle mDevicePolicyGlobalUserRestrictions;
|
||||
private final SparseArray<Bundle> mDevicePolicyGlobalUserRestrictions = new SparseArray<>();
|
||||
|
||||
/**
|
||||
* Id of the user that set global restrictions.
|
||||
*/
|
||||
@GuardedBy("mRestrictionsLock")
|
||||
private int mGlobalRestrictionOwnerUserId = UserHandle.USER_NULL;
|
||||
private int mDeviceOwnerUserId = UserHandle.USER_NULL;
|
||||
|
||||
/**
|
||||
* User restrictions set by {@link com.android.server.devicepolicy.DevicePolicyManagerService}
|
||||
* for each user.
|
||||
* for each user. Only non-empty restriction bundles are stored.
|
||||
*/
|
||||
@GuardedBy("mRestrictionsLock")
|
||||
private final SparseArray<Bundle> mDevicePolicyLocalUserRestrictions = new SparseArray<>();
|
||||
@@ -1176,39 +1183,36 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link UserManagerInternal#setDevicePolicyUserRestrictions(int, Bundle, Bundle)}
|
||||
* See {@link UserManagerInternal#setDevicePolicyUserRestrictions}
|
||||
*/
|
||||
void setDevicePolicyUserRestrictionsInner(int userId, @NonNull Bundle local,
|
||||
@Nullable Bundle global) {
|
||||
Preconditions.checkNotNull(local);
|
||||
boolean globalChanged = false;
|
||||
boolean localChanged;
|
||||
private void setDevicePolicyUserRestrictionsInner(int userId, @Nullable Bundle restrictions,
|
||||
boolean isDeviceOwner, int cameraRestrictionScope) {
|
||||
final Bundle global = new Bundle();
|
||||
final Bundle local = new Bundle();
|
||||
|
||||
// Sort restrictions into local and global ensuring they don't overlap.
|
||||
UserRestrictionsUtils.sortToGlobalAndLocal(restrictions, isDeviceOwner,
|
||||
cameraRestrictionScope, global, local);
|
||||
|
||||
boolean globalChanged, localChanged;
|
||||
synchronized (mRestrictionsLock) {
|
||||
if (global != null) {
|
||||
// Update global.
|
||||
globalChanged = !UserRestrictionsUtils.areEqual(
|
||||
mDevicePolicyGlobalUserRestrictions, global);
|
||||
if (globalChanged) {
|
||||
mDevicePolicyGlobalUserRestrictions = global;
|
||||
}
|
||||
// Update global and local restrictions if they were changed.
|
||||
globalChanged = updateRestrictionsIfNeededLR(
|
||||
userId, global, mDevicePolicyGlobalUserRestrictions);
|
||||
localChanged = updateRestrictionsIfNeededLR(
|
||||
userId, local, mDevicePolicyLocalUserRestrictions);
|
||||
|
||||
if (isDeviceOwner) {
|
||||
// Remember the global restriction owner userId to be able to make a distinction
|
||||
// in getUserRestrictionSource on who set local policies.
|
||||
mGlobalRestrictionOwnerUserId = userId;
|
||||
mDeviceOwnerUserId = userId;
|
||||
} else {
|
||||
if (mGlobalRestrictionOwnerUserId == userId) {
|
||||
if (mDeviceOwnerUserId == userId) {
|
||||
// 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.
|
||||
mGlobalRestrictionOwnerUserId = UserHandle.USER_NULL;
|
||||
}
|
||||
}
|
||||
{
|
||||
// Update local.
|
||||
final Bundle prev = mDevicePolicyLocalUserRestrictions.get(userId);
|
||||
localChanged = !UserRestrictionsUtils.areEqual(prev, local);
|
||||
if (localChanged) {
|
||||
mDevicePolicyLocalUserRestrictions.put(userId, local);
|
||||
mDeviceOwnerUserId = UserHandle.USER_NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1220,12 +1224,9 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
}
|
||||
// Don't call them within the mRestrictionsLock.
|
||||
synchronized (mPackagesLock) {
|
||||
if (localChanged) {
|
||||
if (localChanged || globalChanged) {
|
||||
writeUserLP(getUserDataNoChecks(userId));
|
||||
}
|
||||
if (globalChanged) {
|
||||
writeUserListLP();
|
||||
}
|
||||
}
|
||||
|
||||
synchronized (mRestrictionsLock) {
|
||||
@@ -1237,11 +1238,30 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates restriction bundle for a given user in a given restriction array. If new bundle is
|
||||
* empty, record is removed from the array.
|
||||
* @return whether restrictions bundle is different from the old one.
|
||||
*/
|
||||
private boolean updateRestrictionsIfNeededLR(int userId, @Nullable Bundle restrictions,
|
||||
SparseArray<Bundle> restrictionsArray) {
|
||||
final boolean changed =
|
||||
!UserRestrictionsUtils.areEqual(restrictionsArray.get(userId), restrictions);
|
||||
if (changed) {
|
||||
if (!UserRestrictionsUtils.isEmpty(restrictions)) {
|
||||
restrictionsArray.put(userId, restrictions);
|
||||
} else {
|
||||
restrictionsArray.delete(userId);
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
@GuardedBy("mRestrictionsLock")
|
||||
private Bundle computeEffectiveUserRestrictionsLR(int userId) {
|
||||
final Bundle baseRestrictions =
|
||||
UserRestrictionsUtils.nonNull(mBaseUserRestrictions.get(userId));
|
||||
final Bundle global = mDevicePolicyGlobalUserRestrictions;
|
||||
final Bundle global = UserRestrictionsUtils.mergeAll(mDevicePolicyGlobalUserRestrictions);
|
||||
final Bundle local = mDevicePolicyLocalUserRestrictions.get(userId);
|
||||
|
||||
if (UserRestrictionsUtils.isEmpty(global) && UserRestrictionsUtils.isEmpty(local)) {
|
||||
@@ -1299,39 +1319,58 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
*/
|
||||
@Override
|
||||
public int getUserRestrictionSource(String restrictionKey, int userId) {
|
||||
checkManageUsersPermission("getUserRestrictionSource");
|
||||
List<EnforcingUser> enforcingUsers = getUserRestrictionSources(restrictionKey, userId);
|
||||
// Get "bitwise or" of restriction sources for all enforcing users.
|
||||
int result = UserManager.RESTRICTION_NOT_SET;
|
||||
for (int i = enforcingUsers.size() - 1; i >= 0; i--) {
|
||||
result |= enforcingUsers.get(i).getUserRestrictionSource();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EnforcingUser> getUserRestrictionSources(
|
||||
String restrictionKey, @UserIdInt int userId) {
|
||||
checkManageUsersPermission("getUserRestrictionSource");
|
||||
|
||||
// Shortcut for the most common case
|
||||
if (!hasUserRestriction(restrictionKey, userId)) {
|
||||
return result;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final List<EnforcingUser> result = new ArrayList<>();
|
||||
|
||||
// Check if it is base restriction.
|
||||
if (hasBaseUserRestriction(restrictionKey, userId)) {
|
||||
result |= UserManager.RESTRICTION_SOURCE_SYSTEM;
|
||||
result.add(new EnforcingUser(
|
||||
UserHandle.USER_NULL, UserManager.RESTRICTION_SOURCE_SYSTEM));
|
||||
}
|
||||
|
||||
synchronized(mRestrictionsLock) {
|
||||
Bundle localRestrictions = mDevicePolicyLocalUserRestrictions.get(userId);
|
||||
if (!UserRestrictionsUtils.isEmpty(localRestrictions)
|
||||
&& localRestrictions.getBoolean(restrictionKey)) {
|
||||
// Local restrictions may have been set by device owner the userId of which is
|
||||
// stored in mGlobalRestrictionOwnerUserId.
|
||||
if (mGlobalRestrictionOwnerUserId == userId) {
|
||||
result |= UserManager.RESTRICTION_SOURCE_DEVICE_OWNER;
|
||||
} else {
|
||||
result |= UserManager.RESTRICTION_SOURCE_PROFILE_OWNER;
|
||||
synchronized (mRestrictionsLock) {
|
||||
// Check if it is set by profile owner.
|
||||
Bundle profileOwnerRestrictions = mDevicePolicyLocalUserRestrictions.get(userId);
|
||||
if (UserRestrictionsUtils.contains(profileOwnerRestrictions, restrictionKey)) {
|
||||
result.add(getEnforcingUserLocked(userId));
|
||||
}
|
||||
|
||||
// Iterate over all users who enforce global restrictions.
|
||||
for (int i = mDevicePolicyGlobalUserRestrictions.size() - 1; i >= 0; i--) {
|
||||
Bundle globalRestrictions = mDevicePolicyGlobalUserRestrictions.valueAt(i);
|
||||
int profileUserId = mDevicePolicyGlobalUserRestrictions.keyAt(i);
|
||||
if (UserRestrictionsUtils.contains(globalRestrictions, restrictionKey)) {
|
||||
result.add(getEnforcingUserLocked(profileUserId));
|
||||
}
|
||||
}
|
||||
if (!UserRestrictionsUtils.isEmpty(mDevicePolicyGlobalUserRestrictions)
|
||||
&& mDevicePolicyGlobalUserRestrictions.getBoolean(restrictionKey)) {
|
||||
result |= UserManager.RESTRICTION_SOURCE_DEVICE_OWNER;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private EnforcingUser getEnforcingUserLocked(@UserIdInt int userId) {
|
||||
int source = mDeviceOwnerUserId == userId ? UserManager.RESTRICTION_SOURCE_DEVICE_OWNER
|
||||
: UserManager.RESTRICTION_SOURCE_PROFILE_OWNER;
|
||||
return new EnforcingUser(userId, source);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return UserRestrictions that are in effect currently. This always returns a new
|
||||
* {@link Bundle}.
|
||||
@@ -1374,28 +1413,26 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
* Optionally updating user restrictions, calculate the effective user restrictions and also
|
||||
* propagate to other services and system settings.
|
||||
*
|
||||
* @param newRestrictions User restrictions to set.
|
||||
* @param newBaseRestrictions User restrictions to set.
|
||||
* If null, will not update user restrictions and only does the propagation.
|
||||
* @param userId target user ID.
|
||||
*/
|
||||
@GuardedBy("mRestrictionsLock")
|
||||
private void updateUserRestrictionsInternalLR(
|
||||
@Nullable Bundle newRestrictions, int userId) {
|
||||
|
||||
@Nullable Bundle newBaseRestrictions, int userId) {
|
||||
final Bundle prevAppliedRestrictions = UserRestrictionsUtils.nonNull(
|
||||
mAppliedUserRestrictions.get(userId));
|
||||
|
||||
// Update base restrictions.
|
||||
if (newRestrictions != null) {
|
||||
// If newRestrictions == the current one, it's probably a bug.
|
||||
if (newBaseRestrictions != null) {
|
||||
// If newBaseRestrictions == the current one, it's probably a bug.
|
||||
final Bundle prevBaseRestrictions = mBaseUserRestrictions.get(userId);
|
||||
|
||||
Preconditions.checkState(prevBaseRestrictions != newRestrictions);
|
||||
Preconditions.checkState(prevBaseRestrictions != newBaseRestrictions);
|
||||
Preconditions.checkState(mCachedEffectiveUserRestrictions.get(userId)
|
||||
!= newRestrictions);
|
||||
!= newBaseRestrictions);
|
||||
|
||||
if (!UserRestrictionsUtils.areEqual(prevBaseRestrictions, newRestrictions)) {
|
||||
mBaseUserRestrictions.put(userId, newRestrictions);
|
||||
if (updateRestrictionsIfNeededLR(userId, newBaseRestrictions, mBaseUserRestrictions)) {
|
||||
scheduleWriteUser(getUserDataNoChecks(userId));
|
||||
}
|
||||
}
|
||||
@@ -1746,7 +1783,9 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
final Bundle newDevicePolicyGlobalUserRestrictions = new Bundle();
|
||||
// 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) {
|
||||
if (type == XmlPullParser.START_TAG) {
|
||||
@@ -1771,29 +1810,30 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
if (type == XmlPullParser.START_TAG) {
|
||||
if (parser.getName().equals(TAG_RESTRICTIONS)) {
|
||||
synchronized (mGuestRestrictions) {
|
||||
UserRestrictionsUtils
|
||||
.readRestrictions(parser, mGuestRestrictions);
|
||||
mGuestRestrictions.putAll(
|
||||
UserRestrictionsUtils.readRestrictions(parser));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (name.equals(TAG_DEVICE_POLICY_RESTRICTIONS)) {
|
||||
UserRestrictionsUtils.readRestrictions(parser,
|
||||
newDevicePolicyGlobalUserRestrictions);
|
||||
} else if (name.equals(TAG_GLOBAL_RESTRICTION_OWNER_ID)) {
|
||||
} 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)) {
|
||||
String ownerUserId = parser.getAttributeValue(null, ATTR_ID);
|
||||
if (ownerUserId != null) {
|
||||
mGlobalRestrictionOwnerUserId = Integer.parseInt(ownerUserId);
|
||||
mDeviceOwnerUserId = Integer.parseInt(ownerUserId);
|
||||
}
|
||||
} else if (name.equals(TAG_DEVICE_POLICY_RESTRICTIONS)) {
|
||||
// Should only happen when upgrading from pre-O (version < 7).
|
||||
oldDevicePolicyGlobalUserRestrictions =
|
||||
UserRestrictionsUtils.readRestrictions(parser);
|
||||
}
|
||||
}
|
||||
}
|
||||
synchronized (mRestrictionsLock) {
|
||||
mDevicePolicyGlobalUserRestrictions = newDevicePolicyGlobalUserRestrictions;
|
||||
}
|
||||
|
||||
updateUserIds();
|
||||
upgradeIfNecessaryLP();
|
||||
upgradeIfNecessaryLP(oldDevicePolicyGlobalUserRestrictions);
|
||||
} catch (IOException | XmlPullParserException e) {
|
||||
fallbackToSingleUserLP();
|
||||
} finally {
|
||||
@@ -1803,8 +1843,9 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
|
||||
/**
|
||||
* Upgrade steps between versions, either for fixing bugs or changing the data format.
|
||||
* @param oldGlobalUserRestrictions Pre-O global device policy restrictions.
|
||||
*/
|
||||
private void upgradeIfNecessaryLP() {
|
||||
private void upgradeIfNecessaryLP(Bundle oldGlobalUserRestrictions) {
|
||||
final int originalVersion = mUserVersion;
|
||||
int userVersion = mUserVersion;
|
||||
if (userVersion < 1) {
|
||||
@@ -1855,6 +1896,23 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
userVersion = 6;
|
||||
}
|
||||
|
||||
if (userVersion < 7) {
|
||||
// Previously only one user could enforce global restrictions, now it is per-user.
|
||||
synchronized (mRestrictionsLock) {
|
||||
if (!UserRestrictionsUtils.isEmpty(oldGlobalUserRestrictions)
|
||||
&& mDeviceOwnerUserId != UserHandle.USER_NULL) {
|
||||
mDevicePolicyGlobalUserRestrictions.put(
|
||||
mDeviceOwnerUserId, oldGlobalUserRestrictions);
|
||||
}
|
||||
// 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
|
||||
);
|
||||
}
|
||||
userVersion = 7;
|
||||
}
|
||||
|
||||
if (userVersion < USER_VERSION) {
|
||||
Slog.w(LOG_TAG, "User version " + mUserVersion + " didn't upgrade as expected to "
|
||||
+ USER_VERSION);
|
||||
@@ -1893,8 +1951,10 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
Log.e(LOG_TAG, "Couldn't find resource: config_defaultFirstUserRestrictions", e);
|
||||
}
|
||||
|
||||
synchronized (mRestrictionsLock) {
|
||||
mBaseUserRestrictions.append(UserHandle.USER_SYSTEM, restrictions);
|
||||
if (!restrictions.isEmpty()) {
|
||||
synchronized (mRestrictionsLock) {
|
||||
mBaseUserRestrictions.append(UserHandle.USER_SYSTEM, restrictions);
|
||||
}
|
||||
}
|
||||
|
||||
updateUserIds();
|
||||
@@ -2004,6 +2064,9 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
UserRestrictionsUtils.writeRestrictions(serializer,
|
||||
mDevicePolicyLocalUserRestrictions.get(userInfo.id),
|
||||
TAG_DEVICE_POLICY_RESTRICTIONS);
|
||||
UserRestrictionsUtils.writeRestrictions(serializer,
|
||||
mDevicePolicyGlobalUserRestrictions.get(userInfo.id),
|
||||
TAG_DEVICE_POLICY_GLOBAL_RESTRICTIONS);
|
||||
}
|
||||
|
||||
if (userData.account != null) {
|
||||
@@ -2057,13 +2120,9 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
.writeRestrictions(serializer, mGuestRestrictions, TAG_RESTRICTIONS);
|
||||
}
|
||||
serializer.endTag(null, TAG_GUEST_RESTRICTIONS);
|
||||
synchronized (mRestrictionsLock) {
|
||||
UserRestrictionsUtils.writeRestrictions(serializer,
|
||||
mDevicePolicyGlobalUserRestrictions, TAG_DEVICE_POLICY_RESTRICTIONS);
|
||||
}
|
||||
serializer.startTag(null, TAG_GLOBAL_RESTRICTION_OWNER_ID);
|
||||
serializer.attribute(null, ATTR_ID, Integer.toString(mGlobalRestrictionOwnerUserId));
|
||||
serializer.endTag(null, TAG_GLOBAL_RESTRICTION_OWNER_ID);
|
||||
serializer.startTag(null, TAG_DEVICE_OWNER_USER_ID);
|
||||
serializer.attribute(null, ATTR_ID, Integer.toString(mDeviceOwnerUserId));
|
||||
serializer.endTag(null, TAG_DEVICE_OWNER_USER_ID);
|
||||
int[] userIdsToWrite;
|
||||
synchronized (mUsersLock) {
|
||||
userIdsToWrite = new int[mUsers.size()];
|
||||
@@ -2125,8 +2184,9 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
String seedAccountName = null;
|
||||
String seedAccountType = null;
|
||||
PersistableBundle seedAccountOptions = null;
|
||||
Bundle baseRestrictions = new Bundle();
|
||||
Bundle localRestrictions = new Bundle();
|
||||
Bundle baseRestrictions = null;
|
||||
Bundle localRestrictions = null;
|
||||
Bundle globalRestrictions = null;
|
||||
|
||||
XmlPullParser parser = Xml.newPullParser();
|
||||
parser.setInput(is, StandardCharsets.UTF_8.name());
|
||||
@@ -2187,9 +2247,11 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
name = parser.getText();
|
||||
}
|
||||
} else if (TAG_RESTRICTIONS.equals(tag)) {
|
||||
UserRestrictionsUtils.readRestrictions(parser, baseRestrictions);
|
||||
baseRestrictions = UserRestrictionsUtils.readRestrictions(parser);
|
||||
} else if (TAG_DEVICE_POLICY_RESTRICTIONS.equals(tag)) {
|
||||
UserRestrictionsUtils.readRestrictions(parser, localRestrictions);
|
||||
localRestrictions = UserRestrictionsUtils.readRestrictions(parser);
|
||||
} else if (TAG_DEVICE_POLICY_GLOBAL_RESTRICTIONS.equals(tag)) {
|
||||
globalRestrictions = UserRestrictionsUtils.readRestrictions(parser);
|
||||
} else if (TAG_ACCOUNT.equals(tag)) {
|
||||
type = parser.next();
|
||||
if (type == XmlPullParser.TEXT) {
|
||||
@@ -2224,8 +2286,15 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
userData.seedAccountOptions = seedAccountOptions;
|
||||
|
||||
synchronized (mRestrictionsLock) {
|
||||
mBaseUserRestrictions.put(id, baseRestrictions);
|
||||
mDevicePolicyLocalUserRestrictions.put(id, localRestrictions);
|
||||
if (baseRestrictions != null) {
|
||||
mBaseUserRestrictions.put(id, baseRestrictions);
|
||||
}
|
||||
if (localRestrictions != null) {
|
||||
mDevicePolicyLocalUserRestrictions.put(id, localRestrictions);
|
||||
}
|
||||
if (globalRestrictions != null) {
|
||||
mDevicePolicyGlobalUserRestrictions.put(id, globalRestrictions);
|
||||
}
|
||||
}
|
||||
return userData;
|
||||
}
|
||||
@@ -2731,6 +2800,10 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
mAppliedUserRestrictions.remove(userHandle);
|
||||
mCachedEffectiveUserRestrictions.remove(userHandle);
|
||||
mDevicePolicyLocalUserRestrictions.remove(userHandle);
|
||||
if (mDevicePolicyGlobalUserRestrictions.get(userHandle) != null) {
|
||||
mDevicePolicyGlobalUserRestrictions.remove(userHandle);
|
||||
applyUserRestrictionsForAllUsersLR();
|
||||
}
|
||||
}
|
||||
// Update the user list
|
||||
synchronized (mPackagesLock) {
|
||||
@@ -3420,6 +3493,9 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
synchronized (mRestrictionsLock) {
|
||||
UserRestrictionsUtils.dumpRestrictions(
|
||||
pw, " ", mBaseUserRestrictions.get(userInfo.id));
|
||||
pw.println(" Device policy global restrictions:");
|
||||
UserRestrictionsUtils.dumpRestrictions(
|
||||
pw, " ", mDevicePolicyGlobalUserRestrictions.get(userInfo.id));
|
||||
pw.println(" Device policy local restrictions:");
|
||||
UserRestrictionsUtils.dumpRestrictions(
|
||||
pw, " ", mDevicePolicyLocalUserRestrictions.get(userInfo.id));
|
||||
@@ -3448,13 +3524,7 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
}
|
||||
}
|
||||
pw.println();
|
||||
pw.println(" Device policy global restrictions:");
|
||||
synchronized (mRestrictionsLock) {
|
||||
UserRestrictionsUtils
|
||||
.dumpRestrictions(pw, " ", mDevicePolicyGlobalUserRestrictions);
|
||||
}
|
||||
pw.println();
|
||||
pw.println(" Global restrictions owner id:" + mGlobalRestrictionOwnerUserId);
|
||||
pw.println(" Device owner id:" + mDeviceOwnerUserId);
|
||||
pw.println();
|
||||
pw.println(" Guest restrictions:");
|
||||
synchronized (mGuestRestrictions) {
|
||||
@@ -3508,10 +3578,10 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
|
||||
private class LocalService extends UserManagerInternal {
|
||||
@Override
|
||||
public void setDevicePolicyUserRestrictions(int userId, @NonNull Bundle localRestrictions,
|
||||
@Nullable Bundle globalRestrictions) {
|
||||
UserManagerService.this.setDevicePolicyUserRestrictionsInner(userId, localRestrictions,
|
||||
globalRestrictions);
|
||||
public void setDevicePolicyUserRestrictions(int userId, @Nullable Bundle restrictions,
|
||||
boolean isDeviceOwner, int cameraRestrictionScope) {
|
||||
UserManagerService.this.setDevicePolicyUserRestrictionsInner(userId, restrictions,
|
||||
isDeviceOwner, cameraRestrictionScope);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -3525,8 +3595,10 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
public void setBaseUserRestrictionsByDpmsForMigration(
|
||||
int userId, Bundle baseRestrictions) {
|
||||
synchronized (mRestrictionsLock) {
|
||||
mBaseUserRestrictions.put(userId, new Bundle(baseRestrictions));
|
||||
invalidateEffectiveUserRestrictionsLR(userId);
|
||||
if (updateRestrictionsIfNeededLR(
|
||||
userId, new Bundle(baseRestrictions), mBaseUserRestrictions)) {
|
||||
invalidateEffectiveUserRestrictionsLR(userId);
|
||||
}
|
||||
}
|
||||
|
||||
final UserData userData = getUserDataNoChecks(userId);
|
||||
|
||||
@@ -30,11 +30,13 @@ import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.os.UserManagerInternal;
|
||||
import android.service.persistentdata.PersistentDataBlockManager;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
@@ -117,9 +119,10 @@ public class UserRestrictionsUtils {
|
||||
);
|
||||
|
||||
/**
|
||||
* User restrictions that can not be set by profile owners.
|
||||
* User restrictions that cannot be set by profile owners of secondary users. When set by DO
|
||||
* they will be applied to all users.
|
||||
*/
|
||||
private static final Set<String> DEVICE_OWNER_ONLY_RESTRICTIONS = Sets.newArraySet(
|
||||
private static final Set<String> PRIMARY_USER_ONLY_RESTRICTIONS = Sets.newArraySet(
|
||||
UserManager.DISALLOW_BLUETOOTH,
|
||||
UserManager.DISALLOW_USB_FILE_TRANSFER,
|
||||
UserManager.DISALLOW_CONFIG_TETHERING,
|
||||
@@ -163,6 +166,13 @@ public class UserRestrictionsUtils {
|
||||
UserManager.DISALLOW_ADD_MANAGED_PROFILE
|
||||
);
|
||||
|
||||
/*
|
||||
* Special user restrictions that are always applied to all users no matter who sets them.
|
||||
*/
|
||||
private static final Set<String> PROFILE_GLOBAL_RESTRICTIONS = Sets.newArraySet(
|
||||
UserManager.ENSURE_VERIFY_APPS
|
||||
);
|
||||
|
||||
/**
|
||||
* Throws {@link IllegalArgumentException} if the given restriction name is invalid.
|
||||
*/
|
||||
@@ -205,6 +215,12 @@ public class UserRestrictionsUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static Bundle readRestrictions(XmlPullParser parser) {
|
||||
final Bundle result = new Bundle();
|
||||
readRestrictions(parser, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code in} itself when it's not null, or an empty bundle (which can writable).
|
||||
*/
|
||||
@@ -216,6 +232,14 @@ public class UserRestrictionsUtils {
|
||||
return (in == null) || (in.size() == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if given bundle is not null and contains {@code true} for a given
|
||||
* restriction.
|
||||
*/
|
||||
public static boolean contains(@Nullable Bundle in, String restriction) {
|
||||
return in != null && in.getBoolean(restriction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of the {@code in} Bundle. If {@code in} is null, it'll return an empty
|
||||
* bundle.
|
||||
@@ -240,6 +264,22 @@ public class UserRestrictionsUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges a sparse array of restrictions bundles into one.
|
||||
*/
|
||||
@Nullable
|
||||
public static Bundle mergeAll(SparseArray<Bundle> restrictions) {
|
||||
if (restrictions.size() == 0) {
|
||||
return null;
|
||||
} else {
|
||||
final Bundle result = new Bundle();
|
||||
for (int i = 0; i < restrictions.size(); i++) {
|
||||
merge(result, restrictions.valueAt(i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if a restriction is settable by device owner.
|
||||
*/
|
||||
@@ -254,7 +294,7 @@ public class UserRestrictionsUtils {
|
||||
public static boolean canProfileOwnerChange(String restriction, int userId) {
|
||||
return !IMMUTABLE_BY_OWNERS.contains(restriction)
|
||||
&& !(userId != UserHandle.USER_SYSTEM
|
||||
&& DEVICE_OWNER_ONLY_RESTRICTIONS.contains(restriction));
|
||||
&& PRIMARY_USER_ONLY_RESTRICTIONS.contains(restriction));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -269,8 +309,15 @@ public class UserRestrictionsUtils {
|
||||
* 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, @NonNull Bundle global,
|
||||
@NonNull Bundle local) {
|
||||
public static void sortToGlobalAndLocal(@Nullable Bundle in, boolean isDeviceOwner,
|
||||
int cameraRestrictionScope,
|
||||
@NonNull Bundle global, @NonNull Bundle local) {
|
||||
// Camera restriction (as well as all others) goes to at most one bundle.
|
||||
if (cameraRestrictionScope == UserManagerInternal.CAMERA_DISABLED_GLOBALLY) {
|
||||
global.putBoolean(UserManager.DISALLOW_CAMERA, true);
|
||||
} else if (cameraRestrictionScope == UserManagerInternal.CAMERA_DISABLED_LOCALLY) {
|
||||
local.putBoolean(UserManager.DISALLOW_CAMERA, true);
|
||||
}
|
||||
if (in == null || in.size() == 0) {
|
||||
return;
|
||||
}
|
||||
@@ -278,7 +325,7 @@ public class UserRestrictionsUtils {
|
||||
if (!in.getBoolean(key)) {
|
||||
continue;
|
||||
}
|
||||
if (DEVICE_OWNER_ONLY_RESTRICTIONS.contains(key) || GLOBAL_RESTRICTIONS.contains(key)) {
|
||||
if (isGlobal(isDeviceOwner, key)) {
|
||||
global.putBoolean(key, true);
|
||||
} else {
|
||||
local.putBoolean(key, true);
|
||||
@@ -286,6 +333,15 @@ public class UserRestrictionsUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether given user restriction should be enforced globally.
|
||||
*/
|
||||
private static boolean isGlobal(boolean isDeviceOwner, String key) {
|
||||
return (isDeviceOwner &&
|
||||
(PRIMARY_USER_ONLY_RESTRICTIONS.contains(key)|| GLOBAL_RESTRICTIONS.contains(key)))
|
||||
|| PROFILE_GLOBAL_RESTRICTIONS.contains(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if two Bundles contain the same user restriction.
|
||||
* A null bundle and an empty bundle are considered to be equal.
|
||||
@@ -485,4 +541,29 @@ public class UserRestrictionsUtils {
|
||||
pw.println(prefix + "null");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves a particular restriction from one array of bundles to another, e.g. for all users.
|
||||
*/
|
||||
public static void moveRestriction(String restrictionKey, SparseArray<Bundle> srcRestrictions,
|
||||
SparseArray<Bundle> destRestrictions) {
|
||||
for (int i = 0; i < srcRestrictions.size(); i++) {
|
||||
int key = srcRestrictions.keyAt(i);
|
||||
Bundle from = srcRestrictions.valueAt(i);
|
||||
if (contains(from, restrictionKey)) {
|
||||
from.remove(restrictionKey);
|
||||
Bundle to = destRestrictions.get(key);
|
||||
if (to == null) {
|
||||
to = new Bundle();
|
||||
destRestrictions.append(key, to);
|
||||
}
|
||||
to.putBoolean(restrictionKey, true);
|
||||
// Don't keep empty bundles.
|
||||
if (from.isEmpty()) {
|
||||
srcRestrictions.removeAt(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1154,7 +1154,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
} else if (TAG_KEEP_UNINSTALLED_PACKAGES.equals(tag)) {
|
||||
keepUninstalledPackages = readPackageList(parser, tag);
|
||||
} else if (TAG_USER_RESTRICTIONS.equals(tag)) {
|
||||
UserRestrictionsUtils.readRestrictions(parser, ensureUserRestrictions());
|
||||
userRestrictions = UserRestrictionsUtils.readRestrictions(parser);
|
||||
} else if (TAG_DEFAULT_ENABLED_USER_RESTRICTIONS.equals(tag)) {
|
||||
readAttributeValues(
|
||||
parser, TAG_RESTRICTION, defaultEnabledRestrictionsAlreadySet);
|
||||
@@ -7767,7 +7767,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
|
||||
final int userHandle = mInjector.userHandleGetCallingUserId();
|
||||
synchronized (this) {
|
||||
ActiveAdmin activeAdmin =
|
||||
final ActiveAdmin activeAdmin =
|
||||
getActiveAdminForCallerLocked(who,
|
||||
DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
|
||||
final boolean isDeviceOwner = isDeviceOwner(who, userHandle);
|
||||
@@ -7782,7 +7782,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
}
|
||||
|
||||
// Save the restriction to ActiveAdmin.
|
||||
activeAdmin.ensureUserRestrictions().putBoolean(key, enabledFromThisOwner);
|
||||
final Bundle restrictions = activeAdmin.ensureUserRestrictions();
|
||||
if (enabledFromThisOwner) {
|
||||
restrictions.putBoolean(key, true);
|
||||
} else {
|
||||
restrictions.remove(key);
|
||||
}
|
||||
saveUserRestrictionsLocked(userHandle);
|
||||
}
|
||||
}
|
||||
@@ -7795,39 +7800,46 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
|
||||
private void pushUserRestrictions(int userId) {
|
||||
synchronized (this) {
|
||||
final Bundle global;
|
||||
final Bundle local = new Bundle();
|
||||
if (mOwners.isDeviceOwnerUserId(userId)) {
|
||||
global = new Bundle();
|
||||
final boolean isDeviceOwner = mOwners.isDeviceOwnerUserId(userId);
|
||||
final Bundle userRestrictions;
|
||||
// Whether device owner enforces camera restriction.
|
||||
boolean disallowCameraGlobally = false;
|
||||
|
||||
if (isDeviceOwner) {
|
||||
final ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked();
|
||||
if (deviceOwner == null) {
|
||||
return; // Shouldn't happen.
|
||||
}
|
||||
|
||||
UserRestrictionsUtils.sortToGlobalAndLocal(deviceOwner.userRestrictions,
|
||||
global, local);
|
||||
userRestrictions = deviceOwner.userRestrictions;
|
||||
// DO can disable camera globally.
|
||||
if (deviceOwner.disableCamera) {
|
||||
global.putBoolean(UserManager.DISALLOW_CAMERA, true);
|
||||
}
|
||||
disallowCameraGlobally = deviceOwner.disableCamera;
|
||||
} else {
|
||||
global = null;
|
||||
final ActiveAdmin profileOwner = getProfileOwnerAdminLocked(userId);
|
||||
userRestrictions = profileOwner != null ? profileOwner.userRestrictions : null;
|
||||
}
|
||||
|
||||
ActiveAdmin profileOwner = getProfileOwnerAdminLocked(userId);
|
||||
if (profileOwner != null) {
|
||||
UserRestrictionsUtils.merge(local, profileOwner.userRestrictions);
|
||||
}
|
||||
}
|
||||
// Also merge in *local* camera restriction.
|
||||
if (getCameraDisabled(/* who= */ null,
|
||||
userId, /* mergeDeviceOwnerRestriction= */ false)) {
|
||||
local.putBoolean(UserManager.DISALLOW_CAMERA, true);
|
||||
}
|
||||
mUserManagerInternal.setDevicePolicyUserRestrictions(userId, local, global);
|
||||
// Whether any admin enforces camera restriction.
|
||||
final int cameraRestrictionScope =
|
||||
getCameraRestrictionScopeLocked(userId, disallowCameraGlobally);
|
||||
|
||||
mUserManagerInternal.setDevicePolicyUserRestrictions(userId, userRestrictions,
|
||||
isDeviceOwner, cameraRestrictionScope);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the scope of camera restriction for a given user if any.
|
||||
*/
|
||||
private int getCameraRestrictionScopeLocked(int userId, boolean disallowCameraGlobally) {
|
||||
if (disallowCameraGlobally) {
|
||||
return UserManagerInternal.CAMERA_DISABLED_GLOBALLY;
|
||||
} else if (getCameraDisabled(
|
||||
/* who= */ null, userId, /* mergeDeviceOwnerRestriction= */ false)) {
|
||||
return UserManagerInternal.CAMERA_DISABLED_LOCALLY;
|
||||
}
|
||||
return UserManagerInternal.CAMERA_NOT_DISABLED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle getUserRestrictions(ComponentName who) {
|
||||
if (!mHasFeature) {
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
*/
|
||||
package com.android.server.devicepolicy;
|
||||
|
||||
import static android.os.UserManagerInternal.CAMERA_DISABLED_GLOBALLY;
|
||||
import static android.os.UserManagerInternal.CAMERA_DISABLED_LOCALLY;
|
||||
import static android.os.UserManagerInternal.CAMERA_NOT_DISABLED;
|
||||
|
||||
import android.Manifest.permission;
|
||||
import android.app.Activity;
|
||||
import android.app.admin.DeviceAdminReceiver;
|
||||
@@ -39,6 +43,7 @@ import android.os.IBinder;
|
||||
import android.os.Process;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.os.UserManagerInternal;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.test.MoreAsserts;
|
||||
@@ -928,9 +933,8 @@ public class DevicePolicyManagerTest extends DpmTestBase {
|
||||
|
||||
verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
|
||||
eq(UserHandle.USER_SYSTEM),
|
||||
MockUtils.checkUserRestrictions(),
|
||||
MockUtils.checkUserRestrictions()
|
||||
);
|
||||
eq(null),
|
||||
eq(true), eq(CAMERA_NOT_DISABLED));
|
||||
|
||||
assertFalse(dpm.isAdminActiveAsUser(admin1, UserHandle.USER_SYSTEM));
|
||||
|
||||
@@ -1287,7 +1291,8 @@ public class DevicePolicyManagerTest extends DpmTestBase {
|
||||
verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
|
||||
eq(UserHandle.USER_SYSTEM),
|
||||
MockUtils.checkUserRestrictions(defaultRestrictions),
|
||||
MockUtils.checkUserRestrictions()
|
||||
eq(true) /* isDeviceOwner */,
|
||||
eq(CAMERA_NOT_DISABLED)
|
||||
);
|
||||
reset(mContext.userManagerInternal);
|
||||
|
||||
@@ -1296,21 +1301,21 @@ public class DevicePolicyManagerTest extends DpmTestBase {
|
||||
}
|
||||
|
||||
assertNoDeviceOwnerRestrictions();
|
||||
reset(mContext.userManagerInternal);
|
||||
|
||||
dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER);
|
||||
verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
|
||||
eq(UserHandle.USER_SYSTEM),
|
||||
MockUtils.checkUserRestrictions(),
|
||||
MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER)
|
||||
);
|
||||
MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER),
|
||||
eq(true), eq(CAMERA_NOT_DISABLED));
|
||||
reset(mContext.userManagerInternal);
|
||||
|
||||
dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
|
||||
verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
|
||||
eq(UserHandle.USER_SYSTEM),
|
||||
MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
|
||||
MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER)
|
||||
);
|
||||
MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS,
|
||||
UserManager.DISALLOW_ADD_USER),
|
||||
eq(true), eq(CAMERA_NOT_DISABLED));
|
||||
reset(mContext.userManagerInternal);
|
||||
|
||||
DpmTestUtils.assertRestrictions(
|
||||
@@ -1328,8 +1333,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
|
||||
verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
|
||||
eq(UserHandle.USER_SYSTEM),
|
||||
MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
|
||||
MockUtils.checkUserRestrictions()
|
||||
);
|
||||
eq(true), eq(CAMERA_NOT_DISABLED));
|
||||
reset(mContext.userManagerInternal);
|
||||
|
||||
DpmTestUtils.assertRestrictions(
|
||||
@@ -1345,8 +1349,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
|
||||
verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
|
||||
eq(UserHandle.USER_SYSTEM),
|
||||
MockUtils.checkUserRestrictions(),
|
||||
MockUtils.checkUserRestrictions()
|
||||
);
|
||||
eq(true), eq(CAMERA_NOT_DISABLED));
|
||||
reset(mContext.userManagerInternal);
|
||||
|
||||
assertNoDeviceOwnerRestrictions();
|
||||
@@ -1358,42 +1361,38 @@ public class DevicePolicyManagerTest extends DpmTestBase {
|
||||
dpm.addUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE);
|
||||
verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
|
||||
eq(UserHandle.USER_SYSTEM),
|
||||
MockUtils.checkUserRestrictions(),
|
||||
MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME,
|
||||
UserManager.DISALLOW_UNMUTE_MICROPHONE)
|
||||
);
|
||||
UserManager.DISALLOW_UNMUTE_MICROPHONE),
|
||||
eq(true), eq(CAMERA_NOT_DISABLED));
|
||||
reset(mContext.userManagerInternal);
|
||||
|
||||
dpm.clearUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME);
|
||||
dpm.clearUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE);
|
||||
|
||||
reset(mContext.userManagerInternal);
|
||||
|
||||
// More tests.
|
||||
dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER);
|
||||
verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
|
||||
eq(UserHandle.USER_SYSTEM),
|
||||
MockUtils.checkUserRestrictions(),
|
||||
MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER)
|
||||
);
|
||||
MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER),
|
||||
eq(true), eq(CAMERA_NOT_DISABLED));
|
||||
reset(mContext.userManagerInternal);
|
||||
|
||||
dpm.addUserRestriction(admin1, UserManager.DISALLOW_FUN);
|
||||
verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
|
||||
eq(UserHandle.USER_SYSTEM),
|
||||
MockUtils.checkUserRestrictions(),
|
||||
MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN,
|
||||
UserManager.DISALLOW_ADD_USER)
|
||||
);
|
||||
UserManager.DISALLOW_ADD_USER),
|
||||
eq(true), eq(CAMERA_NOT_DISABLED));
|
||||
reset(mContext.userManagerInternal);
|
||||
|
||||
dpm.setCameraDisabled(admin1, true);
|
||||
verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
|
||||
eq(UserHandle.USER_SYSTEM),
|
||||
// DISALLOW_CAMERA will be applied to both local and global.
|
||||
MockUtils.checkUserRestrictions(UserManager.DISALLOW_CAMERA),
|
||||
MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN,
|
||||
UserManager.DISALLOW_CAMERA, UserManager.DISALLOW_ADD_USER)
|
||||
);
|
||||
UserManager.DISALLOW_ADD_USER),
|
||||
eq(true), eq(CAMERA_DISABLED_GLOBALLY));
|
||||
reset(mContext.userManagerInternal);
|
||||
|
||||
// Set up another DA and let it disable camera. Now DISALLOW_CAMERA will only be applied
|
||||
@@ -1407,11 +1406,10 @@ public class DevicePolicyManagerTest extends DpmTestBase {
|
||||
|
||||
verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
|
||||
eq(UserHandle.USER_SYSTEM),
|
||||
// DISALLOW_CAMERA will be applied to both local and global.
|
||||
MockUtils.checkUserRestrictions(UserManager.DISALLOW_CAMERA),
|
||||
// DISALLOW_CAMERA will be applied to both local and global. <- TODO: fix this
|
||||
MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN,
|
||||
UserManager.DISALLOW_ADD_USER)
|
||||
);
|
||||
UserManager.DISALLOW_ADD_USER),
|
||||
eq(true), eq(CAMERA_DISABLED_LOCALLY));
|
||||
reset(mContext.userManagerInternal);
|
||||
// TODO Make sure restrictions are written to the file.
|
||||
}
|
||||
@@ -1429,8 +1427,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
|
||||
verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
|
||||
eq(DpmMockContext.CALLER_USER_HANDLE),
|
||||
MockUtils.checkUserRestrictions(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES),
|
||||
isNull(Bundle.class)
|
||||
);
|
||||
eq(false), eq(CAMERA_NOT_DISABLED));
|
||||
reset(mContext.userManagerInternal);
|
||||
|
||||
dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
|
||||
@@ -1438,8 +1435,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
|
||||
eq(DpmMockContext.CALLER_USER_HANDLE),
|
||||
MockUtils.checkUserRestrictions(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
|
||||
UserManager.DISALLOW_OUTGOING_CALLS),
|
||||
isNull(Bundle.class)
|
||||
);
|
||||
eq(false), eq(CAMERA_NOT_DISABLED));
|
||||
reset(mContext.userManagerInternal);
|
||||
|
||||
DpmTestUtils.assertRestrictions(
|
||||
@@ -1462,8 +1458,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
|
||||
verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
|
||||
eq(DpmMockContext.CALLER_USER_HANDLE),
|
||||
MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
|
||||
isNull(Bundle.class)
|
||||
);
|
||||
eq(false), eq(CAMERA_NOT_DISABLED));
|
||||
reset(mContext.userManagerInternal);
|
||||
|
||||
DpmTestUtils.assertRestrictions(
|
||||
@@ -1484,8 +1479,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
|
||||
verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
|
||||
eq(DpmMockContext.CALLER_USER_HANDLE),
|
||||
MockUtils.checkUserRestrictions(),
|
||||
isNull(Bundle.class)
|
||||
);
|
||||
eq(false), eq(CAMERA_NOT_DISABLED));
|
||||
reset(mContext.userManagerInternal);
|
||||
|
||||
DpmTestUtils.assertRestrictions(
|
||||
@@ -1507,18 +1501,15 @@ public class DevicePolicyManagerTest extends DpmTestBase {
|
||||
eq(DpmMockContext.CALLER_USER_HANDLE),
|
||||
MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME,
|
||||
UserManager.DISALLOW_UNMUTE_MICROPHONE),
|
||||
isNull(Bundle.class)
|
||||
);
|
||||
eq(false), eq(CAMERA_NOT_DISABLED));
|
||||
reset(mContext.userManagerInternal);
|
||||
|
||||
dpm.setCameraDisabled(admin1, true);
|
||||
verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
|
||||
eq(DpmMockContext.CALLER_USER_HANDLE),
|
||||
MockUtils.checkUserRestrictions(UserManager.DISALLOW_CAMERA,
|
||||
UserManager.DISALLOW_ADJUST_VOLUME,
|
||||
MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME,
|
||||
UserManager.DISALLOW_UNMUTE_MICROPHONE),
|
||||
isNull(Bundle.class)
|
||||
);
|
||||
eq(false), eq(CAMERA_DISABLED_LOCALLY));
|
||||
reset(mContext.userManagerInternal);
|
||||
|
||||
// TODO Make sure restrictions are written to the file.
|
||||
@@ -1558,7 +1549,8 @@ public class DevicePolicyManagerTest extends DpmTestBase {
|
||||
verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
|
||||
eq(UserHandle.USER_SYSTEM),
|
||||
MockUtils.checkUserRestrictions(defaultRestrictions),
|
||||
MockUtils.checkUserRestrictions()
|
||||
eq(true) /* isDeviceOwner */,
|
||||
eq(CAMERA_NOT_DISABLED)
|
||||
);
|
||||
reset(mContext.userManagerInternal);
|
||||
|
||||
@@ -1600,7 +1592,8 @@ public class DevicePolicyManagerTest extends DpmTestBase {
|
||||
verify(mContext.userManagerInternal, atLeast(1)).setDevicePolicyUserRestrictions(
|
||||
eq(UserHandle.USER_SYSTEM),
|
||||
MockUtils.checkUserRestrictions(newDefaultEnabledRestriction),
|
||||
MockUtils.checkUserRestrictions()
|
||||
eq(true) /* isDeviceOwner */,
|
||||
eq(CAMERA_NOT_DISABLED)
|
||||
);
|
||||
reset(mContext.userManagerInternal);
|
||||
|
||||
|
||||
@@ -16,13 +16,16 @@
|
||||
|
||||
package com.android.server.pm;
|
||||
|
||||
import static com.android.server.devicepolicy.DpmTestUtils.assertRestrictions;
|
||||
import static com.android.server.devicepolicy.DpmTestUtils.newRestrictions;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.os.UserManagerInternal;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
import com.android.server.devicepolicy.DpmTestUtils;
|
||||
import android.util.SparseArray;
|
||||
|
||||
/**
|
||||
* Tests for {@link com.android.server.pm.UserRestrictionsUtils}.
|
||||
@@ -49,14 +52,14 @@ public class UserRestrictionsUtilsTest extends AndroidTestCase {
|
||||
public void testIsEmpty() {
|
||||
assertTrue(UserRestrictionsUtils.isEmpty(null));
|
||||
assertTrue(UserRestrictionsUtils.isEmpty(new Bundle()));
|
||||
assertFalse(UserRestrictionsUtils.isEmpty(DpmTestUtils.newRestrictions("a")));
|
||||
assertFalse(UserRestrictionsUtils.isEmpty(newRestrictions("a")));
|
||||
}
|
||||
|
||||
public void testClone() {
|
||||
Bundle in = new Bundle();
|
||||
Bundle out = UserRestrictionsUtils.clone(in);
|
||||
assertNotSame(in, out);
|
||||
DpmTestUtils.assertRestrictions(out, new Bundle());
|
||||
assertRestrictions(out, new Bundle());
|
||||
|
||||
out = UserRestrictionsUtils.clone(null);
|
||||
assertNotNull(out);
|
||||
@@ -64,16 +67,16 @@ public class UserRestrictionsUtilsTest extends AndroidTestCase {
|
||||
}
|
||||
|
||||
public void testMerge() {
|
||||
Bundle a = DpmTestUtils.newRestrictions("a", "d");
|
||||
Bundle b = DpmTestUtils.newRestrictions("b", "d", "e");
|
||||
Bundle a = newRestrictions("a", "d");
|
||||
Bundle b = newRestrictions("b", "d", "e");
|
||||
|
||||
UserRestrictionsUtils.merge(a, b);
|
||||
|
||||
DpmTestUtils.assertRestrictions(DpmTestUtils.newRestrictions("a", "b", "d", "e"), a);
|
||||
assertRestrictions(newRestrictions("a", "b", "d", "e"), a);
|
||||
|
||||
UserRestrictionsUtils.merge(a, null);
|
||||
|
||||
DpmTestUtils.assertRestrictions(DpmTestUtils.newRestrictions("a", "b", "d", "e"), a);
|
||||
assertRestrictions(newRestrictions("a", "b", "d", "e"), a);
|
||||
|
||||
try {
|
||||
UserRestrictionsUtils.merge(a, a);
|
||||
@@ -114,25 +117,32 @@ public class UserRestrictionsUtilsTest extends AndroidTestCase {
|
||||
final Bundle local = new Bundle();
|
||||
final Bundle global = new Bundle();
|
||||
|
||||
UserRestrictionsUtils.sortToGlobalAndLocal(null, global, local);
|
||||
UserRestrictionsUtils.sortToGlobalAndLocal(null, false /* isDeviceOwner */,
|
||||
UserManagerInternal.CAMERA_NOT_DISABLED, global, local);
|
||||
assertEquals(0, global.size());
|
||||
assertEquals(0, local.size());
|
||||
|
||||
UserRestrictionsUtils.sortToGlobalAndLocal(Bundle.EMPTY, global, local);
|
||||
UserRestrictionsUtils.sortToGlobalAndLocal(Bundle.EMPTY, false /* isDeviceOwner */,
|
||||
UserManagerInternal.CAMERA_NOT_DISABLED, global, local);
|
||||
assertEquals(0, global.size());
|
||||
assertEquals(0, local.size());
|
||||
|
||||
UserRestrictionsUtils.sortToGlobalAndLocal(DpmTestUtils.newRestrictions(
|
||||
// Restrictions set by DO.
|
||||
UserRestrictionsUtils.sortToGlobalAndLocal(newRestrictions(
|
||||
UserManager.DISALLOW_ADJUST_VOLUME,
|
||||
UserManager.DISALLOW_UNMUTE_MICROPHONE,
|
||||
UserManager.DISALLOW_USB_FILE_TRANSFER,
|
||||
UserManager.DISALLOW_CONFIG_TETHERING,
|
||||
UserManager.DISALLOW_OUTGOING_BEAM,
|
||||
UserManager.DISALLOW_APPS_CONTROL
|
||||
), global, local);
|
||||
UserManager.DISALLOW_APPS_CONTROL,
|
||||
UserManager.ENSURE_VERIFY_APPS
|
||||
), true /* isDeviceOwner */, UserManagerInternal.CAMERA_NOT_DISABLED, global, local);
|
||||
|
||||
|
||||
DpmTestUtils.assertRestrictions(DpmTestUtils.newRestrictions(
|
||||
assertRestrictions(newRestrictions(
|
||||
// This one is global no matter who sets it.
|
||||
UserManager.ENSURE_VERIFY_APPS,
|
||||
|
||||
// These can be set by PO too, but when DO sets them, they're global.
|
||||
UserManager.DISALLOW_ADJUST_VOLUME,
|
||||
UserManager.DISALLOW_UNMUTE_MICROPHONE,
|
||||
@@ -142,11 +152,117 @@ public class UserRestrictionsUtilsTest extends AndroidTestCase {
|
||||
UserManager.DISALLOW_CONFIG_TETHERING
|
||||
), global);
|
||||
|
||||
DpmTestUtils.assertRestrictions(DpmTestUtils.newRestrictions(
|
||||
assertRestrictions(newRestrictions(
|
||||
// They can be set by both DO/PO.
|
||||
UserManager.DISALLOW_OUTGOING_BEAM,
|
||||
UserManager.DISALLOW_APPS_CONTROL
|
||||
), local);
|
||||
|
||||
local.clear();
|
||||
global.clear();
|
||||
|
||||
// Restrictions set by PO.
|
||||
UserRestrictionsUtils.sortToGlobalAndLocal(newRestrictions(
|
||||
UserManager.DISALLOW_ADJUST_VOLUME,
|
||||
UserManager.DISALLOW_UNMUTE_MICROPHONE,
|
||||
UserManager.DISALLOW_USB_FILE_TRANSFER,
|
||||
UserManager.DISALLOW_CONFIG_TETHERING,
|
||||
UserManager.DISALLOW_OUTGOING_BEAM,
|
||||
UserManager.DISALLOW_APPS_CONTROL,
|
||||
UserManager.ENSURE_VERIFY_APPS
|
||||
), false /* isDeviceOwner */, UserManagerInternal.CAMERA_NOT_DISABLED, global, local);
|
||||
|
||||
assertRestrictions(newRestrictions(
|
||||
// This one is global no matter who sets it.
|
||||
UserManager.ENSURE_VERIFY_APPS
|
||||
), global);
|
||||
|
||||
assertRestrictions(newRestrictions(
|
||||
// These can be set by PO too, but when PO sets them, they're local.
|
||||
UserManager.DISALLOW_ADJUST_VOLUME,
|
||||
UserManager.DISALLOW_UNMUTE_MICROPHONE,
|
||||
|
||||
// They can be set by both DO/PO.
|
||||
UserManager.DISALLOW_OUTGOING_BEAM,
|
||||
UserManager.DISALLOW_APPS_CONTROL,
|
||||
|
||||
// These can only be set by DO.
|
||||
UserManager.DISALLOW_USB_FILE_TRANSFER,
|
||||
UserManager.DISALLOW_CONFIG_TETHERING
|
||||
), local);
|
||||
|
||||
}
|
||||
|
||||
public void testSortToLocalAndGlobalWithCameraDisabled() {
|
||||
final Bundle local = new Bundle();
|
||||
final Bundle global = new Bundle();
|
||||
|
||||
UserRestrictionsUtils.sortToGlobalAndLocal(Bundle.EMPTY, false,
|
||||
UserManagerInternal.CAMERA_DISABLED_GLOBALLY, global, local);
|
||||
assertRestrictions(newRestrictions(UserManager.DISALLOW_CAMERA), global);
|
||||
assertEquals(0, local.size());
|
||||
global.clear();
|
||||
|
||||
UserRestrictionsUtils.sortToGlobalAndLocal(Bundle.EMPTY, false,
|
||||
UserManagerInternal.CAMERA_DISABLED_LOCALLY, global, local);
|
||||
assertEquals(0, global.size());
|
||||
assertRestrictions(newRestrictions(UserManager.DISALLOW_CAMERA), local);
|
||||
}
|
||||
|
||||
public void testMergeAll() {
|
||||
SparseArray<Bundle> restrictions = new SparseArray<>();
|
||||
assertNull(UserRestrictionsUtils.mergeAll(restrictions));
|
||||
|
||||
restrictions.put(0, newRestrictions(UserManager.DISALLOW_ADJUST_VOLUME));
|
||||
restrictions.put(1, newRestrictions(UserManager.DISALLOW_USB_FILE_TRANSFER));
|
||||
restrictions.put(2, newRestrictions(UserManager.DISALLOW_APPS_CONTROL));
|
||||
|
||||
Bundle result = UserRestrictionsUtils.mergeAll(restrictions);
|
||||
assertRestrictions(
|
||||
newRestrictions(
|
||||
UserManager.DISALLOW_ADJUST_VOLUME,
|
||||
UserManager.DISALLOW_USB_FILE_TRANSFER,
|
||||
UserManager.DISALLOW_APPS_CONTROL),
|
||||
result);
|
||||
}
|
||||
|
||||
public void testMoveRestriction() {
|
||||
SparseArray<Bundle> localRestrictions = new SparseArray<>();
|
||||
SparseArray<Bundle> globalRestrictions = new SparseArray<>();
|
||||
|
||||
// User 0 has only local restrictions, nothing should change.
|
||||
localRestrictions.put(0, newRestrictions(UserManager.DISALLOW_ADJUST_VOLUME));
|
||||
// User 1 has a local restriction to be moved to global and some global already. Local
|
||||
// restrictions should be removed for this user.
|
||||
localRestrictions.put(1, newRestrictions(UserManager.ENSURE_VERIFY_APPS));
|
||||
globalRestrictions.put(1, newRestrictions(UserManager.DISALLOW_ADD_USER));
|
||||
// User 2 has a local restriction to be moved and one to leave local.
|
||||
localRestrictions.put(2, newRestrictions(
|
||||
UserManager.ENSURE_VERIFY_APPS,
|
||||
UserManager.DISALLOW_CONFIG_VPN));
|
||||
|
||||
UserRestrictionsUtils.moveRestriction(
|
||||
UserManager.ENSURE_VERIFY_APPS, localRestrictions, globalRestrictions);
|
||||
|
||||
// Check user 0.
|
||||
assertRestrictions(
|
||||
newRestrictions(UserManager.DISALLOW_ADJUST_VOLUME),
|
||||
localRestrictions.get(0));
|
||||
assertNull(globalRestrictions.get(0));
|
||||
|
||||
// Check user 1.
|
||||
assertNull(localRestrictions.get(1));
|
||||
assertRestrictions(
|
||||
newRestrictions(UserManager.ENSURE_VERIFY_APPS, UserManager.DISALLOW_ADD_USER),
|
||||
globalRestrictions.get(1));
|
||||
|
||||
// Check user 2.
|
||||
assertRestrictions(
|
||||
newRestrictions(UserManager.DISALLOW_CONFIG_VPN),
|
||||
localRestrictions.get(2));
|
||||
assertRestrictions(
|
||||
newRestrictions(UserManager.ENSURE_VERIFY_APPS),
|
||||
globalRestrictions.get(2));
|
||||
}
|
||||
|
||||
public void testAreEqual() {
|
||||
@@ -172,33 +288,33 @@ public class UserRestrictionsUtilsTest extends AndroidTestCase {
|
||||
|
||||
assertFalse(UserRestrictionsUtils.areEqual(
|
||||
null,
|
||||
DpmTestUtils.newRestrictions("a")));
|
||||
newRestrictions("a")));
|
||||
|
||||
assertFalse(UserRestrictionsUtils.areEqual(
|
||||
DpmTestUtils.newRestrictions("a"),
|
||||
newRestrictions("a"),
|
||||
null));
|
||||
|
||||
assertTrue(UserRestrictionsUtils.areEqual(
|
||||
DpmTestUtils.newRestrictions("a"),
|
||||
DpmTestUtils.newRestrictions("a")));
|
||||
newRestrictions("a"),
|
||||
newRestrictions("a")));
|
||||
|
||||
assertFalse(UserRestrictionsUtils.areEqual(
|
||||
DpmTestUtils.newRestrictions("a"),
|
||||
DpmTestUtils.newRestrictions("a", "b")));
|
||||
newRestrictions("a"),
|
||||
newRestrictions("a", "b")));
|
||||
|
||||
assertFalse(UserRestrictionsUtils.areEqual(
|
||||
DpmTestUtils.newRestrictions("a", "b"),
|
||||
DpmTestUtils.newRestrictions("a")));
|
||||
newRestrictions("a", "b"),
|
||||
newRestrictions("a")));
|
||||
|
||||
assertFalse(UserRestrictionsUtils.areEqual(
|
||||
DpmTestUtils.newRestrictions("b", "a"),
|
||||
DpmTestUtils.newRestrictions("a", "a")));
|
||||
newRestrictions("b", "a"),
|
||||
newRestrictions("a", "a")));
|
||||
|
||||
// Make sure false restrictions are handled correctly.
|
||||
final Bundle a = DpmTestUtils.newRestrictions("a");
|
||||
final Bundle a = newRestrictions("a");
|
||||
a.putBoolean("b", true);
|
||||
|
||||
final Bundle b = DpmTestUtils.newRestrictions("a");
|
||||
final Bundle b = newRestrictions("a");
|
||||
b.putBoolean("b", false);
|
||||
|
||||
assertFalse(UserRestrictionsUtils.areEqual(a, b));
|
||||
|
||||
Reference in New Issue
Block a user