Remove UserManager.setSystemControlledUserRestriction()

Now that we don't have UM.setUserRestriction*s*() that could remove
all existing restrictions, there's almost no point handling
DISALLOW_RECORD_AUDIO differently.

Now DISALLOW_RECORD_AUDIO is handled just like other restrictions,
except we don't persist it.

Bug 24954662

Change-Id: I27875b4a74dd95a3ce6bb774081eeaf718eaec15
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index b5bbbbb..c71d6cc 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -56,7 +56,6 @@
     Bundle getUserRestrictions(int userHandle);
     boolean hasUserRestriction(in String restrictionKey, int userHandle);
     void setUserRestriction(String key, boolean value, int userId);
-    void setSystemControlledUserRestriction(String key, boolean value, int userId);
     void setApplicationRestrictions(in String packageName, in Bundle restrictions,
             int userHandle);
     Bundle getApplicationRestrictions(in String packageName);
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index fe9fe50..75886aa 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -5151,12 +5151,12 @@
                     UserInfo userInfo = UserManagerService.getInstance().getUserInfo(userId);
                     killBackgroundUserProcessesWithRecordAudioPermission(userInfo);
                 }
-                UserManagerService.getInstance().setSystemControlledUserRestriction(
+                UserManagerService.getInstance().setUserRestriction(
                         UserManager.DISALLOW_RECORD_AUDIO, true, userId);
             } else if (action.equals(Intent.ACTION_USER_FOREGROUND)) {
                 // Enable audio recording for foreground user/profile
                 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
-                UserManagerService.getInstance().setSystemControlledUserRestriction(
+                UserManagerService.getInstance().setUserRestriction(
                         UserManager.DISALLOW_RECORD_AUDIO, false, userId);
             }
         }
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index b3c40d3..558ea58 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -781,18 +781,6 @@
     @Override
     public void setUserRestriction(String key, boolean value, int userId) {
         checkManageUsersPermission("setUserRestriction");
-        if (!UserRestrictionsUtils.isSystemControlled(key)) {
-            setUserRestrictionNoCheck(key, value, userId);
-        }
-    }
-
-    @Override
-    public void setSystemControlledUserRestriction(String key, boolean value, int userId) {
-        checkSystemOrRoot("setSystemControlledUserRestriction");
-        setUserRestrictionNoCheck(key, value, userId);
-    }
-
-    private void setUserRestrictionNoCheck(String key, boolean value, int userId) {
         synchronized (mRestrictionsLock) {
             // Note we can't modify Bundles stored in mBaseUserRestrictions directly, so create
             // a copy.
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index 129cbd3..85453a8 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -50,7 +50,7 @@
     private UserRestrictionsUtils() {
     }
 
-    public static final String[] USER_RESTRICTIONS = {
+    public static final Set<String> USER_RESTRICTIONS = Sets.newArraySet(
             UserManager.DISALLOW_CONFIG_WIFI,
             UserManager.DISALLOW_MODIFY_ACCOUNTS,
             UserManager.DISALLOW_INSTALL_APPS,
@@ -84,14 +84,7 @@
             UserManager.DISALLOW_SAFE_BOOT,
             UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
             UserManager.DISALLOW_RECORD_AUDIO,
-            UserManager.DISALLOW_CAMERA,
-    };
-
-    /**
-     * Set of user restrictions, which can only be enforced by the system.
-     */
-    public static final Set<String> SYSTEM_CONTROLLED_USER_RESTRICTIONS = Sets.newArraySet(
-            UserManager.DISALLOW_RECORD_AUDIO
+            UserManager.DISALLOW_CAMERA
     );
 
     /**
@@ -143,11 +136,17 @@
         }
 
         serializer.startTag(null, tag);
-        for (String key : USER_RESTRICTIONS) {
-            if (restrictions.getBoolean(key)
-                    && !NON_PERSIST_USER_RESTRICTIONS.contains(key)) {
-                serializer.attribute(null, key, "true");
+        for (String key : restrictions.keySet()) {
+            if (NON_PERSIST_USER_RESTRICTIONS.contains(key)) {
+                continue; // Don't persist.
             }
+            if (USER_RESTRICTIONS.contains(key)) {
+                if (restrictions.getBoolean(key)) {
+                    serializer.attribute(null, key, "true");
+                }
+                continue;
+            }
+            Log.w(TAG, "Unknown user restriction detected: " + key);
         }
         serializer.endTag(null, tag);
     }
@@ -198,14 +197,6 @@
     }
 
     /**
-     * @return true if a restriction is "system controlled"; i.e. can not be overwritten via
-     * {@link UserManager#setUserRestriction}.
-     */
-    public static boolean isSystemControlled(String restriction) {
-        return SYSTEM_CONTROLLED_USER_RESTRICTIONS.contains(restriction);
-    }
-
-    /**
      * @return true if a restriction is settable by device owner.
      */
     public static boolean canDeviceOwnerChange(String restriction) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 4c15809..06fb946 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -1386,11 +1386,11 @@
             }
             migrated = true;
 
-            // Migrate user 0 restrictions to DO, except for "system" restrictions.
+            // Migrate user 0 restrictions to DO.
             final ActiveAdmin deviceOwnerAdmin = getDeviceOwnerAdminLocked();
 
             migrateUserRestrictionsForUser(UserHandle.SYSTEM, deviceOwnerAdmin,
-                    /* exceptionList =*/ UserRestrictionsUtils.SYSTEM_CONTROLLED_USER_RESTRICTIONS);
+                    /* exceptionList =*/ null);
 
             // Push DO user restrictions to user manager.
             pushUserRestrictions(UserHandle.USER_SYSTEM);
@@ -1402,7 +1402,6 @@
         final Set<String> normalExceptionList = Sets.newArraySet(
                 UserManager.DISALLOW_OUTGOING_CALLS,
                 UserManager.DISALLOW_SMS);
-        normalExceptionList.addAll(UserRestrictionsUtils.SYSTEM_CONTROLLED_USER_RESTRICTIONS);
 
         final Set<String> managedExceptionList = new ArraySet<>(normalExceptionList.size() + 1);
         managedExceptionList.addAll(normalExceptionList);
@@ -1446,15 +1445,15 @@
         final Bundle origRestrictions = mUserManagerInternal.getBaseUserRestrictions(
                 user.getIdentifier());
 
-        final Bundle newSystemRestrictions = new Bundle();
+        final Bundle newBaseRestrictions = new Bundle();
         final Bundle newOwnerRestrictions = new Bundle();
 
         for (String key : origRestrictions.keySet()) {
             if (!origRestrictions.getBoolean(key)) {
                 continue;
             }
-            if (exceptionList.contains(key)) {
-                newSystemRestrictions.putBoolean(key, true);
+            if (exceptionList!= null && exceptionList.contains(key)) {
+                newBaseRestrictions.putBoolean(key, true);
             } else {
                 newOwnerRestrictions.putBoolean(key, true);
             }
@@ -1462,11 +1461,11 @@
 
         if (VERBOSE_LOG) {
             Log.v(LOG_TAG, "origRestrictions=" + origRestrictions);
-            Log.v(LOG_TAG, "newSystemRestrictions=" + newSystemRestrictions);
+            Log.v(LOG_TAG, "newBaseRestrictions=" + newBaseRestrictions);
             Log.v(LOG_TAG, "newOwnerRestrictions=" + newOwnerRestrictions);
         }
         mUserManagerInternal.setBaseUserRestrictionsByDpmsForMigration(user.getIdentifier(),
-                newSystemRestrictions);
+                newBaseRestrictions);
 
         if (admin != null) {
             admin.ensureUserRestrictions().clear();
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java
index dfa9f8f..f32f209 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java
@@ -145,16 +145,13 @@
 
         // Check the new base restrictions.
         DpmTestUtils.assertRestrictions(
-                DpmTestUtils.newRestrictions(
-                        UserManager.DISALLOW_RECORD_AUDIO
-                ),
+                DpmTestUtils.newRestrictions(),
                 newBaseRestrictions.get(UserHandle.USER_SYSTEM));
 
         DpmTestUtils.assertRestrictions(
                 DpmTestUtils.newRestrictions(
                         UserManager.DISALLOW_SMS,
-                        UserManager.DISALLOW_OUTGOING_CALLS,
-                        UserManager.DISALLOW_RECORD_AUDIO
+                        UserManager.DISALLOW_OUTGOING_CALLS
                 ),
                 newBaseRestrictions.get(10));
 
@@ -162,28 +159,30 @@
                 DpmTestUtils.newRestrictions(
                         UserManager.DISALLOW_SMS,
                         UserManager.DISALLOW_OUTGOING_CALLS,
-                        UserManager.DISALLOW_WALLPAPER,
-                        UserManager.DISALLOW_RECORD_AUDIO
+                        UserManager.DISALLOW_WALLPAPER
                 ),
                 newBaseRestrictions.get(11));
 
         // Check the new owner restrictions.
         DpmTestUtils.assertRestrictions(
                 DpmTestUtils.newRestrictions(
-                        UserManager.DISALLOW_ADD_USER
+                        UserManager.DISALLOW_ADD_USER,
+                        UserManager.DISALLOW_RECORD_AUDIO
                 ),
                 dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions());
 
         DpmTestUtils.assertRestrictions(
                 DpmTestUtils.newRestrictions(
                         UserManager.DISALLOW_REMOVE_USER,
-                        UserManager.DISALLOW_WALLPAPER
+                        UserManager.DISALLOW_WALLPAPER,
+                        UserManager.DISALLOW_RECORD_AUDIO
                 ),
                 dpms.getProfileOwnerAdminLocked(10).ensureUserRestrictions());
 
         DpmTestUtils.assertRestrictions(
                 DpmTestUtils.newRestrictions(
-                        UserManager.DISALLOW_REMOVE_USER
+                        UserManager.DISALLOW_REMOVE_USER,
+                        UserManager.DISALLOW_RECORD_AUDIO
                 ),
                 dpms.getProfileOwnerAdminLocked(11).ensureUserRestrictions());
     }
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java
new file mode 100644
index 0000000..5542a4f
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2015 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 com.android.server.pm;
+
+import com.android.server.devicepolicy.DpmTestUtils;
+
+import android.os.Bundle;
+import android.os.UserManager;
+import android.test.AndroidTestCase;
+import android.test.MoreAsserts;
+
+/**
+ * Tests for {@link com.android.server.pm.UserRestrictionsUtils}.
+ *
+ * <p>Run with:<pre>
+   m FrameworksServicesTests &&
+   adb install \
+     -r out/target/product/hammerhead/data/app/FrameworksServicesTests/FrameworksServicesTests.apk &&
+   adb shell am instrument -e class com.android.server.pm.UserRestrictionsUtilsTest \
+     -w com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
+ * </pre>
+ */
+public class UserRestrictionsUtilsTest extends AndroidTestCase {
+    public void testNonNull() {
+        Bundle out = UserRestrictionsUtils.nonNull(null);
+        assertNotNull(out);
+        out.putBoolean("a", true); // Should not be Bundle.EMPTY.
+
+        Bundle in = new Bundle();
+        assertSame(in, UserRestrictionsUtils.nonNull(in));
+    }
+
+    public void testIsEmpty() {
+        assertTrue(UserRestrictionsUtils.isEmpty(null));
+        assertTrue(UserRestrictionsUtils.isEmpty(new Bundle()));
+        assertFalse(UserRestrictionsUtils.isEmpty(DpmTestUtils.newRestrictions("a")));
+    }
+
+    public void testClone() {
+        Bundle in = new Bundle();
+        Bundle out = UserRestrictionsUtils.clone(in);
+        assertNotSame(in, out);
+        DpmTestUtils.assertRestrictions(out, new Bundle());
+
+        out = UserRestrictionsUtils.clone(null);
+        assertNotNull(out);
+        out.putBoolean("a", true); // Should not be Bundle.EMPTY.
+    }
+
+    public void testMerge() {
+        Bundle a = DpmTestUtils.newRestrictions("a", "d");
+        Bundle b = DpmTestUtils.newRestrictions("b", "d", "e");
+
+        UserRestrictionsUtils.merge(a, b);
+
+        DpmTestUtils.assertRestrictions(DpmTestUtils.newRestrictions("a", "b", "d", "e"), a);
+
+        UserRestrictionsUtils.merge(a, null);
+
+        DpmTestUtils.assertRestrictions(DpmTestUtils.newRestrictions("a", "b", "d", "e"), a);
+
+        try {
+            UserRestrictionsUtils.merge(a, a);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    public void testCanDeviceOwnerChange() {
+        assertFalse(UserRestrictionsUtils.canDeviceOwnerChange(UserManager.DISALLOW_RECORD_AUDIO));
+        assertFalse(UserRestrictionsUtils.canDeviceOwnerChange(UserManager.DISALLOW_WALLPAPER));
+        assertTrue(UserRestrictionsUtils.canDeviceOwnerChange(UserManager.DISALLOW_ADD_USER));
+    }
+
+    public void testCanProfileOwnerChange() {
+        assertFalse(UserRestrictionsUtils.canProfileOwnerChange(UserManager.DISALLOW_RECORD_AUDIO));
+        assertFalse(UserRestrictionsUtils.canProfileOwnerChange(UserManager.DISALLOW_WALLPAPER));
+        assertFalse(UserRestrictionsUtils.canProfileOwnerChange(UserManager.DISALLOW_ADD_USER));
+        assertTrue(UserRestrictionsUtils.canProfileOwnerChange(UserManager.DISALLOW_ADJUST_VOLUME));
+    }
+
+    public void testSortToGlobalAndLocal() {
+        final Bundle local = new Bundle();
+        final Bundle global = new Bundle();
+
+        UserRestrictionsUtils.sortToGlobalAndLocal(null, global, local);
+        assertEquals(0, global.size());
+        assertEquals(0, local.size());
+
+        UserRestrictionsUtils.sortToGlobalAndLocal(Bundle.EMPTY, global, local);
+        assertEquals(0, global.size());
+        assertEquals(0, local.size());
+
+        UserRestrictionsUtils.sortToGlobalAndLocal(DpmTestUtils.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);
+
+
+        DpmTestUtils.assertRestrictions(DpmTestUtils.newRestrictions(
+                // These can be set by PO too, but when DO sets them, they're global.
+                UserManager.DISALLOW_ADJUST_VOLUME,
+                UserManager.DISALLOW_UNMUTE_MICROPHONE,
+
+                // These can only be set by DO.
+                UserManager.DISALLOW_USB_FILE_TRANSFER,
+                UserManager.DISALLOW_CONFIG_TETHERING
+        ), global);
+
+        DpmTestUtils.assertRestrictions(DpmTestUtils.newRestrictions(
+                // They can be set by both DO/PO.
+                UserManager.DISALLOW_OUTGOING_BEAM,
+                UserManager.DISALLOW_APPS_CONTROL
+        ), local);
+    }
+
+    public void testAreEqual() {
+        assertTrue(UserRestrictionsUtils.areEqual(
+                null,
+                null));
+
+        assertTrue(UserRestrictionsUtils.areEqual(
+                null,
+                Bundle.EMPTY));
+
+        assertTrue(UserRestrictionsUtils.areEqual(
+                Bundle.EMPTY,
+                null));
+
+        assertTrue(UserRestrictionsUtils.areEqual(
+                Bundle.EMPTY,
+                Bundle.EMPTY));
+
+        assertTrue(UserRestrictionsUtils.areEqual(
+                new Bundle(),
+                Bundle.EMPTY));
+
+        assertFalse(UserRestrictionsUtils.areEqual(
+                null,
+                DpmTestUtils.newRestrictions("a")));
+
+        assertFalse(UserRestrictionsUtils.areEqual(
+                DpmTestUtils.newRestrictions("a"),
+                null));
+
+        assertTrue(UserRestrictionsUtils.areEqual(
+                DpmTestUtils.newRestrictions("a"),
+                DpmTestUtils.newRestrictions("a")));
+
+        assertFalse(UserRestrictionsUtils.areEqual(
+                DpmTestUtils.newRestrictions("a"),
+                DpmTestUtils.newRestrictions("a", "b")));
+
+        assertFalse(UserRestrictionsUtils.areEqual(
+                DpmTestUtils.newRestrictions("a", "b"),
+                DpmTestUtils.newRestrictions("a")));
+
+        assertFalse(UserRestrictionsUtils.areEqual(
+                DpmTestUtils.newRestrictions("b", "a"),
+                DpmTestUtils.newRestrictions("a", "a")));
+
+        // Make sure false restrictions are handled correctly.
+        final Bundle a = DpmTestUtils.newRestrictions("a");
+        a.putBoolean("b", true);
+
+        final Bundle b = DpmTestUtils.newRestrictions("a");
+        b.putBoolean("b", false);
+
+        assertFalse(UserRestrictionsUtils.areEqual(a, b));
+        assertFalse(UserRestrictionsUtils.areEqual(b, a));
+    }
+}