OSDN Git Service

Watch for profile changes and push to user manager
authorAmith Yamasani <yamasani@google.com>
Fri, 14 Sep 2012 01:06:49 +0000 (18:06 -0700)
committerAmith Yamasani <yamasani@google.com>
Fri, 14 Sep 2012 06:32:35 +0000 (23:32 -0700)
If the contacts Me Profile changes, push a copy of the photo to
user manager for user by the user switcher.

Also use an async task to load the profile data.

Change-Id: Ie784114622038ff14e3feb70f2ff51c372eecb3f

AndroidManifest.xml
src/com/android/settings/users/ProfileUpdateReceiver.java [new file with mode: 0644]
src/com/android/settings/users/UserSettings.java

index 24fc8b0..b1dd657 100644 (file)
@@ -59,6 +59,7 @@
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
     <uses-permission android:name="android.permission.COPY_PROTECTED_DATA" />
     <uses-permission android:name="android.permission.MANAGE_USERS" />
+    <uses-permission android:name="android.permission.READ_PROFILE" />
 
     <application android:label="@string/settings_label"
             android:icon="@mipmap/ic_launcher_settings"
             </intent-filter>
         </receiver>
 
+        <!-- Watch for ContactsContract.Profile changes and update the user's photo.  -->
+        <receiver android:name=".users.ProfileUpdateReceiver">
+            <intent-filter>
+                <action android:name="android.provider.Contacts.PROFILE_CHANGED" />
+            </intent-filter>
+        </receiver>
+
     </application>
 </manifest>
diff --git a/src/com/android/settings/users/ProfileUpdateReceiver.java b/src/com/android/settings/users/ProfileUpdateReceiver.java
new file mode 100644 (file)
index 0000000..5513608
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.users;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.UserInfo;
+import android.net.Uri;
+import android.os.ParcelFileDescriptor;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Profile;
+import android.util.Log;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Watches for changes to Me Profile in Contacts and writes the photo to the User Manager.
+ */
+public class ProfileUpdateReceiver extends BroadcastReceiver {
+
+    @Override
+    public void onReceive(final Context context, Intent intent) {
+        // Profile changed, lets get the photo and write to user manager
+        new Thread() {
+            public void run() {
+                copyProfilePhoto(context, null);
+            }
+        }.start();
+    }
+
+    /* Used by UserSettings as well. Call this on a non-ui thread. */
+    static boolean copyProfilePhoto(Context context, UserInfo user) {
+        Uri contactUri = Profile.CONTENT_URI;
+
+        InputStream avatarDataStream = Contacts.openContactPhotoInputStream(
+                    context.getContentResolver(),
+                    contactUri, true);
+        // If there's no profile photo, assign a default avatar
+        if (avatarDataStream == null) {
+            return false;
+        }
+        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;
+        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;
+    }
+}
index fe1bd90..28fe4c1 100644 (file)
@@ -31,6 +31,7 @@ import android.graphics.BitmapFactory;
 import android.graphics.Bitmap.CompressFormat;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
@@ -98,10 +99,10 @@ public class UserSettings extends SettingsPreferenceFragment
     private EditTextPreference mNicknamePreference;
     private int mRemovingUserId = -1;
     private boolean mAddingUser;
+    private boolean mProfileExists;
 
     private final Object mUserLock = new Object();
     private UserManager mUserManager;
-    private boolean mProfileChanged;
 
     private Handler mHandler = new Handler() {
         @Override
@@ -114,13 +115,6 @@ public class UserSettings extends SettingsPreferenceFragment
         }
     };
 
-    private ContentObserver mProfileObserver = new ContentObserver(mHandler) {
-        @Override
-        public void onChange(boolean selfChange) {
-            mProfileChanged = true;
-        }
-    };
-
     private BroadcastReceiver mUserChangeReceiver = new BroadcastReceiver() {
 
         @Override
@@ -143,11 +137,8 @@ public class UserSettings extends SettingsPreferenceFragment
         mNicknamePreference = (EditTextPreference) findPreference(KEY_USER_NICKNAME);
         mNicknamePreference.setOnPreferenceChangeListener(this);
         mNicknamePreference.setSummary(mUserManager.getUserInfo(UserHandle.myUserId()).name);
-        loadProfile(false);
+        loadProfile();
         setHasOptionsMenu(true);
-        // Register to watch for profile changes
-        getActivity().getContentResolver().registerContentObserver(
-                ContactsContract.Profile.CONTENT_URI, false, mProfileObserver);
         getActivity().registerReceiver(mUserChangeReceiver,
                 new IntentFilter(Intent.ACTION_USER_REMOVED));
     }
@@ -155,17 +146,13 @@ public class UserSettings extends SettingsPreferenceFragment
     @Override
     public void onResume() {
         super.onResume();
-        if (mProfileChanged) {
-            loadProfile(true);
-            mProfileChanged = false;
-        }
+        loadProfile();
         updateUserList();
     }
 
     @Override
     public void onDestroy() {
         super.onDestroy();
-        getActivity().getContentResolver().unregisterContentObserver(mProfileObserver);
         getActivity().unregisterReceiver(mUserChangeReceiver);
     }
 
@@ -198,13 +185,29 @@ public class UserSettings extends SettingsPreferenceFragment
         }
     }
 
-    private void loadProfile(boolean force) {
-        UserInfo user = mUserManager.getUserInfo(UserHandle.myUserId());
-        if (force || user.iconPath == null || user.iconPath.equals("")) {
-            assignProfilePhoto(user);
-        }
-        String profileName = getProfileName();
+    private void loadProfile() {
+        mProfileExists = false;
+        new AsyncTask<Void, Void, String>() {
+            @Override
+            protected void onPostExecute(String result) {
+                finishLoadProfile(result);
+            }
+
+            @Override
+            protected String doInBackground(Void... values) {
+                UserInfo user = mUserManager.getUserInfo(UserHandle.myUserId());
+                if (user.iconPath == null || user.iconPath.equals("")) {
+                    assignProfilePhoto(user);
+                }
+                String profileName = getProfileName();
+                return profileName;
+            }
+        }.execute();
+    }
+
+    private void finishLoadProfile(String profileName) {
         mMePreference.setTitle(profileName);
+        setPhotoId(mMePreference, mUserManager.getUserInfo(UserHandle.myUserId()));
     }
 
     private void onAddUserClicked() {
@@ -343,37 +346,10 @@ public class UserSettings extends SettingsPreferenceFragment
         getActivity().invalidateOptionsMenu();
     }
 
-    /* TODO: Put this in an AsyncTask */
     private void assignProfilePhoto(final UserInfo user) {
-        // If the contact is "me", then use my local profile photo. Otherwise, build a
-        // uri to get the avatar of the contact.
-        Uri contactUri = Profile.CONTENT_URI;
-
-        InputStream avatarDataStream = Contacts.openContactPhotoInputStream(
-                    getActivity().getContentResolver(),
-                    contactUri, true);
-        // If there's no profile photo, assign a default avatar
-        if (avatarDataStream == null) {
+        if (!ProfileUpdateReceiver.copyProfilePhoto(getActivity(), user)) {
             assignDefaultPhoto(user);
-            setPhotoId(mMePreference, user);
-            return;
-        }
-
-        ParcelFileDescriptor fd = mUserManager.setUserIcon(user.id);
-        FileOutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
-        byte[] buffer = new byte[4096];
-        int readSize;
-        try {
-            while ((readSize = avatarDataStream.read(buffer)) > 0) {
-                os.write(buffer, 0, readSize);
-            }
-            os.close();
-            avatarDataStream.close();
-        } catch (IOException ioe) {
-            Log.e(TAG, "Error copying profile photo " + ioe);
         }
-
-        setPhotoId(mMePreference, user);
     }
 
     private String getProfileName() {
@@ -387,6 +363,7 @@ public class UserSettings extends SettingsPreferenceFragment
 
         try {
             if (cursor.moveToFirst()) {
+                mProfileExists = true;
                 return cursor.getString(cursor.getColumnIndex(Phone.DISPLAY_NAME));
             }
         } finally {
@@ -421,8 +398,14 @@ public class UserSettings extends SettingsPreferenceFragment
     @Override
     public boolean onPreferenceClick(Preference pref) {
         if (pref == mMePreference) {
-            Intent editProfile = new Intent(Intent.ACTION_EDIT);
-            editProfile.setData(ContactsContract.Profile.CONTENT_URI);
+            Intent editProfile;
+            if (!mProfileExists) {
+                editProfile = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
+                // TODO: Make this a proper API
+                editProfile.putExtra("newLocalProfile", true);
+            } else {
+                editProfile = new Intent(Intent.ACTION_EDIT, ContactsContract.Profile.CONTENT_URI);
+            }
             // To make sure that it returns back here when done
             // TODO: Make this a proper API
             editProfile.putExtra("finishActivityOnSaveCompleted", true);