Added the ability to create a contact widget from the contact details view

If the contact details view is on the user profile (i.e., me), then the
menu option to create a contact widget does not show up in the menu.

Bug:5346555
Change-Id: I392ca60a53168139a30ad70d72013da28fbecf24
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index c9fc2e8..826fd3d 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -47,6 +47,7 @@
     <uses-permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL" />
     <uses-permission android:name="com.android.voicemail.permission.READ_WRITE_ALL_VOICEMAIL" />
     <uses-permission android:name="android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK" />
+    <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
     <!-- allow broadcasting secret code intents that reboot the phone -->
     <uses-permission android:name="android.permission.REBOOT" />
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
diff --git a/res/menu-sw580dp-w720dp/view_contact.xml b/res/menu-sw580dp-w720dp/view_contact.xml
index c1f99a8..ead176c 100644
--- a/res/menu-sw580dp-w720dp/view_contact.xml
+++ b/res/menu-sw580dp-w720dp/view_contact.xml
@@ -31,4 +31,8 @@
         android:id="@+id/menu_delete"
         android:title="@string/menu_deleteContact" />
 
+    <item
+        android:id="@+id/menu_create_contact_shortcut"
+        android:title="@string/menu_create_contact_shortcut" />
+
 </menu>
diff --git a/res/menu-sw580dp/view_contact.xml b/res/menu-sw580dp/view_contact.xml
index 0f285db..516a2ae 100644
--- a/res/menu-sw580dp/view_contact.xml
+++ b/res/menu-sw580dp/view_contact.xml
@@ -30,4 +30,8 @@
         android:id="@+id/menu_delete"
         android:title="@string/menu_deleteContact" />
 
+    <item
+        android:id="@+id/menu_create_contact_shortcut"
+        android:title="@string/menu_create_contact_shortcut" />
+
 </menu>
diff --git a/res/menu/view_contact.xml b/res/menu/view_contact.xml
index 6712cb6..8c36924 100644
--- a/res/menu/view_contact.xml
+++ b/res/menu/view_contact.xml
@@ -37,4 +37,8 @@
         android:id="@+id/menu_send_to_voicemail"
         android:checkable="true"
         android:title="@string/menu_redirect_calls_to_vm" />
+
+    <item
+        android:id="@+id/menu_create_contact_shortcut"
+        android:title="@string/menu_create_contact_shortcut" />
 </menu>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 6fc84a9..bff222e 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -115,6 +115,9 @@
     <!-- Menu item used to delete a specific contact -->
     <string name="menu_deleteContact">Delete</string>
 
+    <!-- Menu item used to create a contact shortcut when viewing contact details. [CHAR LIMIT=30] -->
+    <string name="menu_create_contact_shortcut">Place on Home screen</string>
+
     <!-- Menu item used to call a specific contact when viewing the details of that contact. -->
     <string name="menu_call">Call contact</string>
 
@@ -206,6 +209,9 @@
          for some reason doesn't exist anymore. [CHAR LIMIT=NONE]-->
     <string name="invalidContactMessage">The contact doesn\'t exist.</string>
 
+    <!-- Message displayed in a toast after you create a contact shortcut in the launcher [CHAR LIMIT=NONE]-->
+    <string name="createContactShortcutSuccessful">Contact widget added to Home screen.</string>
+
     <!-- When picking a contact from a list of all contacts there is an entry at the top of the
          list that allows the user to create a new contact, which this string is used for -->
     <string name="pickerNewContactHeader">Create new contact</string>
diff --git a/src/com/android/contacts/detail/ContactLoaderFragment.java b/src/com/android/contacts/detail/ContactLoaderFragment.java
index fd1f458..d8fa158 100644
--- a/src/com/android/contacts/detail/ContactLoaderFragment.java
+++ b/src/com/android/contacts/detail/ContactLoaderFragment.java
@@ -20,6 +20,8 @@
 import com.android.contacts.ContactSaveService;
 import com.android.contacts.R;
 import com.android.contacts.activities.ContactDetailActivity.FragmentKeyListener;
+import com.android.contacts.list.ShortcutIntentBuilder;
+import com.android.contacts.list.ShortcutIntentBuilder.OnShortcutIntentCreatedListener;
 import com.android.contacts.util.PhoneCapabilityTester;
 import com.android.internal.util.Objects;
 
@@ -57,10 +59,14 @@
     /** The launch code when picking a ringtone */
     private static final int REQUEST_CODE_PICK_RINGTONE = 1;
 
+    /** This is the Intent action to install a shortcut in the launcher. */
+    private static final String ACTION_INSTALL_SHORTCUT =
+            "com.android.launcher.action.INSTALL_SHORTCUT";
 
     private boolean mOptionsMenuOptions;
     private boolean mOptionsMenuEditable;
     private boolean mOptionsMenuShareable;
+    private boolean mOptionsMenuCanCreateShortcut;
     private boolean mSendToVoicemailState;
     private String mCustomRingtone;
 
@@ -222,7 +228,8 @@
     public boolean isOptionsMenuChanged() {
         return mOptionsMenuOptions != isContactOptionsChangeEnabled()
                 || mOptionsMenuEditable != isContactEditable()
-                || mOptionsMenuShareable != isContactShareable();
+                || mOptionsMenuShareable != isContactShareable()
+                || mOptionsMenuCanCreateShortcut != isContactCanCreateShortcut();
     }
 
     @Override
@@ -230,6 +237,7 @@
         mOptionsMenuOptions = isContactOptionsChangeEnabled();
         mOptionsMenuEditable = isContactEditable();
         mOptionsMenuShareable = isContactShareable();
+        mOptionsMenuCanCreateShortcut = isContactCanCreateShortcut();
         if (mContactData != null) {
             mSendToVoicemailState = mContactData.isSendToVoicemail();
             mCustomRingtone = mContactData.getCustomRingtone();
@@ -255,6 +263,9 @@
 
         final MenuItem shareMenu = menu.findItem(R.id.menu_share);
         shareMenu.setVisible(mOptionsMenuShareable);
+
+        final MenuItem createContactShortcutMenu = menu.findItem(R.id.menu_create_contact_shortcut);
+        createContactShortcutMenu.setVisible(mOptionsMenuCanCreateShortcut);
     }
 
     public boolean isContactOptionsChangeEnabled() {
@@ -270,6 +281,10 @@
         return mContactData != null && !mContactData.isDirectoryEntry();
     }
 
+    public boolean isContactCanCreateShortcut() {
+        return mContactData != null && !mContactData.isUserProfile();
+    }
+
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
@@ -322,11 +337,45 @@
                 mContext.startService(intent);
                 return true;
             }
+            case R.id.menu_create_contact_shortcut: {
+                // Create a launcher shortcut with this contact
+                createLauncherShortcutWithContact();
+                return true;
+            }
         }
         return false;
     }
 
     /**
+     * Creates a launcher shortcut with the current contact.
+     */
+    private void createLauncherShortcutWithContact() {
+        // Hold the parent activity of this fragment in case this fragment is destroyed
+        // before the callback to onShortcutIntentCreated(...)
+        final Activity parentActivity = getActivity();
+
+        ShortcutIntentBuilder builder = new ShortcutIntentBuilder(parentActivity,
+                new OnShortcutIntentCreatedListener() {
+
+            @Override
+            public void onShortcutIntentCreated(Uri uri, Intent shortcutIntent) {
+                // Broadcast the shortcutIntent to the launcher to create a
+                // shortcut to this contact
+                shortcutIntent.setAction(ACTION_INSTALL_SHORTCUT);
+                parentActivity.sendBroadcast(shortcutIntent);
+
+                // Send a toast to give feedback to the user that a shortcut to this
+                // contact was added to the launcher.
+                Toast.makeText(parentActivity,
+                        R.string.createContactShortcutSuccessful,
+                        Toast.LENGTH_SHORT).show();
+            }
+
+        });
+        builder.createContactShortcutIntent(mLookupUri);
+    }
+
+    /**
      * Calls into the contacts provider to get a pre-authorized version of the given URI.
      */
     private Uri getPreAuthorizedUri(Uri uri) {
diff --git a/src/com/android/contacts/list/ContactPickerFragment.java b/src/com/android/contacts/list/ContactPickerFragment.java
index 43081e5..ef51732 100644
--- a/src/com/android/contacts/list/ContactPickerFragment.java
+++ b/src/com/android/contacts/list/ContactPickerFragment.java
@@ -205,6 +205,7 @@
         }
     }
 
+    @Override
     public void onShortcutIntentCreated(Uri uri, Intent shortcutIntent) {
         mListener.onShortcutIntentCreated(shortcutIntent);
     }