Changed parameters in setDevicePolicyUserRestriction

In the new COPE mode, some user restrictions should be applied globally
when called by the Work Profile PO. This CL introduces a new @IntDef int
parameter, called admin, which can be either DEVICE_OWNER, PROFILE_OWNER or
PROFILE_OWNER_ORG_OWNED_DEVICE.

If admin is PROFILE_OWNER_ORG_OWNER_DEVICE then specific user restrictions
will be added to the global bundle instead of the local bundle.

This CL also removes the parameter cameraRestrictionScope and isDeviceOwner.

Bug: 138709470
Test: UserRestrictionsUtilsTest
      DevicePolicyManagerTest
      UserRestrictionsTest

Change-Id: Iaa0abbac47708d2d54bcf6c3df582414dff5a6c3
diff --git a/services/core/java/android/os/UserManagerInternal.java b/services/core/java/android/os/UserManagerInternal.java
index 9a7cb3f..a2e9341 100644
--- a/services/core/java/android/os/UserManagerInternal.java
+++ b/services/core/java/android/os/UserManagerInternal.java
@@ -15,6 +15,7 @@
  */
 package android.os;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
@@ -22,13 +23,24 @@
 import android.content.pm.UserInfo;
 import android.graphics.Bitmap;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * @hide Only for use within the system server.
  */
 public abstract class UserManagerInternal {
-    public static final int CAMERA_NOT_DISABLED = 0;
-    public static final int CAMERA_DISABLED_LOCALLY = 1;
-    public static final int CAMERA_DISABLED_GLOBALLY = 2;
+
+    public static final int OWNER_TYPE_DEVICE_OWNER = 0;
+    public static final int OWNER_TYPE_PROFILE_OWNER = 1;
+    public static final int OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE = 2;
+    public static final int OWNER_TYPE_NO_OWNER = 3;
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(value = {OWNER_TYPE_DEVICE_OWNER, OWNER_TYPE_PROFILE_OWNER,
+            OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE, OWNER_TYPE_NO_OWNER})
+    public @interface OwnerType {
+    }
 
     public interface UserRestrictionsListener {
         /**
@@ -47,13 +59,19 @@
      *
      * @param userId target user id for the local restrictions.
      * @param restrictions a bundle of user restrictions.
-     * @param isDeviceOwner whether {@code userId} corresponds to device owner user id.
-     * @param cameraRestrictionScope is camera disabled and if so what is the scope of restriction.
-     *        Should be one of {@link #CAMERA_NOT_DISABLED}, {@link #CAMERA_DISABLED_LOCALLY} or
-     *                               {@link #CAMERA_DISABLED_GLOBALLY}
+     * @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
      */
     public abstract void setDevicePolicyUserRestrictions(int userId, @Nullable Bundle restrictions,
-            boolean isDeviceOwner, int cameraRestrictionScope);
+            @OwnerType int restrictionOwnerType);
 
     /**
      * 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 8144338..faff394 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1634,13 +1634,14 @@
      * See {@link UserManagerInternal#setDevicePolicyUserRestrictions}
      */
     private void setDevicePolicyUserRestrictionsInner(@UserIdInt int userId,
-            @Nullable Bundle restrictions, boolean isDeviceOwner, int cameraRestrictionScope) {
+            @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, isDeviceOwner,
-                cameraRestrictionScope, global, local);
+        UserRestrictionsUtils.sortToGlobalAndLocal(restrictions, restrictionOwnerType, global,
+                local);
 
         boolean globalChanged, localChanged;
         synchronized (mRestrictionsLock) {
@@ -1650,7 +1651,7 @@
             localChanged = updateRestrictionsIfNeededLR(
                     userId, local, mDevicePolicyLocalUserRestrictions);
 
-            if (isDeviceOwner) {
+            if (restrictionOwnerType == UserManagerInternal.OWNER_TYPE_DEVICE_OWNER) {
                 // Remember the global restriction owner userId to be able to make a distinction
                 // in getUserRestrictionSource on who set local policies.
                 mDeviceOwnerUserId = userId;
@@ -4484,9 +4485,9 @@
     private class LocalService extends UserManagerInternal {
         @Override
         public void setDevicePolicyUserRestrictions(@UserIdInt int userId,
-                @Nullable Bundle restrictions, boolean isDeviceOwner, int cameraRestrictionScope) {
-            UserManagerService.this.setDevicePolicyUserRestrictionsInner(userId, restrictions,
-                isDeviceOwner, cameraRestrictionScope);
+                @Nullable Bundle restrictions, @OwnerType int restrictionOwnerType) {
+            UserManagerService.this.setDevicePolicyUserRestrictionsInner(userId,
+                    restrictions, restrictionOwnerType);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index 3be51c5..f071c65 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -194,7 +194,18 @@
             UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
             UserManager.DISALLOW_RUN_IN_BACKGROUND,
             UserManager.DISALLOW_UNMUTE_MICROPHONE,
-            UserManager.DISALLOW_UNMUTE_DEVICE
+            UserManager.DISALLOW_UNMUTE_DEVICE,
+            UserManager.DISALLOW_CAMERA
+    );
+
+    /**
+     * Special user restrictions that are applied globally when set by the profile owner of a
+     * managed profile that was created during the device provisioning flow.
+     */
+    private static final Set<String> PROFILE_OWNER_ORGANIZATION_OWNED_GLOBAL_RESTRICTIONS =
+            Sets.newArraySet(
+                    UserManager.DISALLOW_CONFIG_DATE_TIME,
+                    UserManager.DISALLOW_CAMERA
     );
 
     /**
@@ -419,15 +430,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, boolean isDeviceOwner,
-            int cameraRestrictionScope,
-            @NonNull Bundle global, @NonNull Bundle local) {
-        // Camera restriction (as well as all others) goes to at most one bundle.
-        if (cameraRestrictionScope == UserManagerInternal.CAMERA_DISABLED_GLOBALLY) {
-            global.putBoolean(UserManager.DISALLOW_CAMERA, true);
-        } else if (cameraRestrictionScope == UserManagerInternal.CAMERA_DISABLED_LOCALLY) {
-            local.putBoolean(UserManager.DISALLOW_CAMERA, true);
-        }
+    public static void sortToGlobalAndLocal(@Nullable Bundle in,
+            @UserManagerInternal.OwnerType int restrictionOwnerType, @NonNull Bundle global,
+            @NonNull Bundle local) {
         if (in == null || in.size() == 0) {
             return;
         }
@@ -435,7 +440,7 @@
             if (!in.getBoolean(key)) {
                 continue;
             }
-            if (isGlobal(isDeviceOwner, key)) {
+            if (isGlobal(restrictionOwnerType, key)) {
                 global.putBoolean(key, true);
             } else {
                 local.putBoolean(key, true);
@@ -446,9 +451,13 @@
     /**
      * Whether given user restriction should be enforced globally.
      */
-    private static boolean isGlobal(boolean isDeviceOwner, String key) {
-        return (isDeviceOwner &&
-                (PRIMARY_USER_ONLY_RESTRICTIONS.contains(key) || GLOBAL_RESTRICTIONS.contains(key)))
+    private 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)))
+                || ((restrictionOwnerType
+                == UserManagerInternal.OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE)
+                && PROFILE_OWNER_ORGANIZATION_OWNED_GLOBAL_RESTRICTIONS.contains(key))
                 || PROFILE_GLOBAL_RESTRICTIONS.contains(key)
                 || DEVICE_OWNER_ONLY_RESTRICTIONS.contains(key);
     }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index b033492..a9a580a 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -5568,8 +5568,8 @@
         }
     }
 
-    private void enforceProfileOwnerOfCorpOwnedDevice(ActiveAdmin admin) {
-        if (!isProfileOwnerOfOrganizationOwnedDevicte(admin)) {
+    private void enforceProfileOwnerOfOrganizationOwnedDevice(ActiveAdmin admin) {
+        if (!isProfileOwnerOfOrganizationOwnedDevice(admin)) {
             throw new SecurityException(String.format("Provided admin %s is either not a profile "
                     + "owner or not on a corporate-owned device.", admin));
         }
@@ -6639,7 +6639,7 @@
         }
 
         boolean calledByProfileOwnerOnOrgOwnedDevice =
-                isProfileOwnerOfOrganizationOwnedDevicte(admin);
+                isProfileOwnerOfOrganizationOwnedDevice(admin);
 
         if (calledOnParentInstance && !calledByProfileOwnerOnOrgOwnedDevice) {
             throw new SecurityException("Wiping the entire device can only be done by a profile"
@@ -8020,7 +8020,7 @@
      * {@code getActiveAdminForCallerLocked} or one of the similar variants, not caller-supplied
      * input.
      */
-    private boolean isProfileOwnerOfOrganizationOwnedDevicte(@Nullable ActiveAdmin admin) {
+    private boolean isProfileOwnerOfOrganizationOwnedDevice(@Nullable ActiveAdmin admin) {
         if (admin == null) {
             return false;
         }
@@ -10223,8 +10223,7 @@
         synchronized (getLockObject()) {
             final boolean isDeviceOwner = mOwners.isDeviceOwnerUserId(userId);
             final Bundle userRestrictions;
-            // Whether device owner enforces camera restriction.
-            boolean disallowCameraGlobally = false;
+            final int restrictionOwnerType;
 
             if (isDeviceOwner) {
                 final ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked();
@@ -10232,33 +10231,45 @@
                     return; // Shouldn't happen.
                 }
                 userRestrictions = deviceOwner.userRestrictions;
-                // DO can disable camera globally.
-                disallowCameraGlobally = deviceOwner.disableCamera;
+                addOrRemoveDisableCameraRestriction(userRestrictions, deviceOwner);
+                restrictionOwnerType = UserManagerInternal.OWNER_TYPE_DEVICE_OWNER;
             } else {
                 final ActiveAdmin profileOwner = getProfileOwnerAdminLocked(userId);
                 userRestrictions = profileOwner != null ? profileOwner.userRestrictions : null;
+                addOrRemoveDisableCameraRestriction(userRestrictions, userId);
+
+                if (isProfileOwnerOfOrganizationOwnedDevice(profileOwner)) {
+                    restrictionOwnerType =
+                          UserManagerInternal.OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE;
+                } else if (profileOwner != null) {
+                    restrictionOwnerType = UserManagerInternal.OWNER_TYPE_PROFILE_OWNER;
+                } else {
+                    restrictionOwnerType = UserManagerInternal.OWNER_TYPE_NO_OWNER;
+                }
             }
 
-            // Whether any admin enforces camera restriction.
-            final int cameraRestrictionScope =
-                    getCameraRestrictionScopeLocked(userId, disallowCameraGlobally);
-
             mUserManagerInternal.setDevicePolicyUserRestrictions(userId, userRestrictions,
-                    isDeviceOwner, cameraRestrictionScope);
+                    restrictionOwnerType);
         }
     }
 
-    /**
-     * Get the scope of camera restriction for a given user if any.
-     */
-    private int getCameraRestrictionScopeLocked(int userId, boolean disallowCameraGlobally) {
-        if (disallowCameraGlobally) {
-            return UserManagerInternal.CAMERA_DISABLED_GLOBALLY;
-        } else if (getCameraDisabled(
-                /* who= */ null, userId, /* mergeDeviceOwnerRestriction= */ false)) {
-            return UserManagerInternal.CAMERA_DISABLED_LOCALLY;
+    private void addOrRemoveDisableCameraRestriction(Bundle userRestrictions, ActiveAdmin admin) {
+        if (userRestrictions == null) return;
+        if (admin.disableCamera) {
+            userRestrictions.putBoolean(UserManager.DISALLOW_CAMERA, true);
+        } else {
+            userRestrictions.remove(UserManager.DISALLOW_CAMERA);
         }
-        return UserManagerInternal.CAMERA_NOT_DISABLED;
+    }
+
+    private void addOrRemoveDisableCameraRestriction(Bundle userRestrictions, int userId) {
+        if (userRestrictions == null) return;
+        if (getCameraDisabled(/* who= */ null, userId, /* mergeDeviceOwnerRestriction= */
+                false)) {
+            userRestrictions.putBoolean(UserManager.DISALLOW_CAMERA, true);
+        } else {
+            userRestrictions.remove(UserManager.DISALLOW_CAMERA);
+        }
     }
 
     @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 ed55aeb..5d11775 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -26,9 +26,6 @@
 import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE;
 import static android.app.admin.DevicePolicyManager.WIPE_EUICC;
 import static android.app.admin.PasswordMetrics.computeForPassword;
-import static android.os.UserManagerInternal.CAMERA_DISABLED_GLOBALLY;
-import static android.os.UserManagerInternal.CAMERA_DISABLED_LOCALLY;
-import static android.os.UserManagerInternal.CAMERA_NOT_DISABLED;
 
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
 import static com.android.internal.widget.LockPatternUtils.EscrowTokenStateChangeCallback;
@@ -82,6 +79,7 @@
 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;
@@ -1154,9 +1152,8 @@
                 MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
 
         verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
-                eq(UserHandle.USER_SYSTEM),
-                eq(null),
-                eq(true), eq(CAMERA_NOT_DISABLED));
+                eq(UserHandle.USER_SYSTEM), eq(null),
+                eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER));
 
         verify(getServices().usageStatsManagerInternal).setActiveAdminApps(
                 null, UserHandle.USER_SYSTEM);
@@ -1725,8 +1722,7 @@
         verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(defaultRestrictions),
-                eq(true) /* isDeviceOwner */,
-                eq(CAMERA_NOT_DISABLED)
+                eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER)
         );
         reset(getServices().userManagerInternal);
 
@@ -1741,7 +1737,7 @@
         verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER),
-                eq(true), eq(CAMERA_NOT_DISABLED));
+                eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER));
         reset(getServices().userManagerInternal);
 
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
@@ -1749,7 +1745,7 @@
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS,
                         UserManager.DISALLOW_ADD_USER),
-                eq(true), eq(CAMERA_NOT_DISABLED));
+                eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER));
         reset(getServices().userManagerInternal);
 
         DpmTestUtils.assertRestrictions(
@@ -1767,7 +1763,7 @@
         verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
-                eq(true), eq(CAMERA_NOT_DISABLED));
+                eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER));
         reset(getServices().userManagerInternal);
 
         DpmTestUtils.assertRestrictions(
@@ -1783,7 +1779,7 @@
         verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(),
-                eq(true), eq(CAMERA_NOT_DISABLED));
+                eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER));
         reset(getServices().userManagerInternal);
 
         assertNoDeviceOwnerRestrictions();
@@ -1797,7 +1793,7 @@
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME,
                         UserManager.DISALLOW_UNMUTE_MICROPHONE),
-                eq(true), eq(CAMERA_NOT_DISABLED));
+                eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER));
         reset(getServices().userManagerInternal);
 
         dpm.clearUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME);
@@ -1809,7 +1805,7 @@
         verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER),
-                eq(true), eq(CAMERA_NOT_DISABLED));
+                eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER));
         reset(getServices().userManagerInternal);
 
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_FUN);
@@ -1817,16 +1813,16 @@
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN,
                         UserManager.DISALLOW_ADD_USER),
-                eq(true), eq(CAMERA_NOT_DISABLED));
+                eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER));
         reset(getServices().userManagerInternal);
 
         dpm.setCameraDisabled(admin1, true);
         verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
-                // DISALLOW_CAMERA will be applied to both local and global.
+                // DISALLOW_CAMERA will be applied globally.
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN,
-                        UserManager.DISALLOW_ADD_USER),
-                eq(true), eq(CAMERA_DISABLED_GLOBALLY));
+                        UserManager.DISALLOW_ADD_USER, UserManager.DISALLOW_CAMERA),
+                eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER));
         reset(getServices().userManagerInternal);
     }
 
@@ -1872,7 +1868,7 @@
         verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(DpmMockContext.CALLER_USER_HANDLE),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES),
-                eq(false), eq(CAMERA_NOT_DISABLED));
+                eq(UserManagerInternal.OWNER_TYPE_PROFILE_OWNER));
         reset(getServices().userManagerInternal);
 
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
@@ -1880,7 +1876,7 @@
                 eq(DpmMockContext.CALLER_USER_HANDLE),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
                         UserManager.DISALLOW_OUTGOING_CALLS),
-                eq(false), eq(CAMERA_NOT_DISABLED));
+                eq(UserManagerInternal.OWNER_TYPE_PROFILE_OWNER));
         reset(getServices().userManagerInternal);
 
         DpmTestUtils.assertRestrictions(
@@ -1903,7 +1899,7 @@
         verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(DpmMockContext.CALLER_USER_HANDLE),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
-                eq(false), eq(CAMERA_NOT_DISABLED));
+                eq(UserManagerInternal.OWNER_TYPE_PROFILE_OWNER));
         reset(getServices().userManagerInternal);
 
         DpmTestUtils.assertRestrictions(
@@ -1924,7 +1920,7 @@
         verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(DpmMockContext.CALLER_USER_HANDLE),
                 MockUtils.checkUserRestrictions(),
-                eq(false), eq(CAMERA_NOT_DISABLED));
+                eq(UserManagerInternal.OWNER_TYPE_PROFILE_OWNER));
         reset(getServices().userManagerInternal);
 
         DpmTestUtils.assertRestrictions(
@@ -1946,20 +1942,52 @@
                 eq(DpmMockContext.CALLER_USER_HANDLE),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME,
                         UserManager.DISALLOW_UNMUTE_MICROPHONE),
-                eq(false), eq(CAMERA_NOT_DISABLED));
+                eq(UserManagerInternal.OWNER_TYPE_PROFILE_OWNER));
         reset(getServices().userManagerInternal);
 
         dpm.setCameraDisabled(admin1, true);
         verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(DpmMockContext.CALLER_USER_HANDLE),
                 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME,
-                        UserManager.DISALLOW_UNMUTE_MICROPHONE),
-                eq(false), eq(CAMERA_DISABLED_LOCALLY));
+                        UserManager.DISALLOW_UNMUTE_MICROPHONE, UserManager.DISALLOW_CAMERA),
+                eq(UserManagerInternal.OWNER_TYPE_PROFILE_OWNER));
         reset(getServices().userManagerInternal);
 
         // TODO Make sure restrictions are written to the file.
     }
 
+    public void testSetUserRestriction_asPoOfOrgOwnedDevice() throws Exception {
+        setupProfileOwner();
+
+        final long ident = mServiceContext.binder.clearCallingIdentity();
+        configureContextForAccess(mServiceContext, true);
+
+        mServiceContext.binder.callingUid =
+                UserHandle.getUid(DpmMockContext.CALLER_USER_HANDLE,
+                        DpmMockContext.CALLER_MANAGED_PROVISIONING_UID);
+        try {
+            runAsCaller(mServiceContext, dpms, dpm -> {
+                dpm.markProfileOwnerOnOrganizationOwnedDevice(admin1);
+            });
+        } finally {
+            mServiceContext.binder.restoreCallingIdentity(ident);
+        }
+
+        dpm.addUserRestriction(admin1, UserManager.DISALLOW_CONFIG_DATE_TIME);
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
+                eq(DpmMockContext.CALLER_USER_HANDLE),
+                MockUtils.checkUserRestrictions(UserManager.DISALLOW_CONFIG_DATE_TIME),
+                eq(UserManagerInternal.OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE));
+        reset(getServices().userManagerInternal);
+
+        dpm.setCameraDisabled(admin1, true);
+        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
+                eq(DpmMockContext.CALLER_USER_HANDLE),
+                MockUtils.checkUserRestrictions(UserManager.DISALLOW_CONFIG_DATE_TIME,
+                        UserManager.DISALLOW_CAMERA),
+                eq(UserManagerInternal.OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE));
+        reset(getServices().userManagerInternal);
+    }
 
     public void testDefaultEnabledUserRestrictions() throws Exception {
         mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
@@ -1994,8 +2022,7 @@
         verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                 eq(UserHandle.USER_SYSTEM),
                 MockUtils.checkUserRestrictions(defaultRestrictions),
-                eq(true) /* isDeviceOwner */,
-                eq(CAMERA_NOT_DISABLED)
+                eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER)
         );
         reset(getServices().userManagerInternal);
 
@@ -2035,10 +2062,9 @@
                 dpm.getUserRestrictions(admin1)
             );
             verify(getServices().userManagerInternal, atLeast(1)).setDevicePolicyUserRestrictions(
-                eq(UserHandle.USER_SYSTEM),
-                MockUtils.checkUserRestrictions(newDefaultEnabledRestriction),
-                eq(true) /* isDeviceOwner */,
-                eq(CAMERA_NOT_DISABLED)
+                    eq(UserHandle.USER_SYSTEM),
+                    MockUtils.checkUserRestrictions(newDefaultEnabledRestriction),
+                    eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER)
             );
             reset(getServices().userManagerInternal);
 
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 2cc5323..1a630ff 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java
@@ -122,13 +122,15 @@
         final Bundle local = new Bundle();
         final Bundle global = new Bundle();
 
-        UserRestrictionsUtils.sortToGlobalAndLocal(null, false /* isDeviceOwner */,
-                UserManagerInternal.CAMERA_NOT_DISABLED, global, local);
+        UserRestrictionsUtils.sortToGlobalAndLocal(null,
+                UserManagerInternal.OWNER_TYPE_PROFILE_OWNER,
+                global, local);
         assertEquals(0, global.size());
         assertEquals(0, local.size());
 
-        UserRestrictionsUtils.sortToGlobalAndLocal(Bundle.EMPTY, false /* isDeviceOwner */,
-                UserManagerInternal.CAMERA_NOT_DISABLED, global, local);
+        UserRestrictionsUtils.sortToGlobalAndLocal(Bundle.EMPTY,
+                UserManagerInternal.OWNER_TYPE_PROFILE_OWNER,
+                global, local);
         assertEquals(0, global.size());
         assertEquals(0, local.size());
 
@@ -140,8 +142,10 @@
                 UserManager.DISALLOW_CONFIG_TETHERING,
                 UserManager.DISALLOW_OUTGOING_BEAM,
                 UserManager.DISALLOW_APPS_CONTROL,
-                UserManager.ENSURE_VERIFY_APPS
-        ), true /* isDeviceOwner */, UserManagerInternal.CAMERA_NOT_DISABLED, global, local);
+                UserManager.ENSURE_VERIFY_APPS,
+                UserManager.DISALLOW_CAMERA
+                ), UserManagerInternal.OWNER_TYPE_DEVICE_OWNER,
+                global, local);
 
 
         assertRestrictions(newRestrictions(
@@ -154,7 +158,10 @@
 
                 // These can only be set by DO.
                 UserManager.DISALLOW_USB_FILE_TRANSFER,
-                UserManager.DISALLOW_CONFIG_TETHERING
+                UserManager.DISALLOW_CONFIG_TETHERING,
+
+                // This can be set by DO or PO of organisation owned device
+                UserManager.DISALLOW_CAMERA
         ), global);
 
         assertRestrictions(newRestrictions(
@@ -174,8 +181,10 @@
                 UserManager.DISALLOW_CONFIG_TETHERING,
                 UserManager.DISALLOW_OUTGOING_BEAM,
                 UserManager.DISALLOW_APPS_CONTROL,
-                UserManager.ENSURE_VERIFY_APPS
-        ), false /* isDeviceOwner */, UserManagerInternal.CAMERA_NOT_DISABLED, global, local);
+                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.
@@ -193,23 +202,47 @@
 
                 // These can only be set by DO.
                 UserManager.DISALLOW_USB_FILE_TRANSFER,
-                UserManager.DISALLOW_CONFIG_TETHERING
+                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(Bundle.EMPTY, false,
-                UserManagerInternal.CAMERA_DISABLED_GLOBALLY, global, local);
+        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(Bundle.EMPTY, false,
-                UserManagerInternal.CAMERA_DISABLED_LOCALLY, global, local);
+        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);
     }