Update logic on when raw contact picker dialog is shown

Shouldn't be based on count of raw contacts, but whether writable
raw contacts exist.

Test:
Edit me profile that has 2 G+ accounts linked (where the me profile
has not already been created)
Edit an aggregate composed of 2 read-only accounts.
Edit aggregate of 1 write 1 read
Edit 1 read-only
Edit 1 write

Bug: 32289543
Bug: 31826229
Bug: 31088704
Change-Id: Ib01445b59fa9fc882a6d32d24f39917d726e6174
diff --git a/src/com/android/contacts/activities/ContactEditorSpringBoardActivity.java b/src/com/android/contacts/activities/ContactEditorSpringBoardActivity.java
index 7396bbd..5b71c48 100644
--- a/src/com/android/contacts/activities/ContactEditorSpringBoardActivity.java
+++ b/src/com/android/contacts/activities/ContactEditorSpringBoardActivity.java
@@ -39,6 +39,8 @@
     private Cursor mCursor;
     private MaterialPalette mMaterialPalette;
     private boolean mIsUserProfile;
+    private boolean mHasWritableAccount;
+    private int mWritableAccountPosition;
 
     /**
      * The contact data loader listener.
@@ -61,10 +63,11 @@
                     }
                     mCursor = cursor;
                     mIsUserProfile = ((PickRawContactLoader) loader).isUserProfile();
-                    if (mCursor.getCount() == 1) {
-                        loadEditor();
-                    } else {
+                    setHasWritableAccount();
+                    if (mCursor.getCount() > 1 && mHasWritableAccount) {
                         showDialog();
+                    } else {
+                        loadEditor();
                     }
                 }
 
@@ -142,17 +145,17 @@
     }
 
     /**
-     * Starts the editor for the first (only) raw contact in the cursor.
+     * Starts the editor for the only writable raw contact in the cursor if one exists. Otherwise,
+     * the editor is started normally and handles creation of a new writable raw contact.
      */
     private void loadEditor() {
         final Intent intent;
-        if (isSingleWritableAccount()) {
-            mCursor.moveToFirst();
+        if (mHasWritableAccount) {
+            mCursor.moveToPosition(mWritableAccountPosition);
             final long rawContactId = mCursor.getLong(PickRawContactLoader.RAW_CONTACT_ID);
             intent = getIntentForRawContact(rawContactId);
-
         } else {
-            // If it's a single read-only raw contact, we'll want to let the editor create
+            // If the contact has only read-only raw contacts, we'll want to let the editor create
             // the writable raw contact for it.
             intent = EditorIntents.createEditContactIntent(this, mUri, mMaterialPalette, -1);
             intent.setClass(this, ContactEditorActivity.class);
@@ -164,19 +167,21 @@
     }
 
     /**
-     * @return true if there is only one raw contact in the contact and it is from a writable
-     * account.
+     * Determines if this contact has a writable account.
      */
-    private boolean isSingleWritableAccount() {
-        if (mCursor.getCount() != 1) {
-            return false;
+    private void setHasWritableAccount() {
+        mCursor.moveToPosition(-1);
+        while (mCursor.moveToNext()) {
+            final String accountType = mCursor.getString(PickRawContactLoader.ACCOUNT_TYPE);
+            final String dataSet = mCursor.getString(PickRawContactLoader.DATA_SET);
+            final AccountType account = AccountTypeManager.getInstance(this)
+                    .getAccountType(accountType, dataSet);
+            if (account.areContactsWritable()) {
+                mHasWritableAccount = true;
+                mWritableAccountPosition = mCursor.getPosition();
+                return;
+            }
         }
-        mCursor.moveToFirst();
-        final String accountType = mCursor.getString(PickRawContactLoader.ACCOUNT_TYPE);
-        final String dataSet = mCursor.getString(PickRawContactLoader.DATA_SET);
-        final AccountType account = AccountTypeManager.getInstance(this)
-                .getAccountType(accountType, dataSet);
-        return account.areContactsWritable();
     }
 
     /**
diff --git a/src/com/android/contacts/editor/ContactEditorFragment.java b/src/com/android/contacts/editor/ContactEditorFragment.java
index e013da4..4c5d6ab 100644
--- a/src/com/android/contacts/editor/ContactEditorFragment.java
+++ b/src/com/android/contacts/editor/ContactEditorFragment.java
@@ -980,19 +980,11 @@
     }
 
     /**
-     * Whether the contact being edited spans multiple raw contacts.
-     * The may also span multiple accounts.
-     */
-    private boolean isEditingMultipleRawContacts() {
-        return mState.size() > 1;
-    }
-
-    /**
-     * Whether the contact being edited is composed of a single read-only raw contact
+     * Whether the contact being edited is composed of read-only raw contacts
      * aggregated with a newly created writable raw contact.
      */
     private boolean isEditingReadOnlyRawContactWithNewContact() {
-        return mHasNewContact && mState.size() == 2;
+        return mHasNewContact && mState.size() > 1;
     }
 
     /**
@@ -1015,19 +1007,6 @@
     }
 
     /**
-     * We allow unlinking only if there is more than one raw contact, it is not a user-profile,
-     * and unlinking won't result in an empty contact.  For the empty contact case, we only guard
-     * against this when there is a single read-only contact in the aggregate.  If the user
-     * has joined >1 read-only contacts together, we allow them to unlink it, even if they have
-     * never added their own information and unlinking will create a name only contact.
-     */
-    private boolean canUnlinkRawContacts() {
-        return isEditingMultipleRawContacts()
-                && !isEditingUserProfile()
-                && !isEditingReadOnlyRawContactWithNewContact();
-    }
-
-    /**
      * Determines if changes were made in the editor that need to be saved, while taking into
      * account that name changes are not real for read-only contacts.
      * See go/editing-read-only-contacts
@@ -1060,7 +1039,7 @@
      * name fields as the original.
      */
     private boolean structuredNamesAreEqual(ValuesDelta before, ValuesDelta after) {
-        if (before == null && after == null) return true;
+        if (before == after) return true;
         if (before == null || after == null) return false;
         final ContentValues original = before.getBefore();
         final ContentValues pending = after.getAfter();
@@ -1377,7 +1356,7 @@
         }
         editorView.setState(mState, getMaterialPalette(), mViewIdGenerator,
                 mHasNewContact, mIsUserProfile, mAccountWithDataSet,
-                mRawContactIdToDisplayAlone, isEditingReadOnlyRawContactWithNewContact());
+                mRawContactIdToDisplayAlone);
 
         // Set up the photo widget
         editorView.setPhotoListener(this);
diff --git a/src/com/android/contacts/editor/RawContactEditorView.java b/src/com/android/contacts/editor/RawContactEditorView.java
index 038a8de..1b37dab 100644
--- a/src/com/android/contacts/editor/RawContactEditorView.java
+++ b/src/com/android/contacts/editor/RawContactEditorView.java
@@ -206,7 +206,6 @@
     private RawContactDeltaList mRawContactDeltas;
     private RawContactDelta mCurrentRawContactDelta;
     private long mRawContactIdToDisplayAlone = -1;
-    private boolean mIsEditingReadOnlyRawContactWithNewContact;
     private Map<String, KindSectionData> mKindSectionDataMap = new HashMap<>();
     private Set<String> mSortedMimetypes = new TreeSet<>(new MimeTypeComparator());
 
@@ -429,11 +428,10 @@
     public void setState(RawContactDeltaList rawContactDeltas,
             MaterialColorMapUtils.MaterialPalette materialPalette, ViewIdGenerator viewIdGenerator,
             boolean hasNewContact, boolean isUserProfile, AccountWithDataSet primaryAccount,
-            long rawContactIdToDisplayAlone, boolean isEditingReadOnlyRawContactWithNewContact) {
+            long rawContactIdToDisplayAlone) {
 
         mRawContactDeltas = rawContactDeltas;
         mRawContactIdToDisplayAlone = rawContactIdToDisplayAlone;
-        mIsEditingReadOnlyRawContactWithNewContact = isEditingReadOnlyRawContactWithNewContact;
 
         mKindSectionViewMap.clear();
         mKindSectionViews.removeAllViews();