Merge "Import translations. DO NOT MERGE"
diff --git a/proguard.flags b/proguard.flags
index 863d27a..b7b9f18 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -15,6 +15,7 @@
 # Needed for tests
 -keep class com.android.contacts.common.compat.CompatUtils { *; }
 -keep class com.android.contacts.common.Collapser { *; }
+-keep class com.android.contacts.common.ContactPhotoManager { *; }
 -keep class com.android.contacts.common.ContactsUtils { *; }
 -keep class com.android.contacts.common.database.NoNullCursorAsyncQueryHandler { *; }
 -keep class com.android.contacts.common.format.FormatUtils { *; }
@@ -64,6 +65,7 @@
 -keep class com.android.contacts.common.model.ValuesDelta { *; }
 -keep class com.android.contacts.common.MoreContactUtils { *; }
 -keep class com.android.contacts.common.preference.ContactsPreferences { *; }
+-keep class com.android.contacts.common.test.mocks.MockContactPhotoManager { *; }
 -keep class com.android.contacts.common.testing.InjectedServices { *; }
 -keep class com.android.contacts.common.util.BitmapUtil { *; }
 -keep class com.android.contacts.common.util.ContactDisplayUtils { *; }
diff --git a/res/drawable-hdpi/ic_check_circle_googblue_drawable_24dp.png b/res/drawable-hdpi/ic_check_circle_googblue_drawable_24dp.png
deleted file mode 100644
index da6561d..0000000
--- a/res/drawable-hdpi/ic_check_circle_googblue_drawable_24dp.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_photos_white_24.png b/res/drawable-hdpi/ic_photos_white_24.png
deleted file mode 100644
index a5180a1..0000000
--- a/res/drawable-hdpi/ic_photos_white_24.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_check_circle_googblue_drawable_24dp.png b/res/drawable-mdpi/ic_check_circle_googblue_drawable_24dp.png
deleted file mode 100644
index efa2fdf..0000000
--- a/res/drawable-mdpi/ic_check_circle_googblue_drawable_24dp.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_photos_white_24.png b/res/drawable-mdpi/ic_photos_white_24.png
deleted file mode 100644
index e0e5854..0000000
--- a/res/drawable-mdpi/ic_photos_white_24.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_check_circle_googblue_drawable_24dp.png b/res/drawable-xhdpi/ic_check_circle_googblue_drawable_24dp.png
deleted file mode 100644
index 70a22c9..0000000
--- a/res/drawable-xhdpi/ic_check_circle_googblue_drawable_24dp.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_photos_white_24.png b/res/drawable-xhdpi/ic_photos_white_24.png
deleted file mode 100644
index bc64bb0..0000000
--- a/res/drawable-xhdpi/ic_photos_white_24.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_check_circle_googblue_drawable_24dp.png b/res/drawable-xxhdpi/ic_check_circle_googblue_drawable_24dp.png
deleted file mode 100644
index 7ac3497..0000000
--- a/res/drawable-xxhdpi/ic_check_circle_googblue_drawable_24dp.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_photos_white_24.png b/res/drawable-xxhdpi/ic_photos_white_24.png
deleted file mode 100644
index 2cb5dbc..0000000
--- a/res/drawable-xxhdpi/ic_photos_white_24.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_check_circle_googblue_drawable_24dp.png b/res/drawable-xxxhdpi/ic_check_circle_googblue_drawable_24dp.png
deleted file mode 100644
index c077752..0000000
--- a/res/drawable-xxxhdpi/ic_check_circle_googblue_drawable_24dp.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_photos_white_24.png b/res/drawable-xxxhdpi/ic_photos_white_24.png
deleted file mode 100644
index 5722b4a..0000000
--- a/res/drawable-xxxhdpi/ic_photos_white_24.png
+++ /dev/null
Binary files differ
diff --git a/res/layout/all_photos_button.xml b/res/layout/all_photos_button.xml
deleted file mode 100644
index 83578c3..0000000
--- a/res/layout/all_photos_button.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="@dimen/photo_picker_item_ideal_width"
-    android:layout_height="@dimen/photo_picker_item_ideal_width"
-    android:background="@color/google_grey_600"
-    android:orientation="vertical">
-
-    <ImageView
-        android:id="@+id/image"
-        android:paddingTop="48dp"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:src="@drawable/ic_photos_white_24"
-        android:layout_gravity="center_horizontal"/>
-
-    <TextView
-        android:id="@+id/textLabel"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_centerInParent="true"
-        android:singleLine="true"
-        android:text="@string/all_photos_button"
-        android:textSize="14sp"
-        android:textColor="@color/photo_action_button_color"
-        android:paddingTop="9dp"
-        android:paddingBottom="35dp"
-        android:layout_gravity="center_horizontal"/>
-</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/compact_photo_selection_fragment.xml b/res/layout/compact_photo_selection_fragment.xml
deleted file mode 100644
index 42f5b96..0000000
--- a/res/layout/compact_photo_selection_fragment.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 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.
--->
-
- <GridView xmlns:android="http://schemas.android.com/apk/res/android"
-      android:id="@+id/grid_view"
-      android:layout_width="match_parent"
-      android:layout_height="match_parent"
-      android:numColumns="auto_fit"
-      android:verticalSpacing="3dp"
-      android:horizontalSpacing="3dp"
-      android:stretchMode="columnWidth"
-      android:gravity="center"
-      android:paddingTop="3dp"
-      android:drawSelectorOnTop="true"/>
diff --git a/res/layout/compact_photo_selection_item.xml b/res/layout/compact_photo_selection_item.xml
deleted file mode 100644
index aea8ff6..0000000
--- a/res/layout/compact_photo_selection_item.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 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.
--->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        style="@style/SelectableItem"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent">
-
-    <ImageView
-            android:id="@+id/image"
-            android:layout_width="match_parent"
-            android:layout_height="@dimen/photo_picker_item_ideal_width"
-            android:adjustViewBounds="true"
-            android:layout_centerInParent="true"
-            android:scaleType="centerCrop" />
-
-    <ImageView
-            android:id="@+id/check"
-            android:layout_width="24dp"
-            android:layout_height="24dp"
-            android:layout_alignParentTop="true"
-            android:layout_alignParentStart="true"
-            android:layout_margin="8dp"
-            android:src="@drawable/ic_check_circle_googblue_drawable_24dp"
-            android:visibility="gone"/>
-
-    <ImageView
-            android:id="@+id/account_type"
-            android:layout_width="30dp"
-            android:layout_height="30dp"
-            android:layout_alignParentBottom="true"
-            android:layout_alignParentStart="true"
-            android:paddingBottom="8dp"
-            android:paddingStart="8dp"/>
-
-</RelativeLayout>
diff --git a/res/layout/take_a_photo_button.xml b/res/layout/take_a_photo_button.xml
deleted file mode 100644
index b837e85..0000000
--- a/res/layout/take_a_photo_button.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="@dimen/photo_picker_item_ideal_width"
-    android:layout_height="@dimen/photo_picker_item_ideal_width"
-    android:background="@color/google_grey_600"
-    android:orientation="vertical">
-
-    <ImageView
-        android:id="@+id/image"
-        android:paddingTop="48dp"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:src="@drawable/ic_photo_camera_white_24dp"
-        android:layout_gravity="center_horizontal"/>
-
-    <TextView
-        android:id="@+id/textLabel"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_centerInParent="true"
-        android:singleLine="true"
-        android:text="@string/take_a_photo_button"
-        android:textSize="14sp"
-        android:textColor="@color/photo_action_button_color"
-        android:paddingTop="9dp"
-        android:paddingBottom="35dp"
-        android:layout_gravity="center_horizontal"/>
-</LinearLayout>
\ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 64c5e5b..081d579 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -71,12 +71,6 @@
     <!-- Color of disabled text and unfocused hint text inside the contact editor. 25% black. -->
     <color name="editor_disabled_text_color">#40000000</color>
 
-    <!-- Color of button background in compact photo picker. -->
-    <color name="google_grey_600">#757575</color>
-
-    <!-- Color of button text in compact photo picker, 85% white. -->
-    <color name="photo_action_button_color">#D9FFFFFF</color>
-
     <!-- Color of text on disabled link contacts button, 25% black. -->
     <color name="disabled_button_text">#40000000</color>
 
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index e1c70ff..bcea910 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -241,9 +241,6 @@
 
     <dimen name="contact_browser_list_item_height">56dp</dimen>
 
-    <!-- Ideal item width in photo picker -->
-    <dimen name="photo_picker_item_ideal_width">135dp</dimen>
-
     <!-- Margin between name field and whatever fields are above it. -->
     <dimen name="compact_editor_name_top_margin">8dp</dimen>
 
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 5e778c2..5af7000 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -296,6 +296,9 @@
     <!-- The text displayed when there's no contacts in the main contacts list [CHAR LIMIT=70] -->
     <string name="emptyMainList">Your contacts list is empty</string>
 
+    <!-- Toast displayed when a contact is saved [CHAR LIMIT=30] -->
+    <string name="contactSavedNamedToast"><xliff:g id="display_name">%s</xliff:g> saved</string>
+
     <!-- Toast displayed when a contact is saved [CHAR LIMIT=NONE] -->
     <string name="contactSavedToast">Contact saved</string>
 
@@ -859,12 +862,6 @@
     <!-- Title of profile photos that are from your various accounts -->
     <string name="from_your_accounts">From your accounts</string>
 
-    <!-- Button used in photo picker to open camera [CHAR LIMIT=30]-->
-    <string name="take_a_photo_button">Take a photo</string>
-
-    <!-- Button used in photo picker to open photo/gallery [CHAR LIMIT=20]-->
-    <string name="all_photos_button">All photos</string>
-
     <!-- Title of photo picker [CHAR LIMIT=30]-->
     <string name="photo_picker_title">Choose photo</string>
 
diff --git a/src/com/android/contacts/activities/CompactContactEditorActivity.java b/src/com/android/contacts/activities/CompactContactEditorActivity.java
index 3778400..6d969ba 100644
--- a/src/com/android/contacts/activities/CompactContactEditorActivity.java
+++ b/src/com/android/contacts/activities/CompactContactEditorActivity.java
@@ -16,23 +16,6 @@
 
 package com.android.contacts.activities;
 
-import com.android.contacts.ContactSaveService;
-import com.android.contacts.ContactsActivity;
-import com.android.contacts.R;
-import com.android.contacts.common.activity.RequestPermissionsActivity;
-import com.android.contacts.common.model.AccountTypeManager;
-import com.android.contacts.common.model.RawContactDeltaList;
-import com.android.contacts.common.model.account.AccountType;
-import com.android.contacts.common.model.account.AccountWithDataSet;
-import com.android.contacts.common.util.ImplicitIntentsUtil;
-import com.android.contacts.detail.PhotoSelectionHandler;
-import com.android.contacts.editor.CompactContactEditorFragment;
-import com.android.contacts.editor.CompactPhotoSelectionFragment;
-import com.android.contacts.editor.EditorIntents;
-import com.android.contacts.editor.PhotoSourceDialogFragment;
-import com.android.contacts.interactions.ContactDeletionInteraction;
-import com.android.contacts.util.DialogManager;
-
 import android.app.ActionBar;
 import android.app.Dialog;
 import android.app.FragmentTransaction;
@@ -46,6 +29,22 @@
 import android.view.View;
 import android.view.inputmethod.InputMethodManager;
 
+import com.android.contacts.ContactSaveService;
+import com.android.contacts.ContactsActivity;
+import com.android.contacts.R;
+import com.android.contacts.common.activity.RequestPermissionsActivity;
+import com.android.contacts.common.model.AccountTypeManager;
+import com.android.contacts.common.model.RawContactDeltaList;
+import com.android.contacts.common.model.account.AccountType;
+import com.android.contacts.common.model.account.AccountWithDataSet;
+import com.android.contacts.common.util.ImplicitIntentsUtil;
+import com.android.contacts.detail.PhotoSelectionHandler;
+import com.android.contacts.editor.CompactContactEditorFragment;
+import com.android.contacts.editor.EditorIntents;
+import com.android.contacts.editor.PhotoSourceDialogFragment;
+import com.android.contacts.interactions.ContactDeletionInteraction;
+import com.android.contacts.util.DialogManager;
+
 import java.io.FileNotFoundException;
 import java.util.ArrayList;
 
@@ -53,7 +52,7 @@
  * Contact editor with only the most important fields displayed initially.
  */
 public class CompactContactEditorActivity extends ContactsActivity implements
-        PhotoSourceDialogFragment.Listener, CompactPhotoSelectionFragment.Listener,
+        PhotoSourceDialogFragment.Listener,
         DialogManager.DialogShowingViewActivity {
     private static final String TAG = "ContactEditorActivity";
 
@@ -74,10 +73,8 @@
             "com.android.contacts.SAVE_TO_DEVICE_FLAG";
 
     private static final String TAG_COMPACT_EDITOR = "compact_editor";
-    private static final String TAG_PHOTO_SELECTION = "photo_selector";
 
     private static final String STATE_PHOTO_MODE = "photo_mode";
-    private static final String STATE_IS_PHOTO_SELECTION = "is_photo_selection";
     private static final String STATE_ACTION_BAR_TITLE = "action_bar_title";
     private static final String STATE_PHOTO_URI = "photo_uri";
 
@@ -211,18 +208,12 @@
             @Override
             public void onRemovePictureChosen() {
                 getEditorFragment().removePhoto();
-                if (mIsPhotoSelection) {
-                    showEditorFragment();
-                }
             }
 
             @Override
             public void onPhotoSelected(Uri uri) throws FileNotFoundException {
                 mPhotoUri = uri;
                 getEditorFragment().updatePhoto(uri);
-                if (mIsPhotoSelection) {
-                    showEditorFragment();
-                }
 
                 // Re-create the photo handler the next time we need it so that additional photo
                 // selections create a new temp file (and don't hit the one that was just added
@@ -237,16 +228,12 @@
 
             @Override
             public void onPhotoSelectionDismissed() {
-                if (mIsPhotoSelection) {
-                    showEditorFragment();
-                }
             }
         }
 
         private final CompactPhotoActionListener mPhotoActionListener;
-        private boolean mIsPhotoSelection;
 
-        public CompactPhotoSelectionHandler(int photoMode, boolean isPhotoSelection) {
+        public CompactPhotoSelectionHandler(int photoMode) {
             // We pass a null changeAnchorView since we are overriding onClick so that we
             // can show the photo options in a dialog instead of a ListPopupWindow (which would
             // be anchored at changeAnchorView).
@@ -255,7 +242,6 @@
             super(CompactContactEditorActivity.this, /* changeAnchorView =*/ null, photoMode,
                     /* isDirectoryContact =*/ false, new RawContactDeltaList());
             mPhotoActionListener = new CompactPhotoActionListener();
-            mIsPhotoSelection = isPhotoSelection;
         }
 
         @Override
@@ -275,11 +261,9 @@
     private boolean mFinishActivityOnSaveCompleted;
     private DialogManager mDialogManager = new DialogManager(this);
 
-    private CompactPhotoSelectionFragment mPhotoSelectionFragment;
     private CompactPhotoSelectionHandler mPhotoSelectionHandler;
     private Uri mPhotoUri;
     private int mPhotoMode;
-    private boolean mIsPhotoSelection;
 
     private final CompactContactEditorFragment.Listener  mFragmentListener =
             new CompactContactEditorFragment.Listener() {
@@ -428,38 +412,25 @@
         if (savedState == null) {
             // Create the editor and photo selection fragments
             mFragment = new CompactContactEditorFragment();
-            mPhotoSelectionFragment = new CompactPhotoSelectionFragment();
             getFragmentManager().beginTransaction()
                     .add(R.id.fragment_container, getEditorFragment(), TAG_COMPACT_EDITOR)
-                    .add(R.id.fragment_container, mPhotoSelectionFragment, TAG_PHOTO_SELECTION)
-                    .hide(mPhotoSelectionFragment)
                     .commit();
         } else {
             // Restore state
             mPhotoMode = savedState.getInt(STATE_PHOTO_MODE);
-            mIsPhotoSelection = savedState.getBoolean(STATE_IS_PHOTO_SELECTION);
             mActionBarTitleResId = savedState.getInt(STATE_ACTION_BAR_TITLE);
             mPhotoUri = Uri.parse(savedState.getString(STATE_PHOTO_URI));
 
             // Show/hide the editor and photo selection fragments (w/o animations)
             mFragment = (CompactContactEditorFragment) getFragmentManager()
                     .findFragmentByTag(TAG_COMPACT_EDITOR);
-            mPhotoSelectionFragment = (CompactPhotoSelectionFragment) getFragmentManager()
-                    .findFragmentByTag(TAG_PHOTO_SELECTION);
             final FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
-            if (mIsPhotoSelection) {
-                fragmentTransaction.hide(getEditorFragment()).show(mPhotoSelectionFragment);
-                getActionBar().setTitle(getResources().getString(R.string.photo_picker_title));
-            } else {
-                fragmentTransaction.show(getEditorFragment()).hide(mPhotoSelectionFragment);
-                getActionBar().setTitle(getResources().getString(mActionBarTitleResId));
-            }
-            fragmentTransaction.commit();
+            fragmentTransaction.show(getEditorFragment()).commit();
+            getActionBar().setTitle(getResources().getString(mActionBarTitleResId));
         }
 
         // Set listeners
         mFragment.setListener(mFragmentListener);
-        mPhotoSelectionFragment.setListener(this);
 
         // Load editor data (even if it's hidden)
         final Uri uri = Intent.ACTION_EDIT.equals(action) ? getIntent().getData() : null;
@@ -517,7 +488,6 @@
     protected void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
         outState.putInt(STATE_PHOTO_MODE, mPhotoMode);
-        outState.putBoolean(STATE_IS_PHOTO_SELECTION, mIsPhotoSelection);
         outState.putInt(STATE_ACTION_BAR_TITLE, mActionBarTitleResId);
         outState.putString(STATE_PHOTO_URI,
                 mPhotoUri != null ? mPhotoUri.toString() : Uri.EMPTY.toString());
@@ -536,53 +506,20 @@
 
     @Override
     public void onBackPressed() {
-        if (mIsPhotoSelection) {
-            mIsPhotoSelection = false;
-            showEditorFragment();
-        } else if (mFragment != null) {
+        if (mFragment != null) {
             mFragment.revert();
         }
     }
 
     /**
-     * Displays photos from all raw contacts, clicking one set it as the super primary photo.
-     */
-    public void selectPhoto(ArrayList<CompactPhotoSelectionFragment.Photo> photos, int photoMode) {
-        mPhotoMode = photoMode;
-        mIsPhotoSelection = true;
-        mPhotoSelectionFragment.setPhotos(photos, photoMode);
-        showPhotoSelectionFragment();
-    }
-
-    /**
      * Opens a dialog showing options for the user to change their photo (take, choose, or remove
      * photo).
      */
     public void changePhoto(int photoMode) {
         mPhotoMode = photoMode;
-        mIsPhotoSelection = false;
         PhotoSourceDialogFragment.show(this, mPhotoMode);
     }
 
-    private void showPhotoSelectionFragment() {
-        getFragmentManager().beginTransaction()
-                .setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out)
-                .hide(getEditorFragment())
-                .show(mPhotoSelectionFragment)
-                .commit();
-        getActionBar().setTitle(getResources().getString(R.string.photo_picker_title));
-    }
-
-    private void showEditorFragment() {
-        getFragmentManager().beginTransaction()
-                .setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out)
-                .hide(mPhotoSelectionFragment)
-                .show((CompactContactEditorFragment) mFragment)
-                .commit();
-        getActionBar().setTitle(getResources().getString(mActionBarTitleResId));
-        mIsPhotoSelection = false;
-    }
-
     @Override
     public void onRemovePictureChosen() {
         getPhotoSelectionHandler().getListener().onRemovePictureChosen();
@@ -598,16 +535,9 @@
         getPhotoSelectionHandler().getListener().onPickFromGalleryChosen();
     }
 
-    @Override
-    public void onPhotoSelected(CompactPhotoSelectionFragment.Photo photo) {
-        getEditorFragment().setPrimaryPhoto(photo);
-        showEditorFragment();
-    }
-
     private PhotoSelectionHandler getPhotoSelectionHandler() {
         if (mPhotoSelectionHandler == null) {
-            mPhotoSelectionHandler = new CompactPhotoSelectionHandler(
-                    mPhotoMode, mIsPhotoSelection);
+            mPhotoSelectionHandler = new CompactPhotoSelectionHandler(mPhotoMode);
         }
         return mPhotoSelectionHandler;
     }
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index 0d29e06..09963f2 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -197,6 +197,24 @@
         return (mProviderStatus != null) && mProviderStatus.equals(ProviderStatus.STATUS_NORMAL);
     }
 
+    /**
+     * Initialize fragments that are (or may not be) in the layout.
+     *
+     * For the fragments that are in the layout, we initialize them in
+     * {@link #createViewsAndFragments()} after inflating the layout.
+     *
+     * However, the {@link ContactsUnavailableFragment} is a special fragment which may not
+     * be in the layout, so we have to do the initialization here.
+     *
+     * The ContactsUnavailableFragment is always created at runtime.
+     */
+    @Override
+    public void onAttachFragment(Fragment fragment) {
+        if (fragment instanceof ContactsUnavailableFragment) {
+            mContactsUnavailableFragment = (ContactsUnavailableFragment)fragment;
+        }
+    }
+
     @Override
     protected void onCreate(Bundle savedState) {
         if (Log.isLoggable(Constants.PERFORMANCE_TAG, Log.DEBUG)) {
diff --git a/src/com/android/contacts/common/model/Contact.java b/src/com/android/contacts/common/model/Contact.java
index 2187b1d..c84ff2a 100644
--- a/src/com/android/contacts/common/model/Contact.java
+++ b/src/com/android/contacts/common/model/Contact.java
@@ -25,6 +25,7 @@
 import android.provider.ContactsContract.DisplayNameSources;
 
 import com.android.contacts.common.model.account.AccountType;
+import com.android.contacts.common.model.account.SimAccountType;
 import com.android.contacts.common.util.DataStatus;
 import com.android.contacts.group.GroupMetaData;
 
@@ -471,6 +472,19 @@
         return mIsUserProfile;
     }
 
+    /**
+     * @return true if all the raw contacts are from SIM accounts, and false otherwise.
+     */
+    public boolean areAllRawContactsSimAccounts(final Context context) {
+        if (getRawContacts() == null) return false;
+
+        for (RawContact rawContact : getRawContacts()) {
+            final AccountType accountType = rawContact.getAccountType(context);
+            if (!(accountType instanceof SimAccountType)) return false;
+        }
+        return true;
+    }
+
     @Override
     public String toString() {
         return "{requested=" + mRequestedUri + ",lookupkey=" + mLookupKey +
diff --git a/src/com/android/contacts/editor/CompactContactEditorFragment.java b/src/com/android/contacts/editor/CompactContactEditorFragment.java
index 879eba2..f228b70 100644
--- a/src/com/android/contacts/editor/CompactContactEditorFragment.java
+++ b/src/com/android/contacts/editor/CompactContactEditorFragment.java
@@ -21,6 +21,7 @@
 import android.app.Fragment;
 import android.app.LoaderManager;
 import android.content.ActivityNotFoundException;
+import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
@@ -195,6 +196,8 @@
     /**
      * Intent key to pass the ID of the photo to display on the editor.
      */
+    // TODO: This can be cleaned up if we decide to not pass the photo id through
+    // QuickContactActivity.
     public static final String INTENT_EXTRA_PHOTO_ID = "photo_id";
 
     /**
@@ -346,7 +349,6 @@
     protected boolean mDisableDeleteMenuOption;
     protected boolean mNewLocalProfile;
     protected MaterialColorMapUtils.MaterialPalette mMaterialPalette;
-    protected long mPhotoId = -1;
 
     //
     // Helpers
@@ -513,7 +515,6 @@
             mDisableDeleteMenuOption = savedState.getBoolean(KEY_DISABLE_DELETE_MENU_OPTION);
             mNewLocalProfile = savedState.getBoolean(KEY_NEW_LOCAL_PROFILE);
             mMaterialPalette = savedState.getParcelable(KEY_MATERIAL_PALETTE);
-            mPhotoId = savedState.getLong(KEY_PHOTO_ID);
 
             mRawContacts = ImmutableList.copyOf(savedState.<RawContact>getParcelableArrayList(
                     KEY_RAW_CONTACTS));
@@ -638,8 +639,6 @@
         if (mMaterialPalette != null) {
             outState.putParcelable(KEY_MATERIAL_PALETTE, mMaterialPalette);
         }
-        outState.putLong(KEY_PHOTO_ID, mPhotoId);
-
         outState.putParcelable(KEY_VIEW_ID_GENERATOR, mViewIdGenerator);
 
         outState.putParcelableArrayList(KEY_RAW_CONTACTS, mRawContacts == null ?
@@ -1364,10 +1363,9 @@
         // Add input fields for the loaded Contact
         final CompactRawContactsEditorView editorView = getContent();
         editorView.setListener(this);
-        editorView.setState(mState, getMaterialPalette(), mViewIdGenerator, mPhotoId,
+        editorView.setState(mState, getMaterialPalette(), mViewIdGenerator,
                 mHasNewContact, mIsUserProfile, mAccountWithDataSet,
-                mRawContactIdToDisplayAlone, mRawContactDisplayAloneIsReadOnly,
-                isEditingReadOnlyRawContactWithNewContact());
+                mRawContactIdToDisplayAlone, isEditingReadOnlyRawContactWithNewContact());
         if (mHasNewContact && !TextUtils.isEmpty(mReadOnlyDisplayName)) {
             mReadOnlyNameEditorView = editorView.getPrimaryNameEditorView();
             editorView.maybeSetReadOnlyDisplayNameAsPrimary(mReadOnlyDisplayName);
@@ -1485,10 +1483,6 @@
                         mIntentExtras.getInt(INTENT_EXTRA_MATERIAL_PALETTE_PRIMARY_COLOR),
                         mIntentExtras.getInt(INTENT_EXTRA_MATERIAL_PALETTE_SECONDARY_COLOR));
             }
-            // If the user selected a different photo, don't restore the one from the Intent
-            if (mPhotoId < 0) {
-                mPhotoId = mIntentExtras.getLong(INTENT_EXTRA_PHOTO_ID);
-            }
             mRawContactIdToDisplayAlone = mIntentExtras.getLong(
                     INTENT_EXTRA_RAW_CONTACT_ID_TO_DISPLAY_ALONE, -1);
             mRawContactDisplayAloneIsReadOnly = mIntentExtras.getBoolean(
@@ -1531,8 +1525,16 @@
                                 .show();
                         break;
                     default:
-                        Toast.makeText(mContext, R.string.contactSavedToast, Toast.LENGTH_SHORT)
-                                .show();
+                        final String displayName = getContent().getPrimaryNameEditorView()
+                                .getDisplayName();
+                        final String toastMessage;
+                        if (!TextUtils.isEmpty(displayName)) {
+                            toastMessage = getResources().getString(
+                                    R.string.contactSavedNamedToast, displayName);
+                        } else {
+                            toastMessage = getResources().getString(R.string.contactSavedToast);
+                        }
+                        Toast.makeText(mContext, toastMessage, Toast.LENGTH_SHORT).show();
                 }
 
             } else {
@@ -1664,7 +1666,7 @@
             return;
         }
 
-        final View anchorView = getAggregationAnchorView(mAggregationSuggestionsRawContactId);
+        final View anchorView = getAggregationAnchorView();
         if (anchorView == null) {
             return; // Raw contact deleted?
         }
@@ -1691,10 +1693,9 @@
     }
 
     /**
-     * Returns the raw contact editor view for the given rawContactId that should be used as the
-     * anchor for aggregation suggestions.
+     * Returns the editor view that should be used as the anchor for aggregation suggestions.
      */
-    protected View getAggregationAnchorView(long rawContactId) {
+    protected View getAggregationAnchorView() {
         return getContent().getAggregationAnchorView();
     }
 
@@ -1805,11 +1806,8 @@
         getContent().updatePhoto(uri);
     }
 
-    public void setPrimaryPhoto(CompactPhotoSelectionFragment.Photo photo) {
-        getContent().setPrimaryPhoto(photo);
-
-        // Update the photo ID we will try to match when selecting the photo to display
-        mPhotoId = photo.photoId;
+    public void setPrimaryPhoto() {
+        getContent().setPrimaryPhoto();
     }
 
     @Override
@@ -1856,41 +1854,6 @@
         getEditorActivity().changePhoto(getPhotoMode());
     }
 
-    // This method override photo's primary flag based on photoId and set the photo currently
-    // shown in the editor to be the new primary no matter how many primary photos there are in
-    // the photo picker. This is because the photos returned by "getPhoto" may contain 0, 1,
-    // or 2+ primary photos and when we link contacts in the editor, the photos returned may change.
-    // We need to put check mark on the photo currently shown in editor, so we override "primary".
-    // This doesn't modify anything in the database,so there would be no pending changes.
-    private void updatePrimaryForSelection(ArrayList<CompactPhotoSelectionFragment.Photo> photos) {
-        for (CompactPhotoSelectionFragment.Photo photo : photos) {
-            if (photo.photoId == mPhotoId) {
-                photo.primary = true;
-            } else {
-                photo.primary = false;
-            }
-            updateContentDescription(photo);
-        }
-    }
-
-    private void updateContentDescription(CompactPhotoSelectionFragment.Photo photo) {
-        if (!TextUtils.isEmpty(photo.accountType)) {
-            photo.contentDescription = getResources().getString(photo.primary ?
-                            R.string.photo_view_description_checked :
-                            R.string.photo_view_description_not_checked,
-                    photo.accountType, photo.accountName);
-            photo.contentDescriptionChecked = getResources().getString(
-                    R.string.photo_view_description_checked,
-                    photo.accountType, photo.accountName);
-        } else {
-            photo.contentDescription = getResources().getString(photo.primary ?
-                    R.string.photo_view_description_checked_no_info :
-                    R.string.photo_view_description_not_checked_no_info);
-            photo.contentDescriptionChecked = getResources().getString(
-                    R.string.photo_view_description_checked_no_info);
-        }
-    }
-
     @Override
     public void onRawContactSelected(long rawContactId, boolean isReadOnly) {
         mRawContactDisplayAloneIsReadOnly = isReadOnly;
@@ -1898,18 +1861,9 @@
         bindEditors();
     }
 
-    @Override
-    public Bundle getUpdatedPhotos() {
-        return mUpdatedPhotos;
-    }
-
     private int getPhotoMode() {
-        if (getContent().isWritablePhotoSet()) {
-            return isEditingMultipleRawContacts()
-                    ? PhotoActionPopup.Modes.MULTIPLE_WRITE_ABLE_PHOTOS
-                    : PhotoActionPopup.Modes.WRITE_ABLE_PHOTO;
-        }
-        return PhotoActionPopup.Modes.NO_PHOTO;
+        return getContent().isWritablePhotoSet() ? PhotoActionPopup.Modes.WRITE_ABLE_PHOTO
+                : PhotoActionPopup.Modes.NO_PHOTO;
     }
 
     private CompactContactEditorActivity getEditorActivity() {
diff --git a/src/com/android/contacts/editor/CompactPhotoEditorView.java b/src/com/android/contacts/editor/CompactPhotoEditorView.java
index 39e4fae..66fe68a 100644
--- a/src/com/android/contacts/editor/CompactPhotoEditorView.java
+++ b/src/com/android/contacts/editor/CompactPhotoEditorView.java
@@ -65,6 +65,7 @@
     private View mPhotoIcon;
     private View mPhotoIconOverlay;
     private View mPhotoTouchInterceptOverlay;
+    private MaterialPalette mMaterialPalette;
 
     private boolean mReadOnly;
     private boolean mIsNonDefaultPhotoBound;
@@ -122,12 +123,16 @@
         }
     }
 
+    public void setPalette(MaterialPalette palette) {
+        mMaterialPalette = palette;
+    }
+
     /**
      * Tries to bind a full size photo or a bitmap loaded from the given ValuesDelta,
      * and falls back to the default avatar, tinted using the given MaterialPalette (if it's not
      * null);
      */
-    public void setPhoto(ValuesDelta valuesDelta, MaterialPalette materialPalette) {
+    public void setPhoto(ValuesDelta valuesDelta) {
         // Check if we can update to the full size photo immediately
         final Long photoFileId = EditorUiUtils.getPhotoFileId(valuesDelta);
         if (photoFileId != null) {
@@ -146,7 +151,7 @@
             return;
         }
 
-        setDefaultPhoto(materialPalette);
+        setDefaultPhoto(mMaterialPalette);
         adjustDimensions();
     }
 
@@ -206,6 +211,7 @@
     }
 
     private void setDefaultPhoto(MaterialPalette materialPalette) {
+        mIsNonDefaultPhotoBound = false;
         EditorUiUtils.setDefaultPhoto(mPhotoImageView, getResources(), materialPalette);
     }
 
@@ -222,9 +228,7 @@
      * Removes the current bound photo bitmap.
      */
     public void removePhoto() {
-        mPhotoImageView.setImageBitmap(/* bitmap =*/ null);
-        mIsNonDefaultPhotoBound = false;
-        setDefaultPhoto(/* materialPalette =*/ null);
+        setDefaultPhoto(mMaterialPalette);
     }
 
     @Override
diff --git a/src/com/android/contacts/editor/CompactPhotoSelectionFragment.java b/src/com/android/contacts/editor/CompactPhotoSelectionFragment.java
deleted file mode 100644
index 0a8894f..0000000
--- a/src/com/android/contacts/editor/CompactPhotoSelectionFragment.java
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * Copyright (C) 2015 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.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.net.Uri;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.provider.ContactsContract;
-import android.util.DisplayMetrics;
-import android.view.Display;
-import android.view.LayoutInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.accessibility.AccessibilityEvent;
-import android.widget.AdapterView;
-import android.widget.BaseAdapter;
-import android.widget.GridView;
-import android.widget.ImageView;
-
-import java.util.ArrayList;
-
-/**
- * Displays {@link Photo}s in a grid and calls back the host when one is clicked.
- */
-public class CompactPhotoSelectionFragment extends Fragment {
-
-    private static final String STATE_PHOTOS = "photos";
-    private static final String STATE_PHOTO_MODE = "photoMode";
-    private final int VIEW_TYPE_TAKE_PHOTO = 0;
-    private final int VIEW_TYPE_ALL_PHOTOS = 1;
-    private final int VIEW_TYPE_IMAGE = 2;
-
-    /**
-     * Callbacks hosts this Fragment.
-     */
-    public interface Listener {
-
-        /**
-         * Invoked when the user wants to change their photo.
-         */
-        void onPhotoSelected(Photo photo);
-    }
-
-    /**
-     * Holds a photo {@link ValuesDelta} and {@link AccountType} information to draw
-     * an account type icon over it.
-     */
-    public static final class Photo implements Parcelable {
-
-        public static final Creator<Photo> CREATOR = new Creator<Photo>() {
-
-            public Photo createFromParcel(Parcel in) {
-                return new Photo(in);
-            }
-
-            public Photo[] newArray(int size) {
-                return new Photo[size];
-            }
-        };
-
-        public Photo() {
-        }
-
-        private Photo(Parcel source) {
-            readFromParcel(source);
-        }
-
-        // From AccountType, everything we need to display the account type icon
-        public int titleRes;
-        public int iconRes;
-        public String syncAdapterPackageName;
-
-        public String contentDescription;
-        public String contentDescriptionChecked; // Talkback announcement when the photo is checked
-        public String accountType;
-        public String accountName;
-
-        public ValuesDelta valuesDelta;
-
-        /**
-         * Whether the photo is being displayed for the aggregate contact.
-         * This may be because it is marked super primary or it is the one quick contacts picked
-         * randomly to display because none is marked super primary.
-         */
-        public boolean primary;
-
-        /**
-         * Pointer back to the KindSectionDataList this photo came from.
-         * See {@link CompactRawContactsEditorView#getPhotos}
-         * See {@link CompactRawContactsEditorView#setPrimaryPhoto}
-         */
-        public int kindSectionDataListIndex = -1;
-        public int valuesDeltaListIndex = -1;
-
-        /** Newly taken or selected photo that has not yet been saved to CP2. */
-        public Uri updatedPhotoUri;
-
-        public long photoId;
-
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        @Override
-        public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(titleRes);
-            dest.writeInt(iconRes);
-            dest.writeString(syncAdapterPackageName);
-            dest.writeParcelable(valuesDelta, flags);
-            dest.writeInt(primary ? 1 : 0);
-            dest.writeInt(kindSectionDataListIndex);
-            dest.writeInt(valuesDeltaListIndex);
-            dest.writeParcelable(updatedPhotoUri, flags);
-            dest.writeLong(photoId);
-        }
-
-        private void readFromParcel(Parcel source) {
-            final ClassLoader classLoader = getClass().getClassLoader();
-            titleRes = source.readInt();
-            iconRes = source.readInt();
-            syncAdapterPackageName = source.readString();
-            valuesDelta = source.readParcelable(classLoader);
-            primary = source.readInt() == 1;
-            kindSectionDataListIndex = source.readInt();
-            valuesDeltaListIndex = source.readInt();
-            updatedPhotoUri = source.readParcelable(classLoader);
-            photoId = source.readLong();
-        }
-    }
-
-    private final class PhotoAdapter extends BaseAdapter {
-
-        private final Context mContext;
-        private final LayoutInflater mLayoutInflater;
-
-        public PhotoAdapter() {
-            mContext = getContext();
-            mLayoutInflater = LayoutInflater.from(mContext);
-        }
-
-        @Override
-        public int getCount() {
-            return mPhotos == null ? 2 : mPhotos.size() + 2;
-        }
-
-        @Override
-        public Object getItem(int index) {
-            return mPhotos == null ? null : mPhotos.get(index);
-        }
-
-        @Override
-        public long getItemId(int index) {
-            return index;
-        }
-
-        @Override
-        public int getItemViewType(int index) {
-            if (index == 0) {
-                return VIEW_TYPE_TAKE_PHOTO;
-            } else if (index == 1) {
-                return VIEW_TYPE_ALL_PHOTOS;
-            } else {
-                return VIEW_TYPE_IMAGE;
-            }
-        }
-
-        @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            if (mPhotos == null) return null;
-
-            // when position is 0 or 1, we should make sure account_type *is not* in convertView
-            // before reusing it.
-            if (getItemViewType(position) == 0){
-                if (convertView == null || convertView.findViewById(R.id.account_type) != null) {
-                    return mLayoutInflater.inflate(R.layout.take_a_photo_button, /* root =*/ null);
-                }
-                return convertView;
-            }
-
-            if (getItemViewType(position) == 1) {
-                if (convertView == null || convertView.findViewById(R.id.account_type) != null) {
-                    return mLayoutInflater.inflate(R.layout.all_photos_button, /* root =*/ null);
-                }
-                return convertView;
-            }
-
-            // when position greater than 1, we should make sure account_type *is* in convertView
-            // before reusing it.
-            position -= 2;
-
-            final View photoItemView;
-            if (convertView == null || convertView.findViewById(R.id.account_type) == null) {
-                photoItemView = mLayoutInflater.inflate(
-                        R.layout.compact_photo_selection_item, /* root =*/ null);
-            } else {
-                photoItemView = convertView;
-            }
-
-            final Photo photo = mPhotos.get(position);
-
-            // Bind the photo
-            final ImageView imageView = (ImageView) photoItemView.findViewById(R.id.image);
-            if (photo.updatedPhotoUri != null) {
-                EditorUiUtils.loadPhoto(ContactPhotoManager.getInstance(mContext),
-                        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(mContext),
-                            imageView, photoUri);
-                } else {
-                    imageView.setImageBitmap(EditorUiUtils.getPhotoBitmap(photo.valuesDelta));
-                }
-            }
-
-            // Add the account type icon
-            final ImageView accountTypeImageView = (ImageView)
-                    photoItemView.findViewById(R.id.account_type);
-            accountTypeImageView.setImageDrawable(AccountType.getDisplayIcon(
-                    mContext, photo.titleRes, photo.iconRes, photo.syncAdapterPackageName));
-
-            // Display a check icon over the primary photo
-            final ImageView checkImageView = (ImageView) photoItemView.findViewById(R.id.check);
-            checkImageView.setVisibility(photo.primary ? View.VISIBLE : View.GONE);
-
-            photoItemView.setContentDescription(photo.contentDescription);
-
-            return photoItemView;
-        }
-    }
-
-    private ArrayList<Photo> mPhotos;
-    private int mPhotoMode;
-    private Listener mListener;
-    private GridView mGridView;
-
-    public void setListener(Listener listener) {
-        mListener = listener;
-    }
-
-    public void setPhotos(ArrayList<Photo> photos, int photoMode) {
-        mPhotos = photos;
-        mPhotoMode = photoMode;
-        mGridView.setAccessibilityDelegate(new View.AccessibilityDelegate() {});
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        if (savedInstanceState != null) {
-            mPhotos = savedInstanceState.getParcelableArrayList(STATE_PHOTOS);
-            mPhotoMode = savedInstanceState.getInt(STATE_PHOTO_MODE, 0);
-        }
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
-        setHasOptionsMenu(true);
-
-        final PhotoAdapter photoAdapter = new PhotoAdapter();
-
-        final View view = inflater.inflate(R.layout.compact_photo_selection_fragment,
-                container, false);
-        mGridView = (GridView) view.findViewById(R.id.grid_view);
-        mGridView.setAdapter(photoAdapter);
-        mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
-            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-                final PhotoSourceDialogFragment.Listener listener =
-                        (PhotoSourceDialogFragment.Listener) getActivity();
-                if (position == 0) {
-                    listener.onTakePhotoChosen();
-                } else if (position == 1) {
-                    listener.onPickFromGalleryChosen();
-                } else {
-                    // Call the host back so it can set the new photo as primary
-                    final Photo photo = (Photo) photoAdapter.getItem(position - 2);
-                    if (mListener != null) {
-                        mListener.onPhotoSelected(photo);
-                    }
-                    handleAccessibility(photo, position);
-                }
-            }
-        });
-
-        final Display display = getActivity().getWindowManager().getDefaultDisplay();
-        final DisplayMetrics outMetrics = new DisplayMetrics ();
-        display.getRealMetrics(outMetrics); // real metrics include the navigation Bar
-
-        final float numColumns = outMetrics.widthPixels /
-                getResources().getDimension(R.dimen.photo_picker_item_ideal_width);
-        mGridView.setNumColumns(Math.round(numColumns));
-
-        return view;
-    }
-
-    private void handleAccessibility(Photo photo, int position) {
-        // Use custom AccessibilityDelegate when closing this fragment to suppress event.
-        mGridView.setAccessibilityDelegate(new View.AccessibilityDelegate() {
-            @Override
-            public boolean onRequestSendAccessibilityEvent(
-                    ViewGroup host, View child,AccessibilityEvent event) {
-                if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED) {
-                    return false;
-                }
-                return super.onRequestSendAccessibilityEvent(host, child, event);
-            }
-        });
-        final ViewGroup clickedView = (ViewGroup) mGridView.getChildAt(position);
-        clickedView.announceForAccessibility(photo.contentDescriptionChecked);
-    }
-
-    @Override
-    public void onSaveInstanceState(Bundle outState) {
-        outState.putParcelableArrayList(STATE_PHOTOS, mPhotos);
-        outState.putInt(STATE_PHOTO_MODE, mPhotoMode);
-        super.onSaveInstanceState(outState);
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            case android.R.id.home:
-                getActivity().onBackPressed();
-                return true;
-            default:
-                return super.onOptionsItemSelected(item);
-        }
-    }
-
-    @Override
-    public Context getContext() {
-        return getActivity();
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/contacts/editor/CompactRawContactsEditorView.java b/src/com/android/contacts/editor/CompactRawContactsEditorView.java
index e09960a..dd7d587 100644
--- a/src/com/android/contacts/editor/CompactRawContactsEditorView.java
+++ b/src/com/android/contacts/editor/CompactRawContactsEditorView.java
@@ -21,7 +21,6 @@
 import android.database.Cursor;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
-import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.provider.ContactsContract.CommonDataKinds.Email;
@@ -126,12 +125,6 @@
          * Invoked when a rawcontact from linked contacts is selected in editor.
          */
         void onRawContactSelected(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();
     }
 
     /**
@@ -280,14 +273,12 @@
 
     private ViewIdGenerator mViewIdGenerator;
     private MaterialColorMapUtils.MaterialPalette mMaterialPalette;
-    private long mAggregatePhotoId = -1;
     private boolean mHasNewContact;
     private boolean mIsUserProfile;
     private AccountWithDataSet mPrimaryAccount;
     private RawContactDeltaList mRawContactDeltas;
     private RawContactDelta mCurrentRawContactDelta;
     private long mRawContactIdToDisplayAlone = -1;
-    private boolean mRawContactDisplayAloneIsReadOnly;
     private boolean mIsEditingReadOnlyRawContactWithNewContact;
     private Map<String, KindSectionData> mKindSectionDataMap = new HashMap<>();
     private Set<String> mSortedMimetypes = new TreeSet<>(new MimeTypeComparator());
@@ -299,10 +290,6 @@
     private ImageView mAccountHeaderIcon;
     private ImageView mAccountHeaderExpanderIcon;
 
-    // Raw contacts selector
-    private View mRawContactContainer;
-    private TextView mRawContactSummary;
-
     private CompactPhotoEditorView mPhotoView;
     private ViewGroup mKindSectionViews;
     private Map<String, CompactKindSectionView> mKindSectionViewMap = new HashMap<>();
@@ -310,7 +297,6 @@
 
     private boolean mIsExpanded;
 
-    private long mPhotoRawContactId;
     private ValuesDelta mPhotoValuesDelta;
 
     public CompactRawContactsEditorView(Context context) {
@@ -344,10 +330,6 @@
         mAccountHeaderIcon = (ImageView) findViewById(R.id.account_type_icon);
         mAccountHeaderExpanderIcon = (ImageView) findViewById(R.id.account_expander_icon);
 
-        // Raw contacts selector
-        mRawContactContainer = findViewById(R.id.all_rawcontacts_accounts_container);
-        mRawContactSummary = (TextView) findViewById(R.id.rawcontacts_accounts_summary);
-
         mPhotoView = (CompactPhotoEditorView) findViewById(R.id.photo_editor);
         mKindSectionViews = (LinearLayout) findViewById(R.id.kind_section_views);
         mMoreFields = findViewById(R.id.more_fields);
@@ -402,6 +384,7 @@
     public void removePhoto() {
         mPhotoValuesDelta.setFromTemplate(true);
         mPhotoValuesDelta.put(Photo.PHOTO, (byte[]) null);
+        mPhotoValuesDelta.put(Photo.PHOTO_FILE_ID, (String) null);
 
         mPhotoView.removePhoto();
     }
@@ -467,7 +450,7 @@
      * Get the raw contact ID for the CompactHeaderView photo.
      */
     public long getPhotoRawContactId() {
-        return mPhotoRawContactId;
+        return mCurrentRawContactDelta.getRawContactId();
     }
 
     public StructuredNameEditorView getPrimaryNameEditorView() {
@@ -478,20 +461,20 @@
 
 
     /**
-     * Marks the raw contact photo given as primary for the aggregate contact and updates the
-     * UI.
+     * Marks the raw contact photo given as primary for the aggregate contact.
      */
-    public void setPrimaryPhoto(CompactPhotoSelectionFragment.Photo photo) {
+    public void setPrimaryPhoto() {
 
         // Update values delta
         final ValuesDelta valuesDelta = mCurrentRawContactDelta
                 .getSuperPrimaryEntry(Photo.CONTENT_ITEM_TYPE);
+        if (valuesDelta == null) {
+            Log.wtf(TAG, "setPrimaryPhoto: had no ValuesDelta for the current RawContactDelta");
+            return;
+        }
         valuesDelta.setFromTemplate(false);
         unsetSuperPrimaryFromAllPhotos();
         valuesDelta.setSuperPrimary(true);
-
-        // Update the UI
-        mPhotoView.setPhoto(valuesDelta, mMaterialPalette);
     }
 
     public View getAggregationAnchorView() {
@@ -514,14 +497,11 @@
 
     public void setState(RawContactDeltaList rawContactDeltas,
             MaterialColorMapUtils.MaterialPalette materialPalette, ViewIdGenerator viewIdGenerator,
-            long photoId, boolean hasNewContact, boolean isUserProfile,
-            AccountWithDataSet primaryAccount, long rawContactIdToDisplayAlone,
-            boolean rawContactDisplayAloneIsReadOnly,
-            boolean isEditingReadOnlyRawContactWithNewContact) {
+            boolean hasNewContact, boolean isUserProfile, AccountWithDataSet primaryAccount,
+            long rawContactIdToDisplayAlone, boolean isEditingReadOnlyRawContactWithNewContact) {
 
         mRawContactDeltas = rawContactDeltas;
         mRawContactIdToDisplayAlone = rawContactIdToDisplayAlone;
-        mRawContactDisplayAloneIsReadOnly = rawContactDisplayAloneIsReadOnly;
         mIsEditingReadOnlyRawContactWithNewContact = isEditingReadOnlyRawContactWithNewContact;
 
         mKindSectionViewMap.clear();
@@ -530,7 +510,6 @@
 
         mMaterialPalette = materialPalette;
         mViewIdGenerator = viewIdGenerator;
-        mAggregatePhotoId = photoId;
 
         mHasNewContact = hasNewContact;
         mIsUserProfile = isUserProfile;
@@ -785,7 +764,6 @@
 
     private void addAccountInfo() {
         mAccountHeaderContainer.setVisibility(View.GONE);
-        mRawContactContainer.setVisibility(View.GONE);
 
         final AccountDisplayInfo account =
                 mAccountDisplayInfoFactory.getAccountDisplayInfoFor(mCurrentRawContactDelta);
@@ -805,16 +783,16 @@
             } else {
                 addAccountHeader(accountLabel);
             }
-        } else if (mIsUserProfile || !shouldHideAccountContainer(mRawContactDeltas)) {
-            addAccountHeader(accountLabel);
-        }
-
-        // The raw contact selector should only display linked raw contacts that can be edited in
-        // the full editor (i.e. they are not newly created raw contacts)
-        final RawContactAccountListAdapter adapter =  new RawContactAccountListAdapter(getContext(),
-                getRawContactDeltaListForSelector(mRawContactDeltas));
-        if (adapter.getCount() > 0 && !mIsEditingReadOnlyRawContactWithNewContact) {
-            addRawContactAccountSelector(accountLabel, adapter);
+        } else {
+            // The raw contact selector should only display linked raw contacts that can be edited
+            // in the full editor (i.e. they are not newly created raw contacts)
+            final RawContactAccountListAdapter adapter =  new RawContactAccountListAdapter(
+                    getContext(), getRawContactDeltaListForSelector(mRawContactDeltas));
+            if (adapter.getCount() > 0 && !mIsEditingReadOnlyRawContactWithNewContact) {
+                addRawContactAccountSelector(accountLabel, adapter);
+            } else {
+                addAccountHeader(accountLabel);
+            }
         }
     }
 
@@ -841,23 +819,6 @@
         return result;
     }
 
-    // Returns true if there are multiple writable rawcontacts and no read-only ones,
-    // or there are both writable and read-only rawcontacts.
-    private boolean shouldHideAccountContainer(RawContactDeltaList rawContactDeltas) {
-        int writable = 0;
-        int readonly = 0;
-        for (RawContactDelta rawContactDelta : rawContactDeltas) {
-            if (rawContactDelta.isVisible() && rawContactDelta.getRawContactId() > 0) {
-                if (rawContactDelta.getRawContactAccountType(getContext()).areContactsWritable()) {
-                    writable++;
-                } else {
-                    readonly++;
-                }
-            }
-        }
-        return (writable > 1 || (writable > 0 && readonly > 0));
-    }
-
     private void addAccountHeader(String accountLabel) {
         mAccountHeaderContainer.setVisibility(View.VISIBLE);
 
@@ -965,23 +926,29 @@
     private void addPhotoView() {
         if (!mCurrentRawContactDelta.hasMimeEntries(Photo.CONTENT_ITEM_TYPE)) {
             wlog("No photo mimetype for this raw contact.");
-            mPhotoView.setVisibility(View.GONE);
+            mPhotoView.setVisibility(GONE);
             return;
         } else {
-            mPhotoView.setVisibility(View.VISIBLE);
+            mPhotoView.setVisibility(VISIBLE);
         }
 
         final ValuesDelta superPrimaryDelta = mCurrentRawContactDelta
                 .getSuperPrimaryEntry(Photo.CONTENT_ITEM_TYPE);
+        if (superPrimaryDelta == null) {
+            Log.wtf(TAG, "addPhotoView: no ValueDelta found for current RawContactDelta"
+                    + "that supports a photo.");
+            mPhotoView.setVisibility(GONE);
+            return;
+        }
         // Set the photo view
-        mPhotoView.setPhoto(superPrimaryDelta, mMaterialPalette);
+        mPhotoView.setPalette(mMaterialPalette);
+        mPhotoView.setPhoto(superPrimaryDelta);
 
         if (isReadOnlyRawContact()) {
             mPhotoView.setReadOnly(true);
             return;
         }
         mPhotoView.setReadOnly(false);
-        mPhotoRawContactId = mCurrentRawContactDelta.getRawContactId();
         mPhotoValuesDelta = superPrimaryDelta;
     }
 
diff --git a/src/com/android/contacts/quickcontact/QuickContactActivity.java b/src/com/android/contacts/quickcontact/QuickContactActivity.java
index 7c60b70..15f29a6 100644
--- a/src/com/android/contacts/quickcontact/QuickContactActivity.java
+++ b/src/com/android/contacts/quickcontact/QuickContactActivity.java
@@ -1615,7 +1615,7 @@
                 mScroller);
 
         if (contactCardEntries.size() == 0 && aboutCardEntries.size() == 0) {
-            initializeNoContactDetailCard();
+            initializeNoContactDetailCard(cp2DataCardModel.areAllRawContactsSimAccounts);
         } else {
             mNoContactDetailsCard.setVisibility(View.GONE);
         }
@@ -1636,8 +1636,9 @@
 
     /**
      * Create a card that shows "Add email" and "Add phone number" entries in grey.
+     * When contact is a SIM contact, only shows "Add phone number".
      */
-    private void initializeNoContactDetailCard() {
+    private void initializeNoContactDetailCard(boolean areAllRawContactsSimAccounts) {
         final Drawable phoneIcon = getResources().getDrawable(
                 R.drawable.ic_phone_24dp).mutate();
         final Entry phonePromptEntry = new Entry(CARD_ENTRY_ID_EDIT_CONTACT,
@@ -1654,25 +1655,28 @@
                 /* thirdExtras = */ null,
                 R.drawable.ic_phone_24dp);
 
-        final Drawable emailIcon = getResources().getDrawable(
-                R.drawable.ic_email_24dp).mutate();
-        final Entry emailPromptEntry = new Entry(CARD_ENTRY_ID_EDIT_CONTACT,
-                emailIcon, getString(R.string.quickcontact_add_email), /* subHeader = */ null,
-                /* subHeaderIcon = */ null,
-                /* text = */ null, /* textIcon = */ null, /* primaryContentDescription = */ null,
-                getEditContactIntent(), /* alternateIcon = */ null,
-                /* alternateIntent = */ null, /* alternateContentDescription = */ null,
-                /* shouldApplyColor = */ true, /* isEditable = */ false,
-                /* EntryContextMenuInfo = */ null, /* thirdIcon = */ null,
-                /* thirdIntent = */ null, /* thirdContentDescription = */ null,
-                /* thirdAction = */ Entry.ACTION_NONE, /* thirdExtras = */ null,
-                R.drawable.ic_email_24dp);
-
         final List<List<Entry>> promptEntries = new ArrayList<>();
         promptEntries.add(new ArrayList<Entry>(1));
-        promptEntries.add(new ArrayList<Entry>(1));
         promptEntries.get(0).add(phonePromptEntry);
-        promptEntries.get(1).add(emailPromptEntry);
+
+        if (!areAllRawContactsSimAccounts) {
+            final Drawable emailIcon = getResources().getDrawable(
+                    R.drawable.ic_email_24dp).mutate();
+            final Entry emailPromptEntry = new Entry(CARD_ENTRY_ID_EDIT_CONTACT,
+                    emailIcon, getString(R.string.quickcontact_add_email), /* subHeader = */ null,
+                    /* subHeaderIcon = */ null,
+                    /* text = */ null, /* textIcon = */ null, /* primaryContentDescription = */ null,
+                    getEditContactIntent(), /* alternateIcon = */ null,
+                    /* alternateIntent = */ null, /* alternateContentDescription = */ null,
+                    /* shouldApplyColor = */ true, /* isEditable = */ false,
+                    /* EntryContextMenuInfo = */ null, /* thirdIcon = */ null,
+                    /* thirdIntent = */ null, /* thirdContentDescription = */ null,
+                    /* thirdAction = */ Entry.ACTION_NONE, /* thirdExtras = */ null,
+                    R.drawable.ic_email_24dp);
+
+            promptEntries.add(new ArrayList<Entry>(1));
+            promptEntries.get(1).add(emailPromptEntry);
+        }
 
         final int subHeaderTextColor = getResources().getColor(
                 R.color.quickcontact_entry_sub_header_text_color);
@@ -1783,6 +1787,7 @@
         dataModel.aboutCardEntries = aboutCardEntries;
         dataModel.contactCardEntries = contactCardEntries;
         dataModel.dataItemsMap = dataItemsMap;
+        dataModel.areAllRawContactsSimAccounts = data.areAllRawContactsSimAccounts(this);
         return dataModel;
     }
 
@@ -1799,6 +1804,7 @@
         public List<List<Entry>> aboutCardEntries;
         public List<List<Entry>> contactCardEntries;
         public String customAboutCardName;
+        public boolean areAllRawContactsSimAccounts;
     }
 
     private static class MutableString {
diff --git a/tests/src/com/android/contacts/common/preference/ContactsPreferencesTest.java b/tests/src/com/android/contacts/common/preference/ContactsPreferencesTest.java
index 4b5c300..a841902 100644
--- a/tests/src/com/android/contacts/common/preference/ContactsPreferencesTest.java
+++ b/tests/src/com/android/contacts/common/preference/ContactsPreferencesTest.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.content.res.Resources;
+import android.support.test.InstrumentationRegistry;
 import android.test.InstrumentationTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
@@ -59,7 +60,12 @@
         Mockito.when(mSharedPreferences.contains(ContactsPreferences.DISPLAY_ORDER_KEY))
                 .thenReturn(true);
 
-        mContactsPreferences = new ContactsPreferences(mContext);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                mContactsPreferences = new ContactsPreferences(mContext);
+            }
+        });
     }
 
     public void testGetSortOrderDefault() {