Show custom contact fields in Contact card About card

bug 3457984

Change-Id: Id1963a258842f665123c63a75fb2726f48ddc552
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 12c83f0..836e4c8 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1212,6 +1212,9 @@
          about a contact -->
     <string name="label_notes">Notes</string>
 
+    <!-- The label describing the custom field of a contact. [CHAR LIMIT=20] -->
+    <string name="label_custom_field">Custom</string>
+
     <!-- The label describing the SIP address field of a contact. [CHAR LIMIT=20] -->
     <string name="label_sip_address">SIP</string>
 
diff --git a/src/com/android/contacts/common/model/account/BaseAccountType.java b/src/com/android/contacts/common/model/account/BaseAccountType.java
index 6481c06..46c57d4 100644
--- a/src/com/android/contacts/common/model/account/BaseAccountType.java
+++ b/src/com/android/contacts/common/model/account/BaseAccountType.java
@@ -19,6 +19,7 @@
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.res.Resources;
+import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.CommonDataKinds.BaseTypes;
 import android.provider.ContactsContract.CommonDataKinds.Email;
 import android.provider.ContactsContract.CommonDataKinds.Event;
@@ -39,6 +40,7 @@
 import android.view.inputmethod.EditorInfo;
 
 import com.android.contacts.common.R;
+import com.android.contacts.common.model.dataitem.CustomDataItem;
 import com.android.contacts.common.model.dataitem.DataKind;
 import com.android.contacts.common.testing.NeededForTesting;
 import com.android.contacts.common.util.CommonDateUtils;
@@ -445,6 +447,13 @@
         return kind;
     }
 
+    protected DataKind addDataKindCustomField(Context context) throws DefinitionException {
+        final DataKind kind = addKind(new DataKind(CustomDataItem.MIMETYPE_CUSTOM_FIELD,
+                R.string.label_custom_field, Weight.NONE, /* editable */ false));
+        kind.actionBody = new SimpleInflater(Data.DATA2);
+        return kind;
+    }
+
     /**
      * Simple inflater that assumes a string resource has a "%s" that will be
      * filled from the given column.
diff --git a/src/com/android/contacts/common/model/account/GoogleAccountType.java b/src/com/android/contacts/common/model/account/GoogleAccountType.java
index 8f7f172..8c83b90 100644
--- a/src/com/android/contacts/common/model/account/GoogleAccountType.java
+++ b/src/com/android/contacts/common/model/account/GoogleAccountType.java
@@ -68,6 +68,7 @@
             addDataKindGroupMembership(context);
             addDataKindRelation(context);
             addDataKindEvent(context);
+            addDataKindCustomField(context);
 
             mIsInitialized = true;
         } catch (DefinitionException e) {
diff --git a/src/com/android/contacts/common/model/dataitem/CustomDataItem.java b/src/com/android/contacts/common/model/dataitem/CustomDataItem.java
new file mode 100644
index 0000000..589d88e
--- /dev/null
+++ b/src/com/android/contacts/common/model/dataitem/CustomDataItem.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2016 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.model.dataitem;
+
+import android.content.ContentValues;
+import android.provider.ContactsContract.Data;
+
+/**
+ * Represents a custom field data item.
+ */
+public class CustomDataItem extends DataItem {
+
+    /**
+     * MIME type for custom field data defined in Contact Provider.
+     */
+    public static final String MIMETYPE_CUSTOM_FIELD =
+            "vnd.com.google.cursor.item/contact_user_defined_field";
+
+    CustomDataItem(ContentValues values) {super(values);}
+
+    public String getSummary() {
+        return getContentValues().getAsString(Data.DATA1);
+    }
+
+    public String getContent() {
+        return getContentValues().getAsString(Data.DATA2);
+    }
+}
diff --git a/src/com/android/contacts/common/model/dataitem/DataItem.java b/src/com/android/contacts/common/model/dataitem/DataItem.java
index 4e66e32..44ceeda 100644
--- a/src/com/android/contacts/common/model/dataitem/DataItem.java
+++ b/src/com/android/contacts/common/model/dataitem/DataItem.java
@@ -88,6 +88,8 @@
             return new IdentityDataItem(values);
         } else if (Photo.CONTENT_ITEM_TYPE.equals(mimeType)) {
             return new PhotoDataItem(values);
+        } else if (CustomDataItem.MIMETYPE_CUSTOM_FIELD.equals(mimeType)) {
+            return new CustomDataItem(values);
         }
 
         // generic
diff --git a/src/com/android/contacts/quickcontact/QuickContactActivity.java b/src/com/android/contacts/quickcontact/QuickContactActivity.java
index c595f23..66c2e19 100644
--- a/src/com/android/contacts/quickcontact/QuickContactActivity.java
+++ b/src/com/android/contacts/quickcontact/QuickContactActivity.java
@@ -145,6 +145,7 @@
 import com.android.contacts.common.model.dataitem.StructuredNameDataItem;
 import com.android.contacts.common.model.dataitem.StructuredPostalDataItem;
 import com.android.contacts.common.model.dataitem.WebsiteDataItem;
+import com.android.contacts.common.model.dataitem.CustomDataItem;
 import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.common.util.ImplicitIntentsUtil;
 import com.android.contacts.common.util.DateUtils;
@@ -347,6 +348,7 @@
             Im.CONTENT_ITEM_TYPE,
             GroupMembership.CONTENT_ITEM_TYPE,
             Identity.CONTENT_ITEM_TYPE,
+            CustomDataItem.MIMETYPE_CUSTOM_FIELD,
             Note.CONTENT_ITEM_TYPE);
 
     private static final BidiFormatter sBidiFormatter = BidiFormatter.getInstance();
@@ -1876,6 +1878,14 @@
                 entryContextMenuInfo = new EntryContextMenuInfo(subHeader, header,
                         dataItem.getMimeType(), dataItem.getId(), dataItem.isSuperPrimary());
             }
+        } else if (dataItem instanceof CustomDataItem) {
+            final CustomDataItem customDataItem = (CustomDataItem) dataItem;
+            final String summary = customDataItem.getSummary();
+            header = TextUtils.isEmpty(summary)
+                    ? res.getString(R.string.label_custom_field) : summary;
+            subHeader = customDataItem.getContent();
+            entryContextMenuInfo = new EntryContextMenuInfo(subHeader, header,
+                    dataItem.getMimeType(), dataItem.getId(), dataItem.isSuperPrimary());
         } else if (dataItem instanceof NoteDataItem) {
             final NoteDataItem note = (NoteDataItem) dataItem;
             header = res.getString(R.string.header_note_entry);