Use Bitmap instead of ParcelFileDescriptor to get the user's icon.

Change-Id: I1dd7261b47ba98a2a0834dbfb8c22de369e6cc58
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index 1d4a6da..1a5c82c 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -27,6 +27,8 @@
 import android.content.res.Resources;
 import android.content.res.Resources.NotFoundException;
 import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
 import android.graphics.drawable.Drawable;
 import android.net.ConnectivityManager;
 import android.net.LinkProperties;
@@ -473,24 +475,12 @@
         }
         int userId = user != null ? user.id : UserHandle.myUserId();
         UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
-        ParcelFileDescriptor fd = um.setUserIcon(userId);
-        FileOutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
-        byte[] buffer = new byte[4096];
-        int readSize;
+        Bitmap icon = BitmapFactory.decodeStream(avatarDataStream);
+        um.setUserIcon(userId, icon);
         try {
-            while ((readSize = avatarDataStream.read(buffer)) > 0) {
-                os.write(buffer, 0, readSize);
-            }
-            return true;
-        } catch (IOException ioe) {
-            Log.e("copyProfilePhoto", "Error copying profile photo " + ioe);
-        } finally {
-            try {
-                os.close();
-                avatarDataStream.close();
-            } catch (IOException ioe) { }
-        }
-        return false;
+            avatarDataStream.close();
+        } catch (IOException ioe) { }
+        return true;
     }
 
     public static String getMeProfileName(Context context) {
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index 3c7addc..515005d 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -30,6 +30,7 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Bitmap.CompressFormat;
+import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.AsyncTask;
@@ -50,6 +51,7 @@
 import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.text.InputType;
 import android.util.Log;
+import android.util.SparseArray;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
@@ -65,6 +67,7 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.ArrayList;
 import java.util.List;
 
 public class UserSettings extends SettingsPreferenceFragment
@@ -111,6 +114,7 @@
 
     private final Object mUserLock = new Object();
     private UserManager mUserManager;
+    private SparseArray<Drawable> mUserIcons = new SparseArray<Drawable>();
 
     private Handler mHandler = new Handler() {
         @Override
@@ -127,9 +131,16 @@
     };
 
     private BroadcastReceiver mUserChangeReceiver = new BroadcastReceiver() {
-
         @Override
         public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(Intent.ACTION_USER_REMOVED)) {
+                mRemovingUserId = -1;
+            } else if (intent.getAction().equals(Intent.ACTION_USER_INFO_CHANGED)) {
+                int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
+                if (userHandle != -1) {
+                    mUserIcons.remove(userHandle);
+                }
+            }
             mHandler.sendEmptyMessage(MESSAGE_UPDATE_LIST);
         }
     };
@@ -151,8 +162,10 @@
                 InputType.TYPE_TEXT_VARIATION_NORMAL | InputType.TYPE_TEXT_FLAG_CAP_WORDS);
         loadProfile();
         setHasOptionsMenu(true);
-        getActivity().registerReceiver(mUserChangeReceiver,
-                new IntentFilter(Intent.ACTION_USER_REMOVED));
+        IntentFilter filter = new IntentFilter(Intent.ACTION_USER_REMOVED);
+        filter.addAction(Intent.ACTION_USER_INFO_CHANGED);
+        getActivity().registerReceiverAsUser(mUserChangeReceiver, UserHandle.ALL, filter, null,
+                mHandler);
     }
 
     @Override
@@ -219,7 +232,13 @@
 
     private void finishLoadProfile(String profileName) {
         mMePreference.setTitle(profileName);
-        setPhotoId(mMePreference, mUserManager.getUserInfo(UserHandle.myUserId()));
+        int myUserId = UserHandle.myUserId();
+        Bitmap b = mUserManager.getUserIcon(myUserId);
+        if (b != null) {
+            Drawable d = new BitmapDrawable(b);
+            mMePreference.setIcon(d);
+            mUserIcons.put(myUserId, d);
+        }
     }
 
     private void onAddUserClicked() {
@@ -302,10 +321,8 @@
             new Thread() {
                 public void run() {
                     synchronized (mUserLock) {
-                        // TODO: Show some progress while removing the user
                         mUserManager.removeUser(mRemovingUserId);
                         mHandler.sendEmptyMessage(MESSAGE_UPDATE_LIST);
-                        mRemovingUserId = -1;
                     }
                 }
             }.start();
@@ -354,14 +371,18 @@
     }
 
     private void updateUserList() {
+        if (getActivity() == null) return;
         List<UserInfo> users = mUserManager.getUsers();
 
         mUserListCategory.removeAll();
         mUserListCategory.setOrderingAsAdded(false);
 
+        final ArrayList<Integer> missingIcons = new ArrayList<Integer>();
         for (UserInfo user : users) {
             Preference pref;
-            if (user.id == UserHandle.myUserId()) {
+            if (user.id == mRemovingUserId) {
+                continue;
+            } else if (user.id == UserHandle.myUserId()) {
                 pref = mMePreference;
                 mNicknamePreference.setText(user.name);
                 mNicknamePreference.setSummary(user.name);
@@ -377,7 +398,12 @@
                 pref.setTitle(user.name);
             }
             if (user.iconPath != null) {
-                setPhotoId(pref, user);
+                if (mUserIcons.get(user.id) == null) {
+                    missingIcons.add(user.id);
+                    pref.setIcon(R.drawable.ic_user);
+                } else {
+                    setPhotoId(pref, user);
+                }
             }
         }
         // Add a temporary entry for the user being created
@@ -391,8 +417,33 @@
             mUserListCategory.addPreference(pref);
         }
         getActivity().invalidateOptionsMenu();
+
+        // Load the icons
+        if (missingIcons.size() > 0) {
+            loadIconsAsync(missingIcons);
+        }
     }
 
+    private void loadIconsAsync(List<Integer> missingIcons) {
+        new AsyncTask<List<Integer>, Void, Void>() {
+            @Override
+            protected void onPostExecute(Void result) {
+                updateUserList();
+            }
+
+            @Override
+            protected Void doInBackground(List<Integer>... values) {
+                if (getActivity() == null) return null;
+                for (int userId : values[0]) {
+                    Bitmap bitmap = mUserManager.getUserIcon(userId);
+                    Drawable d = new BitmapDrawable(getResources(), bitmap);
+                    mUserIcons.append(userId, d);
+                }
+                return null;
+            }
+        }.execute(missingIcons);
+
+    }
     private void assignProfilePhoto(final UserInfo user) {
         if (!Utils.copyMeProfilePhoto(getActivity(), user)) {
             assignDefaultPhoto(user);
@@ -410,17 +461,13 @@
     private void assignDefaultPhoto(UserInfo user) {
         Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
                 USER_DRAWABLES[user.id % USER_DRAWABLES.length]);
-        ParcelFileDescriptor fd = mUserManager.setUserIcon(user.id);
-        if (fd != null) {
-            bitmap.compress(CompressFormat.PNG, 100,
-                    new ParcelFileDescriptor.AutoCloseOutputStream(fd));
-        }
+        mUserManager.setUserIcon(user.id, bitmap);
     }
 
     private void setPhotoId(Preference pref, UserInfo user) {
-        Drawable icon = UserUtils.getUserIcon(mUserManager, user);
-        if (icon != null) {
-            pref.setIcon(icon);
+        Drawable d = mUserIcons.get(user.id); // UserUtils.getUserIcon(mUserManager, user);
+        if (d != null) {
+            pref.setIcon(d);
         }
     }
 
diff --git a/src/com/android/settings/users/UserUtils.java b/src/com/android/settings/users/UserUtils.java
index 19b9c84..433cbd3 100644
--- a/src/com/android/settings/users/UserUtils.java
+++ b/src/com/android/settings/users/UserUtils.java
@@ -17,6 +17,8 @@
 package com.android.settings.users;
 
 import android.content.pm.UserInfo;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.ParcelFileDescriptor;
 import android.os.UserManager;
@@ -25,10 +27,8 @@
 
     public static Drawable getUserIcon(UserManager um, UserInfo user) {
         if (user.iconPath == null) return null;
-        ParcelFileDescriptor fd = um.getUserIcon(user.id);
-        if (fd == null) return null;
-        Drawable d = Drawable.createFromStream(new ParcelFileDescriptor.AutoCloseInputStream(fd),
-                user.iconPath);
-        return d;
+        Bitmap icon = um.getUserIcon(user.id);
+        if (icon == null) return null;
+        return new BitmapDrawable(icon);
     }
 }