Add call log list item actions for adding contacts.

+ Add two actions: create new contact and add to existing contact.
+ Pass in ContactInfo to the CallLogListItem's ViewHolder.

Bug: 20433758
Change-Id: Ic1387b33ebe027fa6ddbdb971996fc7d4c4ac88b
diff --git a/res/layout/call_log_list_item_actions.xml b/res/layout/call_log_list_item_actions.xml
index 43da5d2..5740aaa 100644
--- a/res/layout/call_log_list_item_actions.xml
+++ b/res/layout/call_log_list_item_actions.xml
@@ -51,9 +51,39 @@
 
         <TextView
             style="@style/CallLogActionTextStyle"
-            android:text="@string/call_log_action_voicemail"
-            android:nextFocusLeft="@+id/video_call_action"
-            android:nextFocusRight="@+id/details_action" />
+            android:text="@string/call_log_action_voicemail" />
+
+    </LinearLayout>
+
+    <LinearLayout
+        android:id="@+id/create_new_contact_action"
+        style="@style/CallLogActionStyle"
+        android:nextFocusLeft="@+id/voicemail_action"
+        android:nextFocusRight="@+id/add_to_existing_contact_action">
+
+        <ImageView
+            style="@style/CallLogActionIconStyle"
+            android:src="@drawable/ic_person_add_24dp" />
+
+        <TextView
+            style="@style/CallLogActionTextStyle"
+            android:text="@string/search_shortcut_create_new_contact" />
+
+    </LinearLayout>
+
+    <LinearLayout
+        android:id="@+id/add_to_existing_contact_action"
+        style="@style/CallLogActionStyle"
+        android:nextFocusLeft="@+id/create_new_contact_action"
+        android:nextFocusRight="@+id/details_action">
+
+        <ImageView
+            style="@style/CallLogActionIconStyle"
+            android:src="@drawable/ic_person_24dp" />
+
+        <TextView
+            style="@style/CallLogActionTextStyle"
+            android:text="@string/search_shortcut_add_to_existing_contact" />
 
     </LinearLayout>
 
diff --git a/src/com/android/dialer/calllog/CallLogAdapter.java b/src/com/android/dialer/calllog/CallLogAdapter.java
index 8e22834..77b2a43 100644
--- a/src/com/android/dialer/calllog/CallLogAdapter.java
+++ b/src/com/android/dialer/calllog/CallLogAdapter.java
@@ -21,7 +21,6 @@
 import android.content.res.Resources;
 import android.database.Cursor;
 import android.net.Uri;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.support.v7.widget.RecyclerView.ViewHolder;
 import android.telecom.PhoneAccountHandle;
 import android.telephony.PhoneNumberUtils;
@@ -381,7 +380,7 @@
 
         final PhoneCallDetails details;
 
-        views.reported = info.isBadData;
+        views.info = info;
 
         // The entry can only be reported as invalid if it has a valid ID and the source of the
         // entry supports marking entries as invalid.
@@ -414,7 +413,6 @@
 
         views.setPhoto(photoId, photoUri, lookupUri, nameForDefaultImage, isVoicemailNumber,
                 mContactInfoHelper.isBusiness(info.sourceType));
-        views.quickContactView.setPrioritizedMimeType(Phone.CONTENT_ITEM_TYPE);
 
         views.updateCallButton();
 
diff --git a/src/com/android/dialer/calllog/CallLogListItemViewHolder.java b/src/com/android/dialer/calllog/CallLogListItemViewHolder.java
index 2e12d9a..4fa6561 100644
--- a/src/com/android/dialer/calllog/CallLogListItemViewHolder.java
+++ b/src/com/android/dialer/calllog/CallLogListItemViewHolder.java
@@ -21,6 +21,7 @@
 import android.content.Intent;
 import android.net.Uri;
 import android.provider.CallLog.Calls;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.support.v7.widget.CardView;
 import android.support.v7.widget.RecyclerView;
 import android.telecom.PhoneAccountHandle;
@@ -36,6 +37,7 @@
 import com.android.contacts.common.ContactPhotoManager;
 import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
 import com.android.contacts.common.testing.NeededForTesting;
+import com.android.contacts.common.util.UriUtils;
 import com.android.dialer.PhoneCallDetailsHelper;
 import com.android.dialer.PhoneCallDetailsViews;
 import com.android.dialer.R;
@@ -62,15 +64,15 @@
     public final CardView callLogEntryView;
     /** The actionable view which places a call to the number corresponding to the call log row. */
     public final View callActionView;
+
     /** The view containing call log item actions.  Null until the ViewStub is inflated. */
     public View actionsView;
-    /** The "video call" action button - assigned only when the action section is expanded. */
+    /** The button views below are assigned only when the action section is expanded. */
     public View videoCallButtonView;
-    /** The "voicemail" action button - assigned only when the action section is expanded. */
     public View voicemailButtonView;
-    /** The "details" action button - assigned only when the action section is expanded. */
+    public View createNewContactButtonView;
+    public View addToExistingContactButtonView;
     public View detailsButtonView;
-    /** The "report" action button. */
     public View reportButtonView;
 
     /**
@@ -123,16 +125,16 @@
     public CharSequence nameOrNumber;
 
     /**
-     * Whether or not the item has been reported by user as incorrect.
-     */
-    public boolean reported;
-
-    /**
      * Whether or not the contact info can be marked as invalid from the source where
      * it was obtained.
      */
     public boolean canBeReportedAsInvalid;
 
+    /**
+     * The contact info for the contact displayed in this list item.
+     */
+    public ContactInfo info;
+
     private static final int VOICEMAIL_TRANSCRIPTION_MAX_LINES = 10;
 
     private final Context mContext;
@@ -176,6 +178,8 @@
         phoneCallDetailsViews.nameView.setElegantTextHeight(false);
         phoneCallDetailsViews.callLocationAndDate.setElegantTextHeight(false);
 
+        quickContactView.setPrioritizedMimeType(Phone.CONTENT_ITEM_TYPE);
+
         if (callActionView != null) {
             callActionView.setOnClickListener(mActionListener);
         }
@@ -218,14 +222,28 @@
 
         if (videoCallButtonView == null) {
             videoCallButtonView = actionsView.findViewById(R.id.video_call_action);
+            videoCallButtonView.setOnClickListener(mActionListener);
         }
 
         if (voicemailButtonView == null) {
             voicemailButtonView = actionsView.findViewById(R.id.voicemail_action);
+            voicemailButtonView.setOnClickListener(mActionListener);
+        }
+
+        if (createNewContactButtonView == null) {
+            createNewContactButtonView = actionsView.findViewById(R.id.create_new_contact_action);
+            createNewContactButtonView.setOnClickListener(mActionListener);
+        }
+
+        if (addToExistingContactButtonView == null) {
+            addToExistingContactButtonView =
+                    actionsView.findViewById(R.id.add_to_existing_contact_action);
+            addToExistingContactButtonView.setOnClickListener(mActionListener);
         }
 
         if (detailsButtonView == null) {
             detailsButtonView = actionsView.findViewById(R.id.details_action);
+            detailsButtonView.setOnClickListener(mActionListener);
         }
 
         if (reportButtonView == null) {
@@ -287,7 +305,6 @@
                 phoneCallDetailsViews.callTypeIcons.isVideoShown()) {
             videoCallButtonView.setTag(IntentProvider.getReturnVideoCallIntentProvider(number));
             videoCallButtonView.setVisibility(View.VISIBLE);
-            videoCallButtonView.setOnClickListener(mActionListener);
         } else {
             videoCallButtonView.setTag(null);
             videoCallButtonView.setVisibility(View.GONE);
@@ -295,7 +312,6 @@
 
         // For voicemail calls, show the "VOICEMAIL" action button; hide otherwise.
         if (callType == Calls.VOICEMAIL_TYPE) {
-            voicemailButtonView.setOnClickListener(mActionListener);
             voicemailButtonView.setTag(
                     IntentProvider.getPlayVoicemailIntentProvider(rowId, voicemailUri));
             voicemailButtonView.setVisibility(View.VISIBLE);
@@ -305,15 +321,27 @@
             voicemailButtonView.setTag(null);
             voicemailButtonView.setVisibility(View.GONE);
 
-            detailsButtonView.setOnClickListener(mActionListener);
             detailsButtonView.setTag(
                     IntentProvider.getCallDetailIntentProvider(rowId, callIds, null));
+        }
 
-            if (canBeReportedAsInvalid && !reported) {
-                reportButtonView.setVisibility(View.VISIBLE);
-            } else {
-                reportButtonView.setVisibility(View.GONE);
-            }
+        if (canBeReportedAsInvalid && !info.isBadData) {
+            reportButtonView.setVisibility(View.VISIBLE);
+        } else {
+            reportButtonView.setVisibility(View.GONE);
+        }
+
+        if (UriUtils.isEncodedContactUri(info.lookupUri)) {
+            createNewContactButtonView.setTag(IntentProvider.getAddContactIntentProvider(
+                    info.lookupUri, info.name, info.number, info.type, true /* isNewContact */));
+            createNewContactButtonView.setVisibility(View.VISIBLE);
+
+            addToExistingContactButtonView.setTag(IntentProvider.getAddContactIntentProvider(
+                    info.lookupUri, info.name, info.number, info.type, false /* isNewContact */));
+            addToExistingContactButtonView.setVisibility(View.VISIBLE);
+        } else {
+            createNewContactButtonView.setVisibility(View.GONE);
+            addToExistingContactButtonView.setVisibility(View.GONE);
         }
 
         mCallLogListItemHelper.setActionContentDescriptions(this);
diff --git a/src/com/android/dialer/calllog/IntentProvider.java b/src/com/android/dialer/calllog/IntentProvider.java
index 73c7e82..4be2d1c 100644
--- a/src/com/android/dialer/calllog/IntentProvider.java
+++ b/src/com/android/dialer/calllog/IntentProvider.java
@@ -135,26 +135,33 @@
 
     /**
      * Retrieves an add contact intent for the given contact and phone call details.
-     *
-     * @param info The contact info.
-     * @param details The phone call details.
      */
     public static IntentProvider getAddContactIntentProvider(
-            final ContactInfo info, final PhoneCallDetails details) {
+            final Uri lookupUri,
+            final CharSequence name,
+            final CharSequence number,
+            final int numberType,
+            final boolean isNewContact) {
         return new IntentProvider() {
             @Override
             public Intent getIntent(Context context) {
                 Contact contactToSave = null;
 
-                if (info.lookupUri != null) {
-                    contactToSave = ContactLoader.parseEncodedContactEntity(info.lookupUri);
+                if (lookupUri != null) {
+                    contactToSave = ContactLoader.parseEncodedContactEntity(lookupUri);
                 }
 
                 if (contactToSave != null) {
                     // Populate the intent with contact information stored in the lookup URI.
                     // Note: This code mirrors code in Contacts/QuickContactsActivity.
-                    final Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
-                    intent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
+                    final Intent intent;
+                    if (isNewContact) {
+                        intent = new Intent(
+                                Intent.ACTION_INSERT, ContactsContract.Contacts.CONTENT_URI);
+                    } else {
+                        intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
+                        intent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
+                    }
 
                     ArrayList<ContentValues> values = contactToSave.getContentValues();
                     // Only pre-fill the name field if the provided display name is an nickname
@@ -189,9 +196,16 @@
                     return intent;
                 } else {
                     // If no lookup uri is provided, rely on the available phone number and name.
-                    return DialtactsActivity.getAddToContactIntent(details.name,
-                            details.number,
-                            details.numberType);
+                    if (isNewContact) {
+                        return DialtactsActivity.getAddToContactIntent(name, number, numberType);
+                    } else {
+                        Intent intent = new Intent(
+                                Intent.ACTION_INSERT, ContactsContract.Contacts.CONTENT_URI);
+                        intent.putExtra(ContactsContract.Intents.Insert.NAME, name);
+                        intent.putExtra(ContactsContract.Intents.Insert.PHONE, number);
+                        intent.putExtra(ContactsContract.Intents.Insert.PHONE_TYPE, numberType);
+                        return intent;
+                    }
                 }
             }
         };