Merge "Fix bug for exchange account editor." into ub-contactsdialer-a-dev
diff --git a/src/com/android/contacts/editor/CompactKindSectionView.java b/src/com/android/contacts/editor/CompactKindSectionView.java
index 8962de1..c1e659f 100644
--- a/src/com/android/contacts/editor/CompactKindSectionView.java
+++ b/src/com/android/contacts/editor/CompactKindSectionView.java
@@ -330,7 +330,7 @@
                 } else {
                     editorListener = new NonNameEditorListener();
                 }
-                for (ValuesDelta valuesDelta : kindSectionData.getValuesDeltas()) {
+                for (ValuesDelta valuesDelta : kindSectionData.getVisibleValuesDeltas()) {
                     addNonNameEditorView(kindSectionData.getRawContactDelta(),
                             kindSectionData.getDataKind(), valuesDelta, editorListener);
                 }
diff --git a/src/com/android/contacts/editor/CompactRawContactsEditorView.java b/src/com/android/contacts/editor/CompactRawContactsEditorView.java
index d4d991b..b5f46f7 100644
--- a/src/com/android/contacts/editor/CompactRawContactsEditorView.java
+++ b/src/com/android/contacts/editor/CompactRawContactsEditorView.java
@@ -464,7 +464,7 @@
     public void updatePhoto(Uri photoUri) {
         mPhotoValuesDelta.setFromTemplate(false);
         // Unset primary for all photos
-        unsetSuperPrimary();
+        unsetSuperPrimaryFromAllWritablePhotos();
         // Mark the currently displayed photo as primary
         mPhotoValuesDelta.setSuperPrimary(true);
 
@@ -487,13 +487,14 @@
         mPhotoView.setFullSizedPhoto(photoUri);
     }
 
-    private void unsetSuperPrimary() {
+    private void unsetSuperPrimaryFromAllWritablePhotos() {
         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);
+            if (kindSectionData.getAccountType().areContactsWritable()) {
+                for (ValuesDelta valuesDelta : kindSectionData.getNonEmptyValuesDeltas()) {
+                    valuesDelta.setSuperPrimary(false);
+                }
             }
         }
     }
@@ -532,10 +533,10 @@
         for (int i = 0; i < kindSectionDataList.size(); i++) {
             final KindSectionData kindSectionData = kindSectionDataList.get(i);
             final AccountType accountType = kindSectionData.getAccountType();
-            final List<ValuesDelta> valuesDeltaList = kindSectionData.getValuesDeltas();
-            if (valuesDeltaList == null || valuesDeltaList.isEmpty()) continue;
-            for (int j = 0; j < valuesDeltaList.size(); j++) {
-                final ValuesDelta valuesDelta = valuesDeltaList.get(j);
+            final List<ValuesDelta> valuesDeltas = kindSectionData.getNonEmptyValuesDeltas();
+            if (valuesDeltas.isEmpty()) continue;
+            for (int j = 0; j < valuesDeltas.size(); j++) {
+                final ValuesDelta valuesDelta = valuesDeltas.get(j);
                 final Bitmap bitmap = EditorUiUtils.getPhotoBitmap(valuesDelta);
                 if (bitmap == null) continue;
 
@@ -578,7 +579,7 @@
         }
         final KindSectionData kindSectionData =
                 kindSectionDataList.get(photo.kindSectionDataListIndex);
-        final List<ValuesDelta> valuesDeltaList = kindSectionData.getValuesDeltas();
+        final List<ValuesDelta> valuesDeltaList = kindSectionData.getNonEmptyValuesDeltas();
         if (photo.valuesDeltaListIndex >= valuesDeltaList.size()) {
             wlog("Invalid values delta list index");
             return;
@@ -586,7 +587,7 @@
         final ValuesDelta valuesDelta = valuesDeltaList.get(photo.valuesDeltaListIndex);
         valuesDelta.setFromTemplate(false);
         // Unset primary for all photos
-        unsetSuperPrimary();
+        unsetSuperPrimaryFromAllWritablePhotos();
         // Mark the currently displayed photo as primary
         valuesDelta.setSuperPrimary(true);
         // Update the UI
@@ -708,7 +709,10 @@
                 kindSectionDataList.add(kindSectionData);
 
                 vlog("parse: " + i + " " + dataKind.mimeType + " " +
-                        kindSectionData.getValuesDeltas().size() + " value(s)");
+                        kindSectionData.getValuesDeltas().size() + " value(s) " +
+                        kindSectionData.getNonEmptyValuesDeltas().size() + " non-empty value(s)" +
+                        kindSectionData.getVisibleValuesDeltas().size() +
+                        " visible value(s)");
             }
         }
     }
diff --git a/src/com/android/contacts/editor/KindSectionData.java b/src/com/android/contacts/editor/KindSectionData.java
index 8921099..bd9f687 100644
--- a/src/com/android/contacts/editor/KindSectionData.java
+++ b/src/com/android/contacts/editor/KindSectionData.java
@@ -22,11 +22,9 @@
 import com.android.contacts.common.model.account.AccountType.EditField;
 import com.android.contacts.common.model.dataitem.DataKind;
 
-import android.provider.ContactsContract.CommonDataKinds.Nickname;
-import android.provider.ContactsContract.CommonDataKinds.StructuredName;
-import android.provider.ContactsContract.CommonDataKinds.Event;
 import android.text.TextUtils;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -35,7 +33,6 @@
 public final class KindSectionData {
 
     private final AccountType mAccountType;
-    private final List<ValuesDelta> mValuesDeltas;
     private final DataKind mDataKind;
     private final RawContactDelta mRawContactDelta;
 
@@ -44,20 +41,44 @@
         mAccountType = accountType;
         mDataKind = dataKind;
         mRawContactDelta = rawContactDelta;
-        mValuesDeltas = mRawContactDelta.getMimeEntries(dataKind.mimeType, /* lazyCreate= */ true);
     }
 
     public AccountType getAccountType() {
         return mAccountType;
     }
 
+    /** Returns all ValuesDeltas for the data kind this section represents.*/
     public List<ValuesDelta> getValuesDeltas() {
-        return mValuesDeltas;
+        final List<ValuesDelta> valuesDeltas = mRawContactDelta.getMimeEntries(mDataKind.mimeType);
+        return valuesDeltas == null ? new ArrayList<ValuesDelta>() : valuesDeltas;
+    }
+
+    /** Returns visible and non no-op ValuesDeltas for the data kind this section represents. */
+    public List<ValuesDelta> getVisibleValuesDeltas() {
+        final ArrayList<ValuesDelta> valuesDeltas = new ArrayList<> ();
+        for (ValuesDelta valuesDelta : getValuesDeltas()) {
+            // Same conditions as KindSectionView#rebuildFromState
+            if (valuesDelta.isVisible() && !valuesDelta.isNoop()) {
+                valuesDeltas.add(valuesDelta);
+            }
+        }
+        return valuesDeltas;
+    }
+
+    /** Returns non-empty ValuesDeltas for the data kind this section represents. */
+    public List<ValuesDelta> getNonEmptyValuesDeltas() {
+        final ArrayList<ValuesDelta> valuesDeltas = new ArrayList<> ();
+        for (ValuesDelta valuesDelta : getValuesDeltas()) {
+            if (!isEmpty(valuesDelta)) {
+                valuesDeltas.add(valuesDelta);
+            }
+        }
+        return valuesDeltas;
     }
 
     /** Returns the super primary ValuesDelta for the data kind this section represents. */
     public ValuesDelta getSuperPrimaryValuesDelta() {
-        for (ValuesDelta valuesDelta : mValuesDeltas) {
+        for (ValuesDelta valuesDelta : getValuesDeltas()) {
             if (valuesDelta.isSuperPrimary()) return valuesDelta;
         }
         return null;
@@ -65,7 +86,7 @@
 
     /** Returns the ValuesDelta with the given ID. */
     public ValuesDelta getValuesDeltaById(Long id) {
-        for (ValuesDelta valuesDelta : mValuesDeltas) {
+        for (ValuesDelta valuesDelta : getValuesDeltas()) {
             if (valuesDelta.getId().equals(id)) return valuesDelta;
         }
         return null;
@@ -73,24 +94,21 @@
 
     /** Returns the first non empty ValuesDelta for the data kind this section represents. */
     public ValuesDelta getFirstNonEmptyValuesDelta() {
-        for (ValuesDelta valuesDelta : mValuesDeltas) {
+        for (ValuesDelta valuesDelta : getValuesDeltas()) {
             if (!isEmpty(valuesDelta)) return valuesDelta;
         }
         return null;
     }
 
-    /** Whether the given ValuesDelta is empty for the data kind this section represents. */
-    public boolean isEmpty(ValuesDelta valuesDelta) {
-        if (valuesDelta.isNoop()) return true;
-
+    private boolean isEmpty(ValuesDelta valuesDelta) {
         if (mDataKind.fieldList != null) {
             for (EditField editField : mDataKind.fieldList) {
                 final String column = editField.column;
                 final String value = valuesDelta.getAsString(column);
-                if (TextUtils.isEmpty(value)) return true;
+                if (!TextUtils.isEmpty(value)) return false;
             }
         }
-        return false;
+        return true;
     }
 
     public DataKind getDataKind() {
@@ -100,12 +118,4 @@
     public RawContactDelta getRawContactDelta() {
         return mRawContactDelta;
     }
-
-    public String toString() {
-        return String.format("%s<accountType=%s dataSet=%s values=%s>",
-                KindSectionData.class.getSimpleName(),
-                mAccountType.accountType,
-                mAccountType.dataSet,
-                getValuesDeltas().size());
-    }
-}
\ No newline at end of file
+}
diff --git a/src/com/android/contacts/editor/KindSectionDataList.java b/src/com/android/contacts/editor/KindSectionDataList.java
index 07c8158..cb82806 100644
--- a/src/com/android/contacts/editor/KindSectionDataList.java
+++ b/src/com/android/contacts/editor/KindSectionDataList.java
@@ -21,7 +21,6 @@
 import com.android.contacts.common.model.dataitem.DataKind;
 import com.android.contacts.common.model.RawContactModifier;
 
-import android.provider.ContactsContract;
 import android.util.Log;
 import android.util.Pair;
 
@@ -105,11 +104,12 @@
         // Just return the first writable entry.
         for (KindSectionData kindSectionData : this) {
             if (kindSectionData.getAccountType().areContactsWritable()) {
-                vlog(mimeType + ": falling back to first kind section data to write");
+                // Create an entry if necessary
                 RawContactModifier.ensureKindExists(kindSectionData.getRawContactDelta(),
                         kindSectionData.getAccountType(), mimeType);
-                if (kindSectionData.getValuesDeltas() != null &&
-                        !kindSectionData.getValuesDeltas().isEmpty()) {
+
+                if (!kindSectionData.getValuesDeltas().isEmpty()) {
+                    vlog(mimeType + ": falling back to first kind section data to write");
                     return new Pair<>(kindSectionData, kindSectionData.getValuesDeltas().get(0));
                 }
             }
@@ -164,7 +164,7 @@
 
         for (KindSectionData kindSectionData : this) {
             final List<ValuesDelta> valuesDeltaList = kindSectionData.getValuesDeltas();
-            if (valuesDeltaList != null && !valuesDeltaList.isEmpty()) {
+            if (!valuesDeltaList.isEmpty()) {
                 vlog(mimeType + ": falling back to first empty entry to display");
                 final ValuesDelta valuesDelta = valuesDeltaList.get(0);
                 return new Pair<>(kindSectionData, valuesDelta);
diff --git a/src/com/android/contacts/editor/TextFieldsEditorView.java b/src/com/android/contacts/editor/TextFieldsEditorView.java
index 8a6141d..98b46ef 100644
--- a/src/com/android/contacts/editor/TextFieldsEditorView.java
+++ b/src/com/android/contacts/editor/TextFieldsEditorView.java
@@ -260,8 +260,8 @@
                 fieldView.setText(value);
             }
 
-            // Show the delete button if we have a non-null value
-            setDeleteButtonVisible(value != null);
+            // Show the delete button if we have a non-empty value
+            setDeleteButtonVisible(!TextUtils.isEmpty(value));
 
             // Prepare listener for writing changes
             fieldView.addTextChangedListener(new TextWatcher() {