Fixing parsing of intent extras for Exchange contacts
Bug: 2969875
Change-Id: Ifd7f1ba2e794ebf24626c53e5ed3a14ae9adc791
diff --git a/src/com/android/contacts/editor/StructuredNameEditorView.java b/src/com/android/contacts/editor/StructuredNameEditorView.java
index fcc57a2..5c9e04b 100644
--- a/src/com/android/contacts/editor/StructuredNameEditorView.java
+++ b/src/com/android/contacts/editor/StructuredNameEditorView.java
@@ -65,9 +65,10 @@
super.setValues(kind, entry, state, readOnly, vig);
if (mSnapshot == null) {
mSnapshot = new ContentValues(getValues().getCompleteValues());
+ mChanged = entry.isInsert();
+ } else {
+ mChanged = false;
}
-
- mChanged = false;
}
@Override
diff --git a/src/com/android/contacts/model/EntityModifier.java b/src/com/android/contacts/model/EntityModifier.java
index 4505142..ab19a35 100644
--- a/src/com/android/contacts/model/EntityModifier.java
+++ b/src/com/android/contacts/model/EntityModifier.java
@@ -26,13 +26,12 @@
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
+import android.net.Uri;
import android.os.Bundle;
-import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
-import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.Intents;
-import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.BaseTypes;
import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
import android.provider.ContactsContract.CommonDataKinds.Im;
import android.provider.ContactsContract.CommonDataKinds.Note;
import android.provider.ContactsContract.CommonDataKinds.Organization;
@@ -40,7 +39,10 @@
import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.Intents;
import android.provider.ContactsContract.Intents.Insert;
+import android.provider.ContactsContract.RawContacts;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseIntArray;
@@ -489,28 +491,8 @@
return;
}
- {
- // StructuredName
- EntityModifier.ensureKindExists(state, accountType, StructuredName.CONTENT_ITEM_TYPE);
- final ValuesDelta child = state.getPrimaryEntry(StructuredName.CONTENT_ITEM_TYPE);
-
- final String name = extras.getString(Insert.NAME);
- if (ContactsUtils.isGraphic(name)) {
- child.put(StructuredName.DISPLAY_NAME, name);
- }
-
- final String phoneticName = extras.getString(Insert.PHONETIC_NAME);
- if (ContactsUtils.isGraphic(phoneticName)) {
- child.put(StructuredName.PHONETIC_GIVEN_NAME, phoneticName);
- }
- }
-
- {
- // StructuredPostal
- final DataKind kind = accountType.getKindForMimetype(StructuredPostal.CONTENT_ITEM_TYPE);
- parseExtras(state, kind, extras, Insert.POSTAL_TYPE, Insert.POSTAL,
- StructuredPostal.FORMATTED_ADDRESS);
- }
+ parseStructuredNameExtra(context, accountType, state, extras);
+ parseStructuredPostalExtra(accountType, state, extras);
{
// Phone
@@ -576,6 +558,87 @@
}
}
+ private static void parseStructuredNameExtra(
+ Context context, AccountType accountType, EntityDelta state, Bundle extras) {
+ // StructuredName
+ EntityModifier.ensureKindExists(state, accountType, StructuredName.CONTENT_ITEM_TYPE);
+ final ValuesDelta child = state.getPrimaryEntry(StructuredName.CONTENT_ITEM_TYPE);
+
+ final String name = extras.getString(Insert.NAME);
+ if (ContactsUtils.isGraphic(name)) {
+ final DataKind kind = accountType.getKindForMimetype(StructuredName.CONTENT_ITEM_TYPE);
+ boolean supportsDisplayName = false;
+ if (kind.fieldList != null) {
+ for (EditField field : kind.fieldList) {
+ if (StructuredName.DISPLAY_NAME.equals(field.column)) {
+ supportsDisplayName = true;
+ break;
+ }
+ }
+ }
+
+ if (supportsDisplayName) {
+ child.put(StructuredName.DISPLAY_NAME, name);
+ } else {
+ Uri uri = ContactsContract.AUTHORITY_URI.buildUpon()
+ .appendPath("complete_name")
+ .appendQueryParameter(StructuredName.DISPLAY_NAME, name)
+ .build();
+ Cursor cursor = context.getContentResolver().query(uri,
+ new String[]{
+ StructuredName.PREFIX,
+ StructuredName.GIVEN_NAME,
+ StructuredName.MIDDLE_NAME,
+ StructuredName.FAMILY_NAME,
+ StructuredName.SUFFIX,
+ }, null, null, null);
+
+ try {
+ if (cursor.moveToFirst()) {
+ child.put(StructuredName.PREFIX, cursor.getString(0));
+ child.put(StructuredName.GIVEN_NAME, cursor.getString(1));
+ child.put(StructuredName.MIDDLE_NAME, cursor.getString(2));
+ child.put(StructuredName.FAMILY_NAME, cursor.getString(3));
+ child.put(StructuredName.SUFFIX, cursor.getString(4));
+ }
+ } finally {
+ cursor.close();
+ }
+ }
+ }
+
+ final String phoneticName = extras.getString(Insert.PHONETIC_NAME);
+ if (ContactsUtils.isGraphic(phoneticName)) {
+ child.put(StructuredName.PHONETIC_GIVEN_NAME, phoneticName);
+ }
+ }
+
+ private static void parseStructuredPostalExtra(
+ AccountType accountType, EntityDelta state, Bundle extras) {
+ // StructuredPostal
+ final DataKind kind = accountType.getKindForMimetype(StructuredPostal.CONTENT_ITEM_TYPE);
+ final ValuesDelta child = parseExtras(state, kind, extras, Insert.POSTAL_TYPE,
+ Insert.POSTAL, StructuredPostal.FORMATTED_ADDRESS);
+ String address = child == null ? null
+ : child.getAsString(StructuredPostal.FORMATTED_ADDRESS);
+ if (!TextUtils.isEmpty(address)) {
+ boolean supportsFormatted = false;
+ if (kind.fieldList != null) {
+ for (EditField field : kind.fieldList) {
+ if (StructuredPostal.FORMATTED_ADDRESS.equals(field.column)) {
+ supportsFormatted = true;
+ break;
+ }
+ }
+ }
+
+ if (!supportsFormatted) {
+ child.put(StructuredPostal.STREET, address);
+ child.putNull(StructuredPostal.FORMATTED_ADDRESS);
+ }
+ }
+ }
+
private static void parseValues(
EntityDelta state, AccountType accountType, ArrayList<ContentValues> dataValueList) {
for (ContentValues values : dataValueList) {
@@ -755,6 +818,7 @@
* Attempt to parse legacy {@link Insert#IM_PROTOCOL} values, replacing them
* with updated values.
*/
+ @SuppressWarnings("deprecation")
private static void fixupLegacyImType(Bundle bundle) {
final String encodedString = bundle.getString(Insert.IM_PROTOCOL);
if (encodedString == null) return;
@@ -782,17 +846,17 @@
* @param valueExtra {@link Bundle} key that holds the incoming value.
* @param valueColumn Column to write value into {@link ValuesDelta}.
*/
- public static void parseExtras(EntityDelta state, DataKind kind, Bundle extras,
+ public static ValuesDelta parseExtras(EntityDelta state, DataKind kind, Bundle extras,
String typeExtra, String valueExtra, String valueColumn) {
final CharSequence value = extras.getCharSequence(valueExtra);
// Bail early if account type doesn't handle this MIME type
- if (kind == null) return;
+ if (kind == null) return null;
// Bail when can't insert type, or value missing
final boolean canInsert = EntityModifier.canInsert(state, kind);
final boolean validValue = (value != null && TextUtils.isGraphic(value));
- if (!validValue || !canInsert) return;
+ if (!validValue || !canInsert) return null;
// Find exact type when requested, otherwise best available type
final boolean hasType = extras.containsKey(typeExtra);
@@ -809,5 +873,7 @@
final String customType = extras.getString(typeExtra);
child.put(editType.customColumn, customType);
}
+
+ return child;
}
}