diff --git a/api/current.txt b/api/current.txt
index 080c6f943e769..5607eabbb4e59 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -18055,6 +18055,7 @@ package android.os {
method public void setUserRestriction(java.lang.String, boolean);
method public void setUserRestrictions(android.os.Bundle);
method public void setUserRestrictions(android.os.Bundle, android.os.UserHandle);
+ field public static final java.lang.String DISALLOW_APP_RESTRICTIONS = "no_app_restrictions";
field public static final java.lang.String DISALLOW_CONFIG_BLUETOOTH = "no_config_bluetooth";
field public static final java.lang.String DISALLOW_CONFIG_CREDENTIALS = "no_config_credentials";
field public static final java.lang.String DISALLOW_CONFIG_WIFI = "no_config_wifi";
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index cdaa868b4484c..83426ae8f77a5 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -140,6 +140,16 @@ public class UserManager {
*/
public static final String DISALLOW_REMOVE_USER = "no_remove_user";
+ /**
+ * Key for user restrictions. Specifies if a user is disallowed from setting app restrictions
+ * via a restrictions PIN. The default is false. If app restrictions have already
+ * been set up, then this user restriction cannot be set to true.
+ *
+ * Type: Boolean
+ * @see #hasRestrictionsPin()
+ */
+ public static final String DISALLOW_APP_RESTRICTIONS = "no_app_restrictions";
+
/** @hide */
public static final int PIN_VERIFICATION_FAILED_INCORRECT = -3;
/** @hide */
diff --git a/services/java/com/android/server/pm/UserManagerService.java b/services/java/com/android/server/pm/UserManagerService.java
index 16c2fe7f77ce5..4ead8d50a40df 100644
--- a/services/java/com/android/server/pm/UserManagerService.java
+++ b/services/java/com/android/server/pm/UserManagerService.java
@@ -416,8 +416,15 @@ public class UserManagerService extends IUserManager.Stub {
@Override
public void setUserRestrictions(Bundle restrictions, int userId) {
checkManageUsersPermission("setUserRestrictions");
+ if (restrictions == null) return;
synchronized (mPackagesLock) {
+ // If the user has restrictions already and call is trying to disallow restrictions,
+ // don't modify the flag.
+ if (hasRestrictionsPinLocked(userId)
+ && restrictions.getBoolean(UserManager.DISALLOW_APP_RESTRICTIONS, false)) {
+ restrictions.putBoolean(UserManager.DISALLOW_APP_RESTRICTIONS, false);
+ }
mUserRestrictions.get(userId).putAll(restrictions);
writeUserLocked(mUsers.get(userId));
}
@@ -681,6 +688,7 @@ public class UserManagerService extends IUserManager.Stub {
writeBoolean(serializer, restrictions, UserManager.DISALLOW_USB_FILE_TRANSFER);
writeBoolean(serializer, restrictions, UserManager.DISALLOW_CONFIG_CREDENTIALS);
writeBoolean(serializer, restrictions, UserManager.DISALLOW_REMOVE_USER);
+ writeBoolean(serializer, restrictions, UserManager.DISALLOW_APP_RESTRICTIONS);
serializer.endTag(null, TAG_RESTRICTIONS);
}
serializer.endTag(null, TAG_USER);
@@ -811,6 +819,7 @@ public class UserManagerService extends IUserManager.Stub {
readBoolean(parser, restrictions, UserManager.DISALLOW_USB_FILE_TRANSFER);
readBoolean(parser, restrictions, UserManager.DISALLOW_CONFIG_CREDENTIALS);
readBoolean(parser, restrictions, UserManager.DISALLOW_REMOVE_USER);
+ readBoolean(parser, restrictions, UserManager.DISALLOW_APP_RESTRICTIONS);
}
}
}
@@ -1196,10 +1205,14 @@ public class UserManagerService extends IUserManager.Stub {
public boolean hasRestrictionsPin() {
int userId = UserHandle.getCallingUserId();
synchronized (mPackagesLock) {
- RestrictionsPinState pinState = mRestrictionsPinStates.get(userId);
- if (pinState == null || pinState.salt == 0 || pinState.pinHash == null) {
- return false;
- }
+ return hasRestrictionsPinLocked(userId);
+ }
+ }
+
+ private boolean hasRestrictionsPinLocked(int userId) {
+ RestrictionsPinState pinState = mRestrictionsPinStates.get(userId);
+ if (pinState == null || pinState.salt == 0 || pinState.pinHash == null) {
+ return false;
}
return true;
}