Move MultiSelect classes up the list hierarchies (1/2)

And have the GroupMembersListFragment extend the
MultiSelectContactsListFragment

Bug 18641067

Change-Id: I6773c4da89c744af8301b65f822cda07a18010de
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index 38cd366..ac88619 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -93,7 +93,7 @@
 import com.android.contacts.list.ContactsIntentResolver;
 import com.android.contacts.list.ContactsRequest;
 import com.android.contacts.list.ContactsUnavailableFragment;
-import com.android.contacts.list.MultiSelectContactsListFragment;
+import com.android.contacts.list.DefaultContactBrowseListFragment;
 import com.android.contacts.list.MultiSelectContactsListFragment.OnCheckBoxListActionListener;
 import com.android.contacts.list.OnContactBrowserActionListener;
 import com.android.contacts.list.OnContactsUnavailableActionListener;
@@ -149,7 +149,7 @@
     /**
      * Showing a list of Contacts. Also used for showing search results in search mode.
      */
-    private MultiSelectContactsListFragment mAllFragment;
+    private DefaultContactBrowseListFragment mAllFragment;
     private GroupsFragment mGroupsFragment;
     private AccountFiltersFragment mAccountFiltersFragment;
 
@@ -375,7 +375,7 @@
         // However, if it's after screen rotation, the fragments have been re-created by
         // the fragment manager, so first see if there're already the target fragments
         // existing.
-        mAllFragment = (MultiSelectContactsListFragment)
+        mAllFragment = (DefaultContactBrowseListFragment)
                 fragmentManager.findFragmentByTag(ALL_TAG);
         mGroupsFragment = (GroupsFragment)
                 fragmentManager.findFragmentByTag(GROUPS_TAG);
@@ -383,7 +383,7 @@
                 fragmentManager.findFragmentByTag(FILTERS_TAG);
 
         if (mAllFragment == null) {
-            mAllFragment = new MultiSelectContactsListFragment();
+            mAllFragment = new DefaultContactBrowseListFragment();
             transaction.add(R.id.tab_pager, mAllFragment, ALL_TAG);
 
             if (areGroupWritableAccountsAvailable()) {
diff --git a/src/com/android/contacts/group/GroupMembersListAdapter.java b/src/com/android/contacts/group/GroupMembersListAdapter.java
index 71e8f8d..f208fc8 100644
--- a/src/com/android/contacts/group/GroupMembersListAdapter.java
+++ b/src/com/android/contacts/group/GroupMembersListAdapter.java
@@ -28,12 +28,12 @@
 import android.view.ViewGroup;
 
 import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
-import com.android.contacts.common.list.ContactEntryListAdapter;
 import com.android.contacts.common.list.ContactListItemView;
+import com.android.contacts.common.list.MultiSelectEntryContactListAdapter;
 import com.android.contacts.common.preference.ContactsPreferences;
 
 /** Group members cursor adapter. */
-public class GroupMembersListAdapter extends ContactEntryListAdapter {
+public class GroupMembersListAdapter extends MultiSelectEntryContactListAdapter {
 
     private static class GroupMembersQuery {
 
@@ -67,7 +67,7 @@
     private long mGroupId;
 
     public GroupMembersListAdapter(Context context) {
-        super(context);
+        super(context, GroupMembersQuery.CONTACT_ID);
         mUnknownNameText = context.getText(android.R.string.unknownName);
         setIndexedPartition(0);
     }
diff --git a/src/com/android/contacts/group/GroupMembersListFragment.java b/src/com/android/contacts/group/GroupMembersListFragment.java
index b8dad5e..6fe206d 100644
--- a/src/com/android/contacts/group/GroupMembersListFragment.java
+++ b/src/com/android/contacts/group/GroupMembersListFragment.java
@@ -41,9 +41,10 @@
 import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.interactions.GroupDeletionDialogFragment;
+import com.android.contacts.list.MultiSelectContactsListFragment;
 
 /** Displays the members of a group. */
-public class GroupMembersListFragment extends ContactEntryListFragment<GroupMembersListAdapter> {
+public class GroupMembersListFragment extends MultiSelectContactsListFragment {
 
     private static final String TAG = "GroupMembersList";
 
@@ -348,6 +349,11 @@
     }
 
     @Override
+    public GroupMembersListAdapter getAdapter() {
+        return (GroupMembersListAdapter) super.getAdapter();
+    }
+
+    @Override
     protected void configureAdapter() {
         super.configureAdapter();
         if (mGroupMetadata != null) {
diff --git a/src/com/android/contacts/list/ContactBrowseListFragment.java b/src/com/android/contacts/list/ContactBrowseListFragment.java
index 4b4b326..ea55333 100644
--- a/src/com/android/contacts/list/ContactBrowseListFragment.java
+++ b/src/com/android/contacts/list/ContactBrowseListFragment.java
@@ -36,7 +36,6 @@
 
 import com.android.common.widget.CompositeCursorAdapter.Partition;
 import com.android.contacts.common.list.AutoScrollListView;
-import com.android.contacts.common.list.ContactEntryListFragment;
 import com.android.contacts.common.list.ContactListAdapter;
 import com.android.contacts.common.list.ContactListFilter;
 import com.android.contacts.common.list.DirectoryPartition;
@@ -49,7 +48,7 @@
  * picking a contact with one of the PICK intents).
  */
 public abstract class ContactBrowseListFragment extends
-        ContactEntryListFragment<ContactListAdapter> {
+        MultiSelectContactsListFragment<ContactListAdapter> {
 
     private static final String TAG = "ContactList";
 
@@ -383,6 +382,11 @@
     }
 
     @Override
+    public ContactListAdapter getAdapter() {
+        return (ContactListAdapter) super.getAdapter();
+    }
+
+    @Override
     protected void configureAdapter() {
         super.configureAdapter();
 
diff --git a/src/com/android/contacts/list/DefaultContactBrowseListFragment.java b/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
index 6e721eb..97bb86a 100644
--- a/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
+++ b/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
@@ -63,6 +63,10 @@
         if (uri == null) {
             return;
         }
+        if (getAdapter().isDisplayingCheckBoxes()) {
+            super.onItemClick(position, id);
+            return;
+        }
         viewContact(uri, getAdapter().isEnterpriseContact(position));
     }
 
@@ -145,4 +149,4 @@
             }
         }
     }
-}
+}
\ No newline at end of file
diff --git a/src/com/android/contacts/list/MultiSelectContactsListFragment.java b/src/com/android/contacts/list/MultiSelectContactsListFragment.java
index aba3a28..53f5a74 100644
--- a/src/com/android/contacts/list/MultiSelectContactsListFragment.java
+++ b/src/com/android/contacts/list/MultiSelectContactsListFragment.java
@@ -16,12 +16,11 @@
 
 package com.android.contacts.list;
 
-import com.android.contacts.common.list.ContactListAdapter;
-import com.android.contacts.common.list.ContactListItemView;
-import com.android.contacts.common.list.DefaultContactListAdapter;
-import com.android.contacts.common.logging.Logger;
+import com.android.contacts.common.list.ContactEntryListFragment;
+import com.android.contacts.common.list.MultiSelectEntryContactListAdapter;
+import com.android.contacts.common.list.MultiSelectEntryContactListAdapter.SelectedContactsListener;
 import com.android.contacts.common.logging.SearchState;
-import com.android.contacts.list.MultiSelectEntryContactListAdapter.SelectedContactsListener;
+import com.android.contacts.common.logging.Logger;
 
 import android.database.Cursor;
 import android.os.Bundle;
@@ -37,7 +36,8 @@
  * Fragment containing a contact list used for browsing contacts and optionally selecting
  * multiple contacts via checkboxes.
  */
-public class MultiSelectContactsListFragment extends DefaultContactBrowseListFragment
+public abstract class MultiSelectContactsListFragment<T extends MultiSelectEntryContactListAdapter>
+        extends ContactEntryListFragment<T>
         implements SelectedContactsListener {
 
     private static final String TAG = "MultiContactsList";
@@ -113,11 +113,6 @@
     }
 
     @Override
-    public MultiSelectEntryContactListAdapter getAdapter() {
-        return (MultiSelectEntryContactListAdapter) super.getAdapter();
-    }
-
-    @Override
     protected void configureAdapter() {
         super.configureAdapter();
         getAdapter().setSelectedContactsListener(this);
@@ -184,7 +179,6 @@
                 mSearchResultClicked = true;
                 Logger.logSearchEvent(createSearchStateForSearchResultClick(position));
             }
-            super.onItemClick(position, id);
         }
         if (mCheckBoxListListener != null && getAdapter().getSelectedContactIds().size() == 0) {
             mCheckBoxListListener.onStopDisplayingCheckBoxes();
@@ -271,14 +265,4 @@
         }
         return searchState;
     }
-
-    @Override
-    protected ContactListAdapter createListAdapter() {
-        DefaultContactListAdapter adapter = new MultiSelectEntryContactListAdapter(getContext());
-        adapter.setSectionHeaderDisplayEnabled(isSectionHeaderDisplayEnabled());
-        adapter.setDisplayPhotos(true);
-        adapter.setPhotoPosition(
-                ContactListItemView.getDefaultPhotoPosition(/* opposite = */ false));
-        return adapter;
-    }
 }
diff --git a/src/com/android/contacts/list/MultiSelectEntryContactListAdapter.java b/src/com/android/contacts/list/MultiSelectEntryContactListAdapter.java
deleted file mode 100644
index 1015a9d..0000000
--- a/src/com/android/contacts/list/MultiSelectEntryContactListAdapter.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-package com.android.contacts.list;
-
-import com.android.contacts.common.list.ContactListItemView;
-import com.android.contacts.common.list.DefaultContactListAdapter;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.provider.ContactsContract;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.CheckBox;
-
-import java.util.TreeSet;
-
-/**
- * An extension of the default contact adapter that adds checkboxes and the ability
- * to select multiple contacts.
- */
-public class MultiSelectEntryContactListAdapter extends DefaultContactListAdapter {
-
-    private SelectedContactsListener mSelectedContactsListener;
-    private TreeSet<Long> mSelectedContactIds = new TreeSet<Long>();
-    private boolean mDisplayCheckBoxes;
-    private final int mContactIdColumnIndex;
-
-    public interface SelectedContactsListener {
-        void onSelectedContactsChanged();
-        void onSelectedContactsChangedViaCheckBox();
-    }
-
-    public MultiSelectEntryContactListAdapter(Context context) {
-        this(context, ContactQuery.CONTACT_ID);
-    }
-
-    /**
-     * @param contactIdColumnIndex the column index of the contact ID in the underlying cursor;
-     *         it is passed in so that this adapter can support different kinds of contact
-     *         lists (e.g. aggregate contacts or raw contacts).
-     */
-    public MultiSelectEntryContactListAdapter(Context context, int contactIdColumnIndex) {
-        super(context);
-        mContactIdColumnIndex = contactIdColumnIndex;
-    }
-
-    /**
-     * Returns the column index of the contact ID in the underlying cursor; the contact ID
-     * retrieved using this index is the value that is selected by this adapter (and returned
-     * by {@link #getSelectedContactIds}).
-     */
-    public int getContactColumnIdIndex() {
-        return mContactIdColumnIndex;
-    }
-
-    public void setSelectedContactsListener(SelectedContactsListener listener) {
-        mSelectedContactsListener = listener;
-    }
-
-    /**
-     * Returns set of selected contacts.
-     */
-    public TreeSet<Long> getSelectedContactIds() {
-        return mSelectedContactIds;
-    }
-
-    /**
-     * Returns the selected contacts as an array.
-     */
-    public long[] getSelectedContactIdsArray() {
-        final Long[] contactIds = mSelectedContactIds.toArray(
-                new Long[mSelectedContactIds.size()]);
-        final long[] result = new long[contactIds.length];
-        for (int i = 0; i < contactIds.length; i++) {
-            result[i] = contactIds[i];
-        }
-        return result;
-    }
-
-    /**
-     * Update set of selected contacts. This changes which checkboxes are set.
-     */
-    public void setSelectedContactIds(TreeSet<Long> selectedContactIds) {
-        this.mSelectedContactIds = selectedContactIds;
-        notifyDataSetChanged();
-        if (mSelectedContactsListener != null) {
-            mSelectedContactsListener.onSelectedContactsChanged();
-        }
-    }
-
-    /**
-     * Shows checkboxes beside contacts if {@param displayCheckBoxes} is {@code TRUE}.
-     * Not guaranteed to work with all configurations of this adapter.
-     */
-    public void setDisplayCheckBoxes(boolean showCheckBoxes) {
-        if (!mDisplayCheckBoxes && showCheckBoxes) {
-            setSelectedContactIds(new TreeSet<Long>());
-        }
-        mDisplayCheckBoxes = showCheckBoxes;
-        notifyDataSetChanged();
-        if (mSelectedContactsListener != null) {
-            mSelectedContactsListener.onSelectedContactsChanged();
-        }
-    }
-
-    /**
-     * Checkboxes are being displayed beside contacts.
-     */
-    public boolean isDisplayingCheckBoxes() {
-        return mDisplayCheckBoxes;
-    }
-
-    /**
-     * Toggle the checkbox beside the contact for {@param contactId}.
-     */
-    public void toggleSelectionOfContactId(long contactId) {
-        if (mSelectedContactIds.contains(contactId)) {
-            mSelectedContactIds.remove(contactId);
-        } else {
-            mSelectedContactIds.add(contactId);
-        }
-        notifyDataSetChanged();
-        if (mSelectedContactsListener != null) {
-            mSelectedContactsListener.onSelectedContactsChanged();
-        }
-    }
-
-    @Override
-    protected void bindView(View itemView, int partition, Cursor cursor, int position) {
-        super.bindView(itemView, partition, cursor, position);
-        final ContactListItemView view = (ContactListItemView) itemView;
-        bindCheckBox(view, cursor, position, partition == ContactsContract.Directory.DEFAULT);
-    }
-
-    private void bindCheckBox(ContactListItemView view, Cursor cursor, int position,
-            boolean isLocalDirectory) {
-        // Disable clicking on all contacts from remote directories when showing check boxes. We do
-        // this by telling the view to handle clicking itself.
-        view.setClickable(!isLocalDirectory && mDisplayCheckBoxes);
-        // Only show checkboxes if mDisplayCheckBoxes is enabled. Also, never show the
-        // checkbox for other directory contacts except local directory.
-        if (!mDisplayCheckBoxes || !isLocalDirectory) {
-            view.hideCheckBox();
-            return;
-        }
-        final CheckBox checkBox = view.getCheckBox();
-        final long contactId = cursor.getLong(mContactIdColumnIndex);
-        checkBox.setChecked(mSelectedContactIds.contains(contactId));
-        checkBox.setTag(contactId);
-        checkBox.setOnClickListener(mCheckBoxClickListener);
-    }
-
-    private final OnClickListener mCheckBoxClickListener = new OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            final CheckBox checkBox = (CheckBox) v;
-            final Long contactId = (Long) checkBox.getTag();
-            if (checkBox.isChecked()) {
-                mSelectedContactIds.add(contactId);
-            } else {
-                mSelectedContactIds.remove(contactId);
-            }
-            notifyDataSetChanged();
-            if (mSelectedContactsListener != null) {
-                mSelectedContactsListener.onSelectedContactsChangedViaCheckBox();
-            }
-        }
-    };
-}