Merge "Changed how user restrictions are pushed to UM" into rvc-dev
diff --git a/services/core/java/android/os/UserManagerInternal.java b/services/core/java/android/os/UserManagerInternal.java
index aedafbb..94f5741 100644
--- a/services/core/java/android/os/UserManagerInternal.java
+++ b/services/core/java/android/os/UserManagerInternal.java
@@ -23,6 +23,8 @@
 import android.content.pm.UserInfo;
 import android.graphics.Bitmap;
 
+import com.android.server.pm.RestrictionsSet;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
@@ -57,21 +59,18 @@
      * Called by {@link com.android.server.devicepolicy.DevicePolicyManagerService} to set
      * restrictions enforced by the user.
      *
-     * @param originatingUserId user id of the user where the restriction originated.
-     * @param restrictions a bundle of user restrictions.
-     * @param restrictionOwnerType determines which admin {@code userId} corresponds to.
-     *             The admin can be either
-     *             {@link UserManagerInternal#OWNER_TYPE_DEVICE_OWNER},
-     *             {@link UserManagerInternal#OWNER_TYPE_PROFILE_OWNER},
-     *             {@link UserManagerInternal#OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE}
-     *             or {@link UserManagerInternal#OWNER_TYPE_NO_OWNER}.
-     *             If the admin is a DEVICE_OWNER or a PROFILE_OWNER_ORG_OWNED_DEVICE then
-     *             a restriction may be applied globally depending on which restriction it is,
-     *             otherwise it will be applied just on the current user.
-     * @see OwnerType
+     * @param originatingUserId user id of the user where the restrictions originated.
+     * @param global            a bundle of global user restrictions. Global restrictions are
+     *                          restrictions that apply device-wide: to the managed profile,
+     *                          primary profile and secondary users and any profile created in
+     *                          any secondary user.
+     * @param local             a restriction set of local user restrictions. The key is the user
+     *                          id of the user whom the restrictions are targeting.
+     * @param isDeviceOwner     whether {@code originatingUserId} corresponds to device owner
+     *                          user id.
      */
     public abstract void setDevicePolicyUserRestrictions(int originatingUserId,
-            @Nullable Bundle restrictions, @OwnerType int restrictionOwnerType);
+            @Nullable Bundle global, @Nullable RestrictionsSet local, boolean isDeviceOwner);
 
     /**
      * Returns the "base" user restrictions.
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index d2443fa..323ffcf 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1716,27 +1716,6 @@
         }
     }
 
-    private void setDevicePolicyUserRestrictionsInner(@UserIdInt int originatingUserId,
-            @Nullable Bundle restrictions,
-            @UserManagerInternal.OwnerType int restrictionOwnerType) {
-        final Bundle global = new Bundle();
-        final Bundle local = new Bundle();
-
-        // Sort restrictions into local and global ensuring they don't overlap.
-        UserRestrictionsUtils.sortToGlobalAndLocal(restrictions, restrictionOwnerType, global,
-                local);
-        boolean isDeviceOwner = restrictionOwnerType == UserManagerInternal.OWNER_TYPE_DEVICE_OWNER;
-
-        RestrictionsSet localRestrictionsSet;
-        if (UserRestrictionsUtils.isEmpty(local)) {
-            localRestrictionsSet = new RestrictionsSet();
-        } else {
-            localRestrictionsSet = new RestrictionsSet(originatingUserId, local);
-        }
-        setDevicePolicyUserRestrictionsInner(originatingUserId, global, localRestrictionsSet,
-                isDeviceOwner);
-    }
-
     /**
      * See {@link UserManagerInternal#setDevicePolicyUserRestrictions}
      */
@@ -4754,10 +4733,10 @@
     private class LocalService extends UserManagerInternal {
         @Override
         public void setDevicePolicyUserRestrictions(@UserIdInt int originatingUserId,
-                @Nullable Bundle restrictions,
-                @OwnerType int restrictionOwnerType) {
+                @NonNull Bundle global, @NonNull RestrictionsSet local,
+                boolean isDeviceOwner) {
             UserManagerService.this.setDevicePolicyUserRestrictionsInner(originatingUserId,
-                    restrictions, restrictionOwnerType);
+                    global, local, isDeviceOwner);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index eec6e02..c0502b8 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -233,6 +233,13 @@
     );
 
     /**
+     * Special user restrictions that profile owner of an organization-owned managed profile can
+     * set on the parent profile instance to apply them on the personal profile.
+     */
+    private static final Set<String> PROFILE_OWNER_ORGANIZATION_OWNED_LOCAL_RESTRICTIONS =
+            Sets.newArraySet();
+
+    /**
      * User restrictions that default to {@code true} for managed profile owners.
      *
      * NB: {@link UserManager#DISALLOW_INSTALL_UNKNOWN_SOURCES} is also set by default but it is
@@ -416,7 +423,8 @@
      * @return true if a restriction is settable by profile owner of an organization owned device.
      */
     public static boolean canProfileOwnerOfOrganizationOwnedDeviceChange(String restriction) {
-        return PROFILE_OWNER_ORGANIZATION_OWNED_GLOBAL_RESTRICTIONS.contains(restriction);
+        return PROFILE_OWNER_ORGANIZATION_OWNED_GLOBAL_RESTRICTIONS.contains(restriction)
+                || PROFILE_OWNER_ORGANIZATION_OWNED_LOCAL_RESTRICTIONS.contains(restriction);
     }
 
     /**
@@ -427,31 +435,9 @@
     }
 
     /**
-     * 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,
-            @UserManagerInternal.OwnerType int restrictionOwnerType, @NonNull Bundle global,
-            @NonNull Bundle local) {
-        if (in == null || in.size() == 0) {
-            return;
-        }
-        for (String key : in.keySet()) {
-            if (!in.getBoolean(key)) {
-                continue;
-            }
-            if (isGlobal(restrictionOwnerType, key)) {
-                global.putBoolean(key, true);
-            } else {
-                local.putBoolean(key, true);
-            }
-        }
-    }
-
-    /**
      * Whether given user restriction should be enforced globally.
      */
-    private static boolean isGlobal(@UserManagerInternal.OwnerType int restrictionOwnerType,
+    public static boolean isGlobal(@UserManagerInternal.OwnerType int restrictionOwnerType,
             String key) {
         return ((restrictionOwnerType == UserManagerInternal.OWNER_TYPE_DEVICE_OWNER) && (
                 PRIMARY_USER_ONLY_RESTRICTIONS.contains(key) || GLOBAL_RESTRICTIONS.contains(key)))
@@ -463,6 +449,14 @@
     }
 
     /**
+     * Whether given user restriction should be enforced locally.
+     */
+    public static boolean isLocal(@UserManagerInternal.OwnerType int restrictionOwnerType,
+            String key) {
+        return !isGlobal(restrictionOwnerType, key);
+    }
+
+    /**
      * @return true if two Bundles contain the same user restriction.
      * A null bundle and an empty bundle are considered to be equal.
      */
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index eed39e1..d1c47d9 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -87,6 +87,9 @@
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
 import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
+import static android.os.UserManagerInternal.OWNER_TYPE_DEVICE_OWNER;
+import static android.os.UserManagerInternal.OWNER_TYPE_PROFILE_OWNER;
+import static android.os.UserManagerInternal.OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE;
 import static android.provider.Settings.Global.PRIVATE_DNS_MODE;
 import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
 import static android.provider.Telephony.Carriers.DPC_URI;
@@ -284,6 +287,7 @@
 import com.android.server.devicepolicy.DevicePolicyManagerService.ActiveAdmin.TrustAgentInfo;
 import com.android.server.inputmethod.InputMethodManagerInternal;
 import com.android.server.net.NetworkPolicyManagerInternal;
+import com.android.server.pm.RestrictionsSet;
 import com.android.server.pm.UserRestrictionsUtils;
 import com.android.server.pm.parsing.pkg.AndroidPackage;
 import com.android.server.storage.DeviceStorageMonitorInternal;
@@ -322,6 +326,7 @@
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.function.Function;
+import java.util.function.Predicate;
 
 /**
  * Implementation of the device policy APIs.
@@ -1828,6 +1833,50 @@
             info = deviceAdminInfo;
         }
 
+        Bundle addSyntheticRestrictions(Bundle restrictions) {
+            if (disableCamera) {
+                restrictions.putBoolean(UserManager.DISALLOW_CAMERA, true);
+            } else {
+                restrictions.remove(UserManager.DISALLOW_CAMERA);
+            }
+            return restrictions;
+        }
+
+        static Bundle removeDeprecatedRestrictions(Bundle restrictions) {
+            for (String deprecatedRestriction: DEPRECATED_USER_RESTRICTIONS) {
+                restrictions.remove(deprecatedRestriction);
+            }
+            return restrictions;
+        }
+
+        static Bundle filterRestrictions(Bundle restrictions, Predicate<String> filter) {
+            Bundle result = new Bundle();
+            for (String key : restrictions.keySet()) {
+                if (!restrictions.getBoolean(key)) {
+                    continue;
+                }
+                if (filter.test(key)) {
+                    result.putBoolean(key, true);
+                }
+            }
+            return result;
+        }
+
+        Bundle getEffectiveRestrictions() {
+            return addSyntheticRestrictions(
+                    removeDeprecatedRestrictions(ensureUserRestrictions()));
+        }
+
+        Bundle getLocalUserRestrictions(int adminType) {
+            return filterRestrictions(getEffectiveRestrictions(),
+                    key -> UserRestrictionsUtils.isLocal(adminType, key));
+        }
+
+        Bundle getGlobalUserRestrictions(int adminType) {
+            return filterRestrictions(getEffectiveRestrictions(),
+                    key -> UserRestrictionsUtils.isGlobal(adminType, key));
+        }
+
         void dump(IndentingPrintWriter pw) {
             pw.print("uid="); pw.println(getUid());
             pw.print("testOnlyAdmin=");
@@ -2772,7 +2821,7 @@
                 Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED, 0, userId) != 0) {
             profileOwner.ensureUserRestrictions().putBoolean(
                     UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, true);
-            saveUserRestrictionsLocked(userId, /* parent = */ false);
+            saveUserRestrictionsLocked(userId);
             mInjector.settingsSecurePutIntForUser(
                     Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED, 0, userId);
         }
@@ -2803,7 +2852,7 @@
             }
             admin.defaultEnabledRestrictionsAlreadySet.addAll(restrictionsToSet);
             Slog.i(LOG_TAG, "Enabled the following restrictions by default: " + restrictionsToSet);
-            saveUserRestrictionsLocked(userId, /* parent = */ false);
+            saveUserRestrictionsLocked(userId);
         }
     }
 
@@ -8222,9 +8271,9 @@
             }
         }
         // Tell the user manager that the restrictions have changed.
-        final int affectedUserId = parent ? getProfileParentId(userHandle) : userHandle;
-        pushUserRestrictions(affectedUserId);
+        pushUserRestrictions(userHandle);
 
+        final int affectedUserId = parent ? getProfileParentId(userHandle) : userHandle;
         if (SecurityLog.isLoggingEnabled()) {
             SecurityLog.writeEvent(SecurityLog.TAG_CAMERA_POLICY_SET,
                     who.getPackageName(), userHandle, affectedUserId, disabled ? 1 : 0);
@@ -10806,10 +10855,14 @@
                             "Cannot use the parent instance in Device Owner mode");
                 }
             } else {
-                if (!(UserRestrictionsUtils.canProfileOwnerChange(key, userHandle) || (
-                        isProfileOwnerOfOrganizationOwnedDevice(activeAdmin) && parent
-                        && UserRestrictionsUtils.canProfileOwnerOfOrganizationOwnedDeviceChange(
-                                key)))) {
+                boolean profileOwnerCanChangeOnItself = !parent
+                        && UserRestrictionsUtils.canProfileOwnerChange(key, userHandle);
+                boolean orgOwnedProfileOwnerCanChangesGlobally = parent
+                        && isProfileOwnerOfOrganizationOwnedDevice(activeAdmin)
+                        && UserRestrictionsUtils
+                                .canProfileOwnerOfOrganizationOwnedDeviceChange(key);
+
+                if (!profileOwnerCanChangeOnItself && !orgOwnedProfileOwnerCanChangesGlobally) {
                     throw new SecurityException("Profile owner cannot set user restriction " + key);
                 }
             }
@@ -10821,7 +10874,7 @@
             } else {
                 restrictions.remove(key);
             }
-            saveUserRestrictionsLocked(userHandle, parent);
+            saveUserRestrictionsLocked(userHandle);
         }
         final int eventId = enabledFromThisOwner
                 ? DevicePolicyEnums.ADD_USER_RESTRICTION
@@ -10839,91 +10892,65 @@
         }
     }
 
-    private void saveUserRestrictionsLocked(int userId, boolean parent) {
+    private void saveUserRestrictionsLocked(int userId) {
         saveSettingsLocked(userId);
-        pushUserRestrictions(parent ? getProfileParentId(userId) : userId);
+        pushUserRestrictions(userId);
         sendChangedNotification(userId);
     }
 
-    private void pushUserRestrictions(int userId) {
+    /**
+     * Pushes the user restrictions originating from a specific user.
+     *
+     * If called by the profile owner of an organization-owned device, the global and local
+     * user restrictions will be an accumulation of the global user restrictions from the profile
+     * owner active admin and its parent active admin. The key of the local user restrictions set
+     * will be the target user id.
+     */
+    private void pushUserRestrictions(int originatingUserId) {
+        final Bundle global;
+        final RestrictionsSet local = new RestrictionsSet();
+        final boolean isDeviceOwner;
         synchronized (getLockObject()) {
-            final boolean isDeviceOwner = mOwners.isDeviceOwnerUserId(userId);
-            Bundle userRestrictions = null;
-            final int restrictionOwnerType;
-            final int originatingUserId;
-
+            isDeviceOwner = mOwners.isDeviceOwnerUserId(originatingUserId);
             if (isDeviceOwner) {
                 final ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked();
                 if (deviceOwner == null) {
                     return; // Shouldn't happen.
                 }
-                userRestrictions = addOrRemoveDisableCameraRestriction(
-                        deviceOwner.userRestrictions, deviceOwner);
-                restrictionOwnerType = UserManagerInternal.OWNER_TYPE_DEVICE_OWNER;
-                originatingUserId = deviceOwner.getUserHandle().getIdentifier();
+                global = deviceOwner.getGlobalUserRestrictions(OWNER_TYPE_DEVICE_OWNER);
+                local.updateRestrictions(originatingUserId, deviceOwner.getLocalUserRestrictions(
+                        OWNER_TYPE_DEVICE_OWNER));
             } else {
-                final ActiveAdmin profileOwnerOfOrganizationOwnedDevice =
-                        getProfileOwnerOfOrganizationOwnedDeviceLocked(userId);
-
-                // If profile owner of an organization owned device, the restrictions will be
-                // pushed to the parent instance.
-                if (profileOwnerOfOrganizationOwnedDevice != null && !isManagedProfile(userId)) {
-                    restrictionOwnerType =
-                          UserManagerInternal.OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE;
-                    final ActiveAdmin parent = profileOwnerOfOrganizationOwnedDevice
-                            .getParentActiveAdmin();
-                    userRestrictions = parent.userRestrictions;
-                    userRestrictions = addOrRemoveDisableCameraRestriction(userRestrictions,
-                            parent);
-                    originatingUserId =
-                            profileOwnerOfOrganizationOwnedDevice.getUserHandle().getIdentifier();
-                } else {
-                    final ActiveAdmin profileOwner = getProfileOwnerAdminLocked(userId);
-
-                    if (profileOwner != null) {
-                        userRestrictions = profileOwner.userRestrictions;
-                        restrictionOwnerType = UserManagerInternal.OWNER_TYPE_PROFILE_OWNER;
-                        originatingUserId = profileOwner.getUserHandle().getIdentifier();
-                    } else {
-                        restrictionOwnerType = UserManagerInternal.OWNER_TYPE_NO_OWNER;
-                        originatingUserId = userId;
-                    }
-                    userRestrictions = addOrRemoveDisableCameraRestriction(
-                            userRestrictions, userId);
+                final ActiveAdmin profileOwner = getProfileOwnerAdminLocked(originatingUserId);
+                if (profileOwner == null) {
+                    return;
+                }
+                global = profileOwner.getGlobalUserRestrictions(OWNER_TYPE_PROFILE_OWNER);
+                local.updateRestrictions(originatingUserId, profileOwner.getLocalUserRestrictions(
+                        OWNER_TYPE_PROFILE_OWNER));
+                // Global (device-wide) and local user restrictions set by the profile owner of an
+                // organization-owned device are stored in the parent ActiveAdmin instance.
+                if (isProfileOwnerOfOrganizationOwnedDevice(
+                        profileOwner.getUserHandle().getIdentifier())) {
+                    // The global restrictions set on the parent ActiveAdmin instance need to be
+                    // merged with the global restrictions set on the profile owner ActiveAdmin
+                    // instance, since both are to be applied device-wide.
+                    UserRestrictionsUtils.merge(global,
+                            profileOwner.getParentActiveAdmin().getGlobalUserRestrictions(
+                                    OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE));
+                    // The local restrictions set on the parent ActiveAdmin instance are only to be
+                    // applied to the primary user. They therefore need to be added the local
+                    // restriction set with the primary user id as the key, in this case the
+                    // primary user id is the target user.
+                    local.updateRestrictions(
+                            getProfileParentId(profileOwner.getUserHandle().getIdentifier()),
+                            profileOwner.getParentActiveAdmin().getLocalUserRestrictions(
+                                    OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE));
                 }
             }
-            // Remove deprecated restrictions.
-            for (String deprecatedRestriction: DEPRECATED_USER_RESTRICTIONS) {
-                userRestrictions.remove(deprecatedRestriction);
-            }
-            mUserManagerInternal.setDevicePolicyUserRestrictions(originatingUserId,
-                    userRestrictions, restrictionOwnerType);
         }
-    }
-
-    private Bundle addOrRemoveDisableCameraRestriction(Bundle userRestrictions, ActiveAdmin admin) {
-        if (userRestrictions == null) {
-            userRestrictions = new Bundle();
-        }
-        if (admin.disableCamera) {
-            userRestrictions.putBoolean(UserManager.DISALLOW_CAMERA, true);
-        } else {
-            userRestrictions.remove(UserManager.DISALLOW_CAMERA);
-        }
-        return userRestrictions;
-    }
-
-    private Bundle addOrRemoveDisableCameraRestriction(Bundle userRestrictions, int userId) {
-        if (userRestrictions == null) {
-            userRestrictions = new Bundle();
-        }
-        if (getCameraDisabled(/* who= */ null, userId, /* mergeDeviceOwnerRestriction= */
-                false)) {
-            userRestrictions.putBoolean(UserManager.DISALLOW_CAMERA, true);
-        } else {
-            userRestrictions.remove(UserManager.DISALLOW_CAMERA);
-        }
-        return userRestrictions;
+        mUserManagerInternal.setDevicePolicyUserRestrictions(originatingUserId, global, local,
+                isDeviceOwner);
     }
 
     @Override
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index fe47cea..d780370 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -83,7 +83,6 @@
 import android.os.Process;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.os.UserManagerInternal;
 import android.platform.test.annotations.Presubmit;
 import android.provider.Settings;
 import android.security.KeyChain;
@@ -1170,7 +1169,6 @@
                 () -> dpm.clearDeviceOwnerApp(admin1.getPackageName()));
 
         when(getServices().userManager.isUserUnlocked(anyInt())).thenReturn(true);
-        reset(getServices().userManagerInternal);
         dpm.clearDeviceOwnerApp(admin1.getPackageName());
 
         // Now DO shouldn't be set.
@@ -1181,9 +1179,8 @@
                 MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
 
         verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
-                eq(UserHandle.USER_SYSTEM),
-                MockUtils.checkUserRestrictions(),
-                eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER));
+                eq(UserHandle.USER_SYSTEM), MockUtils.checkUserRestrictions(),
+                MockUtils.checkUserRestrictions(UserHandle.USER_SYSTEM), eq(true));
 
         verify(getServices().usageStatsManagerInternal).setActiveAdminApps(
                 null, UserHandle.USER_SYSTEM);
@@ -1745,15 +1742,16 @@
         verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER),
-                eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER));
+                MockUtils.checkUserRestrictions(UserHandle.USER_SYSTEM), eq(true));
         reset(getServices().userManagerInternal);
 
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
         verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
-                MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS,
-                        UserManager.DISALLOW_ADD_USER),
-                eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER));
+                MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER),
+                MockUtils.checkUserRestrictions(UserHandle.USER_SYSTEM,
+                        UserManager.DISALLOW_OUTGOING_CALLS),
+                eq(true));
         reset(getServices().userManagerInternal);
 
         DpmTestUtils.assertRestrictions(
@@ -1770,8 +1768,10 @@
         dpm.clearUserRestriction(admin1, UserManager.DISALLOW_ADD_USER);
         verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
-                MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
-                eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER));
+                MockUtils.checkUserRestrictions(),
+                MockUtils.checkUserRestrictions(UserHandle.USER_SYSTEM,
+                        UserManager.DISALLOW_OUTGOING_CALLS),
+                eq(true));
         reset(getServices().userManagerInternal);
 
         DpmTestUtils.assertRestrictions(
@@ -1787,7 +1787,7 @@
         verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(),
-                eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER));
+                MockUtils.checkUserRestrictions(UserHandle.USER_SYSTEM), eq(true));
         reset(getServices().userManagerInternal);
 
         assertNoDeviceOwnerRestrictions();
@@ -1801,7 +1801,7 @@
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME,
                         UserManager.DISALLOW_UNMUTE_MICROPHONE),
-                eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER));
+                MockUtils.checkUserRestrictions(UserHandle.USER_SYSTEM), eq(true));
         reset(getServices().userManagerInternal);
 
         dpm.clearUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME);
@@ -1813,7 +1813,7 @@
         verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER),
-                eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER));
+                MockUtils.checkUserRestrictions(UserHandle.USER_SYSTEM), eq(true));
         reset(getServices().userManagerInternal);
 
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_FUN);
@@ -1821,7 +1821,7 @@
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN,
                         UserManager.DISALLOW_ADD_USER),
-                eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER));
+                MockUtils.checkUserRestrictions(UserHandle.USER_SYSTEM), eq(true));
         reset(getServices().userManagerInternal);
 
         dpm.setCameraDisabled(admin1, true);
@@ -1830,7 +1830,7 @@
                 // DISALLOW_CAMERA will be applied globally.
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN,
                         UserManager.DISALLOW_ADD_USER, UserManager.DISALLOW_CAMERA),
-                eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER));
+                MockUtils.checkUserRestrictions(UserHandle.USER_SYSTEM), eq(true));
         reset(getServices().userManagerInternal);
     }
 
@@ -1887,17 +1887,19 @@
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
         verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(DpmMockContext.CALLER_USER_HANDLE),
-                MockUtils.checkUserRestrictions(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES),
-                eq(UserManagerInternal.OWNER_TYPE_PROFILE_OWNER));
-        reset(getServices().userManagerInternal);
+                MockUtils.checkUserRestrictions(),
+                MockUtils.checkUserRestrictions(DpmMockContext.CALLER_USER_HANDLE,
+                        UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES),
+                eq(false));
 
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
         verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(DpmMockContext.CALLER_USER_HANDLE),
-                MockUtils.checkUserRestrictions(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
+                MockUtils.checkUserRestrictions(),
+                MockUtils.checkUserRestrictions(DpmMockContext.CALLER_USER_HANDLE,
+                        UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
                         UserManager.DISALLOW_OUTGOING_CALLS),
-                eq(UserManagerInternal.OWNER_TYPE_PROFILE_OWNER));
-        reset(getServices().userManagerInternal);
+                eq(false));
 
         DpmTestUtils.assertRestrictions(
                 DpmTestUtils.newRestrictions(
@@ -1918,9 +1920,10 @@
         dpm.clearUserRestriction(admin1, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
         verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(DpmMockContext.CALLER_USER_HANDLE),
-                MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
-                eq(UserManagerInternal.OWNER_TYPE_PROFILE_OWNER));
-        reset(getServices().userManagerInternal);
+                MockUtils.checkUserRestrictions(),
+                MockUtils.checkUserRestrictions(DpmMockContext.CALLER_USER_HANDLE,
+                        UserManager.DISALLOW_OUTGOING_CALLS),
+                eq(false));
 
         DpmTestUtils.assertRestrictions(
                 DpmTestUtils.newRestrictions(
@@ -1940,8 +1943,7 @@
         verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(DpmMockContext.CALLER_USER_HANDLE),
                 MockUtils.checkUserRestrictions(),
-                eq(UserManagerInternal.OWNER_TYPE_PROFILE_OWNER));
-        reset(getServices().userManagerInternal);
+                MockUtils.checkUserRestrictions(DpmMockContext.CALLER_USER_HANDLE), eq(false));
 
         DpmTestUtils.assertRestrictions(
                 DpmTestUtils.newRestrictions(),
@@ -1956,21 +1958,25 @@
         // DISALLOW_ADJUST_VOLUME and DISALLOW_UNMUTE_MICROPHONE can be set by PO too, even
         // though when DO sets them they'll be applied globally.
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME);
-        reset(getServices().userManagerInternal);
+
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE);
         verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(DpmMockContext.CALLER_USER_HANDLE),
-                MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME,
+                MockUtils.checkUserRestrictions(),
+                MockUtils.checkUserRestrictions(DpmMockContext.CALLER_USER_HANDLE,
+                        UserManager.DISALLOW_ADJUST_VOLUME,
                         UserManager.DISALLOW_UNMUTE_MICROPHONE),
-                eq(UserManagerInternal.OWNER_TYPE_PROFILE_OWNER));
-        reset(getServices().userManagerInternal);
+                eq(false));
 
         dpm.setCameraDisabled(admin1, true);
         verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(DpmMockContext.CALLER_USER_HANDLE),
-                MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME,
-                        UserManager.DISALLOW_UNMUTE_MICROPHONE, UserManager.DISALLOW_CAMERA),
-                eq(UserManagerInternal.OWNER_TYPE_PROFILE_OWNER));
+                MockUtils.checkUserRestrictions(),
+                MockUtils.checkUserRestrictions(DpmMockContext.CALLER_USER_HANDLE,
+                        UserManager.DISALLOW_ADJUST_VOLUME,
+                        UserManager.DISALLOW_UNMUTE_MICROPHONE,
+                        UserManager.DISALLOW_CAMERA),
+                eq(false));
         reset(getServices().userManagerInternal);
 
         // TODO Make sure restrictions are written to the file.
@@ -2004,15 +2010,14 @@
             );
 
     public void testSetUserRestriction_asPoOfOrgOwnedDevice() throws Exception {
-        final int MANAGED_PROFILE_USER_ID = DpmMockContext.CALLER_USER_HANDLE;
         final int MANAGED_PROFILE_ADMIN_UID =
-                UserHandle.getUid(MANAGED_PROFILE_USER_ID, DpmMockContext.SYSTEM_UID);
+                UserHandle.getUid(DpmMockContext.CALLER_USER_HANDLE, DpmMockContext.SYSTEM_UID);
         mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
 
         addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
         configureProfileOwnerOfOrgOwnedDevice(admin1, DpmMockContext.CALLER_USER_HANDLE);
 
-        when(getServices().userManager.getProfileParent(MANAGED_PROFILE_USER_ID))
+        when(getServices().userManager.getProfileParent(DpmMockContext.CALLER_USER_HANDLE))
                 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0));
 
         for (String restriction : PROFILE_OWNER_ORGANIZATION_OWNED_GLOBAL_RESTRICTIONS) {
@@ -2021,16 +2026,20 @@
 
         parentDpm.setCameraDisabled(admin1, true);
         verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
-                eq(MANAGED_PROFILE_USER_ID),
+                eq(DpmMockContext.CALLER_USER_HANDLE),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_CAMERA),
-                eq(UserManagerInternal.OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE));
-        reset(getServices().userManagerInternal);
+                MockUtils.checkUserRestrictions(DpmMockContext.CALLER_USER_HANDLE),
+                eq(false));
+        DpmTestUtils.assertRestrictions(
+                DpmTestUtils.newRestrictions(UserManager.DISALLOW_CAMERA),
+                parentDpm.getUserRestrictions(admin1)
+        );
 
         parentDpm.setCameraDisabled(admin1, false);
-        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
-                eq(MANAGED_PROFILE_USER_ID),
-                MockUtils.checkUserRestrictions(),
-                eq(UserManagerInternal.OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE));
+        DpmTestUtils.assertRestrictions(
+                DpmTestUtils.newRestrictions(),
+                parentDpm.getUserRestrictions(admin1)
+        );
         reset(getServices().userManagerInternal);
     }
 
@@ -2039,13 +2048,13 @@
         verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(DpmMockContext.CALLER_USER_HANDLE),
                 MockUtils.checkUserRestrictions(restriction),
-                eq(UserManagerInternal.OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE));
+                MockUtils.checkUserRestrictions(DpmMockContext.CALLER_USER_HANDLE),
+                eq(false));
         parentDpm.clearUserRestriction(admin1, restriction);
         DpmTestUtils.assertRestrictions(
                 DpmTestUtils.newRestrictions(),
                 parentDpm.getUserRestrictions(admin1)
         );
-        reset(getServices().userManagerInternal);
     }
 
     public void testNoDefaultEnabledUserRestrictions() throws Exception {
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockUtils.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockUtils.java
index 09a6819..15f3ed1 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockUtils.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockUtils.java
@@ -15,10 +15,6 @@
  */
 package com.android.server.devicepolicy;
 
-import com.google.common.base.Objects;
-
-import com.android.server.pm.UserRestrictionsUtils;
-
 import android.content.ComponentName;
 import android.content.Intent;
 import android.os.BaseBundle;
@@ -26,6 +22,11 @@
 import android.os.UserHandle;
 import android.util.ArraySet;
 
+import com.android.server.pm.RestrictionsSet;
+import com.android.server.pm.UserRestrictionsUtils;
+
+import com.google.common.base.Objects;
+
 import org.hamcrest.BaseMatcher;
 import org.hamcrest.Description;
 import org.hamcrest.Matcher;
@@ -106,11 +107,14 @@
     }
 
     public static Bundle checkUserRestrictions(String... keys) {
-        final Bundle expected = DpmTestUtils.newRestrictions(java.util.Objects.requireNonNull(keys));
+        final Bundle expected = DpmTestUtils.newRestrictions(
+                java.util.Objects.requireNonNull(keys));
         final Matcher<Bundle> m = new BaseMatcher<Bundle>() {
             @Override
             public boolean matches(Object item) {
-                if (item == null) return false;
+                if (item == null) {
+                    return false;
+                }
                 return UserRestrictionsUtils.areEqual((Bundle) item, expected);
             }
 
@@ -122,6 +126,26 @@
         return MockitoHamcrest.argThat(m);
     }
 
+    public static RestrictionsSet checkUserRestrictions(int userId, String... keys) {
+        final RestrictionsSet expected = DpmTestUtils.newRestrictions(userId,
+                java.util.Objects.requireNonNull(keys));
+        final Matcher<RestrictionsSet> m = new BaseMatcher<RestrictionsSet>() {
+            @Override
+            public boolean matches(Object item) {
+                if (item == null) return false;
+                RestrictionsSet actual = (RestrictionsSet) item;
+                return UserRestrictionsUtils.areEqual(expected.getRestrictions(userId),
+                        actual.getRestrictions(userId));
+            }
+
+            @Override
+            public void describeTo(Description description) {
+                description.appendText("User restrictions=" + getRestrictionsAsString(expected));
+            }
+        };
+        return MockitoHamcrest.argThat(m);
+    }
+
     public static Set<String> checkApps(String... adminApps) {
         final Matcher<Set<String>> m = new BaseMatcher<Set<String>>() {
             @Override
@@ -146,6 +170,23 @@
         return MockitoHamcrest.argThat(m);
     }
 
+    private static String getRestrictionsAsString(RestrictionsSet r) {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("{");
+
+        if (r != null) {
+            String sep = "";
+            for (int i = 0; i < r.size(); i++) {
+                sb.append(sep);
+                sep = ",";
+                sb.append(
+                        String.format("%s= %s", r.keyAt(i), getRestrictionsAsString(r.valueAt(i))));
+            }
+        }
+        sb.append("}");
+        return sb.toString();
+    }
+
     private static String getRestrictionsAsString(Bundle b) {
         final StringBuilder sb = new StringBuilder();
         sb.append("[");
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java
index 1c2313e..dc181a9 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java
@@ -22,7 +22,6 @@
 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 android.util.SparseArray;
@@ -118,135 +117,6 @@
                 UserManager.DISALLOW_ADJUST_VOLUME, user));
     }
 
-    public void testSortToGlobalAndLocal() {
-        final Bundle local = new Bundle();
-        final Bundle global = new Bundle();
-
-        UserRestrictionsUtils.sortToGlobalAndLocal(null,
-                UserManagerInternal.OWNER_TYPE_PROFILE_OWNER,
-                global, local);
-        assertEquals(0, global.size());
-        assertEquals(0, local.size());
-
-        UserRestrictionsUtils.sortToGlobalAndLocal(Bundle.EMPTY,
-                UserManagerInternal.OWNER_TYPE_PROFILE_OWNER,
-                global, local);
-        assertEquals(0, global.size());
-        assertEquals(0, local.size());
-
-        // 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,
-                UserManager.ENSURE_VERIFY_APPS,
-                UserManager.DISALLOW_CAMERA
-                ), UserManagerInternal.OWNER_TYPE_DEVICE_OWNER,
-                global, local);
-
-
-        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,
-
-                // These can only be set by DO.
-                UserManager.DISALLOW_USB_FILE_TRANSFER,
-                UserManager.DISALLOW_CONFIG_TETHERING,
-
-                // This can be set by DO or PO of organisation owned device
-                UserManager.DISALLOW_CAMERA
-        ), global);
-
-        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,
-                UserManager.DISALLOW_CAMERA
-                ), UserManagerInternal.OWNER_TYPE_PROFILE_OWNER,
-                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,
-
-                // This can be set by DO or PO of organisation owned device
-                UserManager.DISALLOW_CAMERA
-        ), local);
-
-        local.clear();
-        global.clear();
-
-        // Restrictions set by PO of organisation owned device
-        UserRestrictionsUtils.sortToGlobalAndLocal(newRestrictions(
-                UserManager.DISALLOW_CONFIG_DATE_TIME
-                ), UserManagerInternal.OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE,
-                global, local);
-
-        assertRestrictions(newRestrictions(
-                // This user restriction is global when set by PO of org owned device
-                UserManager.DISALLOW_CONFIG_DATE_TIME
-        ), global);
-        assertEquals(0, local.size());
-    }
-
-    public void testSortToLocalAndGlobalWithCameraDisabled() {
-        final Bundle local = new Bundle();
-        final Bundle global = new Bundle();
-
-        UserRestrictionsUtils.sortToGlobalAndLocal(newRestrictions(UserManager.DISALLOW_CAMERA),
-                UserManagerInternal.OWNER_TYPE_DEVICE_OWNER, global, local);
-        assertRestrictions(newRestrictions(UserManager.DISALLOW_CAMERA), global);
-        assertEquals(0, local.size());
-        global.clear();
-
-        UserRestrictionsUtils.sortToGlobalAndLocal(newRestrictions(UserManager.DISALLOW_CAMERA),
-                UserManagerInternal.OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE, global,
-                local);
-        assertRestrictions(newRestrictions(UserManager.DISALLOW_CAMERA), global);
-        assertEquals(0, local.size());
-        global.clear();
-
-        UserRestrictionsUtils.sortToGlobalAndLocal(newRestrictions(UserManager.DISALLOW_CAMERA),
-                UserManagerInternal.OWNER_TYPE_PROFILE_OWNER, global, local);
-        assertEquals(0, global.size());
-        assertRestrictions(newRestrictions(UserManager.DISALLOW_CAMERA), local);
-    }
-
     public void testMoveRestriction() {
         SparseArray<RestrictionsSet> localRestrictions = new SparseArray<>();
         RestrictionsSet globalRestrictions = new RestrictionsSet();