Allow supplying extras when assigning QuickContactsBadge

Add assignContactFromEmail(String, boolean, Bundle)
and assignContactFromPhone(String, boolean, Bundle)
that allow the caller to provide a bundle of extras to
pre-populate the ContactEditorFragment with if a contact
is not found with the requested email address or phone number.

Bug: 7038382
Change-Id: Ib77fa484e1c39cb60d7acc27efe3a3fcf3fee62f
diff --git a/api/current.txt b/api/current.txt
index 1cf14aa..71b6b14 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -28963,7 +28963,9 @@
     ctor public QuickContactBadge(android.content.Context, android.util.AttributeSet);
     ctor public QuickContactBadge(android.content.Context, android.util.AttributeSet, int);
     method public void assignContactFromEmail(java.lang.String, boolean);
+    method public void assignContactFromEmail(java.lang.String, boolean, android.os.Bundle);
     method public void assignContactFromPhone(java.lang.String, boolean);
+    method public void assignContactFromPhone(java.lang.String, boolean, android.os.Bundle);
     method public void assignContactUri(android.net.Uri);
     method public void onClick(android.view.View);
     method public void setExcludeMimes(java.lang.String[]);
diff --git a/core/java/android/widget/QuickContactBadge.java b/core/java/android/widget/QuickContactBadge.java
index 786afe2..622ac8f5 100644
--- a/core/java/android/widget/QuickContactBadge.java
+++ b/core/java/android/widget/QuickContactBadge.java
@@ -27,6 +27,7 @@
 import android.graphics.Canvas;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.os.Bundle;
 import android.provider.ContactsContract.CommonDataKinds.Email;
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Intents;
@@ -50,6 +51,7 @@
     private Drawable mOverlay;
     private QueryHandler mQueryHandler;
     private Drawable mDefaultAvatar;
+    private Bundle mExtras = null;
 
     protected String[] mExcludeMimes = null;
 
@@ -58,6 +60,8 @@
     static final private int TOKEN_EMAIL_LOOKUP_AND_TRIGGER = 2;
     static final private int TOKEN_PHONE_LOOKUP_AND_TRIGGER = 3;
 
+    static final private String EXTRA_URI_CONTENT = "uri_content";
+
     static final String[] EMAIL_LOOKUP_PROJECTION = new String[] {
         RawContacts.CONTACT_ID,
         Contacts.LOOKUP_KEY,
@@ -175,7 +179,26 @@
      * until this view is clicked.
      */
     public void assignContactFromEmail(String emailAddress, boolean lazyLookup) {
+        assignContactFromEmail(emailAddress, lazyLookup, null);
+    }
+
+    /**
+     * Assign a contact based on an email address. This should only be used when
+     * the contact's URI is not available, as an extra query will have to be
+     * performed to lookup the URI based on the email.
+
+     @param emailAddress The email address of the contact.
+     @param lazyLookup If this is true, the lookup query will not be performed
+     until this view is clicked.
+     @param extras A bundle of extras to populate the contact edit page with if the contact
+     is not found and the user chooses to add the email address to an existing contact or
+     create a new contact. Uses the same string constants as those found in
+     {@link #ContactsContract.Intents.Insert}
+    */
+
+    public void assignContactFromEmail(String emailAddress, boolean lazyLookup, Bundle extras) {
         mContactEmail = emailAddress;
+        mExtras = extras;
         if (!lazyLookup) {
             mQueryHandler.startQuery(TOKEN_EMAIL_LOOKUP, null,
                     Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, Uri.encode(mContactEmail)),
@@ -186,6 +209,7 @@
         }
     }
 
+
     /**
      * Assign a contact based on a phone number. This should only be used when
      * the contact's URI is not available, as an extra query will have to be
@@ -196,7 +220,25 @@
      * until this view is clicked.
      */
     public void assignContactFromPhone(String phoneNumber, boolean lazyLookup) {
+        assignContactFromPhone(phoneNumber, lazyLookup, new Bundle());
+    }
+
+    /**
+     * Assign a contact based on a phone number. This should only be used when
+     * the contact's URI is not available, as an extra query will have to be
+     * performed to lookup the URI based on the phone number.
+     *
+     * @param phoneNumber The phone number of the contact.
+     * @param lazyLookup If this is true, the lookup query will not be performed
+     * until this view is clicked.
+     * @param extras A bundle of extras to populate the contact edit page with if the contact
+     * is not found and the user chooses to add the phone number to an existing contact or
+     * create a new contact. Uses the same string constants as those found in
+     * {@link #ContactsContract.Intents.Insert}
+     */
+    public void assignContactFromPhone(String phoneNumber, boolean lazyLookup, Bundle extras) {
         mContactPhone = phoneNumber;
+        mExtras = extras;
         if (!lazyLookup) {
             mQueryHandler.startQuery(TOKEN_PHONE_LOOKUP, null,
                     Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, mContactPhone),
@@ -213,15 +255,21 @@
 
     @Override
     public void onClick(View v) {
+        // If contact has been assigned, mExtras should no longer be null, but do a null check
+        // anyway just in case assignContactFromPhone or Email was called with a null bundle or
+        // wasn't assigned previously.
+        final Bundle extras = (mExtras == null) ? new Bundle() : mExtras;
         if (mContactUri != null) {
             QuickContact.showQuickContact(getContext(), QuickContactBadge.this, mContactUri,
                     QuickContact.MODE_LARGE, mExcludeMimes);
         } else if (mContactEmail != null) {
-            mQueryHandler.startQuery(TOKEN_EMAIL_LOOKUP_AND_TRIGGER, mContactEmail,
+            extras.putString(EXTRA_URI_CONTENT, mContactEmail);
+            mQueryHandler.startQuery(TOKEN_EMAIL_LOOKUP_AND_TRIGGER, extras,
                     Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, Uri.encode(mContactEmail)),
                     EMAIL_LOOKUP_PROJECTION, null, null, null);
         } else if (mContactPhone != null) {
-            mQueryHandler.startQuery(TOKEN_PHONE_LOOKUP_AND_TRIGGER, mContactPhone,
+            extras.putString(EXTRA_URI_CONTENT, mContactPhone);
+            mQueryHandler.startQuery(TOKEN_PHONE_LOOKUP_AND_TRIGGER, extras,
                     Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, mContactPhone),
                     PHONE_LOOKUP_PROJECTION, null, null, null);
         } else {
@@ -262,12 +310,12 @@
             Uri lookupUri = null;
             Uri createUri = null;
             boolean trigger = false;
-
+            Bundle extras = (cookie != null) ? (Bundle) cookie : new Bundle();
             try {
                 switch(token) {
                     case TOKEN_PHONE_LOOKUP_AND_TRIGGER:
                         trigger = true;
-                        createUri = Uri.fromParts("tel", (String)cookie, null);
+                        createUri = Uri.fromParts("tel", extras.getString(EXTRA_URI_CONTENT), null);
 
                         //$FALL-THROUGH$
                     case TOKEN_PHONE_LOOKUP: {
@@ -281,7 +329,8 @@
                     }
                     case TOKEN_EMAIL_LOOKUP_AND_TRIGGER:
                         trigger = true;
-                        createUri = Uri.fromParts("mailto", (String)cookie, null);
+                        createUri = Uri.fromParts("mailto",
+                                extras.getString(EXTRA_URI_CONTENT), null);
 
                         //$FALL-THROUGH$
                     case TOKEN_EMAIL_LOOKUP: {
@@ -309,6 +358,10 @@
             } else if (createUri != null) {
                 // Prompt user to add this person to contacts
                 final Intent intent = new Intent(Intents.SHOW_OR_CREATE_CONTACT, createUri);
+                if (extras != null) {
+                    extras.remove(EXTRA_URI_CONTENT);
+                    intent.putExtras(extras);
+                }
                 getContext().startActivity(intent);
             }
         }