Merge "Prevent profile owners from setting certain user restrictions." into lmp-dev
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 5189155..e215669 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -57,8 +57,7 @@
 
     /**
      * Key for user restrictions. Specifies if a user is disallowed from changing Wi-Fi
-     * access points.
-     * The default value is <code>false</code>.
+     * access points. The default value is <code>false</code>.
      * <p/>
      * Type: Boolean
      * @see #setUserRestrictions(Bundle)
@@ -119,7 +118,7 @@
 
     /**
      * Key for user restrictions. Specifies if a user is disallowed from transferring files over
-     * USB. The default value is <code>false</code>.
+     * USB. This can only be set by device owners. The default value is <code>false</code>.
      * <p/>
      * Type: Boolean
      * @see #setUserRestrictions(Bundle)
@@ -139,8 +138,7 @@
 
     /**
      * Key for user restrictions. Specifies if a user is disallowed from removing itself and other
-     * users.
-     * The default value is <code>false</code>.
+     * users. The default value is <code>false</code>.
      * <p/>
      * Type: Boolean
      * @see #setUserRestrictions(Bundle)
@@ -170,7 +168,8 @@
 
     /**
      * Key for user restrictions. Specifies if a user is disallowed from configuring Tethering
-     * & portable hotspots. The default value is <code>false</code>.
+     * & portable hotspots. This can only be set by device owners. The default value is
+     * <code>false</code>.
      * <p/>
      * Type: Boolean
      * @see #setUserRestrictions(Bundle)
@@ -180,8 +179,8 @@
 
     /**
      * Key for user restrictions. Specifies if a user is disallowed from factory resetting
-     * from Settings.
-     * The default value is <code>false</code>.
+     * from Settings. This can only be set by device owners. The default value is
+     * <code>false</code>.
      * <p>
      * @see #setUserRestrictions(Bundle)
      * @see #getUserRestrictions()
@@ -190,7 +189,7 @@
 
     /**
      * Key for user restrictions. Specifies if a user is disallowed from adding new users and
-     * profiles. The default value is <code>false</code>.
+     * profiles. This can only be set by device owners. The default value is <code>false</code>.
      * <p>
      * Type: Boolean
      * @see #setUserRestrictions(Bundle)
@@ -210,7 +209,7 @@
 
     /**
      * Key for user restrictions. Specifies if a user is disallowed from configuring cell
-     * broadcasts. The default value is <code>false</code>.
+     * broadcasts. This can only be set by device owners. The default value is <code>false</code>.
      * <p>
      * Type: Boolean
      * @see #setUserRestrictions(Bundle)
@@ -220,7 +219,7 @@
 
     /**
      * Key for user restrictions. Specifies if a user is disallowed from configuring mobile
-     * networks. The default value is <code>false</code>.
+     * networks. This can only be set by device owners. The default value is <code>false</code>.
      * <p>
      * Type: Boolean
      * @see #setUserRestrictions(Bundle)
@@ -249,7 +248,8 @@
 
     /**
      * Key for user restrictions. Specifies if a user is disallowed from mounting
-     * physical external media. The default value is <code>false</code>.
+     * physical external media. This can only be set by device owners. The default value is
+     * <code>false</code>.
      * <p/>
      * Type: Boolean
      * @see #setUserRestrictions(Bundle)
@@ -259,7 +259,7 @@
 
     /**
      * Key for user restrictions. Specifies if a user is disallowed from adjusting microphone
-     * volume.
+     * volume. If set, the microphone will be muted. This can only be set by device owners.
      * The default value is <code>false</code>.
      * <p/>
      * Type: Boolean
@@ -270,7 +270,7 @@
 
     /**
      * Key for user restrictions. Specifies if a user is disallowed from adjusting the master
-     * volume.
+     * volume. If set, the master volume will be muted. This can only be set by device owners.
      * The default value is <code>false</code>.
      * <p/>
      * Type: Boolean
@@ -292,8 +292,7 @@
 
     /**
      * Key for user restrictions. Specifies that the user is not allowed to send or receive
-     * SMS messages.
-     * The default value is <code>false</code>.
+     * SMS messages. This can only be set by device owners. The default value is <code>false</code>.
      * <p/>
      * Type: Boolean
      * @see #setUserRestrictions(Bundle)
@@ -311,7 +310,7 @@
      * <li>{@link LayoutParams#TYPE_SYSTEM_ERROR}</li>
      * <li>{@link LayoutParams#TYPE_SYSTEM_OVERLAY}</li>
      *
-     * <p>The default value is <code>false</code>.
+     * <p>This can only be set by device owners. The default value is <code>false</code>.
      * <p/>
      * Type: Boolean
      * @see #setUserRestrictions(Bundle)
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 2c3c510..02f8bd5 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -18,18 +18,6 @@
 
 import static android.Manifest.permission.MANAGE_CA_CERTIFICATES;
 
-import android.app.admin.DevicePolicyManagerInternal;
-
-import com.android.internal.R;
-import com.android.internal.os.storage.ExternalStorageFormatter;
-import com.android.internal.util.FastXmlSerializer;
-import com.android.internal.util.JournaledFile;
-import com.android.internal.util.XmlUtils;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.org.conscrypt.TrustedCertificateStore;
-import com.android.server.LocalServices;
-import com.android.server.SystemService;
-
 import android.app.Activity;
 import android.app.ActivityManagerNative;
 import android.app.AlarmManager;
@@ -41,6 +29,7 @@
 import android.app.admin.DeviceAdminInfo;
 import android.app.admin.DeviceAdminReceiver;
 import android.app.admin.DevicePolicyManager;
+import android.app.admin.DevicePolicyManagerInternal;
 import android.app.admin.IDevicePolicyManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -90,6 +79,16 @@
 import android.util.Xml;
 import android.view.IWindowManager;
 
+import com.android.internal.R;
+import com.android.internal.os.storage.ExternalStorageFormatter;
+import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.JournaledFile;
+import com.android.internal.util.XmlUtils;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.org.conscrypt.TrustedCertificateStore;
+import com.android.server.LocalServices;
+import com.android.server.SystemService;
+
 import org.xmlpull.v1.XmlPullParser;
 
 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
@@ -147,6 +146,21 @@
     private static final String ATTR_PERMISSION_PROVIDER = "permission-provider";
     private static final String ATTR_SETUP_COMPLETE = "setup-complete";
 
+    private static final Set<String> DEVICE_OWNER_USER_RESTRICTIONS;
+    static {
+        DEVICE_OWNER_USER_RESTRICTIONS = new HashSet();
+        DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_USB_FILE_TRANSFER);
+        DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_CONFIG_TETHERING);
+        DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_FACTORY_RESET);
+        DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_ADD_USER);
+        DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_CONFIG_CELL_BROADCASTS);
+        DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
+        DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA);
+        DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_UNMUTE_MICROPHONE);
+        DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_ADJUST_VOLUME);
+        DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_SMS);
+    }
+
     final Context mContext;
     final UserManager mUserManager;
     final PowerManager.WakeLock mWakeLock;
@@ -4046,7 +4060,12 @@
             if (who == null) {
                 throw new NullPointerException("ComponentName is null");
             }
-            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+            ActiveAdmin activeAdmin =
+                    getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+            boolean isDeviceOwner = isDeviceOwner(activeAdmin.info.getPackageName());
+            if (!isDeviceOwner && DEVICE_OWNER_USER_RESTRICTIONS.contains(key)) {
+                throw new SecurityException("Profile owners cannot set user restriction " + key);
+            }
 
             long id = Binder.clearCallingIdentity();
             try {