diff options
13 files changed, 115 insertions, 23 deletions
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 191a696..9a50a41 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -1206,7 +1206,8 @@ final class ApplicationPackageManager extends PackageManager { return mPM.getUsers(); } catch (RemoteException re) { ArrayList<UserInfo> users = new ArrayList<UserInfo>(); - UserInfo primary = new UserInfo(0, "Root!", UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY); + UserInfo primary = new UserInfo(0, "Root!", null, + UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY); users.add(primary); return users; } @@ -1240,9 +1241,9 @@ final class ApplicationPackageManager extends PackageManager { * @hide */ @Override - public void updateUserName(int id, String name) { + public void setUserName(int id, String name) { try { - mPM.updateUserName(id, name); + mPM.setUserName(id, name); } catch (RemoteException re) { } } diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 70c0c48..6f00abd 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -41,6 +41,7 @@ import android.content.pm.ServiceInfo; import android.content.pm.UserInfo; import android.content.pm.VerifierDeviceIdentity; import android.net.Uri; +import android.os.ParcelFileDescriptor; import android.content.IntentSender; /** @@ -359,7 +360,8 @@ interface IPackageManager { UserInfo createUser(in String name, int flags); boolean removeUser(int userId); - void updateUserName(int userId, String name); + void setUserName(int userId, String name); + ParcelFileDescriptor setUserIcon(int userId); void installPackageWithVerification(in Uri packageURI, in IPackageInstallObserver observer, int flags, in String installerPackageName, in Uri verificationURI, diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 6de69b0..f9f7e2d 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -2646,7 +2646,7 @@ public abstract class PackageManager { * @param name the new name for the user * @hide */ - public abstract void updateUserName(int id, String name); + public abstract void setUserName(int id, String name); /** * Changes the user's properties specified by the flags. diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java index ba5331c..68a7257 100644 --- a/core/java/android/content/pm/UserInfo.java +++ b/core/java/android/content/pm/UserInfo.java @@ -43,12 +43,18 @@ public class UserInfo implements Parcelable { public int id; public String name; + public String iconPath; public int flags; public UserInfo(int id, String name, int flags) { + this(id, name, null, flags); + } + + public UserInfo(int id, String name, String iconPath, int flags) { this.id = id; this.name = name; this.flags = flags; + this.iconPath = iconPath; } public boolean isPrimary() { @@ -68,6 +74,7 @@ public class UserInfo implements Parcelable { public UserInfo(UserInfo orig) { name = orig.name; + iconPath = orig.iconPath; id = orig.id; flags = orig.flags; } @@ -84,6 +91,7 @@ public class UserInfo implements Parcelable { public void writeToParcel(Parcel dest, int parcelableFlags) { dest.writeInt(id); dest.writeString(name); + dest.writeString(iconPath); dest.writeInt(flags); } @@ -100,6 +108,7 @@ public class UserInfo implements Parcelable { private UserInfo(Parcel source) { id = source.readInt(); name = source.readString(); + iconPath = source.readString(); flags = source.readInt(); } } diff --git a/core/res/res/layout/global_actions_item.xml b/core/res/res/layout/global_actions_item.xml index 694301e..009f37b 100644 --- a/core/res/res/layout/global_actions_item.xml +++ b/core/res/res/layout/global_actions_item.xml @@ -27,11 +27,11 @@ android:paddingBottom="6dip" > <ImageView android:id="@+id/icon" - android:layout_width="wrap_content" - android:layout_height="match_parent" + android:layout_width="56dp" + android:layout_height="56dp" android:layout_gravity="center" android:layout_marginRight="16dip" - /> + android:scaleType="center"/> <LinearLayout android:orientation="vertical" diff --git a/core/res/res/layout/preference_holo.xml b/core/res/res/layout/preference_holo.xml index e574219..8402b36 100644 --- a/core/res/res/layout/preference_holo.xml +++ b/core/res/res/layout/preference_holo.xml @@ -33,11 +33,12 @@ android:orientation="horizontal"> <ImageView android:id="@+android:id/icon" - android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:layout_width="48dp" + android:layout_height="48dp" android:layout_gravity="center" - android:minWidth="48dp" - android:paddingRight="@dimen/preference_item_padding_inner" /> + android:scaleType="centerCrop" + android:layout_marginRight="@dimen/preference_item_padding_inner" + /> </LinearLayout> <RelativeLayout diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java index 5094df18..381e65b 100644 --- a/graphics/java/android/graphics/BitmapFactory.java +++ b/graphics/java/android/graphics/BitmapFactory.java @@ -19,6 +19,7 @@ package android.graphics; import android.content.res.AssetManager; import android.content.res.Resources; import android.util.DisplayMetrics; +import android.util.Log; import android.util.TypedValue; import java.io.BufferedInputStream; @@ -303,6 +304,7 @@ public class BitmapFactory { /* do nothing. If the exception happened on open, bm will be null. */ + Log.e("BitmapFactory", "Unable to decode stream: " + e); } finally { if (stream != null) { try { diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java index f09c010..6eca3b6 100644 --- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java +++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java @@ -246,6 +246,7 @@ public class DefaultContainerService extends IntentService { throw new IllegalStateException(e); } } + }; public DefaultContainerService() { diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java index fc187ce..e9b8267 100644 --- a/policy/src/com/android/internal/policy/impl/GlobalActions.java +++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java @@ -29,6 +29,8 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.UserInfo; import android.database.ContentObserver; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.ScaleDrawable; import android.media.AudioManager; import android.net.ConnectivityManager; import android.os.Handler; @@ -43,6 +45,7 @@ import android.telephony.PhoneStateListener; import android.telephony.ServiceState; import android.telephony.TelephonyManager; import android.util.Log; +import android.view.Gravity; import android.view.IWindowManager; import android.view.LayoutInflater; import android.view.View; @@ -52,6 +55,7 @@ import android.view.WindowManagerPolicy.WindowManagerFuncs; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.ImageView; +import android.widget.ImageView.ScaleType; import android.widget.TextView; import java.util.ArrayList; @@ -243,8 +247,10 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac for (final UserInfo user : users) { boolean isCurrentUser = currentUser == null ? user.id == 0 : (currentUser.id == user.id); + Drawable icon = user.iconPath != null ? Drawable.createFromPath(user.iconPath) + : null; SinglePressAction switchToUser = new SinglePressAction( - com.android.internal.R.drawable.ic_menu_cc, + com.android.internal.R.drawable.ic_menu_cc, icon, (user.name != null ? user.name : "Primary") + (isCurrentUser ? " \u2714" : "")) { public void onPress() { @@ -439,6 +445,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac */ private static abstract class SinglePressAction implements Action { private final int mIconResId; + private final Drawable mIcon; private final int mMessageResId; private final CharSequence mMessage; @@ -446,13 +453,23 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac mIconResId = iconResId; mMessageResId = messageResId; mMessage = null; + mIcon = null; + } + + protected SinglePressAction(int iconResId, Drawable icon, CharSequence message) { + mIconResId = iconResId; + mMessageResId = 0; + mMessage = message; + mIcon = icon; } protected SinglePressAction(int iconResId, CharSequence message) { mIconResId = iconResId; mMessageResId = 0; mMessage = message; + mIcon = null; } + public boolean isEnabled() { return true; } @@ -471,8 +488,12 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac TextView messageView = (TextView) v.findViewById(R.id.message); v.findViewById(R.id.status).setVisibility(View.GONE); - - icon.setImageDrawable(context.getResources().getDrawable(mIconResId)); + if (mIcon != null) { + icon.setImageDrawable(mIcon); + icon.setScaleType(ScaleType.CENTER_CROP); + } else if (mIconResId != 0) { + icon.setImageDrawable(context.getResources().getDrawable(mIconResId)); + } if (mMessage != null) { messageView.setText(mMessage); } else { diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java index e71556e..fee55f3 100644 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -9388,9 +9388,15 @@ public class PackageManagerService extends IPackageManager.Stub { } @Override - public void updateUserName(int userId, String name) { + public void setUserName(int userId, String name) { enforceSystemOrRoot("Only the system can rename users"); - sUserManager.updateUserName(userId, name); + sUserManager.setUserName(userId, name); + } + + @Override + public ParcelFileDescriptor setUserIcon(int userId) { + enforceSystemOrRoot("Only the system can update users"); + return sUserManager.setUserIcon(userId); } @Override diff --git a/services/java/com/android/server/pm/UserManager.java b/services/java/com/android/server/pm/UserManager.java index 4e9e666..738ab08 100644 --- a/services/java/com/android/server/pm/UserManager.java +++ b/services/java/com/android/server/pm/UserManager.java @@ -16,6 +16,9 @@ package com.android.server.pm; +import static android.os.ParcelFileDescriptor.MODE_CREATE; +import static android.os.ParcelFileDescriptor.MODE_READ_WRITE; + import com.android.internal.util.ArrayUtils; import com.android.internal.util.FastXmlSerializer; @@ -24,6 +27,7 @@ import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.os.Environment; import android.os.FileUtils; +import android.os.ParcelFileDescriptor; import android.os.SystemClock; import android.os.UserId; import android.util.Log; @@ -34,6 +38,7 @@ import android.util.Xml; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; @@ -44,10 +49,15 @@ import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; public class UserManager { + + private static final String TAG = "UserManager"; + private static final String TAG_NAME = "name"; private static final String ATTR_FLAGS = "flags"; + private static final String ATTR_ICON_PATH = "icon"; + private static final String ATTR_ID = "id"; private static final String TAG_USERS = "users"; @@ -58,6 +68,7 @@ public class UserManager { private static final String USER_INFO_DIR = "system" + File.separator + "users"; private static final String USER_LIST_FILENAME = "userlist.xml"; + private static final String USER_PHOTO_FILENAME = "photo.png"; private SparseArray<UserInfo> mUsers = new SparseArray<UserInfo>(); @@ -114,7 +125,7 @@ public class UserManager { } } - public void updateUserName(int userId, String name) { + public void setUserName(int userId, String name) { synchronized (mUsers) { UserInfo info = mUsers.get(userId); if (name != null && !name.equals(info.name)) { @@ -124,6 +135,39 @@ public class UserManager { } } + public ParcelFileDescriptor setUserIcon(int userId) { + synchronized (mUsers) { + UserInfo info = mUsers.get(userId); + if (info == null) return null; + ParcelFileDescriptor fd = updateIconBitmapLocked(info); + if (fd != null) { + writeUserLocked(info); + } + return fd; + } + } + + private ParcelFileDescriptor updateIconBitmapLocked(UserInfo info) { + try { + File dir = new File(mUsersDir, Integer.toString(info.id)); + File file = new File(dir, USER_PHOTO_FILENAME); + if (!dir.exists()) { + dir.mkdir(); + FileUtils.setPermissions( + dir.getPath(), + FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, + -1, -1); + } + ParcelFileDescriptor fd = ParcelFileDescriptor.open(file, + MODE_CREATE|MODE_READ_WRITE); + info.iconPath = file.getAbsolutePath(); + return fd; + } catch (FileNotFoundException e) { + Slog.w(TAG, "Error setting photo for user ", e); + } + return null; + } + /** * Returns an array of user ids. This array is cached here for quick access, so do not modify or * cache it elsewhere. @@ -187,7 +231,7 @@ public class UserManager { private void fallbackToSingleUserLocked() { // Create the primary user - UserInfo primary = new UserInfo(0, "Primary", + UserInfo primary = new UserInfo(0, "Primary", null, UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY); mUsers.put(0, primary); updateUserIdsLocked(); @@ -219,6 +263,9 @@ public class UserManager { serializer.startTag(null, TAG_USER); serializer.attribute(null, ATTR_ID, Integer.toString(userInfo.id)); serializer.attribute(null, ATTR_FLAGS, Integer.toString(userInfo.flags)); + if (userInfo.iconPath != null) { + serializer.attribute(null, ATTR_ICON_PATH, userInfo.iconPath); + } serializer.startTag(null, TAG_NAME); serializer.text(userInfo.name); @@ -286,6 +333,7 @@ public class UserManager { private UserInfo readUser(int id) { int flags = 0; String name = null; + String iconPath = null; FileInputStream fis = null; try { @@ -312,6 +360,7 @@ public class UserManager { } String flagString = parser.getAttributeValue(null, ATTR_FLAGS); flags = Integer.parseInt(flagString); + iconPath = parser.getAttributeValue(null, ATTR_ICON_PATH); while ((type = parser.next()) != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT) { @@ -324,7 +373,7 @@ public class UserManager { } } - UserInfo userInfo = new UserInfo(id, name, flags); + UserInfo userInfo = new UserInfo(id, name, iconPath, flags); return userInfo; } catch (IOException ioe) { @@ -342,7 +391,7 @@ public class UserManager { public UserInfo createUser(String name, int flags) { int userId = getNextAvailableId(); - UserInfo userInfo = new UserInfo(userId, name, flags); + UserInfo userInfo = new UserInfo(userId, name, null, flags); File userPath = new File(mBaseUserPath, Integer.toString(userId)); if (!createPackageFolders(userId, userPath)) { return null; diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java index c23e868..416900f 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java @@ -179,7 +179,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { @Override public List<UserInfo> getUsers() { final ArrayList<UserInfo> users = new ArrayList<UserInfo>(); - users.add(new UserInfo(USER_ID, "Primary", UserInfo.FLAG_PRIMARY)); + users.add(new UserInfo(USER_ID, "Primary", null, UserInfo.FLAG_PRIMARY)); users.add(new UserInfo(USER_ID_GUEST, "Guest", 0)); return users; } diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java index 86689f3..0399b3b 100644 --- a/test-runner/src/android/test/mock/MockPackageManager.java +++ b/test-runner/src/android/test/mock/MockPackageManager.java @@ -545,7 +545,7 @@ public class MockPackageManager extends PackageManager { * @hide */ @Override - public void updateUserName(int id, String name) { + public void setUserName(int id, String name) { throw new UnsupportedOperationException(); } |