diff options
| -rw-r--r-- | api/current.txt | 1 | ||||
| -rw-r--r-- | api/system-current.txt | 1 | ||||
| -rw-r--r-- | api/test-current.txt | 1 | ||||
| -rw-r--r-- | core/java/android/os/UserManager.java | 15 | ||||
| -rw-r--r-- | core/java/android/os/UserManagerInternal.java | 10 | ||||
| -rw-r--r-- | services/core/java/com/android/server/pm/UserManagerService.java | 39 | ||||
| -rw-r--r-- | services/core/java/com/android/server/pm/UserRestrictionsUtils.java | 3 | ||||
| -rw-r--r-- | services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java | 2 |
8 files changed, 56 insertions, 16 deletions
diff --git a/api/current.txt b/api/current.txt index e347c4c362d6..9a5ffdc07e7c 100644 --- a/api/current.txt +++ b/api/current.txt @@ -28590,6 +28590,7 @@ package android.os { 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 1a7609745cc8..cdbe01417445 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -30642,6 +30642,7 @@ package android.os { 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 111145b779f9..5f76739907ef 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -28599,6 +28599,7 @@ package android.os { 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 f01f59715f2f..fe834a14e8f1 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -529,6 +529,21 @@ public class UserManager { 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 898b6cffa9d4..f76533697cda 100644 --- a/core/java/android/os/UserManagerInternal.java +++ b/core/java/android/os/UserManagerInternal.java @@ -17,6 +17,7 @@ package android.os; import android.annotation.NonNull; import android.annotation.Nullable; +import android.graphics.Bitmap; /** * @hide Only for use within the system server. @@ -81,4 +82,13 @@ public abstract class UserManagerInternal { * 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 3248fe6178b0..1e057aa2add6 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 @@ public class UserManagerService extends IUserManager.Stub { @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 @@ public class UserManagerService extends IUserManager.Stub { 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 f0ed7907770d..87f505d24ccd 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 @@ public class UserRestrictionsUtils { 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 a23e74b27a34..eb759140bbf6 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 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { int userId = UserHandle.getCallingUserId(); long id = mInjector.binderClearCallingIdentity(); try { - mUserManager.setUserIcon(userId, icon); + mUserManagerInternal.setUserIcon(userId, icon); } finally { mInjector.binderRestoreCallingIdentity(id); } |