| /* |
| * 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 |
| */ |
| package com.android.contacts.activities; |
| |
| import android.app.FragmentManager; |
| import android.app.FragmentTransaction; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.database.Cursor; |
| import android.net.Uri; |
| import android.os.AsyncTask; |
| import android.os.Bundle; |
| import android.provider.ContactsContract.RawContacts; |
| import android.support.v4.content.ContextCompat; |
| import android.support.v4.view.GravityCompat; |
| import android.util.Log; |
| import android.view.Menu; |
| import android.view.MenuItem; |
| import android.widget.Toast; |
| |
| import com.android.contacts.ContactSaveService; |
| import com.android.contacts.ContactsDrawerActivity; |
| import com.android.contacts.R; |
| 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.account.AccountWithDataSet; |
| import com.android.contacts.common.util.ImplicitIntentsUtil; |
| import com.android.contacts.group.GroupMembersFragment; |
| import com.android.contacts.group.GroupMetaData; |
| import com.android.contacts.group.GroupNameEditDialogFragment; |
| import com.android.contacts.group.GroupUtil; |
| 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; |
| |
| /** |
| * Displays the members of a group and allows the user to edit it. |
| */ |
| public class GroupMembersActivity extends ContactsDrawerActivity implements |
| ActionBarAdapter.Listener, |
| MultiSelectContactsListFragment.OnCheckBoxListActionListener, |
| GroupMembersFragment.GroupMembersListener { |
| |
| private static final String TAG = "GroupMembers"; |
| |
| private static final String KEY_GROUP_URI = "groupUri"; |
| private static final String KEY_GROUP_METADATA = "groupMetadata"; |
| private static final String KEY_IS_EDIT_MODE = "editMode"; |
| |
| private static final String TAG_GROUP_MEMBERS = "groupMembers"; |
| private static final String TAG_GROUP_NAME_EDIT_DIALOG = "groupNameEditDialog"; |
| |
| private static final String ACTION_DELETE_GROUP = "deleteGroup"; |
| private static final String ACTION_UPDATE_GROUP = "updateGroup"; |
| 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; |
| |
| /** |
| * Starts an Intent to add/remove the raw contacts for the given contact IDs to/from a group. |
| * Only the raw contacts that belong to the specified account are added or removed. |
| */ |
| private static class UpdateGroupMembersAsyncTask extends AsyncTask<Void, Void, Intent> { |
| |
| static final int TYPE_ADD = 0; |
| static final int TYPE_REMOVE = 1; |
| |
| private final Context mContext; |
| private final int mType; |
| private final long[] mContactIds; |
| private final long mGroupId; |
| private final String mAccountName; |
| private final String mAccountType; |
| private final String mDataSet; |
| |
| private UpdateGroupMembersAsyncTask(int type, Context context, long[] contactIds, |
| long groupId, String accountName, String accountType, String dataSet) { |
| mContext = context; |
| mType = type; |
| mContactIds = contactIds; |
| mGroupId = groupId; |
| mAccountName = accountName; |
| mAccountType = accountType; |
| mDataSet = dataSet; |
| } |
| |
| @Override |
| protected Intent doInBackground(Void... params) { |
| final long[] rawContactIds = getRawContactIds(); |
| if (rawContactIds.length == 0) { |
| return null; |
| } |
| final long[] rawContactIdsToAdd; |
| final long[] rawContactIdsToRemove; |
| final String action; |
| if (mType == TYPE_ADD) { |
| rawContactIdsToAdd = rawContactIds; |
| rawContactIdsToRemove = null; |
| action = GroupMembersActivity.ACTION_ADD_TO_GROUP; |
| } else if (mType == TYPE_REMOVE) { |
| rawContactIdsToAdd = null; |
| rawContactIdsToRemove = rawContactIds; |
| action = GroupMembersActivity.ACTION_REMOVE_FROM_GROUP; |
| } else { |
| throw new IllegalStateException("Unrecognized type " + mType); |
| } |
| return ContactSaveService.createGroupUpdateIntent( |
| mContext, mGroupId, /* newLabel */ null, rawContactIdsToAdd, |
| rawContactIdsToRemove, GroupMembersActivity.class, action); |
| } |
| |
| // ContactSaveService will log a warning if the raw contact is already a member and keep |
| // going but it is not ideal, we could also prune raw contacts that are already members. |
| private long[] getRawContactIds() { |
| final Uri.Builder builder = RawContacts.CONTENT_URI.buildUpon(); |
| // null account names are not valid, see ContactsProvider2#appendAccountFromParameter |
| if (mAccountName != null) { |
| builder.appendQueryParameter(RawContacts.ACCOUNT_NAME, mAccountName); |
| builder.appendQueryParameter(RawContacts.ACCOUNT_TYPE, mAccountType); |
| } |
| if (mDataSet != null) { |
| builder.appendQueryParameter(RawContacts.DATA_SET, mDataSet); |
| } |
| final Uri rawContactUri = builder.build(); |
| final String[] projection = new String[]{RawContacts._ID}; |
| final StringBuilder selection = new StringBuilder(); |
| final String[] selectionArgs = new String[mContactIds.length]; |
| for (int i = 0; i < mContactIds.length; i++) { |
| if (i > 0) { |
| selection.append(" OR "); |
| } |
| selection.append(RawContacts.CONTACT_ID).append("=?"); |
| selectionArgs[i] = Long.toString(mContactIds[i]); |
| } |
| final Cursor cursor = mContext.getContentResolver().query( |
| rawContactUri, projection, selection.toString(), selectionArgs, null, null); |
| final long[] rawContactIds = new long[cursor.getCount()]; |
| try { |
| int i = 0; |
| while (cursor.moveToNext()) { |
| rawContactIds[i] = cursor.getLong(0); |
| i++; |
| } |
| } finally { |
| cursor.close(); |
| } |
| return rawContactIds; |
| } |
| |
| @Override |
| protected void onPostExecute(Intent intent) { |
| if (intent == null) { |
| Toast.makeText(mContext, R.string.groupSavedErrorToast, Toast.LENGTH_SHORT).show(); |
| } else { |
| mContext.startService(intent); |
| } |
| } |
| } |
| |
| private ActionBarAdapter mActionBarAdapter; |
| |
| private GroupMembersFragment mMembersFragment; |
| |
| private Uri mGroupUri; |
| private boolean mIsEditMode; |
| |
| private GroupMetaData mGroupMetaData; |
| |
| @Override |
| public void onCreate(Bundle savedState) { |
| super.onCreate(savedState); |
| |
| // Parse the Intent |
| if (savedState != null) { |
| mGroupUri = savedState.getParcelable(KEY_GROUP_URI); |
| mIsEditMode = savedState.getBoolean(KEY_IS_EDIT_MODE); |
| mGroupMetaData = savedState.getParcelable(KEY_GROUP_METADATA); |
| } else { |
| mGroupUri = getIntent().getData(); |
| setTitle(getIntent().getStringExtra(GroupUtil.EXTRA_GROUP_NAME)); |
| } |
| if (mGroupUri == null) { |
| setResultCanceledAndFinish(R.string.groupLoadErrorToast); |
| return; |
| } |
| |
| // Set up the view |
| setContentView(R.layout.group_members_activity); |
| |
| findViewById(R.id.toolbar_frame).setBackgroundColor( |
| ContextCompat.getColor(this, R.color.group_primary_color)); |
| |
| // Set up the action bar |
| mActionBarAdapter = new ActionBarAdapter(this, this, getSupportActionBar(), |
| /* portraitTabs */ null, /* landscapeTabs */ null, mToolbar, |
| R.string.enter_contact_name); |
| mActionBarAdapter.setShowHomeIcon(true); |
| |
| // Add the members list fragment |
| final FragmentManager fragmentManager = getFragmentManager(); |
| mMembersFragment = (GroupMembersFragment) |
| fragmentManager.findFragmentByTag(TAG_GROUP_MEMBERS); |
| if (mMembersFragment == null) { |
| mMembersFragment = GroupMembersFragment.newInstance(getIntent().getData()); |
| fragmentManager.beginTransaction().replace(R.id.fragment_container_inner, |
| mMembersFragment, TAG_GROUP_MEMBERS).commitAllowingStateLoss(); |
| } |
| mMembersFragment.setListener(this); |
| if (mGroupMetaData != null && mGroupMetaData.editable) { |
| mMembersFragment.setCheckBoxListListener(this); |
| } |
| |
| // Delay action bar initialization until after the fragment is added |
| final ContactsRequest contactsRequest = new ContactsRequest(); |
| contactsRequest.setActionCode(ContactsRequest.ACTION_GROUP); |
| mActionBarAdapter.initialize(savedState, contactsRequest); |
| } |
| |
| @Override |
| public void onSaveInstanceState(Bundle outState) { |
| super.onSaveInstanceState(outState); |
| if (mActionBarAdapter != null) { |
| mActionBarAdapter.onSaveInstanceState(outState); |
| } |
| outState.putParcelable(KEY_GROUP_URI, mGroupUri); |
| outState.putBoolean(KEY_IS_EDIT_MODE, mIsEditMode); |
| outState.putParcelable(KEY_GROUP_METADATA, mGroupMetaData); |
| } |
| |
| // Invoked with results from the ContactSaveService |
| @Override |
| protected void onNewIntent(Intent newIntent) { |
| if (ContactsDrawerActivity.ACTION_CREATE_GROUP.equals(newIntent.getAction())) { |
| super.onNewIntent(newIntent); |
| return; |
| } |
| if (isDeleteAction(newIntent.getAction())) { |
| toast(R.string.groupDeletedToast); |
| setResult(RESULT_OK); |
| finish(); |
| } else if (isSaveAction(newIntent.getAction())) { |
| final Uri groupUri = newIntent.getData(); |
| if (groupUri == null) { |
| setResultCanceledAndFinish(R.string.groupSavedErrorToast); |
| return; |
| } |
| if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "Received group URI " + groupUri); |
| |
| mGroupUri = groupUri; |
| |
| toast(getToastMessageForSaveAction(newIntent.getAction())); |
| |
| if (mIsEditMode) { |
| // If we're removing group members one at a time, don't reload the fragment so |
| // the user can continue to remove group members one by one |
| if (getGroupCount() == 1) { |
| // If we're deleting the last group member, exit edit mode |
| onBackPressed(); |
| } |
| } else if (!ACTION_REMOVE_FROM_GROUP.equals(newIntent.getAction())) { |
| replaceGroupMembersFragment(); |
| invalidateOptionsMenu(); |
| } |
| } |
| } |
| |
| private static boolean isDeleteAction(String action) { |
| return ACTION_DELETE_GROUP.equals(action); |
| } |
| |
| private static boolean isSaveAction(String action) { |
| return ACTION_UPDATE_GROUP.equals(action) |
| || ACTION_ADD_TO_GROUP.equals(action) |
| || ACTION_REMOVE_FROM_GROUP.equals(action); |
| } |
| |
| private static int getToastMessageForSaveAction(String action) { |
| if (ACTION_UPDATE_GROUP.equals(action)) return R.string.groupUpdatedToast; |
| if (ACTION_ADD_TO_GROUP.equals(action)) return R.string.groupMembersAddedToast; |
| if (ACTION_REMOVE_FROM_GROUP.equals(action)) return R.string.groupMembersRemovedToast; |
| throw new IllegalArgumentException("Unhanded contact save action " + action); |
| } |
| |
| private int getGroupCount() { |
| return mMembersFragment != null && mMembersFragment.getAdapter() != null |
| ? mMembersFragment.getAdapter().getCount() : -1; |
| } |
| |
| private void replaceGroupMembersFragment() { |
| mMembersFragment = GroupMembersFragment.newInstance(mGroupUri); |
| mMembersFragment.setListener(this); |
| final FragmentTransaction transaction = getFragmentManager().beginTransaction(); |
| addGroupsAndFiltersFragments(transaction); |
| transaction.replace(R.id.fragment_container_inner, mMembersFragment, TAG_GROUP_MEMBERS) |
| .commitAllowingStateLoss(); |
| if (mGroupMetaData != null && mGroupMetaData.editable) { |
| mMembersFragment.setCheckBoxListListener(this); |
| } |
| } |
| |
| @Override |
| protected void onGroupMenuItemClicked(long groupId, String title) { |
| if (mGroupMetaData.groupId != groupId) { |
| super.onGroupMenuItemClicked(groupId, title); |
| } |
| } |
| |
| @Override |
| protected boolean shouldFinish() { |
| return true; |
| } |
| |
| @Override |
| protected void launchFindDuplicates() { |
| super.launchFindDuplicates(); |
| finish(); |
| } |
| |
| public boolean isEditMode() { |
| return mIsEditMode; |
| } |
| |
| @Override |
| public boolean onCreateOptionsMenu(Menu menu) { |
| if (mGroupMetaData == null) { |
| // Hide menu options until metadata is fully loaded |
| return false; |
| } |
| super.onCreateOptionsMenu(menu); |
| getMenuInflater().inflate(R.menu.view_group, menu); |
| return true; |
| } |
| |
| @Override |
| public boolean onPrepareOptionsMenu(Menu menu) { |
| final boolean isSelectionMode = mActionBarAdapter.isSelectionMode(); |
| final boolean isGroupEditable = mGroupMetaData != null && mGroupMetaData.editable; |
| final boolean isGroupReadOnly = mGroupMetaData != null && mGroupMetaData.readOnly; |
| |
| setVisible(menu, R.id.menu_add, isGroupEditable && !isSelectionMode); |
| setVisible(menu, R.id.menu_rename_group, !isGroupReadOnly && !isSelectionMode); |
| setVisible(menu, R.id.menu_delete_group, !isGroupReadOnly && !isSelectionMode); |
| setVisible(menu, R.id.menu_edit_group, isGroupEditable && !mIsEditMode && !isSelectionMode |
| && !isGroupEmpty()); |
| setVisible(menu, R.id.menu_remove_from_group, isGroupEditable && isSelectionMode && |
| !mIsEditMode); |
| |
| return true; |
| } |
| |
| private boolean isGroupEmpty() { |
| return mMembersFragment != null && mMembersFragment.getAdapter() != null && |
| mMembersFragment.getAdapter().isEmpty(); |
| } |
| |
| private static void setVisible(Menu menu, int id, boolean visible) { |
| final MenuItem menuItem = menu.findItem(id); |
| if (menuItem != null) { |
| menuItem.setVisible(visible); |
| } |
| } |
| |
| public void startGroupAddMemberActivity() { |
| startActivityForResult(GroupUtil.createPickMemberIntent(this, mGroupMetaData, |
| mMembersFragment.getMemberContactIds()), RESULT_GROUP_ADD_MEMBER); |
| } |
| |
| @Override |
| public boolean onOptionsItemSelected(MenuItem item) { |
| switch (item.getItemId()) { |
| case android.R.id.home: { |
| onBackPressed(); |
| return true; |
| } |
| case R.id.menu_add: { |
| startGroupAddMemberActivity(); |
| return true; |
| } |
| case R.id.menu_rename_group: { |
| GroupNameEditDialogFragment.newInstanceForUpdate( |
| new AccountWithDataSet(mGroupMetaData.accountName, |
| mGroupMetaData.accountType, mGroupMetaData.dataSet), |
| ACTION_UPDATE_GROUP, mGroupMetaData.groupId, mGroupMetaData.groupName) |
| .show(getFragmentManager(), TAG_GROUP_NAME_EDIT_DIALOG); |
| return true; |
| } |
| case R.id.menu_delete_group: { |
| deleteGroup(); |
| return true; |
| } |
| case R.id.menu_edit_group: { |
| if (mMembersFragment == null) { |
| return false; |
| } |
| mIsEditMode = true; |
| mActionBarAdapter.setSelectionMode(true); |
| mMembersFragment.displayDeleteButtons(true); |
| return true; |
| } |
| case R.id.menu_remove_from_group: { |
| if (mMembersFragment == null) { |
| return false; |
| } |
| logListEvent(); |
| removeSelectedContacts(); |
| return true; |
| } |
| } |
| return super.onOptionsItemSelected(item); |
| } |
| |
| private void deleteGroup() { |
| if (mMembersFragment.getMemberCount() == 0) { |
| final Intent intent = ContactSaveService.createGroupDeletionIntent(this, |
| mGroupMetaData.groupId); |
| startService(intent); |
| finish(); |
| } else { |
| GroupDeletionDialogFragment.show(getFragmentManager(), mGroupMetaData.groupId, |
| mGroupMetaData.groupName); |
| } |
| } |
| |
| private void logListEvent() { |
| Logger.logListEvent( |
| ListEvent.ActionType.REMOVE_LABEL, |
| mMembersFragment.getListType(), |
| mMembersFragment.getAdapter().getCount(), |
| /* clickedIndex */ -1, |
| mMembersFragment.getAdapter().getSelectedContactIdsArray().length); |
| } |
| |
| private void removeSelectedContacts() { |
| final long[] contactIds = mMembersFragment.getAdapter().getSelectedContactIdsArray(); |
| new UpdateGroupMembersAsyncTask(UpdateGroupMembersAsyncTask.TYPE_REMOVE, |
| this, contactIds, mGroupMetaData.groupId, mGroupMetaData.accountName, |
| mGroupMetaData.accountType, mGroupMetaData.dataSet).execute(); |
| |
| mActionBarAdapter.setSelectionMode(false); |
| } |
| |
| @Override |
| public void onBackPressed() { |
| if (!isSafeToCommitTransactions()) { |
| return; |
| } |
| if (mDrawer.isDrawerOpen(GravityCompat.START)) { |
| mDrawer.closeDrawer(GravityCompat.START); |
| } else if (mIsEditMode) { |
| mIsEditMode = false; |
| mActionBarAdapter.setSelectionMode(false); |
| if (mMembersFragment != null) { |
| mMembersFragment.displayDeleteButtons(false); |
| } |
| } else if (mActionBarAdapter.isSelectionMode()) { |
| mActionBarAdapter.setSelectionMode(false); |
| if (mMembersFragment != null) { |
| mMembersFragment.displayCheckBoxes(false); |
| } |
| } else if (mActionBarAdapter.isSearchMode()) { |
| mActionBarAdapter.setSearchMode(false); |
| } else { |
| switchToAllContacts(); |
| super.onBackPressed(); |
| } |
| } |
| |
| @Override |
| protected void onActivityResult(int requestCode, int resultCode, Intent data) { |
| if (requestCode == RESULT_GROUP_ADD_MEMBER && resultCode == 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; |
| } |
| } |
| new UpdateGroupMembersAsyncTask(UpdateGroupMembersAsyncTask.TYPE_ADD, |
| this, contactIds, mGroupMetaData.groupId, mGroupMetaData.accountName, |
| mGroupMetaData.accountType, mGroupMetaData.dataSet).execute(); |
| } |
| } |
| |
| private void setResultCanceledAndFinish(int resId) { |
| toast(resId); |
| setResult(RESULT_CANCELED); |
| finish(); |
| } |
| |
| private void toast(int resId) { |
| if (resId >= 0) { |
| Toast.makeText(this, resId, Toast.LENGTH_SHORT).show(); |
| } |
| } |
| |
| // ActionBarAdapter callbacks |
| |
| @Override |
| public void onAction(int action) { |
| switch (action) { |
| case ActionBarAdapter.Listener.Action.START_SELECTION_MODE: |
| if (mMembersFragment != null) { |
| if (mIsEditMode) { |
| mMembersFragment.displayDeleteButtons(true); |
| mActionBarAdapter.setActionBarTitle(getString(R.string.title_edit_group)); |
| } else { |
| mMembersFragment.displayCheckBoxes(true); |
| } |
| } |
| invalidateOptionsMenu(); |
| showFabWithAnimation(/* showFabWithAnimation = */ false); |
| break; |
| case ActionBarAdapter.Listener.Action.STOP_SEARCH_AND_SELECTION_MODE: |
| mActionBarAdapter.setSearchMode(false); |
| if (mMembersFragment != null) { |
| if (mIsEditMode) { |
| mMembersFragment.displayDeleteButtons(false); |
| } else { |
| mMembersFragment.displayCheckBoxes(false); |
| } |
| } |
| invalidateOptionsMenu(); |
| showFabWithAnimation(/* showFabWithAnimation */ true); |
| break; |
| case ActionBarAdapter.Listener.Action.BEGIN_STOPPING_SEARCH_AND_SELECTION_MODE: |
| showFabWithAnimation(/* showFabWithAnimation */ true); |
| break; |
| } |
| } |
| |
| private void showFabWithAnimation(boolean showFab) { |
| // TODO: b/28497108 |
| } |
| |
| @Override |
| public void onSelectedTabChanged() { |
| } |
| |
| @Override |
| public void onUpButtonPressed() { |
| onBackPressed(); |
| } |
| |
| // MultiSelect checkbox callbacks |
| |
| @Override |
| public void onStartDisplayingCheckBoxes() { |
| mActionBarAdapter.setSelectionMode(true); |
| } |
| |
| @Override |
| public void onSelectedContactIdsChanged() { |
| if (mIsEditMode) { |
| mActionBarAdapter.setActionBarTitle(getString(R.string.title_edit_group)); |
| } else { |
| mActionBarAdapter.setSelectionCount(mMembersFragment.getSelectedContactIds().size()); |
| } |
| } |
| |
| @Override |
| public void onStopDisplayingCheckBoxes() { |
| mActionBarAdapter.setSelectionMode(false); |
| } |
| |
| // GroupMembersFragment callbacks |
| |
| @Override |
| public void onGroupMetadataLoaded(GroupMetaData groupMetaData) { |
| mGroupMetaData = groupMetaData; |
| updateGroupMenu(mGroupMetaData); |
| setTitle(mGroupMetaData.groupName); |
| invalidateOptionsMenu(); |
| } |
| |
| @Override |
| public void onGroupMetadataLoadFailed() { |
| setResultCanceledAndFinish(R.string.groupLoadErrorToast); |
| } |
| |
| protected GroupMetaData getGroupMetaData() { |
| return mGroupMetaData; |
| } |
| |
| @Override |
| public void onGroupMemberListItemClicked(int position, Uri contactLookupUri) { |
| final int count = mMembersFragment.getAdapter().getCount(); |
| Logger.logListEvent(ListEvent.ActionType.CLICK, ListEvent.ListType.GROUP, count, |
| /* clickedIndex */ position, /* numSelected */ 0); |
| final Intent intent = ImplicitIntentsUtil.composeQuickContactIntent(this, |
| contactLookupUri, QuickContactActivity.MODE_FULLY_EXPANDED); |
| intent.putExtra(QuickContactActivity.EXTRA_PREVIOUS_SCREEN_TYPE, ScreenType.LIST_GROUP); |
| startActivity(intent); |
| } |
| |
| @Override |
| public void onGroupMemberListItemDeleted(int position, long contactId) { |
| final long[] contactIds = new long[1]; |
| contactIds[0] = contactId; |
| new UpdateGroupMembersAsyncTask(UpdateGroupMembersAsyncTask.TYPE_REMOVE, |
| this, contactIds, mGroupMetaData.groupId, mGroupMetaData.accountName, |
| mGroupMetaData.accountType, mGroupMetaData.dataSet).execute(); |
| } |
| } |