From e928d7d95dbb64627e6ff3a0572190c555b59d96 Mon Sep 17 00:00:00 2001 From: Amith Yamasani Date: Mon, 17 Sep 2012 21:46:51 -0700 Subject: Pass Bitmap instead of ParcelFileDescriptor in UserManager Add a USER_INFO_CHANGED intent for lockscreen and quicksettings to use to monitor changes to the user name or icon. Bug: 7164040 Change-Id: Id6fb8b6d38ce04ccd02bbadcf0c10699783d6c03 --- core/java/android/content/Intent.java | 10 ++++++ core/java/android/os/IUserManager.aidl | 5 +-- core/java/android/os/UserManager.java | 18 +++++----- .../com/android/server/pm/UserManagerService.java | 41 +++++++++++++--------- 4 files changed, 47 insertions(+), 27 deletions(-) diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index d3b8648..e8507bc 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -2376,6 +2376,16 @@ public class Intent implements Parcelable, Cloneable { public static final String ACTION_USER_SWITCHED = "android.intent.action.USER_SWITCHED"; + /** + * Broadcast sent to the system when a user's information changes. Carries an extra + * {@link #EXTRA_USER_HANDLE} to indicate which user's information changed. + * This is only sent to registered receivers, not manifest receivers. It is sent to the user + * whose information has changed. + * @hide + */ + public static final String ACTION_USER_INFO_CHANGED = + "android.intent.action.USER_INFO_CHANGED"; + // --------------------------------------------------------------------- // --------------------------------------------------------------------- // Standard intent categories (see addCategory()). diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl index 653c5f3..0798913 100644 --- a/core/java/android/os/IUserManager.aidl +++ b/core/java/android/os/IUserManager.aidl @@ -19,6 +19,7 @@ package android.os; import android.os.ParcelFileDescriptor; import android.content.pm.UserInfo; +import android.graphics.Bitmap; /** * {@hide} @@ -27,8 +28,8 @@ interface IUserManager { UserInfo createUser(in String name, int flags); boolean removeUser(int userHandle); void setUserName(int userHandle, String name); - ParcelFileDescriptor setUserIcon(int userHandle); - ParcelFileDescriptor getUserIcon(int userHandle); + void setUserIcon(int userHandle, in Bitmap icon); + Bitmap getUserIcon(int userHandle); List getUsers(); UserInfo getUserInfo(int userHandle); void setGuestEnabled(boolean enable); diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index cac1e07..81d5b63 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -18,6 +18,7 @@ package android.os; import com.android.internal.R; import android.content.Context; import android.content.pm.UserInfo; +import android.graphics.Bitmap; import android.util.Log; import java.util.List; @@ -40,6 +41,7 @@ public class UserManager { /** * Returns whether the system supports multiple users. * @return true if multiple users can be created, false if it is a single user device. + * @hide */ public boolean supportsMultipleUsers() { return getMaxSupportedUsers() > 1; @@ -151,32 +153,30 @@ public class UserManager { } /** - * Returns a file descriptor for the user's photo. PNG data can be written into this file. + * Sets the user's photo. * @param userHandle the user for whom to change the photo. - * @return a {@link ParcelFileDescriptor} to which to write the photo. + * @param icon the bitmap to set as the photo. * @hide */ - public ParcelFileDescriptor setUserIcon(int userHandle) { + public void setUserIcon(int userHandle, Bitmap icon) { try { - return mService.setUserIcon(userHandle); + mService.setUserIcon(userHandle, icon); } catch (RemoteException re) { Log.w(TAG, "Could not set the user icon ", re); - return null; } } /** * Returns a file descriptor for the user's photo. PNG data can be read from this file. * @param userHandle the user whose photo we want to read. - * @return a {@link ParcelFileDescriptor} from which to read the file, or null if there's no - * photo. + * @return a {@link Bitmap} of the user's photo, or null if there's no photo. * @hide */ - public ParcelFileDescriptor getUserIcon(int userHandle) { + public Bitmap getUserIcon(int userHandle) { try { return mService.getUserIcon(userHandle); } catch (RemoteException re) { - Log.w(TAG, "Could not set the user icon ", re); + Log.w(TAG, "Could not get the user icon ", re); return null; } } diff --git a/services/java/com/android/server/pm/UserManagerService.java b/services/java/com/android/server/pm/UserManagerService.java index 690d7c9..be86628 100644 --- a/services/java/com/android/server/pm/UserManagerService.java +++ b/services/java/com/android/server/pm/UserManagerService.java @@ -29,6 +29,8 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.UserInfo; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.os.Binder; import android.os.Environment; import android.os.FileUtils; @@ -188,30 +190,35 @@ public class UserManagerService extends IUserManager.Stub { writeUserLocked(info); } } + sendUserInfoChangedBroadcast(userId); } @Override - public ParcelFileDescriptor setUserIcon(int userId) { + public void setUserIcon(int userId, Bitmap bitmap) { checkManageUsersPermission("update users"); synchronized (mPackagesLock) { UserInfo info = mUsers.get(userId); - if (info == null) return null; - ParcelFileDescriptor fd = openIconBitmapLocked(info, true /* write */); - if (fd != null) { - writeUserLocked(info); - } - return fd; + if (info == null) return; + writeBitmapLocked(info, bitmap); + writeUserLocked(info); } + sendUserInfoChangedBroadcast(userId); + } + + private void sendUserInfoChangedBroadcast(int userId) { + Intent changedIntent = new Intent(Intent.ACTION_USER_INFO_CHANGED); + changedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); + changedIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); + mContext.sendBroadcastAsUser(changedIntent, new UserHandle(userId)); } @Override - public ParcelFileDescriptor getUserIcon(int userId) { + public Bitmap getUserIcon(int userId) { checkManageUsersPermission("read users"); synchronized (mPackagesLock) { UserInfo info = mUsers.get(userId); if (info == null || info.iconPath == null) return null; - ParcelFileDescriptor fd = openIconBitmapLocked(info, false /* read */); - return fd; + return BitmapFactory.decodeFile(info.iconPath); } } @@ -289,7 +296,7 @@ public class UserManagerService extends IUserManager.Stub { } } - private ParcelFileDescriptor openIconBitmapLocked(UserInfo info, boolean toWrite) { + private void writeBitmapLocked(UserInfo info, Bitmap bitmap) { try { File dir = new File(mUsersDir, Integer.toString(info.id)); File file = new File(dir, USER_PHOTO_FILENAME); @@ -300,16 +307,18 @@ public class UserManagerService extends IUserManager.Stub { FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, -1, -1); } - ParcelFileDescriptor fd = ParcelFileDescriptor.open(file, - toWrite ? MODE_CREATE|MODE_READ_WRITE : MODE_READ_WRITE); - if (toWrite) { + FileOutputStream os; + if (bitmap.compress(Bitmap.CompressFormat.PNG, 100, os = new FileOutputStream(file))) { info.iconPath = file.getAbsolutePath(); } - return fd; + try { + os.close(); + } catch (IOException ioe) { + // What the ... ! + } } catch (FileNotFoundException e) { Slog.w(LOG_TAG, "Error setting photo for user ", e); } - return null; } /** -- cgit v1.1