Split display name into first and last
Remove all support for directly entering the display
name.
Minor fix for getting focus after text editor expands.
Test:
Tested the following editor scenarios:
1) new contact
2) edit writable raw contact
3) edit read-only raw contact (joins a new writable raw contact to it)
a) Not editing the name and saving doesn't save the new writable
raw contact
b) making edits to the name and swapping accounts saves those edits
c) swapping around a lot doesn't create multiple writable raws
4) edit aggregate w/ 1 writable and 1 read-only raw contact
5) edit aggregate w/ 2 writable raw contacts
6) swapping accounts doesn't lose entered data
Bug: 21758689
Change-Id: I8d97083ae1e0db1031ee8e4d860f65d77022a1a1
diff --git a/src/com/android/contacts/common/model/RawContactDeltaList.java b/src/com/android/contacts/common/model/RawContactDeltaList.java
index 6964643..2f281ef 100644
--- a/src/com/android/contacts/common/model/RawContactDeltaList.java
+++ b/src/com/android/contacts/common/model/RawContactDeltaList.java
@@ -31,8 +31,6 @@
import android.util.Log;
import com.android.contacts.common.compat.CompatUtils;
-import com.android.contacts.common.model.CPOWrapper;
-import com.android.contacts.common.model.ValuesDelta;
import com.google.common.collect.Lists;
diff --git a/src/com/android/contacts/common/model/RawContactModifier.java b/src/com/android/contacts/common/model/RawContactModifier.java
index be5f8f2..ee9695a 100644
--- a/src/com/android/contacts/common/model/RawContactModifier.java
+++ b/src/com/android/contacts/common/model/RawContactModifier.java
@@ -988,8 +988,7 @@
for (DataKind kind : newAccountType.getSortedDataKinds()) {
if (!kind.editable) continue;
final String mimeType = kind.mimeType;
- if (DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME.equals(mimeType)
- || DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME.equals(mimeType)) {
+ if (DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME.equals(mimeType)) {
// Ignore pseudo data.
continue;
} else if (StructuredName.CONTENT_ITEM_TYPE.equals(mimeType)) {
@@ -1040,15 +1039,11 @@
return;
}
- boolean supportDisplayName = false;
boolean supportPhoneticFullName = false;
boolean supportPhoneticFamilyName = false;
boolean supportPhoneticMiddleName = false;
boolean supportPhoneticGivenName = false;
for (EditField editField : newDataKind.fieldList) {
- if (StructuredName.DISPLAY_NAME.equals(editField.column)) {
- supportDisplayName = true;
- }
if (DataKind.PSEUDO_COLUMN_PHONETIC_NAME.equals(editField.column)) {
supportPhoneticFullName = true;
}
@@ -1063,26 +1058,6 @@
}
}
- // DISPLAY_NAME <-> PREFIX, GIVEN_NAME, MIDDLE_NAME, FAMILY_NAME, SUFFIX
- final String displayName = values.getAsString(StructuredName.DISPLAY_NAME);
- if (!TextUtils.isEmpty(displayName)) {
- if (!supportDisplayName) {
- // Old data has a display name, while the new account doesn't allow it.
- NameConverter.displayNameToStructuredName(context, displayName, values);
-
- // We don't want to migrate unseen data which may confuse users after the creation.
- values.remove(StructuredName.DISPLAY_NAME);
- }
- } else {
- if (supportDisplayName) {
- // Old data does not have display name, while the new account requires it.
- values.put(StructuredName.DISPLAY_NAME,
- NameConverter.structuredNameToDisplayName(context, values));
- for (String field : NameConverter.STRUCTURED_NAME_FIELDS) {
- values.remove(field);
- }
- }
- }
// Phonetic (full) name <-> PHONETIC_FAMILY_NAME, PHONETIC_MIDDLE_NAME, PHONETIC_GIVEN_NAME
final String phoneticFullName = values.getAsString(DataKind.PSEUDO_COLUMN_PHONETIC_NAME);
diff --git a/src/com/android/contacts/common/model/ValuesDelta.java b/src/com/android/contacts/common/model/ValuesDelta.java
index 844ba36..d6e08a8 100644
--- a/src/com/android/contacts/common/model/ValuesDelta.java
+++ b/src/com/android/contacts/common/model/ValuesDelta.java
@@ -23,9 +23,11 @@
import android.os.Parcelable;
import android.provider.BaseColumns;
import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.text.TextUtils;
import com.android.contacts.common.compat.CompatUtils;
-import com.android.contacts.common.model.BuilderWrapper;
+
import com.google.common.collect.Sets;
import java.util.HashSet;
@@ -83,6 +85,10 @@
return mAfter;
}
+ public ContentValues getBefore() {
+ return mBefore;
+ }
+
public boolean containsKey(String key) {
return ((mAfter != null && mAfter.containsKey(key)) ||
(mBefore != null && mBefore.containsKey(key)));
diff --git a/src/com/android/contacts/common/model/account/BaseAccountType.java b/src/com/android/contacts/common/model/account/BaseAccountType.java
index 2f47c50..c57fa0e 100644
--- a/src/com/android/contacts/common/model/account/BaseAccountType.java
+++ b/src/com/android/contacts/common/model/account/BaseAccountType.java
@@ -148,72 +148,36 @@
}
protected DataKind addDataKindStructuredName(Context context) throws DefinitionException {
- DataKind kind = addKind(new DataKind(StructuredName.CONTENT_ITEM_TYPE,
+ final DataKind kind = addKind(new DataKind(StructuredName.CONTENT_ITEM_TYPE,
R.string.nameLabelsGroup, Weight.NONE, true));
kind.actionHeader = new SimpleInflater(R.string.nameLabelsGroup);
kind.actionBody = new SimpleInflater(Nickname.NAME);
kind.typeOverallMax = 1;
kind.fieldList = Lists.newArrayList();
- kind.fieldList.add(new EditField(StructuredName.DISPLAY_NAME,
- R.string.full_name, FLAGS_PERSON_NAME));
- kind.fieldList.add(new EditField(StructuredName.PREFIX, R.string.name_prefix,
- FLAGS_PERSON_NAME).setLongForm(true));
- kind.fieldList.add(new EditField(StructuredName.FAMILY_NAME, R.string.name_family,
- FLAGS_PERSON_NAME).setLongForm(true));
- kind.fieldList.add(new EditField(StructuredName.MIDDLE_NAME, R.string.name_middle,
- FLAGS_PERSON_NAME).setLongForm(true));
- kind.fieldList.add(new EditField(StructuredName.GIVEN_NAME, R.string.name_given,
- FLAGS_PERSON_NAME).setLongForm(true));
- kind.fieldList.add(new EditField(StructuredName.SUFFIX, R.string.name_suffix,
- FLAGS_PERSON_NAME).setLongForm(true));
- kind.fieldList.add(new EditField(StructuredName.PHONETIC_FAMILY_NAME,
- R.string.name_phonetic_family, FLAGS_PHONETIC));
- kind.fieldList.add(new EditField(StructuredName.PHONETIC_MIDDLE_NAME,
- R.string.name_phonetic_middle, FLAGS_PHONETIC));
- kind.fieldList.add(new EditField(StructuredName.PHONETIC_GIVEN_NAME,
- R.string.name_phonetic_given, FLAGS_PHONETIC));
-
- return kind;
- }
-
- protected DataKind addDataKindDisplayName(Context context) throws DefinitionException {
- DataKind kind = addKind(new DataKind(DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME,
- R.string.nameLabelsGroup, Weight.NONE, true));
- kind.actionHeader = new SimpleInflater(R.string.nameLabelsGroup);
- kind.actionBody = new SimpleInflater(Nickname.NAME);
- kind.typeOverallMax = 1;
-
- kind.fieldList = Lists.newArrayList();
- kind.fieldList.add(new EditField(StructuredName.DISPLAY_NAME,
- R.string.full_name, FLAGS_PERSON_NAME).setShortForm(true));
-
- boolean displayOrderPrimary =
+ final boolean displayOrderPrimary =
context.getResources().getBoolean(R.bool.config_editor_field_order_primary);
+ kind.fieldList.add(new EditField(StructuredName.PREFIX, R.string.name_prefix,
+ FLAGS_PERSON_NAME).setLongForm(true));
if (!displayOrderPrimary) {
- kind.fieldList.add(new EditField(StructuredName.PREFIX, R.string.name_prefix,
- FLAGS_PERSON_NAME).setLongForm(true));
kind.fieldList.add(new EditField(StructuredName.FAMILY_NAME, R.string.name_family,
- FLAGS_PERSON_NAME).setLongForm(true));
+ FLAGS_PERSON_NAME));
kind.fieldList.add(new EditField(StructuredName.MIDDLE_NAME, R.string.name_middle,
FLAGS_PERSON_NAME).setLongForm(true));
kind.fieldList.add(new EditField(StructuredName.GIVEN_NAME, R.string.name_given,
- FLAGS_PERSON_NAME).setLongForm(true));
- kind.fieldList.add(new EditField(StructuredName.SUFFIX, R.string.name_suffix,
- FLAGS_PERSON_NAME).setLongForm(true));
+ FLAGS_PERSON_NAME));
} else {
- kind.fieldList.add(new EditField(StructuredName.PREFIX, R.string.name_prefix,
- FLAGS_PERSON_NAME).setLongForm(true));
kind.fieldList.add(new EditField(StructuredName.GIVEN_NAME, R.string.name_given,
- FLAGS_PERSON_NAME).setLongForm(true));
+ FLAGS_PERSON_NAME));
kind.fieldList.add(new EditField(StructuredName.MIDDLE_NAME, R.string.name_middle,
FLAGS_PERSON_NAME).setLongForm(true));
kind.fieldList.add(new EditField(StructuredName.FAMILY_NAME, R.string.name_family,
- FLAGS_PERSON_NAME).setLongForm(true));
- kind.fieldList.add(new EditField(StructuredName.SUFFIX, R.string.name_suffix,
- FLAGS_PERSON_NAME).setLongForm(true));
+ FLAGS_PERSON_NAME));
}
+ kind.fieldList.add(new EditField(StructuredName.SUFFIX, R.string.name_suffix,
+ FLAGS_PERSON_NAME).setLongForm(true));
+
return kind;
}
@@ -891,15 +855,13 @@
AttributeSet attrs) throws DefinitionException, XmlPullParserException,
IOException {
- // Build 3 data kinds:
+ // Build 2 data kinds:
// - StructuredName.CONTENT_ITEM_TYPE
- // - DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME
// - DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME
final boolean displayOrderPrimary =
context.getResources().getBoolean(R.bool.config_editor_field_order_primary);
- final boolean supportsDisplayName = getAttr(attrs, "supportsDisplayName", false);
final boolean supportsPrefix = getAttr(attrs, "supportsPrefix", false);
final boolean supportsMiddleName = getAttr(attrs, "supportsMiddleName", false);
final boolean supportsSuffix = getAttr(attrs, "supportsSuffix", false);
@@ -911,7 +873,6 @@
getAttr(attrs, "supportsPhoneticGivenName", false);
// For now, every things must be supported.
- checkAttributeTrue(supportsDisplayName, "supportsDisplayName");
checkAttributeTrue(supportsPrefix, "supportsPrefix");
checkAttributeTrue(supportsMiddleName, "supportsMiddleName");
checkAttributeTrue(supportsSuffix, "supportsSuffix");
@@ -927,68 +888,28 @@
new SimpleInflater(R.string.nameLabelsGroup),
new SimpleInflater(Nickname.NAME));
- throwIfList(ks);
- kinds.add(ks);
-
- // Note about setLongForm/setShortForm below.
- // We need to set this only when the type supports display name. (=supportsDisplayName)
- // Otherwise (i.e. Exchange) we don't set these flags, but instead make some fields
- // "optional".
-
- ks.fieldList.add(new EditField(StructuredName.DISPLAY_NAME, R.string.full_name,
- FLAGS_PERSON_NAME));
ks.fieldList.add(new EditField(StructuredName.PREFIX, R.string.name_prefix,
FLAGS_PERSON_NAME).setLongForm(true));
- ks.fieldList.add(new EditField(StructuredName.FAMILY_NAME, R.string.name_family,
- FLAGS_PERSON_NAME).setLongForm(true));
- ks.fieldList.add(new EditField(StructuredName.MIDDLE_NAME, R.string.name_middle,
- FLAGS_PERSON_NAME).setLongForm(true));
- ks.fieldList.add(new EditField(StructuredName.GIVEN_NAME, R.string.name_given,
- FLAGS_PERSON_NAME).setLongForm(true));
+ if (!displayOrderPrimary) {
+ ks.fieldList.add(new EditField(StructuredName.FAMILY_NAME, R.string.name_family,
+ FLAGS_PERSON_NAME));
+ ks.fieldList.add(new EditField(StructuredName.MIDDLE_NAME, R.string.name_middle,
+ FLAGS_PERSON_NAME).setLongForm(true));
+ ks.fieldList.add(new EditField(StructuredName.GIVEN_NAME, R.string.name_given,
+ FLAGS_PERSON_NAME));
+ } else {
+ ks.fieldList.add(new EditField(StructuredName.GIVEN_NAME, R.string.name_given,
+ FLAGS_PERSON_NAME));
+ ks.fieldList.add(new EditField(StructuredName.MIDDLE_NAME, R.string.name_middle,
+ FLAGS_PERSON_NAME).setLongForm(true));
+ ks.fieldList.add(new EditField(StructuredName.FAMILY_NAME, R.string.name_family,
+ FLAGS_PERSON_NAME));
+ }
ks.fieldList.add(new EditField(StructuredName.SUFFIX, R.string.name_suffix,
FLAGS_PERSON_NAME).setLongForm(true));
- ks.fieldList.add(new EditField(StructuredName.PHONETIC_FAMILY_NAME,
- R.string.name_phonetic_family, FLAGS_PHONETIC));
- ks.fieldList.add(new EditField(StructuredName.PHONETIC_MIDDLE_NAME,
- R.string.name_phonetic_middle, FLAGS_PHONETIC));
- ks.fieldList.add(new EditField(StructuredName.PHONETIC_GIVEN_NAME,
- R.string.name_phonetic_given, FLAGS_PHONETIC));
- // Display name
- final DataKind kd = newDataKind(context, parser, attrs, true,
- DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME, null,
- R.string.nameLabelsGroup, Weight.NONE,
- new SimpleInflater(R.string.nameLabelsGroup),
- new SimpleInflater(Nickname.NAME));
- kd.typeOverallMax = 1;
- kinds.add(kd);
-
- kd.fieldList.add(new EditField(StructuredName.DISPLAY_NAME,
- R.string.full_name, FLAGS_PERSON_NAME).setShortForm(true));
-
- if (!displayOrderPrimary) {
- kd.fieldList.add(new EditField(StructuredName.PREFIX, R.string.name_prefix,
- FLAGS_PERSON_NAME).setLongForm(true));
- kd.fieldList.add(new EditField(StructuredName.FAMILY_NAME, R.string.name_family,
- FLAGS_PERSON_NAME).setLongForm(true));
- kd.fieldList.add(new EditField(StructuredName.MIDDLE_NAME, R.string.name_middle,
- FLAGS_PERSON_NAME).setLongForm(true));
- kd.fieldList.add(new EditField(StructuredName.GIVEN_NAME, R.string.name_given,
- FLAGS_PERSON_NAME).setLongForm(true));
- kd.fieldList.add(new EditField(StructuredName.SUFFIX, R.string.name_suffix,
- FLAGS_PERSON_NAME).setLongForm(true));
- } else {
- kd.fieldList.add(new EditField(StructuredName.PREFIX, R.string.name_prefix,
- FLAGS_PERSON_NAME).setLongForm(true));
- kd.fieldList.add(new EditField(StructuredName.GIVEN_NAME, R.string.name_given,
- FLAGS_PERSON_NAME).setLongForm(true));
- kd.fieldList.add(new EditField(StructuredName.MIDDLE_NAME, R.string.name_middle,
- FLAGS_PERSON_NAME).setLongForm(true));
- kd.fieldList.add(new EditField(StructuredName.FAMILY_NAME, R.string.name_family,
- FLAGS_PERSON_NAME).setLongForm(true));
- kd.fieldList.add(new EditField(StructuredName.SUFFIX, R.string.name_suffix,
- FLAGS_PERSON_NAME).setLongForm(true));
- }
+ throwIfList(ks);
+ kinds.add(ks);
// Phonetic name
final DataKind kp = newDataKind(context, parser, attrs, true,
diff --git a/src/com/android/contacts/common/model/account/ExchangeAccountType.java b/src/com/android/contacts/common/model/account/ExchangeAccountType.java
index 7020836..339564b 100644
--- a/src/com/android/contacts/common/model/account/ExchangeAccountType.java
+++ b/src/com/android/contacts/common/model/account/ExchangeAccountType.java
@@ -52,7 +52,6 @@
try {
addDataKindStructuredName(context);
- addDataKindDisplayName(context);
addDataKindPhoneticName(context);
addDataKindNickname(context);
addDataKindPhone(context);
@@ -107,39 +106,6 @@
}
@Override
- protected DataKind addDataKindDisplayName(Context context) throws DefinitionException {
- DataKind kind = addKind(new DataKind(DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME,
- R.string.nameLabelsGroup, Weight.NONE, true));
-
- boolean displayOrderPrimary =
- context.getResources().getBoolean(R.bool.config_editor_field_order_primary);
- kind.typeOverallMax = 1;
-
- kind.fieldList = Lists.newArrayList();
- kind.fieldList.add(new EditField(StructuredName.PREFIX, R.string.name_prefix,
- FLAGS_PERSON_NAME).setOptional(true));
- if (!displayOrderPrimary) {
- kind.fieldList.add(new EditField(StructuredName.FAMILY_NAME,
- R.string.name_family, FLAGS_PERSON_NAME));
- kind.fieldList.add(new EditField(StructuredName.MIDDLE_NAME,
- R.string.name_middle, FLAGS_PERSON_NAME).setOptional(true));
- kind.fieldList.add(new EditField(StructuredName.GIVEN_NAME,
- R.string.name_given, FLAGS_PERSON_NAME));
- } else {
- kind.fieldList.add(new EditField(StructuredName.GIVEN_NAME,
- R.string.name_given, FLAGS_PERSON_NAME));
- kind.fieldList.add(new EditField(StructuredName.MIDDLE_NAME,
- R.string.name_middle, FLAGS_PERSON_NAME).setOptional(true));
- kind.fieldList.add(new EditField(StructuredName.FAMILY_NAME,
- R.string.name_family, FLAGS_PERSON_NAME));
- }
- kind.fieldList.add(new EditField(StructuredName.SUFFIX,
- R.string.name_suffix, FLAGS_PERSON_NAME).setOptional(true));
-
- return kind;
- }
-
- @Override
protected DataKind addDataKindPhoneticName(Context context) throws DefinitionException {
DataKind kind = addKind(new DataKind(DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME,
R.string.name_phonetic, Weight.NONE, true));
diff --git a/src/com/android/contacts/common/model/account/ExternalAccountType.java b/src/com/android/contacts/common/model/account/ExternalAccountType.java
index 1d7fc3e..685322a 100644
--- a/src/com/android/contacts/common/model/account/ExternalAccountType.java
+++ b/src/com/android/contacts/common/model/account/ExternalAccountType.java
@@ -132,13 +132,11 @@
needLineNumberInErrorLog = false;
if (mHasEditSchema) {
checkKindExists(StructuredName.CONTENT_ITEM_TYPE);
- checkKindExists(DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME);
checkKindExists(DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME);
checkKindExists(Photo.CONTENT_ITEM_TYPE);
} else {
// Bring in name and photo from fallback source, which are non-optional
addDataKindStructuredName(context);
- addDataKindDisplayName(context);
addDataKindPhoneticName(context);
addDataKindPhoto(context);
}
diff --git a/src/com/android/contacts/common/model/account/FallbackAccountType.java b/src/com/android/contacts/common/model/account/FallbackAccountType.java
index 7c6d17c..5a75c8e 100644
--- a/src/com/android/contacts/common/model/account/FallbackAccountType.java
+++ b/src/com/android/contacts/common/model/account/FallbackAccountType.java
@@ -38,7 +38,6 @@
try {
addDataKindStructuredName(context);
- addDataKindDisplayName(context);
addDataKindPhoneticName(context);
addDataKindNickname(context);
addDataKindPhone(context);
diff --git a/src/com/android/contacts/common/model/account/GoogleAccountType.java b/src/com/android/contacts/common/model/account/GoogleAccountType.java
index 8c83b90..3cfb44a 100644
--- a/src/com/android/contacts/common/model/account/GoogleAccountType.java
+++ b/src/com/android/contacts/common/model/account/GoogleAccountType.java
@@ -53,7 +53,6 @@
try {
addDataKindStructuredName(context);
- addDataKindDisplayName(context);
addDataKindPhoneticName(context);
addDataKindNickname(context);
addDataKindPhone(context);
diff --git a/src/com/android/contacts/common/model/account/SamsungAccountType.java b/src/com/android/contacts/common/model/account/SamsungAccountType.java
index 85a9ab8..00f6687 100644
--- a/src/com/android/contacts/common/model/account/SamsungAccountType.java
+++ b/src/com/android/contacts/common/model/account/SamsungAccountType.java
@@ -54,7 +54,6 @@
try {
addDataKindStructuredName(context);
- addDataKindDisplayName(context);
addDataKindPhoneticName(context);
addDataKindNickname(context);
addDataKindPhone(context);
diff --git a/src/com/android/contacts/common/model/account/SimAccountType.java b/src/com/android/contacts/common/model/account/SimAccountType.java
index 5d2e52d..e7d7ee2 100644
--- a/src/com/android/contacts/common/model/account/SimAccountType.java
+++ b/src/com/android/contacts/common/model/account/SimAccountType.java
@@ -17,10 +17,14 @@
import android.accounts.AuthenticatorDescription;
import android.content.Context;
+import android.provider.ContactsContract.CommonDataKinds.Nickname;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
-import com.android.contacts.R;
+import com.android.contacts.common.R;
import com.android.contacts.common.model.dataitem.DataKind;
+import com.google.common.collect.Lists;
+
import java.util.Collections;
/**
@@ -33,12 +37,7 @@
this.iconRes = R.drawable.ic_sim_card_tinted_24dp;
try {
- addDataKindDisplayName(context);
- // SIM cards probably don't natively support full structured name data (separate
- // first and last names) but restricting to just a single field in
- // StructuredNameEditorView will require more significant changes.
addDataKindStructuredName(context);
-
final DataKind phoneKind = addDataKindPhone(context);
phoneKind.typeOverallMax = 1;
// SIM card contacts don't necessarily support separate types (based on data exposed
@@ -67,4 +66,31 @@
public void initializeFieldsFromAuthenticator(AuthenticatorDescription authenticator) {
// Do nothing. We want to use our local icon and title
}
+
+ @Override
+ protected DataKind addDataKindStructuredName(Context context) throws DefinitionException {
+ final DataKind kind = addKind(new DataKind(StructuredName.CONTENT_ITEM_TYPE,
+ R.string.nameLabelsGroup, Weight.NONE, true));
+ kind.actionHeader = new SimpleInflater(R.string.nameLabelsGroup);
+ kind.actionBody = new SimpleInflater(Nickname.NAME);
+ kind.typeOverallMax = 1;
+
+ final boolean displayOrderPrimary =
+ context.getResources().getBoolean(R.bool.config_editor_field_order_primary);
+
+ kind.fieldList = Lists.newArrayList();
+ if (!displayOrderPrimary) {
+ kind.fieldList.add(new EditField(StructuredName.FAMILY_NAME, R.string.name_family,
+ FLAGS_PERSON_NAME));
+ kind.fieldList.add(new EditField(StructuredName.GIVEN_NAME, R.string.name_given,
+ FLAGS_PERSON_NAME));
+ } else {
+ kind.fieldList.add(new EditField(StructuredName.GIVEN_NAME, R.string.name_given,
+ FLAGS_PERSON_NAME));
+ kind.fieldList.add(new EditField(StructuredName.FAMILY_NAME, R.string.name_family,
+ FLAGS_PERSON_NAME));
+ }
+
+ return kind;
+ }
}
diff --git a/src/com/android/contacts/common/util/NameConverter.java b/src/com/android/contacts/common/util/NameConverter.java
index 9706353..227a0ec 100644
--- a/src/com/android/contacts/common/util/NameConverter.java
+++ b/src/com/android/contacts/common/util/NameConverter.java
@@ -27,9 +27,6 @@
import com.android.contacts.common.model.dataitem.StructuredNameDataItem;
-import java.util.Map;
-import java.util.TreeMap;
-
/**
* Utility class for converting between a display name and structured name (and vice-versa), via
* calls to the contact provider.
@@ -48,28 +45,6 @@
};
/**
- * Converts the given structured name (provided as a map from {@link StructuredName} fields to
- * corresponding values) into a display name string.
- * <p>
- * Note that this operates via a call back to the ContactProvider, but it does not access the
- * database, so it should be safe to call from the UI thread. See
- * ContactsProvider2.completeName() for the underlying method call.
- * @param context Activity context.
- * @param structuredName The structured name map to convert.
- * @return The display name computed from the structured name map.
- */
- public static String structuredNameToDisplayName(Context context,
- Map<String, String> structuredName) {
- Builder builder = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name");
- for (String key : STRUCTURED_NAME_FIELDS) {
- if (structuredName.containsKey(key)) {
- appendQueryParameter(builder, key, structuredName.get(key));
- }
- }
- return fetchDisplayName(context, builder.build());
- }
-
- /**
* Converts the given structured name (provided as ContentValues) into a display name string.
* @param context Activity context.
* @param values The content values containing values comprising the structured name.
@@ -106,70 +81,13 @@
return displayName;
}
- /**
- * Converts the given display name string into a structured name (as a map from
- * {@link StructuredName} fields to corresponding values).
- * <p>
- * Note that this operates via a call back to the ContactProvider, but it does not access the
- * database, so it should be safe to call from the UI thread.
- * @param context Activity context.
- * @param displayName The display name to convert.
- * @return The structured name map computed from the display name.
- */
- public static Map<String, String> displayNameToStructuredName(Context context,
- String displayName) {
- Map<String, String> structuredName = new TreeMap<String, String>();
- Builder builder = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name");
-
- appendQueryParameter(builder, StructuredName.DISPLAY_NAME, displayName);
- Cursor cursor = context.getContentResolver().query(builder.build(), STRUCTURED_NAME_FIELDS,
- null, null, null);
-
- if (cursor != null) {
- try {
- if (cursor.moveToFirst()) {
- for (int i = 0; i < STRUCTURED_NAME_FIELDS.length; i++) {
- structuredName.put(STRUCTURED_NAME_FIELDS[i], cursor.getString(i));
- }
- }
- } finally {
- cursor.close();
- }
- }
- return structuredName;
- }
-
- /**
- * Converts the given display name string into a structured name (inserting the structured
- * values into a new or existing ContentValues object).
- * <p>
- * Note that this operates via a call back to the ContactProvider, but it does not access the
- * database, so it should be safe to call from the UI thread.
- * @param context Activity context.
- * @param displayName The display name to convert.
- * @param contentValues The content values object to place the structured name values into. If
- * null, a new one will be created and returned.
- * @return The ContentValues object containing the structured name fields derived from the
- * display name.
- */
- public static ContentValues displayNameToStructuredName(Context context, String displayName,
- ContentValues contentValues) {
- if (contentValues == null) {
- contentValues = new ContentValues();
- }
- Map<String, String> mapValues = displayNameToStructuredName(context, displayName);
- for (String key : mapValues.keySet()) {
- contentValues.put(key, mapValues.get(key));
- }
- return contentValues;
- }
-
private static void appendQueryParameter(Builder builder, String field, String value) {
if (!TextUtils.isEmpty(value)) {
builder.appendQueryParameter(field, value);
}
}
+
/**
* Parses phonetic name and returns parsed data (family, middle, given) as ContentValues.
* Parsed data should be {@link StructuredName#PHONETIC_FAMILY_NAME},
diff --git a/src/com/android/contacts/editor/CompactContactEditorFragment.java b/src/com/android/contacts/editor/CompactContactEditorFragment.java
index 5ad2391..6a5edae 100644
--- a/src/com/android/contacts/editor/CompactContactEditorFragment.java
+++ b/src/com/android/contacts/editor/CompactContactEditorFragment.java
@@ -160,7 +160,8 @@
// Join Activity
private static final String KEY_CONTACT_ID_FOR_JOIN = "contactidforjoin";
- private static final String KEY_READ_ONLY_DISPLAY_NAME = "readOnlyDisplayName";
+ private static final String KEY_READ_ONLY_DISPLAY_NAME_ID = "readOnlyDisplayNameId";
+ private static final String KEY_COPY_READ_ONLY_DISPLAY_NAME = "copyReadOnlyDisplayName";
protected static final int REQUEST_CODE_JOIN = 0;
protected static final int REQUEST_CODE_ACCOUNTS_CHANGED = 1;
@@ -387,15 +388,8 @@
protected long mContactIdForJoin;
// Used to pre-populate the editor with a display name when a user edits a read-only contact.
- protected String mReadOnlyDisplayName;
-
- //
- // Not saved/restored on rotates
- //
-
- // The name editor view for the new raw contact that was created so that the user can
- // edit a read-only contact (to which the new raw contact was joined)
- protected StructuredNameEditorView mReadOnlyNameEditorView;
+ protected long mReadOnlyDisplayNameId;
+ protected boolean mCopyReadOnlyName;
/**
* The contact data loader listener.
@@ -535,7 +529,8 @@
// Join Activity
mContactIdForJoin = savedState.getLong(KEY_CONTACT_ID_FOR_JOIN);
- mReadOnlyDisplayName = savedState.getString(KEY_READ_ONLY_DISPLAY_NAME);
+ mReadOnlyDisplayNameId = savedState.getLong(KEY_READ_ONLY_DISPLAY_NAME_ID);
+ mCopyReadOnlyName = savedState.getBoolean(KEY_COPY_READ_ONLY_DISPLAY_NAME, false);
mPhotoRawContactId = savedState.getLong(KEY_PHOTO_RAW_CONTACT_ID);
mUpdatedPhotos = savedState.getParcelable(KEY_UPDATED_PHOTOS);
@@ -660,7 +655,8 @@
// Join Activity
outState.putLong(KEY_CONTACT_ID_FOR_JOIN, mContactIdForJoin);
- outState.putString(KEY_READ_ONLY_DISPLAY_NAME, mReadOnlyDisplayName);
+ outState.putLong(KEY_READ_ONLY_DISPLAY_NAME_ID, mReadOnlyDisplayNameId);
+ outState.putBoolean(KEY_COPY_READ_ONLY_DISPLAY_NAME, mCopyReadOnlyName);
outState.putLong(KEY_PHOTO_RAW_CONTACT_ID, mPhotoRawContactId);
outState.putParcelable(KEY_UPDATED_PHOTOS, mUpdatedPhotos);
@@ -1047,11 +1043,14 @@
* See go/editing-read-only-contacts
*/
private boolean hasPendingChanges() {
- if (mReadOnlyNameEditorView != null && mReadOnlyDisplayName != null) {
+ if (isEditingReadOnlyRawContactWithNewContact()) {
// We created a new raw contact delta with a default display name.
// We must test for pending changes while ignoring the default display name.
- final String displayName = mReadOnlyNameEditorView.getDisplayName();
- if (mReadOnlyDisplayName.equals(displayName)) {
+ final ValuesDelta beforeDelta = mState.getByRawContactId(mReadOnlyDisplayNameId)
+ .getSuperPrimaryEntry(StructuredName.CONTENT_ITEM_TYPE);
+ final ValuesDelta pendingDelta = mState
+ .getSuperPrimaryEntry(StructuredName.CONTENT_ITEM_TYPE);
+ if (structuredNamesAreEqual(beforeDelta, pendingDelta)) {
final Set<String> excludedMimeTypes = new HashSet<>();
excludedMimeTypes.add(StructuredName.CONTENT_ITEM_TYPE);
return hasPendingRawContactChanges(excludedMimeTypes);
@@ -1062,6 +1061,49 @@
}
/**
+ * Compares the two {@link ValuesDelta} to see if the structured name is changed. We made a copy
+ * of a read only delta and now we want to check if the copied delta has changes.
+ *
+ * @param before original {@link ValuesDelta}
+ * @param after copied {@link ValuesDelta}
+ * @return true if the copied {@link ValuesDelta} has all the same values in the structured
+ * name fields as the original.
+ */
+ private boolean structuredNamesAreEqual(ValuesDelta before, ValuesDelta after) {
+ if (before == null && after == null) return true;
+ if (before == null || after == null) return false;
+ final ContentValues original = before.getBefore();
+ final ContentValues pending = after.getAfter();
+ if (original != null && pending != null) {
+ final String beforeDisplayName = original.getAsString(
+ StructuredName.DISPLAY_NAME);
+ final String afterDisplayName = pending.getAsString(StructuredName.DISPLAY_NAME);
+ if (!TextUtils.equals(beforeDisplayName, afterDisplayName)) return false;
+
+ final String beforePrefix = original.getAsString(StructuredName.PREFIX);
+ final String afterPrefix = pending.getAsString(StructuredName.PREFIX);
+ if (!TextUtils.equals(beforePrefix, afterPrefix)) return false;
+
+ final String beforeFirstName = original.getAsString(StructuredName.GIVEN_NAME);
+ final String afterFirstName = pending.getAsString(StructuredName.GIVEN_NAME);
+ if (!TextUtils.equals(beforeFirstName, afterFirstName)) return false;
+
+ final String beforeMiddleName = original.getAsString(StructuredName.MIDDLE_NAME);
+ final String afterMiddleName = pending.getAsString(StructuredName.MIDDLE_NAME);
+ if (!TextUtils.equals(beforeMiddleName, afterMiddleName)) return false;
+
+ final String beforeLastName = original.getAsString(StructuredName.FAMILY_NAME);
+ final String afterLastName = pending.getAsString(StructuredName.FAMILY_NAME);
+ if (!TextUtils.equals(beforeLastName, afterLastName)) return false;
+
+ final String beforeSuffix = original.getAsString(StructuredName.SUFFIX);
+ final String afterSuffix = pending.getAsString(StructuredName.SUFFIX);
+ return TextUtils.equals(beforeSuffix, afterSuffix);
+ }
+ return false;
+ }
+
+ /**
* Whether editor inputs and the options menu should be enabled.
*/
private boolean isEnabled() {
@@ -1145,23 +1187,19 @@
}
mRawContacts = contact.getRawContacts();
- String readOnlyDisplayName = null;
// Check for writable raw contacts. If there are none, then we need to create one so user
// can edit. For the user profile case, there is already an editable contact.
if (!contact.isUserProfile() && !contact.isWritableContact(mContext)) {
mHasNewContact = true;
-
+ mReadOnlyDisplayNameId = contact.getNameRawContactId();
+ mCopyReadOnlyName = true;
// This is potentially an asynchronous call and will add deltas to list.
selectAccountAndCreateContact();
-
- readOnlyDisplayName = contact.getDisplayName();
} else {
mHasNewContact = false;
}
- // This also adds deltas to list. If readOnlyDisplayName is null at this point it is
- // simply ignored later on by the editor.
- setStateForExistingContact(readOnlyDisplayName, contact.isUserProfile(), mRawContacts);
+ setStateForExistingContact(contact.isUserProfile(), mRawContacts);
if (mAutoAddToDefaultGroup
&& InvisibleContactUtil.isInvisibleAndAddable(contact, getContext())) {
InvisibleContactUtil.markAddToDefaultGroup(contact, mState, getContext());
@@ -1236,10 +1274,9 @@
/**
* Prepare {@link #mState} for an existing contact.
*/
- private void setStateForExistingContact(String readOnlyDisplayName, boolean isUserProfile,
+ private void setStateForExistingContact(boolean isUserProfile,
ImmutableList<RawContact> rawContacts) {
setEnabled(true);
- mReadOnlyDisplayName = readOnlyDisplayName;
mState.addAll(rawContacts.iterator());
setIntentExtras(mIntentExtras);
@@ -1315,6 +1352,23 @@
return result;
}
+ private void copyReadOnlyName() {
+ // We should only ever be doing this if we're creating a new writable contact to attach to
+ // a read only contact.
+ if (!isEditingReadOnlyRawContactWithNewContact()) {
+ return;
+ }
+ final int writableIndex = mState.indexOfFirstWritableRawContact(getContext());
+ final RawContactDelta writable = mState.get(writableIndex);
+ final RawContactDelta readOnly = mState.get(writableIndex == 0 ? 1 : 0);
+ final ValuesDelta writeNameDelta = writable
+ .getSuperPrimaryEntry(StructuredName.CONTENT_ITEM_TYPE);
+ final ValuesDelta readNameDelta = readOnly
+ .getSuperPrimaryEntry(StructuredName.CONTENT_ITEM_TYPE);
+ writeNameDelta.copyStructuredNameFieldsFrom(readNameDelta);
+ mCopyReadOnlyName = false;
+ }
+
/**
* Bind editors using {@link #mState} and other members initialized from the loaded (or new)
* Contact.
@@ -1327,13 +1381,12 @@
// Add input fields for the loaded Contact
final CompactRawContactsEditorView editorView = getContent();
editorView.setListener(this);
+ if (mCopyReadOnlyName) {
+ copyReadOnlyName();
+ }
editorView.setState(mState, getMaterialPalette(), mViewIdGenerator,
mHasNewContact, mIsUserProfile, mAccountWithDataSet,
mRawContactIdToDisplayAlone, isEditingReadOnlyRawContactWithNewContact());
- if (mHasNewContact && !TextUtils.isEmpty(mReadOnlyDisplayName)) {
- mReadOnlyNameEditorView = editorView.getPrimaryNameEditorView();
- editorView.maybeSetReadOnlyDisplayNameAsPrimary(mReadOnlyDisplayName);
- }
// Set up the photo widget
editorView.setPhotoListener(this);
@@ -1407,8 +1460,7 @@
setStateForNewContact(newAccount, newAccountType, oldState, oldAccountType,
isEditingUserProfile());
if (mIsEdit) {
- setStateForExistingContact(mReadOnlyDisplayName, isEditingUserProfile(),
- mRawContacts);
+ setStateForExistingContact(isEditingUserProfile(), mRawContacts);
}
}
@@ -1482,7 +1534,7 @@
.show();
break;
default:
- final String displayName = getContent().getPrimaryNameEditorView()
+ final String displayName = getContent().getNameEditorView()
.getDisplayName();
final String toastMessage;
if (!TextUtils.isEmpty(displayName)) {
diff --git a/src/com/android/contacts/editor/CompactKindSectionView.java b/src/com/android/contacts/editor/CompactKindSectionView.java
index cbc4772..66ef691 100644
--- a/src/com/android/contacts/editor/CompactKindSectionView.java
+++ b/src/com/android/contacts/editor/CompactKindSectionView.java
@@ -245,34 +245,7 @@
return true;
}
- /**
- * Sets the given display name as the structured name as if the user input it, but
- * without informing editor listeners.
- */
- public void setName(String displayName) {
- if (!StructuredName.CONTENT_ITEM_TYPE.equals(mKindSectionData.getMimeType())) {
- return;
- }
- for (int i = 0; i < mEditors.getChildCount(); i++) {
- final View view = mEditors.getChildAt(i);
- if (view instanceof StructuredNameEditorView) {
- final StructuredNameEditorView editor = (StructuredNameEditorView) view;
-
- // Detach listeners since so we don't show suggested aggregations
- final Editor.EditorListener editorListener = editor.getEditorListener();
- editor.setEditorListener(null);
-
- editor.setDisplayName(displayName);
-
- // Reattach listeners
- editor.setEditorListener(editorListener);
-
- return;
- }
- }
- }
-
- public StructuredNameEditorView getPrimaryNameEditorView() {
+ public StructuredNameEditorView getNameEditorView() {
if (!StructuredName.CONTENT_ITEM_TYPE.equals(mKindSectionData.getMimeType())
|| mEditors.getChildCount() == 0) {
return null;
@@ -291,8 +264,7 @@
* displayed, even if it is empty.
*/
public void setState(KindSectionData kindSectionData,
- ViewIdGenerator viewIdGenerator, CompactRawContactsEditorView.Listener listener,
- ValuesDelta primaryValuesDelta) {
+ ViewIdGenerator viewIdGenerator, CompactRawContactsEditorView.Listener listener) {
mKindSectionData = kindSectionData;
mViewIdGenerator = viewIdGenerator;
mListener = listener;
@@ -308,18 +280,18 @@
}
}
- rebuildFromState(primaryValuesDelta);
+ rebuildFromState();
updateEmptyEditors(/* shouldAnimate = */ false);
}
- private void rebuildFromState(ValuesDelta primaryValuesDelta) {
+ private void rebuildFromState() {
mEditors.removeAllViews();
final String mimeType = mKindSectionData.getMimeType();
if (StructuredName.CONTENT_ITEM_TYPE.equals(mimeType)) {
addNameEditorViews(mKindSectionData.getAccountType(),
- primaryValuesDelta, mKindSectionData.getRawContactDelta());
+ mKindSectionData.getRawContactDelta());
} else if (GroupMembership.CONTENT_ITEM_TYPE.equals(mimeType)) {
addGroupEditorView(mKindSectionData.getRawContactDelta(),
mKindSectionData.getDataKind());
@@ -340,9 +312,10 @@
}
}
- private void addNameEditorViews(AccountType accountType,
- ValuesDelta valuesDelta, RawContactDelta rawContactDelta) {
+ private void addNameEditorViews(AccountType accountType, RawContactDelta rawContactDelta) {
final boolean readOnly = !accountType.areContactsWritable();
+ final ValuesDelta nameValuesDelta = rawContactDelta
+ .getSuperPrimaryEntry(StructuredName.CONTENT_ITEM_TYPE);
if (readOnly) {
final View nameView = mLayoutInflater.inflate(
@@ -351,7 +324,7 @@
// Display name
((TextView) nameView.findViewById(R.id.display_name))
- .setText(valuesDelta.getDisplayName());
+ .setText(nameValuesDelta.getDisplayName());
// Account type info
final LinearLayout accountTypeLayout = (LinearLayout)
@@ -372,12 +345,12 @@
if (!mIsUserProfile) {
// Don't set super primary for the me contact
nameView.setEditorListener(new StructuredNameEditorListener(
- valuesDelta, rawContactDelta.getRawContactId(), mListener));
+ nameValuesDelta, rawContactDelta.getRawContactId(), mListener));
}
nameView.setDeletable(false);
nameView.setValues(
- accountType.getKindForMimetype(DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME),
- valuesDelta, rawContactDelta, /* readOnly =*/ false, mViewIdGenerator);
+ accountType.getKindForMimetype(StructuredName.CONTENT_ITEM_TYPE),
+ nameValuesDelta, rawContactDelta, /* readOnly =*/ false, mViewIdGenerator);
// Correct start margin since there is a second icon in the structured name layout
nameView.findViewById(R.id.kind_icon).setVisibility(View.GONE);
@@ -395,7 +368,7 @@
phoneticNameView.setDeletable(false);
phoneticNameView.setValues(
accountType.getKindForMimetype(DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME),
- valuesDelta, rawContactDelta, /* readOnly =*/ false, mViewIdGenerator);
+ nameValuesDelta, rawContactDelta, /* readOnly =*/ false, mViewIdGenerator);
// Fix the start margin for phonetic name views
final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
diff --git a/src/com/android/contacts/editor/CompactRawContactsEditorView.java b/src/com/android/contacts/editor/CompactRawContactsEditorView.java
index 97d2f67..f41b33e 100644
--- a/src/com/android/contacts/editor/CompactRawContactsEditorView.java
+++ b/src/com/android/contacts/editor/CompactRawContactsEditorView.java
@@ -453,10 +453,11 @@
return mCurrentRawContactDelta.getRawContactId();
}
- public StructuredNameEditorView getPrimaryNameEditorView() {
- final CompactKindSectionView primaryNameKindSectionView = getPrimaryNameKindSectionView();
- return primaryNameKindSectionView == null
- ? null : primaryNameKindSectionView.getPrimaryNameEditorView();
+ public StructuredNameEditorView getNameEditorView() {
+ final CompactKindSectionView nameKindSectionView = mKindSectionViewMap
+ .get(StructuredName.CONTENT_ITEM_TYPE);
+ return nameKindSectionView == null
+ ? null : nameKindSectionView.getNameEditorView();
}
public RawContactDelta getCurrentRawContactDelta() {
@@ -481,7 +482,7 @@
}
public View getAggregationAnchorView() {
- final StructuredNameEditorView nameEditorView = getPrimaryNameEditorView();
+ final StructuredNameEditorView nameEditorView = getNameEditorView();
return nameEditorView != null ? nameEditorView.findViewById(R.id.anchor_view) : null;
}
@@ -967,9 +968,7 @@
}
final CompactKindSectionView kindSectionView;
final KindSectionData kindSectionData = mKindSectionDataMap.get(mimeType);
- final ValuesDelta primaryDelta = mCurrentRawContactDelta.getPrimaryEntry(mimeType);
- kindSectionView = inflateKindSectionView(mKindSectionViews, kindSectionData, mimeType,
- primaryDelta);
+ kindSectionView = inflateKindSectionView(mKindSectionViews, kindSectionData, mimeType);
mKindSectionViews.addView(kindSectionView);
// Keep a pointer to the KindSectionView for each mimeType
@@ -978,8 +977,7 @@
}
private CompactKindSectionView inflateKindSectionView(ViewGroup viewGroup,
- KindSectionData kindSectionData, String mimeType,
- ValuesDelta primaryValuesDelta) {
+ KindSectionData kindSectionData, String mimeType) {
final CompactKindSectionView kindSectionView = (CompactKindSectionView)
mLayoutInflater.inflate(R.layout.compact_item_kind_section, viewGroup,
/* attachToRoot =*/ false);
@@ -996,25 +994,11 @@
// they will be the only types you add new values to initially for new contacts
kindSectionView.setShowOneEmptyEditor(true);
- kindSectionView.setState(kindSectionData, mViewIdGenerator, mListener,
- primaryValuesDelta);
+ kindSectionView.setState(kindSectionData, mViewIdGenerator, mListener);
return kindSectionView;
}
- void maybeSetReadOnlyDisplayNameAsPrimary(String readOnlyDisplayName) {
- if (TextUtils.isEmpty(readOnlyDisplayName)) return;
- final CompactKindSectionView primaryNameKindSectionView = getPrimaryNameKindSectionView();
- if (primaryNameKindSectionView != null && primaryNameKindSectionView.isEmptyName()) {
- vlog("name: using read only display name as primary name");
- primaryNameKindSectionView.setName(readOnlyDisplayName);
- }
- }
-
- private CompactKindSectionView getPrimaryNameKindSectionView() {
- return mKindSectionViewMap.get(StructuredName.CONTENT_ITEM_TYPE);
- }
-
private void showAllFields() {
// Stop hiding empty editors and allow the user to enter values for all kinds now
for (int i = 0; i < mKindSectionViews.getChildCount(); i++) {
diff --git a/src/com/android/contacts/editor/StructuredNameEditorView.java b/src/com/android/contacts/editor/StructuredNameEditorView.java
index 2fcc19d..5aca809 100644
--- a/src/com/android/contacts/editor/StructuredNameEditorView.java
+++ b/src/com/android/contacts/editor/StructuredNameEditorView.java
@@ -21,35 +21,18 @@
import android.content.res.Resources;
import android.os.Parcel;
import android.os.Parcelable;
-import android.provider.ContactsContract.CommonDataKinds.StructuredName;
-import android.text.TextUtils;
import android.util.AttributeSet;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
import com.android.contacts.R;
import com.android.contacts.common.model.RawContactDelta;
import com.android.contacts.common.model.ValuesDelta;
-import com.android.contacts.common.model.account.AccountType;
import com.android.contacts.common.model.dataitem.DataItem;
import com.android.contacts.common.model.dataitem.DataKind;
import com.android.contacts.common.model.dataitem.StructuredNameDataItem;
import com.android.contacts.common.util.NameConverter;
-import java.util.HashMap;
-import java.util.Map;
-
/**
- * A dedicated editor for structured name. When the user collapses/expands
- * the structured name, it will reparse or recompose the name, but only
- * if the user has made changes. This distinction will be particularly
- * obvious if the name has a non-standard structure. Consider this structure:
- * first name="John Doe", family name="". As long as the user does not change
- * the full name, expand and collapse will preserve this. However, if the user
- * changes "John Doe" to "Jane Doe" and then expands the view, we will reparse
- * and show first name="Jane", family name="Doe".
+ * A dedicated editor for structured name.
*/
public class StructuredNameEditorView extends TextFieldsEditorView {
@@ -92,18 +75,6 @@
updateEmptiness();
}
- /**
- * Displays the icon and name for the given account under the name name input fields.
- */
- public void setAccountType(AccountType accountType) {
- final LinearLayout layout = (LinearLayout) findViewById(R.id.account_type);
- layout.setVisibility(View.VISIBLE);
- final ImageView imageView = (ImageView) layout.findViewById(R.id.account_type_icon);
- imageView.setImageDrawable(accountType.getDisplayIcon(getContext()));
- final TextView textView = (TextView) layout.findViewById(R.id.account_type_name);
- textView.setText(accountType.getDisplayLabel(getContext()));
- }
-
@Override
public void onFieldChanged(String column, String value) {
if (!isFieldChanged(column, value)) {
@@ -114,148 +85,16 @@
saveValue(column, value);
mChanged = true;
- // Next make sure the display name and the structured name are synced
- if (hasShortAndLongForms()) {
- if (areOptionalFieldsVisible()) {
- rebuildFullName(getValues());
- } else {
- rebuildStructuredName(getValues());
- }
- }
-
- // Then notify the listener, which will rely on the display and structured names to be
- // synced (in order to provide aggregate suggestions).
+ // Then notify the listener.
notifyEditorListener();
}
- @Override
- protected void onOptionalFieldVisibilityChange() {
- if (hasShortAndLongForms()) {
- if (areOptionalFieldsVisible()) {
- switchFromFullNameToStructuredName();
- } else {
- switchFromStructuredNameToFullName();
- }
- }
-
- super.onOptionalFieldVisibilityChange();
- }
-
- private void switchFromFullNameToStructuredName() {
- ValuesDelta values = getValues();
-
- if (!mChanged) {
- for (String field : NameConverter.STRUCTURED_NAME_FIELDS) {
- values.put(field, mSnapshot.getContentValues().getAsString(field));
- }
- return;
- }
-
- String displayName = values.getDisplayName();
- Map<String, String> structuredNameMap = NameConverter.displayNameToStructuredName(
- getContext(), displayName);
- if (!structuredNameMap.isEmpty()) {
- eraseFullName(values);
- for (String field : structuredNameMap.keySet()) {
- values.put(field, structuredNameMap.get(field));
- }
- }
-
- mSnapshot.getContentValues().clear();
- mSnapshot.getContentValues().putAll(values.getCompleteValues());
- mSnapshot.setDisplayName(displayName);
- }
-
- private void switchFromStructuredNameToFullName() {
- ValuesDelta values = getValues();
-
- if (!mChanged) {
- values.setDisplayName(mSnapshot.getDisplayName());
- return;
- }
-
- Map<String, String> structuredNameMap = valuesToStructuredNameMap(values);
- String displayName = NameConverter.structuredNameToDisplayName(getContext(),
- structuredNameMap);
- if (!TextUtils.isEmpty(displayName)) {
- eraseStructuredName(values);
- values.put(StructuredName.DISPLAY_NAME, displayName);
- }
-
- mSnapshot.getContentValues().clear();
- mSnapshot.setDisplayName(values.getDisplayName());
- mSnapshot.setMimeType(StructuredName.CONTENT_ITEM_TYPE);
- for (String field : structuredNameMap.keySet()) {
- mSnapshot.getContentValues().put(field, structuredNameMap.get(field));
- }
- }
-
- private Map<String, String> valuesToStructuredNameMap(ValuesDelta values) {
- Map<String, String> structuredNameMap = new HashMap<String, String>();
- for (String key : NameConverter.STRUCTURED_NAME_FIELDS) {
- structuredNameMap.put(key, values.getAsString(key));
- }
- return structuredNameMap;
- }
-
- private void eraseFullName(ValuesDelta values) {
- values.setDisplayName(null);
- }
-
- private void rebuildFullName(ValuesDelta values) {
- Map<String, String> structuredNameMap = valuesToStructuredNameMap(values);
- String displayName = NameConverter.structuredNameToDisplayName(getContext(),
- structuredNameMap);
- values.setDisplayName(displayName);
- }
-
- private void eraseStructuredName(ValuesDelta values) {
- for (String field : NameConverter.STRUCTURED_NAME_FIELDS) {
- values.putNull(field);
- }
- }
-
- private void rebuildStructuredName(ValuesDelta values) {
- String displayName = values.getDisplayName();
- Map<String, String> structuredNameMap = NameConverter.displayNameToStructuredName(
- getContext(), displayName);
- for (String field : structuredNameMap.keySet()) {
- values.put(field, structuredNameMap.get(field));
- }
- }
-
- /**
- * Set the display name onto the text field directly. This does not affect the underlying
- * data structure so it is similar to the user typing the value in on the field directly.
- *
- * @param name The name to set on the text field.
- */
- public void setDisplayName(String name) {
- // For now, assume the first text field is the name.
- // TODO: Find a better way to get a hold of the name field,
- // including given_name and family_name.
- super.setValue(0, name);
- getValues().setDisplayName(name);
- rebuildStructuredName(getValues());
- super.setValue(1, getValues().getAsString(StructuredName.GIVEN_NAME));
- super.setValue(3, getValues().getAsString(StructuredName.FAMILY_NAME));
- }
-
/**
* Returns the display name currently displayed in the editor.
*/
public String getDisplayName() {
- final ValuesDelta valuesDelta = getValues();
- rebuildFullName(valuesDelta);
- if (hasShortAndLongForms() && areOptionalFieldsVisible()) {
- final Map<String, String> structuredNameMap = valuesToStructuredNameMap(valuesDelta);
- final String displayName = NameConverter.structuredNameToDisplayName(
- getContext(), structuredNameMap);
- if (!TextUtils.isEmpty(displayName)) {
- return displayName;
- }
- }
- return valuesDelta.getDisplayName();
+ return NameConverter.structuredNameToDisplayName(getContext(),
+ getValues().getCompleteValues());
}
@Override
diff --git a/src/com/android/contacts/editor/TextFieldsEditorView.java b/src/com/android/contacts/editor/TextFieldsEditorView.java
index 8bdbcd4..6fd03bf 100644
--- a/src/com/android/contacts/editor/TextFieldsEditorView.java
+++ b/src/com/android/contacts/editor/TextFieldsEditorView.java
@@ -112,7 +112,7 @@
mPreviousViewHeight = mFields.getHeight();
// Save focus
- final View focusedChild = getFocusedChild();
+ final View focusedChild = findFocus();
final int focusedViewId = focusedChild == null ? -1 : focusedChild.getId();
// Reconfigure GUI
diff --git a/tests/res/xml/contacts_contactsdatakind.xml b/tests/res/xml/contacts_contactsdatakind.xml
index c289e6e..c7d3bd9 100644
--- a/tests/res/xml/contacts_contactsdatakind.xml
+++ b/tests/res/xml/contacts_contactsdatakind.xml
@@ -30,7 +30,6 @@
>
<DataKind kind="name"
maxOccurs="1"
- supportsDisplayName="true"
supportsPrefix="true"
supportsMiddleName="true"
supportsSuffix="true"
diff --git a/tests/res/xml/contacts_fallback.xml b/tests/res/xml/contacts_fallback.xml
index 7034d5e..7e731f4 100644
--- a/tests/res/xml/contacts_fallback.xml
+++ b/tests/res/xml/contacts_fallback.xml
@@ -30,7 +30,6 @@
>
<DataKind kind="name"
maxOccurs="1"
- supportsDisplayName="true"
supportsPrefix="true"
supportsMiddleName="true"
supportsSuffix="true"
diff --git a/tests/res/xml/missing_contacts_base.xml b/tests/res/xml/missing_contacts_base.xml
index 2c9aa6d..66917b3 100644
--- a/tests/res/xml/missing_contacts_base.xml
+++ b/tests/res/xml/missing_contacts_base.xml
@@ -25,7 +25,6 @@
<EditSchema>
<DataKind kind="name"
maxOccurs="1"
- supportsDisplayName="true"
supportsPrefix="true"
supportsMiddleName="true"
supportsSuffix="true"
diff --git a/tests/res/xml/missing_contacts_name_attr1.xml b/tests/res/xml/missing_contacts_name_attr1.xml
deleted file mode 100644
index b7b0f19..0000000
--- a/tests/res/xml/missing_contacts_name_attr1.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/**
- * Copyright (c) 2011, 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.
- */
--->
-
-<!-- XML for must-have checks. Missing one of the "support*" attributes". -->
-
-<ContactsAccountType
- xmlns:android="http://schemas.android.com/apk/res/android"
- >
- <EditSchema>
- <DataKind kind="name"
- maxOccurs="1"
- supportsPrefix="true"
- supportsMiddleName="true"
- supportsSuffix="true"
- supportsPhoneticFamilyName="true"
- supportsPhoneticMiddleName="true"
- supportsPhoneticGivenName="true"
- />
- <DataKind kind="photo" maxOccurs="1" />
- </EditSchema>
-</ContactsAccountType>
diff --git a/tests/res/xml/missing_contacts_name_attr2.xml b/tests/res/xml/missing_contacts_name_attr2.xml
index 41be9e8..77f25d2 100644
--- a/tests/res/xml/missing_contacts_name_attr2.xml
+++ b/tests/res/xml/missing_contacts_name_attr2.xml
@@ -25,7 +25,6 @@
<EditSchema>
<DataKind kind="name"
maxOccurs="1"
- supportsDisplayName="true"
supportsMiddleName="true"
supportsSuffix="true"
supportsPhoneticFamilyName="true"
diff --git a/tests/res/xml/missing_contacts_name_attr3.xml b/tests/res/xml/missing_contacts_name_attr3.xml
index e639a76..d06c4c1 100644
--- a/tests/res/xml/missing_contacts_name_attr3.xml
+++ b/tests/res/xml/missing_contacts_name_attr3.xml
@@ -25,7 +25,6 @@
<EditSchema>
<DataKind kind="name"
maxOccurs="1"
- supportsDisplayName="true"
supportsPrefix="true"
supportsSuffix="true"
supportsPhoneticFamilyName="true"
diff --git a/tests/res/xml/missing_contacts_name_attr4.xml b/tests/res/xml/missing_contacts_name_attr4.xml
index b42cdcd..6d597fe 100644
--- a/tests/res/xml/missing_contacts_name_attr4.xml
+++ b/tests/res/xml/missing_contacts_name_attr4.xml
@@ -25,7 +25,6 @@
<EditSchema>
<DataKind kind="name"
maxOccurs="1"
- supportsDisplayName="true"
supportsPrefix="true"
supportsMiddleName="true"
supportsPhoneticFamilyName="true"
diff --git a/tests/res/xml/missing_contacts_name_attr5.xml b/tests/res/xml/missing_contacts_name_attr5.xml
index 3778d2f..cf2d5cc 100644
--- a/tests/res/xml/missing_contacts_name_attr5.xml
+++ b/tests/res/xml/missing_contacts_name_attr5.xml
@@ -25,7 +25,6 @@
<EditSchema>
<DataKind kind="name"
maxOccurs="1"
- supportsDisplayName="true"
supportsPrefix="true"
supportsMiddleName="true"
supportsSuffix="true"
diff --git a/tests/res/xml/missing_contacts_name_attr6.xml b/tests/res/xml/missing_contacts_name_attr6.xml
index b3a3411..cfa589b 100644
--- a/tests/res/xml/missing_contacts_name_attr6.xml
+++ b/tests/res/xml/missing_contacts_name_attr6.xml
@@ -25,7 +25,6 @@
<EditSchema>
<DataKind kind="name"
maxOccurs="1"
- supportsDisplayName="true"
supportsPrefix="true"
supportsMiddleName="true"
supportsSuffix="true"
diff --git a/tests/res/xml/missing_contacts_name_attr7.xml b/tests/res/xml/missing_contacts_name_attr7.xml
index c87e4f1..7b08706 100644
--- a/tests/res/xml/missing_contacts_name_attr7.xml
+++ b/tests/res/xml/missing_contacts_name_attr7.xml
@@ -25,7 +25,6 @@
<EditSchema>
<DataKind kind="name"
maxOccurs="1"
- supportsDisplayName="true"
supportsPrefix="true"
supportsMiddleName="true"
supportsSuffix="true"
diff --git a/tests/res/xml/missing_contacts_photo.xml b/tests/res/xml/missing_contacts_photo.xml
index 87f4fc6..d73529c 100644
--- a/tests/res/xml/missing_contacts_photo.xml
+++ b/tests/res/xml/missing_contacts_photo.xml
@@ -25,7 +25,6 @@
<EditSchema>
<DataKind kind="name"
maxOccurs="1"
- supportsDisplayName="true"
supportsPrefix="true"
supportsMiddleName="true"
supportsSuffix="true"
diff --git a/tests/res/xml/test_basic_contacts.xml b/tests/res/xml/test_basic_contacts.xml
index 0047204..56e6e16 100644
--- a/tests/res/xml/test_basic_contacts.xml
+++ b/tests/res/xml/test_basic_contacts.xml
@@ -56,7 +56,6 @@
<!-- Fallback/Google definition. Supports all. -->
<DataKind kind="name"
maxOccurs="1"
- supportsDisplayName="true"
supportsPrefix="true"
supportsMiddleName="true"
supportsSuffix="true"
@@ -68,7 +67,6 @@
<!-- Exchange definition. No display-name, no phonetic-middle.
<DataKind kind="name"
- supportsDisplayName="false"
supportsPrefix="true"
supportsMiddleName="true"
supportsSuffix="true"
diff --git a/tests/src/com/android/contacts/common/RawContactModifierTests.java b/tests/src/com/android/contacts/common/RawContactModifierTests.java
index 755838b..9765af6 100644
--- a/tests/src/com/android/contacts/common/RawContactModifierTests.java
+++ b/tests/src/com/android/contacts/common/RawContactModifierTests.java
@@ -830,7 +830,7 @@
assertEquals("Expected to create organization", 1, count);
}
- public void testMigrateWithDisplayNameFromGoogleToExchange1() {
+ public void testMigrateNameFromGoogleToExchange() {
AccountType oldAccountType = new GoogleAccountType(getContext(), "");
AccountType newAccountType = new ExchangeAccountType(getContext(), "", EXCHANGE_ACCT_TYPE);
DataKind kind = newAccountType.getKindForMimetype(StructuredName.CONTENT_ITEM_TYPE);
@@ -866,91 +866,6 @@
assertEquals("PHONETIC_GIVEN", output.getAsString(StructuredName.PHONETIC_GIVEN_NAME));
}
- public void testMigrateWithDisplayNameFromGoogleToExchange2() {
- AccountType oldAccountType = new GoogleAccountType(getContext(), "");
- AccountType newAccountType = new ExchangeAccountType(getContext(), "", EXCHANGE_ACCT_TYPE);
- DataKind kind = newAccountType.getKindForMimetype(StructuredName.CONTENT_ITEM_TYPE);
-
- ContactsMockContext context = new ContactsMockContext(getContext());
- MockContentProvider provider = context.getContactsProvider();
-
- String inputDisplayName = "prefix given middle family suffix";
- // The method will ask the provider to split/join StructuredName.
- Uri uriForBuildDisplayName =
- ContactsContract.AUTHORITY_URI
- .buildUpon()
- .appendPath("complete_name")
- .appendQueryParameter(StructuredName.DISPLAY_NAME, inputDisplayName)
- .build();
- provider.expectQuery(uriForBuildDisplayName)
- .returnRow("prefix", "given", "middle", "family", "suffix")
- .withProjection(StructuredName.PREFIX, StructuredName.GIVEN_NAME,
- StructuredName.MIDDLE_NAME, StructuredName.FAMILY_NAME,
- StructuredName.SUFFIX);
-
- RawContactDelta oldState = new RawContactDelta();
- ContentValues mockNameValues = new ContentValues();
- mockNameValues.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
- mockNameValues.put(StructuredName.DISPLAY_NAME, inputDisplayName);
- oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
-
- RawContactDelta newState = new RawContactDelta();
- RawContactModifier.migrateStructuredName(context, oldState, newState, kind);
- List<ValuesDelta> list = newState.getMimeEntries(StructuredName.CONTENT_ITEM_TYPE);
- assertEquals(1, list.size());
-
- ContentValues outputValues = list.get(0).getAfter();
- assertEquals("prefix", outputValues.getAsString(StructuredName.PREFIX));
- assertEquals("given", outputValues.getAsString(StructuredName.GIVEN_NAME));
- assertEquals("middle", outputValues.getAsString(StructuredName.MIDDLE_NAME));
- assertEquals("family", outputValues.getAsString(StructuredName.FAMILY_NAME));
- assertEquals("suffix", outputValues.getAsString(StructuredName.SUFFIX));
- }
-
- public void testMigrateWithStructuredNameFromExchangeToGoogle() {
- AccountType oldAccountType = new ExchangeAccountType(getContext(), "", EXCHANGE_ACCT_TYPE);
- AccountType newAccountType = new GoogleAccountType(getContext(), "");
- DataKind kind = newAccountType.getKindForMimetype(StructuredName.CONTENT_ITEM_TYPE);
-
- ContactsMockContext context = new ContactsMockContext(getContext());
- MockContentProvider provider = context.getContactsProvider();
-
- // The method will ask the provider to split/join StructuredName.
- Uri uriForBuildDisplayName =
- ContactsContract.AUTHORITY_URI
- .buildUpon()
- .appendPath("complete_name")
- .appendQueryParameter(StructuredName.PREFIX, "prefix")
- .appendQueryParameter(StructuredName.GIVEN_NAME, "given")
- .appendQueryParameter(StructuredName.MIDDLE_NAME, "middle")
- .appendQueryParameter(StructuredName.FAMILY_NAME, "family")
- .appendQueryParameter(StructuredName.SUFFIX, "suffix")
- .build();
- provider.expectQuery(uriForBuildDisplayName)
- .returnRow("prefix given middle family suffix")
- .withProjection(StructuredName.DISPLAY_NAME);
-
- RawContactDelta oldState = new RawContactDelta();
- ContentValues mockNameValues = new ContentValues();
- mockNameValues.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
- mockNameValues.put(StructuredName.PREFIX, "prefix");
- mockNameValues.put(StructuredName.GIVEN_NAME, "given");
- mockNameValues.put(StructuredName.MIDDLE_NAME, "middle");
- mockNameValues.put(StructuredName.FAMILY_NAME, "family");
- mockNameValues.put(StructuredName.SUFFIX, "suffix");
- oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
-
- RawContactDelta newState = new RawContactDelta();
- RawContactModifier.migrateStructuredName(context, oldState, newState, kind);
-
- List<ValuesDelta> list = newState.getMimeEntries(StructuredName.CONTENT_ITEM_TYPE);
- assertNotNull(list);
- assertEquals(1, list.size());
- ContentValues outputValues = list.get(0).getAfter();
- assertEquals("prefix given middle family suffix",
- outputValues.getAsString(StructuredName.DISPLAY_NAME));
- }
-
public void testMigratePostalFromGoogleToExchange() {
AccountType oldAccountType = new GoogleAccountType(getContext(), "");
AccountType newAccountType = new ExchangeAccountType(getContext(), "", EXCHANGE_ACCT_TYPE);
diff --git a/tests/src/com/android/contacts/common/model/account/ExternalAccountTypeTest.java b/tests/src/com/android/contacts/common/model/account/ExternalAccountTypeTest.java
index 50a5110..684a379 100644
--- a/tests/src/com/android/contacts/common/model/account/ExternalAccountTypeTest.java
+++ b/tests/src/com/android/contacts/common/model/account/ExternalAccountTypeTest.java
@@ -92,7 +92,6 @@
// Let's just check if the DataKinds are registered.
assertNotNull(type.getKindForMimetype(StructuredName.CONTENT_ITEM_TYPE));
- assertNotNull(type.getKindForMimetype(DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME));
assertNotNull(type.getKindForMimetype(DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME));
assertNotNull(type.getKindForMimetype(Email.CONTENT_ITEM_TYPE));
assertNotNull(type.getKindForMimetype(StructuredPostal.CONTENT_ITEM_TYPE));
@@ -130,7 +129,6 @@
checkEditSchema_mustHaveChecks(R.xml.missing_contacts_base, true);
checkEditSchema_mustHaveChecks(R.xml.missing_contacts_photo, false);
checkEditSchema_mustHaveChecks(R.xml.missing_contacts_name, false);
- checkEditSchema_mustHaveChecks(R.xml.missing_contacts_name_attr1, false);
checkEditSchema_mustHaveChecks(R.xml.missing_contacts_name_attr2, false);
checkEditSchema_mustHaveChecks(R.xml.missing_contacts_name_attr3, false);
checkEditSchema_mustHaveChecks(R.xml.missing_contacts_name_attr4, false);
@@ -161,12 +159,11 @@
// Shouldn't have a "null" mimetype.
assertTrue(type.getKindForMimetype(null) == null);
- // 3 kinds are defined in XML and 4 are added by default.
- assertEquals(4 + 3, type.getSortedDataKinds().size());
+ // 3 kinds are defined in XML and 3 are added by default.
+ assertEquals(3 + 3, type.getSortedDataKinds().size());
// Check for the default kinds.
assertNotNull(type.getKindForMimetype(StructuredName.CONTENT_ITEM_TYPE));
- assertNotNull(type.getKindForMimetype(DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME));
assertNotNull(type.getKindForMimetype(DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME));
assertNotNull(type.getKindForMimetype(Photo.CONTENT_ITEM_TYPE));
diff --git a/tests/src/com/android/contacts/common/util/NameConverterTests.java b/tests/src/com/android/contacts/common/util/NameConverterTests.java
deleted file mode 100644
index 5a261eb..0000000
--- a/tests/src/com/android/contacts/common/util/NameConverterTests.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2011 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.common.util;
-
-import android.provider.ContactsContract.CommonDataKinds.StructuredName;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.text.TextUtils;
-
-import com.android.contacts.common.util.NameConverter;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Tests for {@link NameConverter}.
- */
-@SmallTest
-public class NameConverterTests extends AndroidTestCase {
-
- public void testStructuredNameToDisplayName() {
- Map<String, String> structuredName = new HashMap<String, String>();
- structuredName.put(StructuredName.PREFIX, "Mr.");
- structuredName.put(StructuredName.GIVEN_NAME, "John");
- structuredName.put(StructuredName.MIDDLE_NAME, "Quincy");
- structuredName.put(StructuredName.FAMILY_NAME, "Adams");
- structuredName.put(StructuredName.SUFFIX, "Esquire");
-
- assertEquals("Mr. John Quincy Adams, Esquire",
- NameConverter.structuredNameToDisplayName(mContext, structuredName));
-
- structuredName.remove(StructuredName.SUFFIX);
- assertEquals("Mr. John Quincy Adams",
- NameConverter.structuredNameToDisplayName(mContext, structuredName));
-
- structuredName.remove(StructuredName.MIDDLE_NAME);
- assertEquals("Mr. John Adams",
- NameConverter.structuredNameToDisplayName(mContext, structuredName));
- }
-
- public void testDisplayNameToStructuredName() {
- assertStructuredName("Mr. John Quincy Adams, Esquire",
- "Mr.", "John", "Quincy", "Adams", "Esquire");
- assertStructuredName("John Doe", null, "John", null, "Doe", null);
- assertStructuredName("Ms. Jane Eyre", "Ms.", "Jane", null, "Eyre", null);
- assertStructuredName("Dr Leo Spaceman, PhD", "Dr", "Leo", null, "Spaceman", "PhD");
- }
-
- /**
- * Helper method to check whether a given display name parses out to the other parameters.
- * @param displayName Display name to break into a structured name.
- * @param prefix Expected prefix (null if not expected).
- * @param givenName Expected given name (null if not expected).
- * @param middleName Expected middle name (null if not expected).
- * @param familyName Expected family name (null if not expected).
- * @param suffix Expected suffix (null if not expected).
- */
- private void assertStructuredName(String displayName, String prefix,
- String givenName, String middleName, String familyName, String suffix) {
- Map<String, String> structuredName = NameConverter.displayNameToStructuredName(mContext,
- displayName);
- checkNameComponent(StructuredName.PREFIX, prefix, structuredName);
- checkNameComponent(StructuredName.GIVEN_NAME, givenName, structuredName);
- checkNameComponent(StructuredName.MIDDLE_NAME, middleName, structuredName);
- checkNameComponent(StructuredName.FAMILY_NAME, familyName, structuredName);
- checkNameComponent(StructuredName.SUFFIX, suffix, structuredName);
- assertEquals(0, structuredName.size());
- }
-
- /**
- * Checks that the given field and value are present in the structured name map (or not present
- * if the given value is null). If the value is present and matches, the key is removed from
- * the map - once all components of the name are checked, the map should be empty.
- * @param field Field to check.
- * @param value Expected value for the field (null if it is not expected to be populated).
- * @param structuredName The map of structured field names to values.
- */
- private void checkNameComponent(String field, String value,
- Map<String, String> structuredName) {
- if (TextUtils.isEmpty(value)) {
- assertNull(structuredName.get(field));
- } else {
- assertEquals(value, structuredName.get(field));
- }
- structuredName.remove(field);
- }
-}