User restriction API to disable single-user restrictions feature.

Change-Id: I80e08b38b5e32f3cb1af51398907510508ec199f
diff --git a/api/current.txt b/api/current.txt
index 0ec8d85..dd0ddb57 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -18027,6 +18027,7 @@
     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 cdaa868..83426ae 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -140,6 +140,16 @@
      */
     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 <code>false</code>. If app restrictions have already
+     * been set up, then this user restriction cannot be set to true.
+     * <p/>
+     * 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 16c2fe7..4ead8d5 100644
--- a/services/java/com/android/server/pm/UserManagerService.java
+++ b/services/java/com/android/server/pm/UserManagerService.java
@@ -416,8 +416,15 @@
     @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 @@
                 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 @@
                         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 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;
     }