Move photo querying off main thread.
Fixes bug http://b/issue?id=2265642
diff --git a/core/java/com/android/internal/widget/ContactHeaderWidget.java b/core/java/com/android/internal/widget/ContactHeaderWidget.java
index d441155..19debec 100644
--- a/core/java/com/android/internal/widget/ContactHeaderWidget.java
+++ b/core/java/com/android/internal/widget/ContactHeaderWidget.java
@@ -119,6 +119,14 @@
int CONTACT_STATUS_RES_PACKAGE = 8;
int CONTACT_STATUS_LABEL = 9;
}
+
+ private interface PhotoQuery {
+ String[] COLUMNS = new String[] {
+ Photo.PHOTO
+ };
+
+ int PHOTO = 0;
+ }
//Projection used for looking up contact id from phone number
protected static final String[] PHONE_LOOKUP_PROJECTION = new String[] {
@@ -144,6 +152,7 @@
private static final int TOKEN_CONTACT_INFO = 0;
private static final int TOKEN_PHONE_LOOKUP = 1;
private static final int TOKEN_EMAIL_LOOKUP = 2;
+ private static final int TOKEN_PHOTO_QUERY = 3;
public ContactHeaderWidget(Context context) {
this(context, null);
@@ -229,11 +238,36 @@
protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
try{
switch (token) {
- case TOKEN_CONTACT_INFO: {
- bindContactInfo(cursor);
+ case TOKEN_PHOTO_QUERY: {
+ //Set the photo
+ Bitmap photoBitmap = null;
+ if (cursor != null && cursor.moveToFirst()
+ && !cursor.isNull(PhotoQuery.PHOTO)) {
+ byte[] photoData = cursor.getBlob(PhotoQuery.PHOTO);
+ photoBitmap = BitmapFactory.decodeByteArray(photoData, 0,
+ photoData.length, null);
+ }
+
+ if (photoBitmap == null) {
+ photoBitmap = loadPlaceholderPhoto(null);
+ }
+ mPhotoView.setImageBitmap(photoBitmap);
+ if (cookie != null && cookie instanceof Uri) {
+ mPhotoView.assignContactUri((Uri) cookie);
+ }
invalidate();
break;
}
+ case TOKEN_CONTACT_INFO: {
+ if (cursor != null && cursor.moveToFirst()) {
+ bindContactInfo(cursor);
+ Uri lookupUri = Contacts.getLookupUri(cursor.getLong(ContactQuery._ID),
+ cursor.getString(ContactQuery.LOOKUP_KEY));
+ startPhotoQuery(cursor.getLong(ContactQuery.PHOTO_ID), lookupUri);
+ invalidate();
+ }
+ break;
+ }
case TOKEN_PHONE_LOOKUP: {
if (cursor != null && cursor.moveToFirst()) {
long contactId = cursor.getLong(PHONE_LOOKUP_CONTACT_ID_COLUMN_INDEX);
@@ -375,8 +409,6 @@
*/
public void bindFromContactUri(Uri contactUri) {
mContactUri = contactUri;
- long contactId = ContentUris.parseId(contactUri);
-
startContactQuery(contactUri);
}
@@ -424,30 +456,24 @@
null, null, null);
}
+ protected void startPhotoQuery(long photoId, Uri lookupKey) {
+ mQueryHandler.startQuery(TOKEN_PHOTO_QUERY, lookupKey,
+ ContentUris.withAppendedId(Data.CONTENT_URI, photoId), PhotoQuery.COLUMNS,
+ null, null, null);
+ }
+
/**
* Bind the contact details provided by the given {@link Cursor}.
*/
protected void bindContactInfo(Cursor c) {
- if (c == null || !c.moveToFirst()) return;
-
// TODO: Bring back phonetic name
final String displayName = c.getString(ContactQuery.DISPLAY_NAME);
- final long contactId = c.getLong(ContactQuery._ID);
- final String lookupKey = c.getString(ContactQuery.LOOKUP_KEY);
final String phoneticName = null;
this.setDisplayName(displayName, null);
final boolean starred = c.getInt(ContactQuery.STARRED) != 0;
mStarredView.setChecked(starred);
- //Set the photo
- Bitmap photoBitmap = loadContactPhoto(c.getLong(ContactQuery.PHOTO_ID), null);
- if (photoBitmap == null) {
- photoBitmap = loadPlaceholderPhoto(null);
- }
- mPhotoView.setImageBitmap(photoBitmap);
- mPhotoView.assignContactUri(Contacts.getLookupUri(contactId, lookupKey));
-
//Set the presence status
if (!c.isNull(ContactQuery.CONTACT_PRESENCE_STATUS)) {
int presence = c.getInt(ContactQuery.CONTACT_PRESENCE_STATUS);
@@ -554,30 +580,6 @@
}
}
- private Bitmap loadContactPhoto(long photoId, BitmapFactory.Options options) {
- Cursor photoCursor = null;
- Bitmap photoBm = null;
-
- try {
- photoCursor = mContentResolver.query(
- ContentUris.withAppendedId(Data.CONTENT_URI, photoId),
- new String[] { Photo.PHOTO },
- null, null, null);
-
- if (photoCursor != null && photoCursor.moveToFirst() && !photoCursor.isNull(0)) {
- byte[] photoData = photoCursor.getBlob(0);
- photoBm = BitmapFactory.decodeByteArray(photoData, 0,
- photoData.length, options);
- }
- } finally {
- if (photoCursor != null) {
- photoCursor.close();
- }
- }
-
- return photoBm;
- }
-
private Bitmap loadPlaceholderPhoto(BitmapFactory.Options options) {
if (mNoPhotoResource == 0) {
return null;