summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/system-current.txt8
-rw-r--r--core/java/android/os/IUserManager.aidl1
-rw-r--r--core/java/android/os/UserManager.java59
-rw-r--r--services/core/java/com/android/server/pm/UserManagerService.java75
4 files changed, 143 insertions, 0 deletions
diff --git a/api/system-current.txt b/api/system-current.txt
index c489435bc093..aea96bd12482 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -31928,6 +31928,7 @@ package android.os {
method public deprecated void setUserRestrictions(android.os.Bundle);
method public deprecated void setUserRestrictions(android.os.Bundle, android.os.UserHandle);
method public static boolean supportsMultipleUsers();
+ method public int getUserRestrictionSource(java.lang.String, android.os.UserHandle);
field public static final java.lang.String ALLOW_PARENT_PROFILE_APP_LINKING = "allow_parent_profile_app_linking";
field public static final java.lang.String DISALLOW_ADD_USER = "no_add_user";
field public static final java.lang.String DISALLOW_ADJUST_VOLUME = "no_adjust_volume";
@@ -31965,6 +31966,13 @@ package android.os {
field public static final java.lang.String KEY_RESTRICTIONS_PENDING = "restrictions_pending";
field public static final int USER_CREATION_FAILED_NOT_PERMITTED = 1; // 0x1
field public static final int USER_CREATION_FAILED_NO_MORE_USERS = 2; // 0x2
+ field public static final int RESTRICTION_NOT_SET = 0; // 0x0
+ field public static final int RESTRICTION_SOURCE_SYSTEM = 1; // 0x1
+ field public static final int RESTRICTION_SOURCE_DEVICE_OWNER = 2; // 0x2
+ field public static final int RESTRICTION_SOURCE_PROFILE_OWNER = 4; // 0x4
+ }
+
+ public static abstract class UserManager.UserRestrictionSource implements java.lang.annotation.Annotation {
}
public abstract class Vibrator {
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index 55b0d2a15317..b27cb32bd4eb 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -58,6 +58,7 @@ interface IUserManager {
boolean canHaveRestrictedProfile(int userHandle);
int getUserSerialNumber(int userHandle);
int getUserHandle(int userSerialNumber);
+ int getUserRestrictionSource(String restrictionKey, int userHandle);
Bundle getUserRestrictions(int userHandle);
boolean hasBaseUserRestriction(String restrictionKey, int userHandle);
boolean hasUserRestriction(in String restrictionKey, int userHandle);
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index cd3205976aa8..1a7d8516d8d3 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -18,6 +18,7 @@ package android.os;
import android.Manifest;
import android.accounts.AccountManager;
+import android.annotation.IntDef;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
@@ -44,6 +45,8 @@ import android.view.WindowManager.LayoutParams;
import com.android.internal.R;
import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
@@ -64,6 +67,41 @@ public class UserManager {
private final Context mContext;
/**
+ * @hide
+ * No user restriction.
+ */
+ @SystemApi
+ public static final int RESTRICTION_NOT_SET = 0x0;
+
+ /**
+ * @hide
+ * User restriction set by system/user.
+ */
+ @SystemApi
+ public static final int RESTRICTION_SOURCE_SYSTEM = 0x1;
+
+ /**
+ * @hide
+ * User restriction set by a device owner.
+ */
+ @SystemApi
+ public static final int RESTRICTION_SOURCE_DEVICE_OWNER = 0x2;
+
+ /**
+ * @hide
+ * User restriction set by a profile owner.
+ */
+ @SystemApi
+ public static final int RESTRICTION_SOURCE_PROFILE_OWNER = 0x4;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag=true, value={RESTRICTION_NOT_SET, RESTRICTION_SOURCE_SYSTEM,
+ RESTRICTION_SOURCE_DEVICE_OWNER, RESTRICTION_SOURCE_PROFILE_OWNER})
+ @SystemApi
+ public @interface UserRestrictionSource {}
+
+ /**
* Specifies if a user is disallowed from adding and removing accounts, unless they are
* {@link android.accounts.AccountManager#addAccountExplicitly programmatically} added by
* Authenticator.
@@ -1006,6 +1044,27 @@ public class UserManager {
}
/**
+ * @hide
+ *
+ * Returns who set a user restriction on a 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 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}
+ */
+ @SystemApi
+ @UserRestrictionSource
+ public int getUserRestrictionSource(String restrictionKey, UserHandle userHandle) {
+ try {
+ return mService.getUserRestrictionSource(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.
*/
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 7ea59190981a..8d1abb0c7d1c 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -23,6 +23,7 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.annotation.UserIdInt;
import android.app.Activity;
import android.app.ActivityManager;
@@ -31,7 +32,9 @@ import android.app.ActivityManagerNative;
import android.app.IActivityManager;
import android.app.IStopUserCallback;
import android.app.KeyguardManager;
+import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -143,6 +146,7 @@ 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_GLOBAL_RESTRICTION_OWNER_ID = "globalRestrictionOwnerUserId";
private static final String TAG_ENTRY = "entry";
private static final String TAG_VALUE = "value";
private static final String TAG_SEED_ACCOUNT_OPTIONS = "seedAccountOptions";
@@ -276,6 +280,12 @@ public class UserManagerService extends IUserManager.Stub {
private Bundle mDevicePolicyGlobalUserRestrictions;
/**
+ * Id of the user that set global restrictions.
+ */
+ @GuardedBy("mRestrictionsLock")
+ private int mGlobalRestrictionOwnerUserId = UserHandle.USER_NULL;
+
+ /**
* User restrictions set by {@link com.android.server.devicepolicy.DevicePolicyManagerService}
* for each user.
*/
@@ -991,6 +1001,13 @@ public class UserManagerService extends IUserManager.Stub {
if (globalChanged) {
mDevicePolicyGlobalUserRestrictions = global;
}
+ // Remember the global restriction owner userId to be able to make a distinction
+ // in getUserRestrictionSource on who set local policies.
+ mGlobalRestrictionOwnerUserId = userId;
+ } else {
+ // When profile owner sets restrictions it passes null global bundle and we reset
+ // global restriction owner userId.
+ mGlobalRestrictionOwnerUserId = UserHandle.USER_NULL;
}
{
// Update local.
@@ -1074,6 +1091,54 @@ public class UserManagerService extends IUserManager.Stub {
}
/**
+ * @hide
+ *
+ * Returns who set a user restriction on a user.
+ * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
+ * @param restrictionKey the string key representing the restriction
+ * @param userId the id of the user for whom to retrieve the restrictions.
+ * @return The source of user restriction. Any combination of
+ * {@link UserManager#RESTRICTION_NOT_SET},
+ * {@link UserManager#RESTRICTION_SOURCE_SYSTEM},
+ * {@link UserManager#RESTRICTION_SOURCE_DEVICE_OWNER}
+ * and {@link UserManager#RESTRICTION_SOURCE_PROFILE_OWNER}
+ */
+ @Override
+ public int getUserRestrictionSource(String restrictionKey, int userId) {
+ checkManageUsersPermission("getUserRestrictionSource");
+ int result = UserManager.RESTRICTION_NOT_SET;
+
+ // Shortcut for the most common case
+ if (!hasUserRestriction(restrictionKey, userId)) {
+ return result;
+ }
+
+ if (hasBaseUserRestriction(restrictionKey, userId)) {
+ result |= 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;
+ }
+ }
+ if (!UserRestrictionsUtils.isEmpty(mDevicePolicyGlobalUserRestrictions)
+ && mDevicePolicyGlobalUserRestrictions.getBoolean(restrictionKey)) {
+ result |= UserManager.RESTRICTION_SOURCE_DEVICE_OWNER;
+ }
+ }
+
+ return result;
+ }
+
+ /**
* @return UserRestrictions that are in effect currently. This always returns a new
* {@link Bundle}.
*/
@@ -1470,6 +1535,11 @@ public class UserManagerService extends IUserManager.Stub {
break;
}
}
+ } else if (name.equals(TAG_GLOBAL_RESTRICTION_OWNER_ID)) {
+ String ownerUserId = parser.getAttributeValue(null, ATTR_ID);
+ if (ownerUserId != null) {
+ mGlobalRestrictionOwnerUserId = Integer.parseInt(ownerUserId);
+ }
}
}
}
@@ -1729,6 +1799,9 @@ public class UserManagerService extends IUserManager.Stub {
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);
int[] userIdsToWrite;
synchronized (mUsersLock) {
userIdsToWrite = new int[mUsers.size()];
@@ -2964,6 +3037,8 @@ public class UserManagerService extends IUserManager.Stub {
.dumpRestrictions(pw, " ", mDevicePolicyGlobalUserRestrictions);
}
pw.println();
+ pw.println(" Global restrictions owner id:" + mGlobalRestrictionOwnerUserId);
+ pw.println();
pw.println(" Guest restrictions:");
synchronized (mGuestRestrictions) {
UserRestrictionsUtils.dumpRestrictions(pw, " ", mGuestRestrictions);