Added send button to group/selection picker.

Added send button for the picker fragments and
activity. All selected items will be added to
the send intent.

Test: Verified all features are working as intended.
Send button will only appear if at least one item is
selected

Bug: 31648014
Change-Id: Iaf51c9c750b4e824dfca455c2c3871fcbf4056cf
diff --git a/res/layout/multi_select_send_button.xml b/res/layout/multi_select_send_button.xml
new file mode 100644
index 0000000..50a4d45
--- /dev/null
+++ b/res/layout/multi_select_send_button.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<Button xmlns:android="http://schemas.android.com/apk/res/android"
+    style="?android:attr/buttonBarButtonStyle"
+    android:id="@+id/multi_select_send_button"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:text="@string/send_to_selection"
+    android:textColor="@color/action_bar_button_text_color"
+    android:textSize="14sp">
+</Button>
diff --git a/res/menu/group_member_picker.xml b/res/menu/group_member_picker.xml
index 9e623f6..2dd1990 100644
--- a/res/menu/group_member_picker.xml
+++ b/res/menu/group_member_picker.xml
@@ -19,7 +19,7 @@
 
     <item
         android:id="@+id/menu_select"
-        android:title="@string/menu_selectForGroup" />
+        android:title="@string/menu_selectForGroup"
         contacts:showAsAction="never" />
 
 </menu>
diff --git a/res/menu/items_multi_select.xml b/res/menu/items_multi_select.xml
new file mode 100644
index 0000000..5bb39d4
--- /dev/null
+++ b/res/menu/items_multi_select.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+    <item
+        app:actionLayout="@layout/multi_select_send_button"
+        app:showAsAction="always"
+        android:id="@+id/menu_send"
+        android:title="@string/send_to_selection" />
+</menu>
\ No newline at end of file
diff --git a/src/com/android/contacts/common/list/MultiSelectEntryContactListAdapter.java b/src/com/android/contacts/common/list/MultiSelectEntryContactListAdapter.java
index 991ad52..b08e367 100644
--- a/src/com/android/contacts/common/list/MultiSelectEntryContactListAdapter.java
+++ b/src/com/android/contacts/common/list/MultiSelectEntryContactListAdapter.java
@@ -86,6 +86,10 @@
         return mSelectedContactIds;
     }
 
+    public boolean hasSelectedItems() {
+        return mSelectedContactIds.size() > 0;
+    }
+
     /**
      * Returns the selected contacts as an array.
      */
diff --git a/src/com/android/contacts/group/GroupMembersFragment.java b/src/com/android/contacts/group/GroupMembersFragment.java
index 77f193c..1135939 100644
--- a/src/com/android/contacts/group/GroupMembersFragment.java
+++ b/src/com/android/contacts/group/GroupMembersFragment.java
@@ -87,6 +87,7 @@
     private static final int LOADER_GROUP_METADATA = 0;
     private static final int MSG_FAIL_TO_LOAD = 1;
     private static final int RESULT_GROUP_ADD_MEMBER = 100;
+    private static final int RESULT_SEND_TO_SELECTION = 200;
 
     /** Filters out duplicate contacts. */
     private class FilterCursorWrapper extends CursorWrapper {
@@ -293,7 +294,7 @@
     /**
      * Helper class for cp2 query used to look up all contact's emails and phone numbers.
      */
-    private static abstract class ContactQuery {
+    private static abstract class Query {
         public static final String EMAIL_SELECTION =
                 ContactsContract.Data.MIMETYPE + "='"
                         + ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE + "'";
@@ -308,11 +309,43 @@
                 ContactsContract.Data.DATA1
         };
 
-        public static final int CONTACT_ID = 0;
+        public static final int ID = 0;
         public static final int IS_PRIMARY = 1;
         public static final int DATA1 = 2;
     }
 
+    private List<String> getSendToDataForIds(long[] ids, String scheme) {
+        final List<String> items = new ArrayList<>();
+        final String sIds = GroupUtil.convertArrayToString(ids);
+        final String select = (ContactsUtils.SCHEME_MAILTO.equals(scheme)
+                ? Query.EMAIL_SELECTION
+                + " AND " + ContactsContract.CommonDataKinds.Email._ID + " IN (" + sIds + ")"
+                : Query.PHONE_SELECTION
+                + " AND " + ContactsContract.CommonDataKinds.Phone._ID + " IN (" + sIds + ")");
+        final ContentResolver contentResolver = getContext().getContentResolver();
+        final Cursor cursor = contentResolver.query(ContactsContract.Data.CONTENT_URI,
+                Query.PROJECTION, select, null, null);
+
+        if (cursor == null) {
+            return items;
+        }
+
+        try {
+            cursor.moveToPosition(-1);
+            while (cursor.moveToNext()) {
+                final String data = cursor.getString(Query.DATA1);
+
+                if (!TextUtils.isEmpty(data)) {
+                    items.add(data);
+                }
+            }
+        } finally {
+            cursor.close();
+        }
+
+        return items;
+    }
+
     private void sendToGroup(long[] ids, String sendScheme, String title) {
         if(ids == null || ids.length == 0) return;
 
@@ -321,12 +354,12 @@
         final Set<String> usedContactIds = new HashSet<>();
         final String sIds = GroupUtil.convertArrayToString(ids);
         final String select = (ContactsUtils.SCHEME_MAILTO.equals(sendScheme)
-                ? ContactQuery.EMAIL_SELECTION
-                : ContactQuery.PHONE_SELECTION)
+                ? Query.EMAIL_SELECTION
+                : Query.PHONE_SELECTION)
                 + " AND " + ContactsContract.Data.CONTACT_ID + " IN (" + sIds + ")";
         final ContentResolver contentResolver = getContext().getContentResolver();
         final Cursor cursor = contentResolver.query(ContactsContract.Data.CONTENT_URI,
-                ContactQuery.PROJECTION, select, null, null);
+                Query.PROJECTION, select, null, null);
 
         if (cursor == null) {
             return;
@@ -335,14 +368,14 @@
         try {
             cursor.moveToPosition(-1);
             while (cursor.moveToNext()) {
-                final String contactId = cursor.getString(ContactQuery.CONTACT_ID);
-                final String data = cursor.getString(ContactQuery.DATA1);
+                final String contactId = cursor.getString(Query.ID);
+                final String data = cursor.getString(Query.DATA1);
 
                 if (!usedContactIds.contains(contactId)) {
                     usedContactIds.add(contactId);
                 } else {
                     // If we found a contact with multiple items (email, phone), start the picker
-                    startSendToSelectionPickerActivity(ids, sendScheme);
+                    startSendToSelectionPickerActivity(ids, sendScheme, title);
                     return;
                 } if (!TextUtils.isEmpty(data)) {
                     itemsData.add(data);
@@ -371,8 +404,9 @@
         startActivity(GroupUtil.createSendToSelectionIntent(listItems, sendScheme, title));
     }
 
-    private void startSendToSelectionPickerActivity(long[] ids, String sendScheme) {
-        startActivity(GroupUtil.createSendToSelectionPickerIntent(getContext(), ids, sendScheme));
+    private void startSendToSelectionPickerActivity(long[] ids, String sendScheme, String title) {
+        startActivityForResult(GroupUtil.createSendToSelectionPickerIntent(getContext(), ids,
+                sendScheme, title), RESULT_SEND_TO_SELECTION);
     }
 
     private void startGroupAddMemberActivity() {
@@ -446,22 +480,37 @@
 
     @Override
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (requestCode == RESULT_GROUP_ADD_MEMBER && resultCode ==
-                Activity.RESULT_OK && data != null) {
-            long[] contactIds = data.getLongArrayExtra(
-                    UiIntentActions.TARGET_CONTACT_IDS_EXTRA_KEY);
-            if (contactIds == null) {
-                final long contactId = data.getLongExtra(
-                        UiIntentActions.TARGET_CONTACT_ID_EXTRA_KEY, -1);
-                if (contactId > -1) {
-                    contactIds = new long[1];
-                    contactIds[0] = contactId;
+        if (resultCode != Activity.RESULT_OK || data == null) {
+            return;
+        }
+        switch(requestCode) {
+            case RESULT_GROUP_ADD_MEMBER: {
+                long[] contactIds = data.getLongArrayExtra(
+                        UiIntentActions.TARGET_CONTACT_IDS_EXTRA_KEY);
+                if (contactIds == null) {
+                    final long contactId = data.getLongExtra(
+                            UiIntentActions.TARGET_CONTACT_ID_EXTRA_KEY, -1);
+                    if (contactId > -1) {
+                        contactIds = new long[1];
+                        contactIds[0] = contactId;
+                    }
                 }
+                new UpdateGroupMembersAsyncTask(
+                        UpdateGroupMembersAsyncTask.TYPE_ADD,
+                        getContext(), contactIds, mGroupMetaData.groupId, mGroupMetaData.accountName,
+                        mGroupMetaData.accountType, mGroupMetaData.dataSet).execute();
+                break;
             }
-            new UpdateGroupMembersAsyncTask(
-                    UpdateGroupMembersAsyncTask.TYPE_ADD,
-                    getContext(), contactIds, mGroupMetaData.groupId, mGroupMetaData.accountName,
-                    mGroupMetaData.accountType, mGroupMetaData.dataSet).execute();
+            case RESULT_SEND_TO_SELECTION: {
+                final long[] ids = data.getLongArrayExtra(
+                        UiIntentActions.TARGET_CONTACT_IDS_EXTRA_KEY);
+                final String sendScheme = data.getStringExtra(UiIntentActions.SELECTION_SEND_SCHEME);
+                final String sendTitle = data.getStringExtra(UiIntentActions.SELECTION_SEND_TITLE);
+                final List<String> items = getSendToDataForIds(ids, sendScheme);
+                final String list = GroupUtil.convertListToString(items);
+                startSendToSelectionActivity(list, sendScheme, sendTitle);
+                break;
+            }
         }
     }
 
diff --git a/src/com/android/contacts/group/GroupUtil.java b/src/com/android/contacts/group/GroupUtil.java
index 1faf2c9..e9af483 100644
--- a/src/com/android/contacts/group/GroupUtil.java
+++ b/src/com/android/contacts/group/GroupUtil.java
@@ -110,13 +110,16 @@
 
     /** Returns an Intent to pick emails/phones to send to selection (or group) */
     public static Intent createSendToSelectionPickerIntent(
-            Context context, long[] ids, String sendScheme) {
+            Context context, long[] ids, String sendScheme, String title) {
         final Intent intent = new Intent(context, ContactSelectionActivity.class);
         intent.setAction(UiIntentActions.ACTION_SELECT_ITEMS);
         intent.setType(ContactsUtils.SCHEME_MAILTO.equals(sendScheme)
                 ? ContactsContract.CommonDataKinds.Email.CONTENT_TYPE
                 : ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
         intent.putExtra(UiIntentActions.LIST_CONTACTS, ids);
+        intent.putExtra(UiIntentActions.SELECTION_SEND_SCHEME, sendScheme);
+        intent.putExtra(UiIntentActions.SELECTION_SEND_TITLE, title);
+
         return intent;
     }
 
diff --git a/src/com/android/contacts/list/MultiSelectEmailAddressesListFragment.java b/src/com/android/contacts/list/MultiSelectEmailAddressesListFragment.java
index 06e44e9..fb33499 100644
--- a/src/com/android/contacts/list/MultiSelectEmailAddressesListFragment.java
+++ b/src/com/android/contacts/list/MultiSelectEmailAddressesListFragment.java
@@ -15,10 +15,16 @@
  */
 package com.android.contacts.list;
 
+import android.app.Activity;
+import android.content.Intent;
 import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
 
+import com.android.contacts.R;
 import com.android.contacts.common.logging.ListEvent;
 
 /** Displays a list of emails with check boxes. */
@@ -29,7 +35,7 @@
         setPhotoLoaderEnabled(true);
         setSectionHeaderDisplayEnabled(true);
         setSearchMode(false);
-        setHasOptionsMenu(false);
+        setHasOptionsMenu(true);
         setListType(ListEvent.ListType.PICK_EMAIL);
     }
 
@@ -42,6 +48,50 @@
     }
 
     @Override
+    public void onSelectedContactsChangedViaCheckBox() {
+        onSelectedContactsChanged();
+    }
+
+    @Override
+    public void onCreateOptionsMenu(Menu menu, final MenuInflater inflater) {
+        super.onCreateOptionsMenu(menu, inflater);
+        inflater.inflate(R.menu.items_multi_select, menu);
+    }
+
+    @Override
+    public void onPrepareOptionsMenu(Menu menu) {
+        final MenuItem item = menu.findItem(R.id.menu_send);
+        item.setVisible(getAdapter().hasSelectedItems());
+        item.getActionView().setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                onOptionsItemSelected(item);
+            }
+        });
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch(item.getItemId()) {
+            case R.id.menu_send: {
+                final String scheme = getActivity().getIntent().getStringExtra(
+                        UiIntentActions.SELECTION_SEND_SCHEME);
+                final String title= getActivity().getIntent().getStringExtra(
+                        UiIntentActions.SELECTION_SEND_TITLE);
+                final Intent intent = new Intent();
+                intent.putExtra(UiIntentActions.TARGET_CONTACT_IDS_EXTRA_KEY,
+                        getAdapter().getSelectedContactIdsArray());
+                intent.putExtra(UiIntentActions.SELECTION_SEND_SCHEME, scheme);
+                intent.putExtra(UiIntentActions.SELECTION_SEND_TITLE, title);
+                getActivity().setResult(Activity.RESULT_OK, intent);
+                getActivity().finish();
+                return true;
+            }
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    @Override
     public void onStart() {
         super.onStart();
         displayCheckBoxes(true);
diff --git a/src/com/android/contacts/list/MultiSelectPhoneNumbersListFragment.java b/src/com/android/contacts/list/MultiSelectPhoneNumbersListFragment.java
index b057911..638a4d4 100644
--- a/src/com/android/contacts/list/MultiSelectPhoneNumbersListFragment.java
+++ b/src/com/android/contacts/list/MultiSelectPhoneNumbersListFragment.java
@@ -15,10 +15,16 @@
  */
 package com.android.contacts.list;
 
+import android.app.Activity;
+import android.content.Intent;
 import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
 
+import com.android.contacts.R;
 import com.android.contacts.common.logging.ListEvent;
 
 /** Displays a list of phone numbers with check boxes. */
@@ -29,7 +35,7 @@
         setPhotoLoaderEnabled(true);
         setSectionHeaderDisplayEnabled(true);
         setSearchMode(false);
-        setHasOptionsMenu(false);
+        setHasOptionsMenu(true);
         setListType(ListEvent.ListType.PICK_PHONE);
     }
 
@@ -42,6 +48,50 @@
     }
 
     @Override
+    public void onSelectedContactsChangedViaCheckBox() {
+        onSelectedContactsChanged();
+    }
+
+    @Override
+    public void onCreateOptionsMenu(Menu menu, final MenuInflater inflater) {
+        super.onCreateOptionsMenu(menu, inflater);
+        inflater.inflate(R.menu.items_multi_select, menu);
+    }
+
+    @Override
+    public void onPrepareOptionsMenu(Menu menu) {
+        final MenuItem item = menu.findItem(R.id.menu_send);
+        item.setVisible(getAdapter().hasSelectedItems());
+        item.getActionView().setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                onOptionsItemSelected(item);
+            }
+        });
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch(item.getItemId()) {
+            case R.id.menu_send: {
+                final String scheme = getActivity().getIntent().getStringExtra(
+                        UiIntentActions.SELECTION_SEND_SCHEME);
+                final String title= getActivity().getIntent().getStringExtra(
+                        UiIntentActions.SELECTION_SEND_TITLE);
+                final Intent intent = new Intent();
+                intent.putExtra(UiIntentActions.TARGET_CONTACT_IDS_EXTRA_KEY,
+                        getAdapter().getSelectedContactIdsArray());
+                intent.putExtra(UiIntentActions.SELECTION_SEND_SCHEME, scheme);
+                intent.putExtra(UiIntentActions.SELECTION_SEND_TITLE, title);
+                getActivity().setResult(Activity.RESULT_OK, intent);
+                getActivity().finish();
+                return true;
+            }
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    @Override
     public void onStart() {
         super.onStart();
         displayCheckBoxes(true);
diff --git a/src/com/android/contacts/list/UiIntentActions.java b/src/com/android/contacts/list/UiIntentActions.java
index e765768..f328fab 100644
--- a/src/com/android/contacts/list/UiIntentActions.java
+++ b/src/com/android/contacts/list/UiIntentActions.java
@@ -47,6 +47,18 @@
             "com.android.contacts.action.LIST_GROUP";
 
     /**
+     * The send scheme for multi email/phone picker fragment
+     */
+    public static final String SELECTION_SEND_SCHEME =
+            "com.android.contacts.extra.SELECTION_SEND_SCHEME";
+
+    /**
+     * The send title for multi email/phone picker fragment
+     */
+    public static final String SELECTION_SEND_TITLE =
+            "com.android.contacts.extra.SELECTION_SEND_TITLE";
+
+    /**
      * When in LIST_GROUP_ACTION mode, this is the group to display.
      */
     public static final String GROUP_NAME_EXTRA_KEY = "com.android.contacts.extra.GROUP";