Fix some photo selection fragment bugs (E18)

* Hide the photo source dialog when there is only
  1 photo in the aggregate
* Fix reverting to photo selection fragment on
  rotate after taking or selecting a photo
* Unset super primary on other photo valuesdeltas
  after taking a new photo (also fixes full
  res image not loading on quick contacts after
  the editor is closed?)
* Show full resolution photos on photo selector
  even if they have not yet been saved to CP2

Bug 19697372
Bug 23589603

Change-Id: Idd6966ba981d251ae713950ea2f0d2d60c7b30c0
diff --git a/src/com/android/contacts/activities/CompactContactEditorActivity.java b/src/com/android/contacts/activities/CompactContactEditorActivity.java
index 358740e..5e2fbff 100644
--- a/src/com/android/contacts/activities/CompactContactEditorActivity.java
+++ b/src/com/android/contacts/activities/CompactContactEditorActivity.java
@@ -90,7 +90,7 @@
         }
 
         private final CompactPhotoActionListener mPhotoActionListener;
-        private final boolean mIsPhotoSelection;
+        private boolean mIsPhotoSelection;
 
         public CompactPhotoSelectionHandler(int photoMode, boolean isPhotoSelection) {
             // We pass a null changeAnchorView since we are overriding onClick so that we
@@ -178,7 +178,11 @@
 
     @Override
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
-        getPhotoSelectionHandler().handlePhotoActivityResult(requestCode, resultCode, data);
+        if (mPhotoSelectionHandler != null &&
+                mPhotoSelectionHandler.handlePhotoActivityResult(requestCode, resultCode, data)) {
+            return;
+        }
+        super.onActivityResult(requestCode, resultCode, data);
     }
 
     @Override
@@ -225,6 +229,8 @@
                 .hide(mPhotoSelectionFragment)
                 .show((CompactContactEditorFragment) mFragment)
                 .commit();
+
+        mIsPhotoSelection = false;
     }
 
     @Override
diff --git a/src/com/android/contacts/editor/CompactContactEditorFragment.java b/src/com/android/contacts/editor/CompactContactEditorFragment.java
index f081d54..058a66c 100644
--- a/src/com/android/contacts/editor/CompactContactEditorFragment.java
+++ b/src/com/android/contacts/editor/CompactContactEditorFragment.java
@@ -245,15 +245,15 @@
     public void onPhotoEditorViewClicked() {
         if (isMultiAccountContact()) {
             final ArrayList<CompactPhotoSelectionFragment.Photo> photos = getContent().getPhotos();
-            if (!photos.isEmpty()) {
+            if (photos.size() > 1) {
                 // For aggregate contacts, the user may select a new super primary photo from among
                 // the (non-default) raw contact photos, or source a new photo from the ActionBar
                 getEditorActivity().selectPhoto(photos, getPhotoMode());
                 return;
             }
         }
-        // For contacts composed of a single writable raw contact, or no raw contacts have photos,
-        // clicking the photo view simply opens the source photo dialog
+        // For contacts composed of a single writable raw contact, or raw contacts have no more
+        // than 1 photo, clicking the photo view simply opens the source photo dialog
         getEditorActivity().changePhoto(getPhotoMode());
     }
 
@@ -267,6 +267,11 @@
         }
     }
 
+    @Override
+    public Bundle getUpdatedPhotos() {
+        return mUpdatedPhotos;
+    }
+
     private int getPhotoMode() {
         if (getContent().isWritablePhotoSet()) {
             return isMultiAccountContact()
diff --git a/src/com/android/contacts/editor/CompactPhotoSelectionFragment.java b/src/com/android/contacts/editor/CompactPhotoSelectionFragment.java
index ce868f9..be4e938 100644
--- a/src/com/android/contacts/editor/CompactPhotoSelectionFragment.java
+++ b/src/com/android/contacts/editor/CompactPhotoSelectionFragment.java
@@ -17,14 +17,19 @@
 package com.android.contacts.editor;
 
 import com.android.contacts.R;
+import com.android.contacts.common.ContactPhotoManager;
 import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.common.model.account.AccountType;
 
 import android.app.Fragment;
 import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.provider.ContactsContract;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
@@ -105,6 +110,9 @@
         public int kindSectionDataListIndex = -1;
         public int valuesDeltaListIndex = -1;
 
+        /** Newly taken or selected photo that has not yet been saved to CP2. */
+        public Uri updatedPhotoUri;
+
         @Override
         public int describeContents() {
             return 0;
@@ -119,6 +127,7 @@
             dest.writeInt(primary ? 1 : 0);
             dest.writeInt(kindSectionDataListIndex);
             dest.writeInt(valuesDeltaListIndex);
+            dest.writeParcelable(updatedPhotoUri, flags);
         }
 
         private void readFromParcel(Parcel source) {
@@ -130,6 +139,7 @@
             primary = source.readInt() == 1;
             kindSectionDataListIndex = source.readInt();
             valuesDeltaListIndex = source.readInt();
+            updatedPhotoUri = source.readParcelable(classLoader);
         }
     }
 
@@ -174,7 +184,20 @@
 
             // Bind the photo
             final ImageView imageView = (ImageView) photoItemView.findViewById(R.id.image);
-            imageView.setImageBitmap(EditorUiUtils.getPhotoBitmap(photo.valuesDelta));
+            if (photo.updatedPhotoUri != null) {
+                EditorUiUtils.loadPhoto(ContactPhotoManager.getInstance(getContext()),
+                        imageView, photo.updatedPhotoUri);
+            } else {
+                final Long photoFileId = EditorUiUtils.getPhotoFileId(photo.valuesDelta);
+                if (photoFileId != null) {
+                    final Uri photoUri = ContactsContract.DisplayPhoto.CONTENT_URI.buildUpon()
+                            .appendPath(photoFileId.toString()).build();
+                    EditorUiUtils.loadPhoto(ContactPhotoManager.getInstance(getContext()),
+                            imageView, photoUri);
+                } else {
+                    imageView.setImageBitmap(EditorUiUtils.getPhotoBitmap(photo.valuesDelta));
+                }
+            }
 
             // Add the account type icon
             final ImageView accountTypeImageView = (ImageView)
diff --git a/src/com/android/contacts/editor/CompactRawContactsEditorView.java b/src/com/android/contacts/editor/CompactRawContactsEditorView.java
index ed5dc3b..6f5a9cb 100644
--- a/src/com/android/contacts/editor/CompactRawContactsEditorView.java
+++ b/src/com/android/contacts/editor/CompactRawContactsEditorView.java
@@ -36,6 +36,7 @@
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.net.Uri;
+import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.provider.ContactsContract;
@@ -126,6 +127,12 @@
          * Invoked when a rawcontact from merged contacts is selected in editor.
          */
         public void onRawContactSelected(Uri uri, long rawContactId, boolean isReadOnly);
+
+        /**
+         * Returns the map of raw contact IDs to newly taken or selected photos that have not
+         * yet been saved to CP2.
+         */
+        public Bundle getUpdatedPhotos();
     }
 
     /**
@@ -509,27 +516,26 @@
     }
 
     public void updatePhoto(Uri photoUri) {
-        // Even though high-res photos cannot be saved by passing them via
-        // an EntityDeltaList (since they cause the Bundle size limit to be
-        // exceeded), we still pass a low-res thumbnail. This simplifies
-        // code all over the place, because we don't have to test whether
-        // there is a change in EITHER the delta-list OR a changed photo...
-        // this way, there is always a change in the delta-list.
-        mPhotoValuesDelta.setFromTemplate(false);
+        // Unset primary for all photos
+        unsetSuperPrimary();
+
+        // Mark the currently displayed photo as primary
         mPhotoValuesDelta.setSuperPrimary(true);
-        try {
-            final byte[] bytes = EditorUiUtils.getCompressedThumbnailBitmapBytes(
-                    getContext(), photoUri);
-            if (bytes != null) {
-                mPhotoValuesDelta.setPhoto(bytes);
-            }
-        } catch (FileNotFoundException e) {
-            elog("Failed to get bitmap from photo Uri");
-        }
 
         mPhotoView.setFullSizedPhoto(photoUri);
     }
 
+    private void unsetSuperPrimary() {
+        final List<KindSectionData> kindSectionDataList =
+                mKindSectionDataMap.get(Photo.CONTENT_ITEM_TYPE);
+        for (KindSectionData kindSectionData : kindSectionDataList) {
+            final List<ValuesDelta> valuesDeltaList = kindSectionData.getValuesDeltas();
+            for (ValuesDelta valuesDelta : valuesDeltaList) {
+                valuesDelta.setSuperPrimary(false);
+            }
+        }
+    }
+
     /**
      * Pass through to {@link CompactPhotoEditorView#isWritablePhotoSet}.
      */
@@ -555,6 +561,8 @@
     public ArrayList<CompactPhotoSelectionFragment.Photo> getPhotos() {
         final ArrayList<CompactPhotoSelectionFragment.Photo> photos = new ArrayList<>();
 
+        final Bundle updatedPhotos = mListener == null ? null : mListener.getUpdatedPhotos();
+
         final List<KindSectionData> kindSectionDataList =
                 mKindSectionDataMap.get(Photo.CONTENT_ITEM_TYPE);
         for (int i = 0; i < kindSectionDataList.size(); i++) {
@@ -576,6 +584,12 @@
                 photo.primary = valuesDelta.isSuperPrimary();
                 photo.kindSectionDataListIndex = i;
                 photo.valuesDeltaListIndex = j;
+
+                if (updatedPhotos != null) {
+                    photo.updatedPhotoUri = (Uri) updatedPhotos.get(String.valueOf(
+                            kindSectionData.getRawContactDelta().getRawContactId()));
+                }
+
                 photos.add(photo);
             }
         }
@@ -588,17 +602,12 @@
      * UI.
      */
     public void setPrimaryPhoto(CompactPhotoSelectionFragment.Photo photo) {
-        // Unset primary for all other photos
-        final List<KindSectionData> kindSectionDataList =
-                mKindSectionDataMap.get(Photo.CONTENT_ITEM_TYPE);
-        for (KindSectionData kindSectionData : kindSectionDataList) {
-            final List<ValuesDelta> valuesDeltaList = kindSectionData.getValuesDeltas();
-            for (ValuesDelta valuesDelta : valuesDeltaList) {
-                valuesDelta.setSuperPrimary(false);
-            }
-        }
+        // Unset primary for all photos
+        unsetSuperPrimary();
 
         // Find the values delta to mark as primary
+        final KindSectionDataList kindSectionDataList =
+                mKindSectionDataMap.get(Photo.CONTENT_ITEM_TYPE);
         if (photo.kindSectionDataListIndex < 0
                 || photo.kindSectionDataListIndex >= kindSectionDataList.size()) {
             wlog("Invalid kind section data list index");
@@ -722,7 +731,7 @@
                     continue;
                 }
 
-                final List<KindSectionData> kindSectionDataList =
+                final KindSectionDataList kindSectionDataList =
                         getOrCreateKindSectionDataList(mimeType);
                 final KindSectionData kindSectionData =
                         new KindSectionData(accountType, dataKind, rawContactDelta);
@@ -740,7 +749,7 @@
         }
     }
 
-    private List<KindSectionData> getOrCreateKindSectionDataList(String mimeType) {
+    private KindSectionDataList getOrCreateKindSectionDataList(String mimeType) {
         // Put structured names and nicknames together
         mimeType = Nickname.CONTENT_ITEM_TYPE.equals(mimeType)
                 ? StructuredName.CONTENT_ITEM_TYPE : mimeType;
diff --git a/src/com/android/contacts/editor/EditorUiUtils.java b/src/com/android/contacts/editor/EditorUiUtils.java
index 0fdae58..24ba7df 100644
--- a/src/com/android/contacts/editor/EditorUiUtils.java
+++ b/src/com/android/contacts/editor/EditorUiUtils.java
@@ -236,7 +236,7 @@
         return currentVersion > Build.VERSION_CODES.M;
     }
 
-    /** Returns teh {@link Photo#PHOTO_FILE_ID} from the given ValuesDelta. */
+    /** Returns the {@link Photo#PHOTO_FILE_ID} from the given ValuesDelta. */
     public static Long getPhotoFileId(ValuesDelta valuesDelta) {
         if (valuesDelta == null) return null;
         if (valuesDelta.getAfter() == null || valuesDelta.getAfter().get(Photo.PHOTO) == null) {