Merge "Import translations. DO NOT MERGE" into ub-contactsdialer-h-dev
diff --git a/src/com/android/contacts/common/ContactPhotoManager.java b/src/com/android/contacts/common/ContactPhotoManager.java
index 5ec1eea..2a8ad15 100644
--- a/src/com/android/contacts/common/ContactPhotoManager.java
+++ b/src/com/android/contacts/common/ContactPhotoManager.java
@@ -467,7 +467,7 @@
     /**
      * Calls {@link #loadThumbnail(ImageView, long, boolean, DefaultImageRequest,
      * DefaultImageProvider)} using the {@link DefaultImageProvider} {@link #DEFAULT_AVATAR}.
-    */
+     */
     public final void loadThumbnail(ImageView view, long photoId, boolean darkTheme,
             boolean isCircular, DefaultImageRequest defaultImageRequest) {
         loadThumbnail(view, photoId, darkTheme, isCircular, defaultImageRequest, DEFAULT_AVATAR);
@@ -830,7 +830,7 @@
         } else {
             if (DEBUG) Log.d(TAG, "loadPhoto request: " + photoId);
             loadPhotoByIdOrUri(view, Request.createFromThumbnailId(photoId, darkTheme, isCircular,
-                    defaultProvider));
+                    defaultProvider, defaultImageRequest));
         }
     }
 
@@ -1178,6 +1178,8 @@
 
     /**
      * Stores the supplied bitmap in cache.
+     * bytes should be null to indicate a failure to load the photo. An empty byte[] signifies
+     * a successful load but no photo was available.
      */
     private void cacheBitmap(Object key, byte[] bytes, boolean preloading, int requestedExtent) {
         if (DEBUG) {
@@ -1203,10 +1205,11 @@
         }
 
         if (bytes != null) {
-            mBitmapHolderCache.put(key, holder);
             if (mBitmapHolderCache.get(key) != holder) {
                 Log.w(TAG, "Bitmap too big to fit in cache.");
                 mBitmapHolderCache.put(key, BITMAP_UNAVAILABLE);
+            } else {
+                mBitmapHolderCache.put(key, holder);
             }
         } else {
             mBitmapHolderCache.put(key, BITMAP_UNAVAILABLE);
@@ -1507,6 +1510,9 @@
                     while (cursor.moveToNext()) {
                         Long id = cursor.getLong(0);
                         byte[] bytes = cursor.getBlob(1);
+                        if (bytes == null) {
+                            bytes = new byte[0];
+                        }
                         cacheBitmap(id, bytes, preloading, -1);
                         mPhotoIds.remove(id);
                     }
@@ -1526,8 +1532,11 @@
                                 ContentUris.withAppendedId(Data.CONTENT_URI, id),
                                 COLUMNS, null, null, null);
                         if (profileCursor != null && profileCursor.moveToFirst()) {
-                            cacheBitmap(profileCursor.getLong(0), profileCursor.getBlob(1),
-                                    preloading, -1);
+                            byte[] bytes = profileCursor.getBlob(1);
+                            if (bytes == null) {
+                                bytes = new byte[0];
+                            }
+                            cacheBitmap(profileCursor.getLong(0), bytes, preloading, -1);
                         } else {
                             // Couldn't load a photo this way either.
                             cacheBitmap(id, null, preloading, -1);
@@ -1641,9 +1650,9 @@
         }
 
         public static Request createFromThumbnailId(long id, boolean darkTheme, boolean isCircular,
-                DefaultImageProvider defaultProvider) {
+                DefaultImageProvider defaultProvider, DefaultImageRequest defaultRequest) {
             return new Request(id, null /* no URI */, -1, darkTheme, isCircular, defaultProvider,
-                    /* defaultRequest */ null);
+                    defaultRequest);
         }
 
         public static Request createFromUri(Uri uri, int requestedExtent, boolean darkTheme,
diff --git a/src/com/android/contacts/editor/ContactEditorFragment.java b/src/com/android/contacts/editor/ContactEditorFragment.java
index 54465fd..dc2171b 100644
--- a/src/com/android/contacts/editor/ContactEditorFragment.java
+++ b/src/com/android/contacts/editor/ContactEditorFragment.java
@@ -331,6 +331,7 @@
     //
     // Used to store existing contact data so it can be re-applied during a rebind call,
     // i.e. account switch.
+    protected Contact mContact;
     protected ImmutableList<RawContact> mRawContacts;
     protected Cursor mGroupMetaData;
 
@@ -1038,6 +1039,7 @@
             Log.v(TAG, "Ignoring background change. This will have to be rebased later");
             return;
         }
+        mContact = contact;
         mRawContacts = contact.getRawContacts();
 
         // Check for writable raw contacts.  If there are none, then we need to create one so user
@@ -1214,7 +1216,7 @@
         }
         final int writableIndex = mState.indexOfFirstWritableRawContact(getContext());
         final RawContactDelta writable = mState.get(writableIndex);
-        final RawContactDelta readOnly = mState.get(writableIndex == 0 ? 1 : 0);
+        final RawContactDelta readOnly = mState.getByRawContactId(mContact.getNameRawContactId());
         final ValuesDelta writeNameDelta = writable
                 .getSuperPrimaryEntry(StructuredName.CONTENT_ITEM_TYPE);
         final ValuesDelta readNameDelta = readOnly
diff --git a/src/com/android/contacts/editor/PickRawContactDialogFragment.java b/src/com/android/contacts/editor/PickRawContactDialogFragment.java
index aa3e015..dd4eb30 100644
--- a/src/com/android/contacts/editor/PickRawContactDialogFragment.java
+++ b/src/com/android/contacts/editor/PickRawContactDialogFragment.java
@@ -3,12 +3,9 @@
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.DialogFragment;
-import android.content.ContentUris;
 import android.content.Context;
 import android.content.DialogInterface;
-import android.net.Uri;
 import android.os.Bundle;
-import android.provider.ContactsContract.RawContacts;
 import android.text.TextUtils;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -100,7 +97,7 @@
 
             String displayName =
                     mPreferences.getDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_PRIMARY
-                    ? rawContact.displayName : rawContact.displayNameAlt;
+                            ? rawContact.displayName : rawContact.displayNameAlt;
 
             if (TextUtils.isEmpty(displayName)) {
                 displayName = mContext.getString(R.string.missing_name);
@@ -130,16 +127,12 @@
             final ContactPhotoManager.DefaultImageRequest
                     request = new ContactPhotoManager.DefaultImageRequest(
                     displayName, String.valueOf(rawContact.id), /* isCircular = */ true);
-            final Uri photoUri = Uri.withAppendedPath(
-                    ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContact.id),
-                    RawContacts.DisplayPhoto.CONTENT_DIRECTORY);
 
-            ContactPhotoManager.getInstance(mContext).loadDirectoryPhoto(holder.photo,
-                    photoUri,
+            ContactPhotoManager.getInstance(mContext).loadThumbnail(holder.photo,
+                    rawContact.photoId,
                     /* darkTheme = */ false,
                     /* isCircular = */ true,
                     request);
-
             return view;
         }
 
diff --git a/src/com/android/contacts/editor/PickRawContactLoader.java b/src/com/android/contacts/editor/PickRawContactLoader.java
index 1939666..b3df4a6 100644
--- a/src/com/android/contacts/editor/PickRawContactLoader.java
+++ b/src/com/android/contacts/editor/PickRawContactLoader.java
@@ -9,12 +9,16 @@
 import android.os.Parcelable;
 import android.provider.ContactsContract;
 import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.Profile;
 import android.provider.ContactsContract.RawContacts;
 
 import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.model.account.AccountType;
 
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * Loader for the pick a raw contact to edit activity. Loads all raw contact metadata for the
@@ -43,6 +47,11 @@
     private static final int DISPLAY_NAME_PRIMARY = 4;
     private static final int DISPLAY_NAME_ALTERNATIVE = 5;
 
+    private static final String PHOTO_SELECTION_PREFIX =
+            ContactsContract.Data.RAW_CONTACT_ID + " IN (";
+    private static final String PHOTO_SELECTION_SUFFIX = ") AND " + ContactsContract.Data.MIMETYPE
+            + "=" + ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE;
+
     public PickRawContactLoader(Context context, Uri contactUri) {
         super(context);
         mContactUri = ensureIsContactUri(contactUri);
@@ -53,7 +62,7 @@
         final ContentResolver resolver = getContext().getContentResolver();
         // Get the id of the contact we're looking at.
         final Cursor contactCursor = resolver.query(
-                mContactUri, new String[]{Contacts._ID, Contacts.IS_USER_PROFILE}, null,
+                mContactUri, new String[] {Contacts._ID, Contacts.IS_USER_PROFILE}, null,
                 null, null);
 
         if (contactCursor == null) {
@@ -92,20 +101,51 @@
         }
 
         rawContactCursor.moveToPosition(-1);
+        final StringBuilder photoSelection = new StringBuilder(PHOTO_SELECTION_PREFIX);
+        final Map<Long, RawContact> rawContactMap = new HashMap<>();
         try {
             while (rawContactCursor.moveToNext()) {
                 RawContact rawContact = new RawContact();
                 rawContact.id = rawContactCursor.getLong(RAW_CONTACT_ID);
+                photoSelection.append(rawContact.id).append(',');
                 rawContact.displayName = rawContactCursor.getString(DISPLAY_NAME_PRIMARY);
                 rawContact.displayNameAlt = rawContactCursor.getString(DISPLAY_NAME_ALTERNATIVE);
                 rawContact.accountName = rawContactCursor.getString(ACCOUNT_NAME);
                 rawContact.accountType = rawContactCursor.getString(ACCOUNT_TYPE);
                 rawContact.accountDataSet = rawContactCursor.getString(DATA_SET);
                 result.rawContacts.add(rawContact);
+                rawContactMap.put(rawContact.id, rawContact);
             }
         } finally {
             rawContactCursor.close();
         }
+
+        // Remove the last ','
+        if (photoSelection.length() > 0) {
+            photoSelection.deleteCharAt(photoSelection.length() - 1);
+        }
+        photoSelection.append(PHOTO_SELECTION_SUFFIX);
+
+        final Uri dataUri = result.isUserProfile
+                ? Uri.withAppendedPath(Profile.CONTENT_URI, Data.CONTENT_URI.getPath())
+                : Data.CONTENT_URI;
+        final Cursor photoCursor = resolver.query(
+                dataUri,
+                new String[] {Data.RAW_CONTACT_ID, Contacts.Photo._ID},
+                photoSelection.toString(), null, null);
+
+        if (photoCursor != null) {
+            try {
+                photoCursor.moveToPosition(-1);
+                while (photoCursor.moveToNext()) {
+                    final long rawContactId = photoCursor.getLong(/* Data.RAW_CONTACT_ID */ 0);
+                    rawContactMap.get(rawContactId).photoId =
+                            photoCursor.getLong(/* PHOTO._ID */ 1);
+                }
+            } finally {
+                photoCursor.close();
+            }
+        }
         return result;
     }
 
@@ -225,6 +265,7 @@
                 };
 
         public long id;
+        public long photoId;
         public String displayName;
         public String displayNameAlt;
         public String accountName;
@@ -235,6 +276,7 @@
 
         private RawContact(Parcel in) {
             id = in.readLong();
+            photoId = in.readLong();
             displayName = in.readString();
             displayNameAlt = in.readString();
             accountName = in.readString();
@@ -250,6 +292,7 @@
         @Override
         public void writeToParcel(Parcel dest, int flags) {
             dest.writeLong(id);
+            dest.writeLong(photoId);
             dest.writeString(displayName);
             dest.writeString(displayNameAlt);
             dest.writeString(accountName);