Merge "Support the contact field "Relation""
diff --git a/res/values/strings.xml b/res/values/strings.xml
index da4856c..49a4186 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -943,6 +943,8 @@
     <string name="websiteLabelsGroup">Website</string>
     <!-- Header that expands to list all event types when editing an event of a contact -->
     <string name="eventLabelsGroup">Event</string>
+    <!-- Header for the list of all relationships for a contact [CHAR LIMIT=15] -->
+    <string name="relationLabelsGroup">Relationship</string>
     <!-- Header for the list of all groups for a contact -->
     <string name="groupsLabel">Groups</string>
 
diff --git a/src/com/android/contacts/model/BaseAccountType.java b/src/com/android/contacts/model/BaseAccountType.java
index 174195e..f598e3e 100644
--- a/src/com/android/contacts/model/BaseAccountType.java
+++ b/src/com/android/contacts/model/BaseAccountType.java
@@ -194,7 +194,6 @@
         public int iconRes;
         public int iconAltRes;
         public int weight;
-        public boolean secondary;
         public boolean editable;
 
         /**
diff --git a/src/com/android/contacts/model/FallbackAccountType.java b/src/com/android/contacts/model/FallbackAccountType.java
index 4519bae..d79177d 100644
--- a/src/com/android/contacts/model/FallbackAccountType.java
+++ b/src/com/android/contacts/model/FallbackAccountType.java
@@ -33,6 +33,7 @@
 import android.provider.ContactsContract.CommonDataKinds.Organization;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.provider.ContactsContract.CommonDataKinds.Photo;
+import android.provider.ContactsContract.CommonDataKinds.Relation;
 import android.provider.ContactsContract.CommonDataKinds.SipAddress;
 import android.provider.ContactsContract.CommonDataKinds.StructuredName;
 import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
@@ -108,6 +109,10 @@
         return new EditType(type, Event.getTypeResource(type));
     }
 
+    protected EditType buildRelationType(int type) {
+        return new EditType(type, Relation.getTypeLabelResource(type));
+    }
+
     protected DataKind inflateStructuredName(Context context, int inflateLevel) {
         DataKind kind = getKindForMimetype(StructuredName.CONTENT_ITEM_TYPE);
         if (kind == null) {
@@ -170,7 +175,6 @@
         if (kind == null) {
             kind = addKind(new DataKind(Nickname.CONTENT_ITEM_TYPE,
                     R.string.nicknameLabelsGroup, -1, 115, true));
-            kind.secondary = true;
             kind.isList = false;
             kind.actionHeader = new SimpleInflater(R.string.nicknameLabelsGroup);
             kind.actionBody = new SimpleInflater(Nickname.NAME);
@@ -291,7 +295,6 @@
         if (kind == null) {
             kind = addKind(new DataKind(Im.CONTENT_ITEM_TYPE, R.string.imLabelsGroup,
                     android.R.drawable.sym_action_chat, 20, true));
-            kind.secondary = true;
             kind.actionHeader = new ImActionInflater();
             kind.actionBody = new SimpleInflater(Im.DATA);
         }
@@ -365,7 +368,6 @@
             kind = addKind(new DataKind(Note.CONTENT_ITEM_TYPE,
                     R.string.label_notes, -1, 110, true));
             kind.isList = false;
-            kind.secondary = true;
             kind.actionHeader = new SimpleInflater(R.string.label_notes);
             kind.actionBody = new SimpleInflater(Note.NOTE);
         }
@@ -383,7 +385,6 @@
         if (kind == null) {
             kind = addKind(new DataKind(Website.CONTENT_ITEM_TYPE,
                     R.string.websiteLabelsGroup, -1, 120, true));
-            kind.secondary = true;
             kind.actionHeader = new SimpleInflater(R.string.websiteLabelsGroup);
             kind.actionBody = new SimpleInflater(Website.URL);
         }
@@ -408,7 +409,6 @@
             // then have a rigid UI and automatic formatting of the date for the sync adapter.
             kind = addKind(new DataKind(Event.CONTENT_ITEM_TYPE,
                     R.string.eventLabelsGroup, -1, 150, false));
-            kind.secondary = true;
             kind.actionHeader = new EventActionInflater();
             kind.actionBody = new SimpleInflater(Event.START_DATE);
 
@@ -443,7 +443,6 @@
                     R.string.label_sip_address, android.R.drawable.sym_action_call, 130, true));
 
             kind.isList = false;
-            kind.secondary = true;
             kind.actionHeader = new SimpleInflater(R.string.label_sip_address);
             kind.actionBody = new SimpleInflater(SipAddress.SIP_ADDRESS);
         }
@@ -663,6 +662,13 @@
         }
     }
 
+    public static class RelationActionInflater extends CommonInflater {
+        @Override
+        protected int getTypeLabelResource(Integer type) {
+            return Relation.getTypeLabelResource(type == null ? Relation.TYPE_CUSTOM : type);
+        }
+    }
+
     public static class PostalActionInflater extends CommonInflater {
         @Override
         protected int getTypeLabelResource(Integer type) {
diff --git a/src/com/android/contacts/model/GoogleAccountType.java b/src/com/android/contacts/model/GoogleAccountType.java
index 404c109..bf3499c 100644
--- a/src/com/android/contacts/model/GoogleAccountType.java
+++ b/src/com/android/contacts/model/GoogleAccountType.java
@@ -19,12 +19,17 @@
 import com.android.contacts.R;
 import com.google.android.collect.Lists;
 
+import android.content.ContentValues;
 import android.content.Context;
 import android.provider.ContactsContract.CommonDataKinds.Email;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.Relation;
+import android.view.inputmethod.EditorInfo;
 
 public class GoogleAccountType extends FallbackAccountType {
     public static final String ACCOUNT_TYPE = "com.google";
+    protected static final int FLAGS_RELATION = EditorInfo.TYPE_CLASS_TEXT
+    | EditorInfo.TYPE_TEXT_FLAG_CAP_WORDS | EditorInfo.TYPE_TEXT_VARIATION_PERSON_NAME;
 
     public GoogleAccountType(String resPackageName) {
         this.accountType = ACCOUNT_TYPE;
@@ -34,23 +39,9 @@
 
     @Override
     protected void inflate(Context context, int inflateLevel) {
+        super.inflate(context, inflateLevel);
 
-        inflateStructuredName(context, inflateLevel);
-        inflateNickname(context, inflateLevel);
-        inflatePhone(context, inflateLevel);
-        inflateEmail(context, inflateLevel);
-        inflateStructuredPostal(context, inflateLevel);
-        inflateIm(context, inflateLevel);
-        inflateOrganization(context, inflateLevel);
-        inflatePhoto(context, inflateLevel);
-        inflateNote(context, inflateLevel);
-        inflateWebsite(context, inflateLevel);
-        inflateEvent(context, inflateLevel);
-        inflateSipAddress(context, inflateLevel);
-        inflateGroupMembership(context, inflateLevel);
-
-        setInflatedLevel(inflateLevel);
-
+        inflateRelation(context, inflateLevel);
     }
 
     @Override
@@ -97,6 +88,44 @@
         return kind;
     }
 
+    protected DataKind inflateRelation(Context context, int inflateLevel) {
+        DataKind kind = getKindForMimetype(Relation.CONTENT_ITEM_TYPE);
+        if (kind == null) {
+            kind = addKind(new DataKind(Relation.CONTENT_ITEM_TYPE,
+                    R.string.relationLabelsGroup, -1, 160, true));
+            kind.actionHeader = new RelationActionInflater();
+            kind.actionBody = new SimpleInflater(Relation.NAME);
+
+            kind.typeColumn = Relation.TYPE;
+            kind.typeList = Lists.newArrayList();
+            kind.typeList.add(buildRelationType(Relation.TYPE_ASSISTANT));
+            kind.typeList.add(buildRelationType(Relation.TYPE_BROTHER));
+            kind.typeList.add(buildRelationType(Relation.TYPE_CHILD));
+            kind.typeList.add(buildRelationType(Relation.TYPE_DOMESTIC_PARTNER));
+            kind.typeList.add(buildRelationType(Relation.TYPE_FATHER));
+            kind.typeList.add(buildRelationType(Relation.TYPE_FRIEND));
+            kind.typeList.add(buildRelationType(Relation.TYPE_MANAGER));
+            kind.typeList.add(buildRelationType(Relation.TYPE_MOTHER));
+            kind.typeList.add(buildRelationType(Relation.TYPE_PARENT));
+            kind.typeList.add(buildRelationType(Relation.TYPE_PARTNER));
+            kind.typeList.add(buildRelationType(Relation.TYPE_REFERRED_BY));
+            kind.typeList.add(buildRelationType(Relation.TYPE_RELATIVE));
+            kind.typeList.add(buildRelationType(Relation.TYPE_SISTER));
+            kind.typeList.add(buildRelationType(Relation.TYPE_SPOUSE));
+            kind.typeList.add(buildRelationType(Relation.TYPE_CUSTOM).setSecondary(true)
+                    .setCustomColumn(Relation.LABEL));
+
+            kind.defaultValues = new ContentValues();
+            kind.defaultValues.put(Relation.TYPE, Relation.TYPE_SPOUSE);
+
+            kind.fieldList = Lists.newArrayList();
+            kind.fieldList.add(new EditField(Relation.DATA, R.string.relationLabelsGroup,
+                    FLAGS_RELATION));
+        }
+
+        return kind;
+    }
+
     @Override
     public int getHeaderColor(Context context) {
         return 0xff89c2c2;
diff --git a/src/com/android/contacts/views/detail/ContactDetailFragment.java b/src/com/android/contacts/views/detail/ContactDetailFragment.java
index e2d04ef..365851f 100644
--- a/src/com/android/contacts/views/detail/ContactDetailFragment.java
+++ b/src/com/android/contacts/views/detail/ContactDetailFragment.java
@@ -67,6 +67,7 @@
 import android.provider.ContactsContract.CommonDataKinds.Note;
 import android.provider.ContactsContract.CommonDataKinds.Organization;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.Relation;
 import android.provider.ContactsContract.CommonDataKinds.SipAddress;
 import android.provider.ContactsContract.CommonDataKinds.StructuredName;
 import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
@@ -161,6 +162,7 @@
     private ArrayList<ViewEntry> mImEntries = new ArrayList<ViewEntry>();
     private ArrayList<ViewEntry> mNicknameEntries = new ArrayList<ViewEntry>();
     private ArrayList<ViewEntry> mGroupEntries = new ArrayList<ViewEntry>();
+    private ArrayList<ViewEntry> mRelationEntries = new ArrayList<ViewEntry>();
     private ArrayList<ViewEntry> mOtherEntries = new ArrayList<ViewEntry>();
     private ArrayList<ArrayList<ViewEntry>> mSections = new ArrayList<ArrayList<ViewEntry>>();
     private LayoutInflater mInflater;
@@ -177,6 +179,7 @@
         mSections.add(mPostalEntries);
         mSections.add(mNicknameEntries);
         mSections.add(mOtherEntries);
+        mSections.add(mRelationEntries);
         mSections.add(mGroupEntries);
     }
 
@@ -491,6 +494,8 @@
                     entry.data = DateUtils.formatDate(mContext, entry.data);
                     entry.uri = null;
                     mOtherEntries.add(entry);
+                } else if (Relation.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
+                    mRelationEntries.add(entry);
                 } else {
                     // Handle showing custom rows
                     entry.intent = new Intent(Intent.ACTION_VIEW, entry.uri);