Allow users to edit photos for read-only contacts again

Similar to ag/711429 (for editing read-only names), we set the
photo bitmap from the read-only contact but set the newly created
(and writable) raw contact as the delta underlying the photo editor
view so that if the photo is updated by the user, the new raw
contact is set as changed and not the read-only raw contact.

Bug 21873945

Change-Id: Ibd40f3d708332fe6f87d247773b871d575d7d12e
diff --git a/src/com/android/contacts/editor/CompactPhotoEditorView.java b/src/com/android/contacts/editor/CompactPhotoEditorView.java
index 0aa5af3..6be1377 100644
--- a/src/com/android/contacts/editor/CompactPhotoEditorView.java
+++ b/src/com/android/contacts/editor/CompactPhotoEditorView.java
@@ -130,6 +130,17 @@
 
         setId(viewIdGenerator.getId(rawContactDelta, dataKind, valuesDelta, /* viewIndex =*/ 0));
 
+        setPhoto(valuesDelta);
+    }
+
+    /**
+     * Sets the photo bitmap on this view from the given ValuesDelta. Note that the
+     * RawContactDelta underlying this view is not modified in any way.  Using this method allows
+     * you to show one photo (from a read-only contact, for example) and yet have a different
+     * raw contact updated when a new photo is set (from the new raw contact created and attached
+     * to the read-only contact). See go/editing-read-only-contacts
+     */
+    public void setPhoto(ValuesDelta valuesDelta) {
         if (valuesDelta == null) {
             setDefaultPhoto();
         } else {
diff --git a/src/com/android/contacts/editor/CompactRawContactsEditorView.java b/src/com/android/contacts/editor/CompactRawContactsEditorView.java
index 49cd2a2..d12ef6d 100644
--- a/src/com/android/contacts/editor/CompactRawContactsEditorView.java
+++ b/src/com/android/contacts/editor/CompactRawContactsEditorView.java
@@ -284,7 +284,7 @@
         mMaterialPalette = materialPalette;
 
         vlog("Setting compact editor state from " + rawContactDeltas);
-        addPhotoView(rawContactDeltas, viewIdGenerator, photoId);
+        addPhotoView(rawContactDeltas, viewIdGenerator, photoId, readOnlyDisplayName);
         addStructuredNameView(rawContactDeltas, nameId, readOnlyDisplayName);
         addEditorViews(rawContactDeltas);
         removeExtraEmptyTextFields(mPhoneNumbers);
@@ -292,7 +292,37 @@
     }
 
     private void addPhotoView(RawContactDeltaList rawContactDeltas,
-            ViewIdGenerator viewIdGenerator, long photoId) {
+            ViewIdGenerator viewIdGenerator, long photoId, String readOnlyDisplayName) {
+        // If we're editing a read-only contact, the display name from the read-only
+        // contact is non empty and we can use it determine whether to back the photo editor with
+        // the empty new raw contact delta.  See go/editing-read-only-contacts
+        final boolean readOnlyContact = !TextUtils.isEmpty(readOnlyDisplayName);
+        if (readOnlyContact) {
+            for (RawContactDelta rawContactDelta : rawContactDeltas) {
+                if (!rawContactDelta.isVisible()) continue;
+                final AccountType accountType = rawContactDelta.getAccountType(mAccountTypeManager);
+
+                // Make sure we have a photo
+                RawContactModifier.ensureKindExists(
+                        rawContactDelta, accountType, Photo.CONTENT_ITEM_TYPE);
+
+                final DataKind dataKind = accountType.getKindForMimetype(Photo.CONTENT_ITEM_TYPE);
+                if (accountType.areContactsWritable()) {
+                    for (ValuesDelta valuesDelta : rawContactDelta.getMimeEntries(
+                            Photo.CONTENT_ITEM_TYPE)) {
+                        if (valuesDelta != null) {
+                            // Break the loop but don't return because we need to keep going to
+                            // in order to show the photo from the read-only contact.
+                            mPhotoRawContactId = rawContactDelta.getRawContactId();
+                            mPhoto.setValues(dataKind, valuesDelta, rawContactDelta,
+                                    /* readOnly =*/ false, mMaterialPalette, viewIdGenerator);
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+
         // Look for a match for the photo ID that was passed in
         for (RawContactDelta rawContactDelta : rawContactDeltas) {
             if (!rawContactDelta.isVisible()) continue;
@@ -308,10 +338,14 @@
                         : rawContactDelta.getMimeEntries(Photo.CONTENT_ITEM_TYPE)) {
                     if (valuesDelta != null && valuesDelta.getId() != null
                             && valuesDelta.getId().equals(photoId)) {
-                        mPhotoRawContactId = rawContactDelta.getRawContactId();
-                        mPhoto.setValues(dataKind, valuesDelta, rawContactDelta,
-                                !accountType.areContactsWritable(),
-                                mMaterialPalette, viewIdGenerator);
+                        if (readOnlyContact) {
+                            mPhoto.setPhoto(valuesDelta);
+                        } else {
+                            mPhotoRawContactId = rawContactDelta.getRawContactId();
+                            mPhoto.setValues(dataKind, valuesDelta, rawContactDelta,
+                                    !accountType.areContactsWritable(),
+                                    mMaterialPalette, viewIdGenerator);
+                        }
                         return;
                     }
                 }
@@ -327,10 +361,14 @@
                 final ValuesDelta valuesDelta = getNonEmptySuperPrimaryValuesDeltas(
                         rawContactDelta, Photo.CONTENT_ITEM_TYPE, dataKind);
                 if (valuesDelta != null) {
-                    mPhotoRawContactId = rawContactDelta.getRawContactId();
-                    mPhoto.setValues(dataKind, valuesDelta, rawContactDelta,
-                            !accountType.areContactsWritable(), mMaterialPalette,
-                            viewIdGenerator);
+                    if (readOnlyContact) {
+                        mPhoto.setPhoto(valuesDelta);
+                    } else {
+                        mPhotoRawContactId = rawContactDelta.getRawContactId();
+                        mPhoto.setValues(dataKind, valuesDelta, rawContactDelta,
+                                !accountType.areContactsWritable(), mMaterialPalette,
+                                viewIdGenerator);
+                    }
                     return;
                 }
             }
@@ -344,10 +382,14 @@
                 final List<ValuesDelta> valuesDeltas = getNonEmptyValuesDeltas(
                         rawContactDelta, Photo.CONTENT_ITEM_TYPE, dataKind);
                 if (valuesDeltas != null && !valuesDeltas.isEmpty()) {
-                    mPhotoRawContactId = rawContactDelta.getRawContactId();
-                    mPhoto.setValues(dataKind, valuesDeltas.get(0), rawContactDelta,
-                            !accountType.areContactsWritable(), mMaterialPalette,
-                            viewIdGenerator);
+                    if (readOnlyContact) {
+                        mPhoto.setPhoto(valuesDeltas.get(0));
+                    } else {
+                        mPhotoRawContactId = rawContactDelta.getRawContactId();
+                        mPhoto.setValues(dataKind, valuesDeltas.get(0), rawContactDelta,
+                                !accountType.areContactsWritable(), mMaterialPalette,
+                                viewIdGenerator);
+                    }
                     return;
                 }
             }
@@ -361,10 +403,14 @@
                 final ValuesDelta valuesDelta = rawContactDelta.getSuperPrimaryEntry(
                         dataKind.mimeType, /* forceSelection =*/ true);
                 if (valuesDelta != null) {
-                    mPhotoRawContactId = rawContactDelta.getRawContactId();
-                    mPhoto.setValues(dataKind, valuesDelta, rawContactDelta,
-                            !accountType.areContactsWritable(), mMaterialPalette,
-                            viewIdGenerator);
+                    if (readOnlyContact) {
+                        mPhoto.setPhoto(valuesDelta);
+                    } else {
+                        mPhotoRawContactId = rawContactDelta.getRawContactId();
+                        mPhoto.setValues(dataKind, valuesDelta, rawContactDelta,
+                                !accountType.areContactsWritable(), mMaterialPalette,
+                                viewIdGenerator);
+                    }
                     return;
                 }
             }