Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f9779ef9 authored by Walter Jang's avatar Walter Jang
Browse files

Add group member selection to ContentSelectionActivity (1/2)

* The GroupMemberPickListAdapter queries RawContacts to get
  the list of potential group members
* The raw contact IDs of existing group members are passed
  in to the pick fragment and these are filtered out of
  results by a CursorWrapper.
* Since we can't get the contact photo ID and contact lookup
  URI from the RawContacts query, these are also provided
  by the CursorWrapper.
* Finally, we move the current search to add contact to group
  functionality in place behind the ActionBar search icon,
  moved to the overflow menu.

Bug 28707265
Bug 18641067

Change-Id: Ifde5446e8ce9c0ed27cd2f98fd704ca669c45f59
parent d6f1be4d
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -23,6 +23,11 @@
        android:title="@string/menu_addToGroup"
        contacts:showAsAction="ifRoom" />

    <item
        android:id="@+id/menu_search"
        android:icon="@drawable/ic_ab_search"
        android:title="@string/menu_search" />

    <item
        android:id="@+id/menu_rename_group"
        android:title="@string/menu_renameGroup"/>
+0 −8
Original line number Diff line number Diff line
@@ -80,14 +80,6 @@ public final class GroupMemberLoader extends CursorLoader {
        return new GroupMemberLoader(context, groupId, GroupEditorQuery.PROJECTION);
    }

    /**
     * @return GroupMemberLoader object used in group detail page.
     */
    public static GroupMemberLoader constructLoaderForGroupDetailQuery(
            Context context, long groupId) {
        return new GroupMemberLoader(context, groupId, GroupDetailQuery.PROJECTION);
    }

    private GroupMemberLoader(Context context, long groupId, String[] projection) {
        super(context);
        mGroupId = groupId;
+30 −4
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.contacts.activities;

import android.app.ActionBar;
import android.app.ActionBar.LayoutParams;
import android.app.Activity;
import android.app.Fragment;
import android.content.ActivityNotFoundException;
import android.content.Context;
@@ -26,7 +25,6 @@ import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Intents.Insert;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
@@ -46,6 +44,8 @@ import com.android.contacts.ContactsActivity;
import com.android.contacts.R;
import com.android.contacts.common.activity.RequestPermissionsActivity;
import com.android.contacts.common.list.ContactEntryListFragment;
import com.android.contacts.list.GroupMemberPickerFragment;
import com.android.contacts.common.model.account.AccountWithDataSet;
import com.android.contacts.editor.EditorIntents;
import com.android.contacts.list.ContactPickerFragment;
import com.android.contacts.list.ContactsIntentResolver;
@@ -62,7 +62,7 @@ import com.android.contacts.list.OnPostalAddressPickerActionListener;
import com.android.contacts.common.list.PhoneNumberPickerFragment;
import com.android.contacts.list.PostalAddressPickerFragment;

import java.util.Set;
import java.util.ArrayList;

/**
 * Displays a list of contacts (or phone numbers or postal addresses) for the
@@ -139,9 +139,10 @@ public class ContactSelectionActivity extends ContactsActivity
                .inflate(R.layout.custom_action_bar, null);
        mSearchView = (SearchView) mSearchViewContainer.findViewById(R.id.search_view);

        // Postal address pickers (and legacy pickers) don't support search, so just show
        // Postal address  group member,and legacy pickers don't support search, so just show
        // "HomeAsUp" button and title.
        if (mRequest.getActionCode() == ContactsRequest.ACTION_PICK_POSTAL ||
                mRequest.getActionCode() == ContactsRequest.ACTION_PICK_GROUP_MEMBERS ||
                mRequest.isLegacyCompatibilityMode()) {
            mSearchView.setVisibility(View.GONE);
            if (actionBar != null) {
@@ -270,6 +271,11 @@ public class ContactSelectionActivity extends ContactsActivity
                setTitle(R.string.titleJoinContactDataWith);
                break;
            }

            case ContactsRequest.ACTION_PICK_GROUP_MEMBERS: {
                setTitle(R.string.contactPickerActivityTitle);
                break;
            }
        }
    }

@@ -350,6 +356,15 @@ public class ContactSelectionActivity extends ContactsActivity
                break;
            }

            case ContactsRequest.ACTION_PICK_GROUP_MEMBERS: {
                final AccountWithDataSet account = getIntent().getParcelableExtra(
                        UiIntentActions.GROUP_ACCOUNT_WITH_DATA_SET);
                final ArrayList<String> rawContactIds = getIntent().getStringArrayListExtra(
                        UiIntentActions.GROUP_RAW_CONTACT_IDS);
                mListFragment = GroupMemberPickerFragment.newInstance(account, rawContactIds);
                break;
            }

            default:
                throw new IllegalStateException("Invalid action code: " + mActionCode);
        }
@@ -389,6 +404,9 @@ public class ContactSelectionActivity extends ContactsActivity
        } else if (mListFragment instanceof JoinContactListFragment) {
            ((JoinContactListFragment) mListFragment).setOnContactPickerActionListener(
                    new JoinContactActionListener());
        } else if (mListFragment instanceof GroupMemberPickerFragment) {
            ((GroupMemberPickerFragment) mListFragment).setListener(
                    new GroupMemberPickerListener());
        } else {
            throw new IllegalStateException("Unsupported list fragment type: " + mListFragment);
        }
@@ -462,6 +480,14 @@ public class ContactSelectionActivity extends ContactsActivity
        }
    }

    private final class GroupMemberPickerListener implements GroupMemberPickerFragment.Listener {

        @Override
        public void onGroupMemberClicked(Uri uri) {
            returnPickerResult(uri);
        }
    }

    private final class PostalAddressPickerActionListener implements
            OnPostalAddressPickerActionListener {
        @Override
+58 −2
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.content.Loader;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Intents;
import android.support.v7.widget.Toolbar;
import android.util.Log;
@@ -41,13 +42,14 @@ import com.android.contacts.GroupMemberLoader;
import com.android.contacts.GroupMemberLoader.GroupEditorQuery;
import com.android.contacts.R;
import com.android.contacts.common.editor.SelectAccountDialogFragment;
import com.android.contacts.common.logging.Logger;
import com.android.contacts.common.logging.ListEvent;
import com.android.contacts.common.logging.Logger;
import com.android.contacts.common.logging.ScreenEvent.ScreenType;
import com.android.contacts.common.model.AccountTypeManager;
import com.android.contacts.common.model.account.AccountWithDataSet;
import com.android.contacts.common.util.AccountsListAdapter.AccountListFilter;
import com.android.contacts.common.util.ImplicitIntentsUtil;
import com.android.contacts.group.GroupMembersListAdapter.GroupMembersQuery;
import com.android.contacts.group.GroupMembersListFragment;
import com.android.contacts.group.GroupMetadata;
import com.android.contacts.group.GroupNameEditDialogFragment;
@@ -57,6 +59,7 @@ import com.android.contacts.group.SuggestedMemberListAdapter.SuggestedMember;
import com.android.contacts.interactions.GroupDeletionDialogFragment;
import com.android.contacts.list.ContactsRequest;
import com.android.contacts.list.MultiSelectContactsListFragment;
import com.android.contacts.list.UiIntentActions;
import com.android.contacts.quickcontact.QuickContactActivity;

import java.util.ArrayList;
@@ -90,6 +93,8 @@ public class GroupMembersActivity extends AppCompatContactsActivity implements
    private static final String ACTION_ADD_TO_GROUP = "addToGroup";
    private static final String ACTION_REMOVE_FROM_GROUP = "removeFromGroup";

    private static final int RESULT_GROUP_ADD_MEMBER = 100;

    /** Loader callbacks for existing group members for the autocomplete text view. */
    private final LoaderCallbacks<Cursor> mGroupMemberCallbacks = new LoaderCallbacks<Cursor>() {

@@ -314,6 +319,9 @@ public class GroupMembersActivity extends AppCompatContactsActivity implements
        setVisible(menu, R.id.menu_add,
                isGroupEditable && !isSelectionMode && !isSearchMode);

        setVisible(menu, R.id.menu_search,
                isGroupEditable && !isSelectionMode && !isSearchMode);

        setVisible(menu, R.id.menu_rename_group,
                isGroupEditable && !isSelectionMode && !isSearchMode);

@@ -341,6 +349,16 @@ public class GroupMembersActivity extends AppCompatContactsActivity implements
                return true;
            }
            case R.id.menu_add: {
                final Intent intent = new Intent(Intent.ACTION_PICK);
                intent.setType(ContactsContract.Groups.CONTENT_ITEM_TYPE);
                intent.putExtra(UiIntentActions.GROUP_ACCOUNT_WITH_DATA_SET,
                        mGroupMetadata.createAccountWithDataSet());
                intent.putExtra(UiIntentActions.GROUP_RAW_CONTACT_IDS,
                        getExistingGroupMemberRawContactIds());
                startActivityForResult(intent, RESULT_GROUP_ADD_MEMBER);
                return true;
            }
            case R.id.menu_search: {
                if (mActionBarAdapter != null) {
                    mActionBarAdapter.setSearchMode(true);
                }
@@ -367,6 +385,17 @@ public class GroupMembersActivity extends AppCompatContactsActivity implements
        return super.onOptionsItemSelected(item);
    }

    private ArrayList<String> getExistingGroupMemberRawContactIds() {
        final ArrayList<String> rawContactIds = new ArrayList<>();
        final Cursor cursor = mMembersListFragment.getAdapter().getCursor(/* partition */ 0);
        if (cursor != null && cursor.moveToFirst()) {
            do {
                rawContactIds.add(cursor.getString(GroupMembersQuery.RAW_CONTACT_ID));
            } while (cursor.moveToNext());
        }
        return rawContactIds;
    }

    private void deleteGroup() {
        if (mGroupMetadata.memberCount == 0) {
            final Intent intent = ContactSaveService.createGroupDeletionIntent(
@@ -417,6 +446,33 @@ public class GroupMembersActivity extends AppCompatContactsActivity implements
        }
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == RESULT_GROUP_ADD_MEMBER && resultCode == RESULT_OK && data != null) {
            final Uri rawContactUri = data.getData();
            if (rawContactUri != null) {
                long rawContactId = -1;
                try {
                    rawContactId = Long.parseLong(rawContactUri.getLastPathSegment());
                } catch (NumberFormatException ignored) {}
                if (rawContactId < 0) {
                    Toast.makeText(this, R.string.groupSavedErrorToast, Toast.LENGTH_SHORT).show();
                    Log.w(TAG, "Failed to parse ID from pick group member result uri " +
                            rawContactUri);
                    return;
                }
                final long[] rawContactIdsToAdd = new long[1];
                rawContactIdsToAdd[0] = rawContactId;
                final Intent intent = ContactSaveService.createGroupUpdateIntent(
                        GroupMembersActivity.this, mGroupMetadata.groupId, /* newLabel */ null,
                        rawContactIdsToAdd, /* rawContactIdsToRemove */ null,
                        GroupMembersActivity.class, GroupMembersActivity.ACTION_ADD_TO_GROUP);
                startService(intent);
            }
        }
    }

    private boolean isSelectAccountDialogFound() {
        return getFragmentManager().findFragmentByTag(TAG_SELECT_ACCOUNT_DIALOG) != null;
    }
+1 −1
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ import com.android.contacts.common.preference.ContactsPreferences;
/** Group members cursor adapter. */
public class GroupMembersListAdapter extends MultiSelectEntryContactListAdapter {

    private static class GroupMembersQuery {
    public static class GroupMembersQuery {

        private static final String[] PROJECTION_PRIMARY = new String[] {
                Data.CONTACT_ID,
Loading