Merge "Added restriction if a user is allowed to change the icon. BUG: 25305966"
diff --git a/api/current.txt b/api/current.txt
index e347c4c..9a5ffdc 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -28590,6 +28590,7 @@
field public static final java.lang.String DISALLOW_OUTGOING_CALLS = "no_outgoing_calls";
field public static final java.lang.String DISALLOW_REMOVE_USER = "no_remove_user";
field public static final java.lang.String DISALLOW_SAFE_BOOT = "no_safe_boot";
+ field public static final java.lang.String DISALLOW_SET_USER_ICON = "no_set_user_icon";
field public static final java.lang.String DISALLOW_SHARE_LOCATION = "no_share_location";
field public static final java.lang.String DISALLOW_SMS = "no_sms";
field public static final java.lang.String DISALLOW_UNINSTALL_APPS = "no_uninstall_apps";
diff --git a/api/system-current.txt b/api/system-current.txt
index 1a76097..cdbe014 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -30642,6 +30642,7 @@
field public static final java.lang.String DISALLOW_OUTGOING_CALLS = "no_outgoing_calls";
field public static final java.lang.String DISALLOW_REMOVE_USER = "no_remove_user";
field public static final java.lang.String DISALLOW_SAFE_BOOT = "no_safe_boot";
+ field public static final java.lang.String DISALLOW_SET_USER_ICON = "no_set_user_icon";
field public static final java.lang.String DISALLOW_SHARE_LOCATION = "no_share_location";
field public static final java.lang.String DISALLOW_SMS = "no_sms";
field public static final java.lang.String DISALLOW_UNINSTALL_APPS = "no_uninstall_apps";
diff --git a/api/test-current.txt b/api/test-current.txt
index 111145b..5f76739 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -28599,6 +28599,7 @@
field public static final java.lang.String DISALLOW_OUTGOING_CALLS = "no_outgoing_calls";
field public static final java.lang.String DISALLOW_REMOVE_USER = "no_remove_user";
field public static final java.lang.String DISALLOW_SAFE_BOOT = "no_safe_boot";
+ field public static final java.lang.String DISALLOW_SET_USER_ICON = "no_set_user_icon";
field public static final java.lang.String DISALLOW_SHARE_LOCATION = "no_share_location";
field public static final java.lang.String DISALLOW_SMS = "no_sms";
field public static final java.lang.String DISALLOW_UNINSTALL_APPS = "no_uninstall_apps";
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index f01f597..fe834a1 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -529,6 +529,21 @@
public static final String DISALLOW_DATA_ROAMING = "no_data_roaming";
/**
+ * Specifies if a user is not allowed to change their icon. Device owner and profile owner
+ * can set this restriction. When it is set by device owner, only the target user will be
+ * affected. The default value is <code>false</code>.
+ *
+ * <p>Key for user restrictions.
+ *
+ * <p>Type: Boolean
+ *
+ * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
+ * @see DevicePolicyManager#clearUserRestriction(ComponentName, String)
+ * @see #getUserRestrictions()
+ */
+ public static final String DISALLOW_SET_USER_ICON = "no_set_user_icon";
+
+ /**
* Allows apps in the parent profile to handle web links from the managed profile.
*
* This user restriction has an effect only in a managed profile.
diff --git a/core/java/android/os/UserManagerInternal.java b/core/java/android/os/UserManagerInternal.java
index 898b6cf..f765336 100644
--- a/core/java/android/os/UserManagerInternal.java
+++ b/core/java/android/os/UserManagerInternal.java
@@ -17,6 +17,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.graphics.Bitmap;
/**
* @hide Only for use within the system server.
@@ -81,4 +82,13 @@
* whether the user is managed by profile owner.
*/
public abstract void setUserManaged(int userId, boolean isManaged);
+
+ /**
+ * Called by {@link com.android.server.devicepolicy.DevicePolicyManagerService} to omit
+ * restriction check, because DevicePolicyManager must always be able to set user icon
+ * regardless of any restriction.
+ * Also called by {@link com.android.server.pm.UserManagerService} because the logic of setting
+ * the icon is in this method.
+ */
+ public abstract void setUserIcon(int userId, Bitmap bitmap);
}
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 3248fe6..1e057aa 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -730,23 +730,15 @@
@Override
public void setUserIcon(int userId, Bitmap bitmap) {
checkManageUsersPermission("update users");
- long ident = Binder.clearCallingIdentity();
- try {
- synchronized (mPackagesLock) {
- UserData userData = getUserDataNoChecks(userId);
- if (userData == null || userData.info.partial) {
- Slog.w(LOG_TAG, "setUserIcon: unknown user #" + userId);
- return;
- }
- writeBitmapLP(userData.info, bitmap);
- writeUserLP(userData);
- }
- sendUserInfoChangedBroadcast(userId);
- } finally {
- Binder.restoreCallingIdentity(ident);
+ if (hasUserRestriction(UserManager.DISALLOW_SET_USER_ICON, userId)) {
+ Log.w(LOG_TAG, "Cannot set user icon. DISALLOW_SET_USER_ICON is enabled.");
+ return;
}
+ mLocalService.setUserIcon(userId, bitmap);
}
+
+
private void sendUserInfoChangedBroadcast(int userId) {
Intent changedIntent = new Intent(Intent.ACTION_USER_INFO_CHANGED);
changedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
@@ -2901,6 +2893,25 @@
mIsUserManaged.put(userId, isManaged);
}
}
+
+ @Override
+ public void setUserIcon(int userId, Bitmap bitmap) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (mPackagesLock) {
+ UserData userData = getUserDataNoChecks(userId);
+ if (userData == null || userData.info.partial) {
+ Slog.w(LOG_TAG, "setUserIcon: unknown user #" + userId);
+ return;
+ }
+ writeBitmapLP(userData.info, bitmap);
+ writeUserLP(userData);
+ }
+ sendUserInfoChangedBroadcast(userId);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
}
private class Shell extends ShellCommand {
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index f0ed790..87f505d 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -92,7 +92,8 @@
UserManager.DISALLOW_RECORD_AUDIO,
UserManager.DISALLOW_CAMERA,
UserManager.DISALLOW_RUN_IN_BACKGROUND,
- UserManager.DISALLOW_DATA_ROAMING
+ UserManager.DISALLOW_DATA_ROAMING,
+ UserManager.DISALLOW_SET_USER_ICON
);
/**
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index a23e74b..eb75914 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -7032,7 +7032,7 @@
int userId = UserHandle.getCallingUserId();
long id = mInjector.binderClearCallingIdentity();
try {
- mUserManager.setUserIcon(userId, icon);
+ mUserManagerInternal.setUserIcon(userId, icon);
} finally {
mInjector.binderRestoreCallingIdentity(id);
}