blob: 44bda744e2b3cc104d78001abbc3053bcc5ce5ef [file] [log] [blame]
Walter Jang4715c042016-04-06 17:14:23 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16package com.android.contacts.group;
17
Walter Jangec807e12016-06-27 12:10:40 -070018import android.app.Activity;
Walter Jang44e91b12016-05-22 12:37:00 -070019import android.app.LoaderManager.LoaderCallbacks;
Sean Midfordff6f1bb2016-10-12 09:48:23 -070020import android.content.ContentResolver;
Walter Jang44e91b12016-05-22 12:37:00 -070021import android.content.CursorLoader;
Wenyi Wang6927bf32016-08-15 18:31:24 -070022import android.content.Intent;
Walter Jang44e91b12016-05-22 12:37:00 -070023import android.content.Loader;
24import android.database.Cursor;
Walter Jang2552c112016-06-17 14:29:09 -070025import android.database.CursorWrapper;
Walter Jang4715c042016-04-06 17:14:23 -070026import android.net.Uri;
27import android.os.Bundle;
Wenyi Wang17fe7982016-10-05 13:54:09 -070028import android.os.Handler;
29import android.os.Message;
Sean Midfordff6f1bb2016-10-12 09:48:23 -070030import android.provider.ContactsContract;
Wenyi Wang38860a52016-06-24 17:47:34 -070031import android.provider.ContactsContract.Contacts;
Sean Midfordff6f1bb2016-10-12 09:48:23 -070032import android.text.TextUtils;
Walter Jang44e91b12016-05-22 12:37:00 -070033import android.util.Log;
yaolud8effeb2016-06-29 14:42:38 -070034import android.view.Gravity;
Walter Jang4715c042016-04-06 17:14:23 -070035import android.view.LayoutInflater;
Wenyi Wang6927bf32016-08-15 18:31:24 -070036import android.view.Menu;
37import android.view.MenuInflater;
38import android.view.MenuItem;
Walter Jang4715c042016-04-06 17:14:23 -070039import android.view.View;
40import android.view.ViewGroup;
yaolud8effeb2016-06-29 14:42:38 -070041import android.widget.Button;
42import android.widget.FrameLayout;
43import android.widget.ImageView;
44import android.widget.LinearLayout;
Wenyi Wang6927bf32016-08-15 18:31:24 -070045import android.widget.Toast;
Walter Jang4715c042016-04-06 17:14:23 -070046
Wenyi Wang6927bf32016-08-15 18:31:24 -070047import com.android.contacts.ContactSaveService;
Wenyi Wang79675452016-08-17 10:43:28 -070048import com.android.contacts.ContactsDrawerActivity;
Walter Jang44e91b12016-05-22 12:37:00 -070049import com.android.contacts.GroupMetaDataLoader;
Walter Jang4715c042016-04-06 17:14:23 -070050import com.android.contacts.R;
Wenyi Wang6927bf32016-08-15 18:31:24 -070051import com.android.contacts.activities.ActionBarAdapter;
Sean Midfordff6f1bb2016-10-12 09:48:23 -070052import com.android.contacts.common.ContactsUtils;
Wenyi Wang38860a52016-06-24 17:47:34 -070053import com.android.contacts.common.list.ContactsSectionIndexer;
Wenyi Wang88a9f242016-08-25 16:07:15 -070054import com.android.contacts.common.list.MultiSelectEntryContactListAdapter.DeleteContactListener;
Wenyi Wang6927bf32016-08-15 18:31:24 -070055import com.android.contacts.common.logging.ListEvent;
Walter Jangf9779ef2016-05-25 12:23:05 -070056import com.android.contacts.common.logging.ListEvent.ListType;
Wenyi Wang6927bf32016-08-15 18:31:24 -070057import com.android.contacts.common.logging.Logger;
58import com.android.contacts.common.logging.ScreenEvent;
Wenyi Wang1114fde2016-07-11 21:44:02 -070059import com.android.contacts.common.model.account.AccountWithDataSet;
Wenyi Wang6927bf32016-08-15 18:31:24 -070060import com.android.contacts.common.util.ImplicitIntentsUtil;
Walter Jang90f2fe52016-06-17 16:38:43 -070061import com.android.contacts.group.GroupMembersAdapter.GroupMembersQuery;
Wenyi Wang6927bf32016-08-15 18:31:24 -070062import com.android.contacts.interactions.GroupDeletionDialogFragment;
63import com.android.contacts.list.ContactsRequest;
Walter Jange9ea4f02016-05-10 09:39:46 -070064import com.android.contacts.list.MultiSelectContactsListFragment;
Wenyi Wang6927bf32016-08-15 18:31:24 -070065import com.android.contacts.list.UiIntentActions;
James Laskey1387e782016-10-26 13:34:23 -070066import com.android.contactsbind.FeedbackHelper;
Sean Midford4b2ccd22016-10-14 13:03:49 -070067import com.google.common.primitives.Longs;
Walter Jang4715c042016-04-06 17:14:23 -070068
Walter Jang2552c112016-06-17 14:29:09 -070069import java.util.ArrayList;
Sean Midford4b2ccd22016-10-14 13:03:49 -070070import java.util.HashMap;
Walter Jang2552c112016-06-17 14:29:09 -070071import java.util.HashSet;
Wenyi Wang38860a52016-06-24 17:47:34 -070072import java.util.List;
Sean Midford4b2ccd22016-10-14 13:03:49 -070073import java.util.Map;
Walter Jang2552c112016-06-17 14:29:09 -070074import java.util.Set;
75
Walter Jang4715c042016-04-06 17:14:23 -070076/** Displays the members of a group. */
Wenyi Wang88a9f242016-08-25 16:07:15 -070077public class GroupMembersFragment extends MultiSelectContactsListFragment<GroupMembersAdapter> {
Walter Jang4715c042016-04-06 17:14:23 -070078
Walter Jang44e91b12016-05-22 12:37:00 -070079 private static final String TAG = "GroupMembers";
80
Wenyi Wang6927bf32016-08-15 18:31:24 -070081 private static final String KEY_IS_EDIT_MODE = "editMode";
Walter Jang44e91b12016-05-22 12:37:00 -070082 private static final String KEY_GROUP_URI = "groupUri";
Walter Jang4715c042016-04-06 17:14:23 -070083 private static final String KEY_GROUP_METADATA = "groupMetadata";
84
Wenyi Wang6927bf32016-08-15 18:31:24 -070085 public static final String TAG_GROUP_NAME_EDIT_DIALOG = "groupNameEditDialog";
86
Walter Jang44e91b12016-05-22 12:37:00 -070087 private static final String ARG_GROUP_URI = "groupUri";
88
89 private static final int LOADER_GROUP_METADATA = 0;
Wenyi Wang17fe7982016-10-05 13:54:09 -070090 private static final int MSG_FAIL_TO_LOAD = 1;
Wenyi Wang6927bf32016-08-15 18:31:24 -070091 private static final int RESULT_GROUP_ADD_MEMBER = 100;
Walter Jang4715c042016-04-06 17:14:23 -070092
Walter Jang2552c112016-06-17 14:29:09 -070093 /** Filters out duplicate contacts. */
94 private class FilterCursorWrapper extends CursorWrapper {
95
96 private int[] mIndex;
97 private int mCount = 0;
98 private int mPos = 0;
99
100 public FilterCursorWrapper(Cursor cursor) {
101 super(cursor);
102
103 mCount = super.getCount();
104 mIndex = new int[mCount];
105
Wenyi Wang38860a52016-06-24 17:47:34 -0700106 final List<Integer> indicesToFilter = new ArrayList<>();
107
Walter Jang2552c112016-06-17 14:29:09 -0700108 if (Log.isLoggable(TAG, Log.VERBOSE)) {
109 Log.v(TAG, "Group members CursorWrapper start: " + mCount);
110 }
111
Wenyi Wang38860a52016-06-24 17:47:34 -0700112 final Bundle bundle = cursor.getExtras();
113 final String sections[] = bundle.getStringArray(Contacts
114 .EXTRA_ADDRESS_BOOK_INDEX_TITLES);
115 final int counts[] = bundle.getIntArray(Contacts.EXTRA_ADDRESS_BOOK_INDEX_COUNTS);
116 final ContactsSectionIndexer indexer = (sections == null || counts == null)
117 ? null : new ContactsSectionIndexer(sections, counts);
118
Walter Jang2552c112016-06-17 14:29:09 -0700119 mGroupMemberContactIds.clear();
120 for (int i = 0; i < mCount; i++) {
121 super.moveToPosition(i);
122 final String contactId = getString(GroupMembersQuery.CONTACT_ID);
123 if (!mGroupMemberContactIds.contains(contactId)) {
124 mIndex[mPos++] = i;
125 mGroupMemberContactIds.add(contactId);
Wenyi Wang38860a52016-06-24 17:47:34 -0700126 } else {
127 indicesToFilter.add(i);
Walter Jang2552c112016-06-17 14:29:09 -0700128 }
129 }
Wenyi Wang38860a52016-06-24 17:47:34 -0700130
131 if (indexer != null && GroupUtil.needTrimming(mCount, counts, indexer.getPositions())) {
132 GroupUtil.updateBundle(bundle, indexer, indicesToFilter, sections, counts);
133 }
134
Walter Jang2552c112016-06-17 14:29:09 -0700135 mCount = mPos;
136 mPos = 0;
137 super.moveToFirst();
138
139 if (Log.isLoggable(TAG, Log.VERBOSE)) {
140 Log.v(TAG, "Group members CursorWrapper end: " + mCount);
141 }
142 }
143
144 @Override
145 public boolean move(int offset) {
146 return moveToPosition(mPos + offset);
147 }
148
149 @Override
150 public boolean moveToNext() {
151 return moveToPosition(mPos + 1);
152 }
153
154 @Override
155 public boolean moveToPrevious() {
156 return moveToPosition(mPos - 1);
157 }
158
159 @Override
160 public boolean moveToFirst() {
161 return moveToPosition(0);
162 }
163
164 @Override
165 public boolean moveToLast() {
166 return moveToPosition(mCount - 1);
167 }
168
169 @Override
170 public boolean moveToPosition(int position) {
John Shao2b0d2982016-07-26 14:50:05 -0700171 if (position >= mCount) {
172 mPos = mCount;
173 return false;
174 } else if (position < 0) {
175 mPos = -1;
176 return false;
177 }
178 mPos = mIndex[position];
179 return super.moveToPosition(mPos);
Walter Jang2552c112016-06-17 14:29:09 -0700180 }
181
182 @Override
183 public int getCount() {
184 return mCount;
185 }
186
187 @Override
188 public int getPosition() {
189 return mPos;
190 }
191 }
192
Walter Jang5a496962016-09-09 18:32:50 -0700193 private final LoaderCallbacks<Cursor> mGroupMetaDataCallbacks = new LoaderCallbacks<Cursor>() {
Walter Jang44e91b12016-05-22 12:37:00 -0700194
195 @Override
196 public CursorLoader onCreateLoader(int id, Bundle args) {
Wenyi Wang79675452016-08-17 10:43:28 -0700197 return new GroupMetaDataLoader(mActivity, mGroupUri);
Walter Jang44e91b12016-05-22 12:37:00 -0700198 }
199
200 @Override
201 public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
202 if (cursor == null || cursor.isClosed() || !cursor.moveToNext()) {
203 Log.e(TAG, "Failed to load group metadata for " + mGroupUri);
Wenyi Wang6927bf32016-08-15 18:31:24 -0700204 Toast.makeText(getContext(), R.string.groupLoadErrorToast, Toast.LENGTH_SHORT)
205 .show();
Wenyi Wang17fe7982016-10-05 13:54:09 -0700206 mHandler.sendEmptyMessage(MSG_FAIL_TO_LOAD);
Walter Jang44e91b12016-05-22 12:37:00 -0700207 return;
208 }
Walter Jang428824e2016-09-09 13:18:35 -0700209 mGroupMetaData = new GroupMetaData(getActivity(), cursor);
Walter Jang44e91b12016-05-22 12:37:00 -0700210 onGroupMetadataLoaded();
211 }
212
213 @Override
214 public void onLoaderReset(Loader<Cursor> loader) {}
215 };
216
Wenyi Wang6927bf32016-08-15 18:31:24 -0700217 private ActionBarAdapter mActionBarAdapter;
218
Wenyi Wang79675452016-08-17 10:43:28 -0700219 private ContactsDrawerActivity mActivity;
220
Walter Jang44e91b12016-05-22 12:37:00 -0700221 private Uri mGroupUri;
222
Wenyi Wang6927bf32016-08-15 18:31:24 -0700223 private boolean mIsEditMode;
Walter Jang4715c042016-04-06 17:14:23 -0700224
Walter Jang428824e2016-09-09 13:18:35 -0700225 private GroupMetaData mGroupMetaData;
Walter Jang4715c042016-04-06 17:14:23 -0700226
Walter Jang2552c112016-06-17 14:29:09 -0700227 private Set<String> mGroupMemberContactIds = new HashSet();
228
Wenyi Wang17fe7982016-10-05 13:54:09 -0700229 private Handler mHandler = new Handler() {
230 @Override
231 public void handleMessage(Message msg) {
232 if(msg.what == MSG_FAIL_TO_LOAD) {
233 mActivity.onBackPressed();
234 }
235 }
236 };
237
Walter Jang90f2fe52016-06-17 16:38:43 -0700238 public static GroupMembersFragment newInstance(Uri groupUri) {
Walter Jang0680a312016-05-18 13:09:01 -0700239 final Bundle args = new Bundle();
Walter Jang44e91b12016-05-22 12:37:00 -0700240 args.putParcelable(ARG_GROUP_URI, groupUri);
Walter Jang0680a312016-05-18 13:09:01 -0700241
Walter Jang90f2fe52016-06-17 16:38:43 -0700242 final GroupMembersFragment fragment = new GroupMembersFragment();
Walter Jang0680a312016-05-18 13:09:01 -0700243 fragment.setArguments(args);
244 return fragment;
245 }
246
Walter Jang90f2fe52016-06-17 16:38:43 -0700247 public GroupMembersFragment() {
Walter Jang4715c042016-04-06 17:14:23 -0700248 setPhotoLoaderEnabled(true);
249 setSectionHeaderDisplayEnabled(true);
Walter Jangdebf9da2016-06-20 12:42:27 -0700250 setHasOptionsMenu(true);
Wenyi Wang2b943992016-05-20 17:21:35 -0700251 setListType(ListType.GROUP);
Walter Jang4715c042016-04-06 17:14:23 -0700252 }
253
Wenyi Wang6927bf32016-08-15 18:31:24 -0700254 @Override
255 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
Walter Jang5a496962016-09-09 18:32:50 -0700256 if (mGroupMetaData == null) {
Wenyi Wang6927bf32016-08-15 18:31:24 -0700257 // Hide menu options until metadata is fully loaded
258 return;
259 }
Wenyi Wang6927bf32016-08-15 18:31:24 -0700260 inflater.inflate(R.menu.view_group, menu);
261 }
262
263 @Override
264 public void onPrepareOptionsMenu(Menu menu) {
265 final boolean isSelectionMode = mActionBarAdapter.isSelectionMode();
Walter Jang5a496962016-09-09 18:32:50 -0700266 final boolean isGroupEditable = mGroupMetaData != null && mGroupMetaData.editable;
267 final boolean isGroupReadOnly = mGroupMetaData != null && mGroupMetaData.readOnly;
Wenyi Wang6927bf32016-08-15 18:31:24 -0700268
Walter Jang9adc9ef2016-11-02 18:50:38 -0700269 setVisible(menu, R.id.menu_multi_send_email, !mIsEditMode && !isGroupEmpty());
270 setVisible(menu, R.id.menu_multi_send_message, !mIsEditMode && !isGroupEmpty());
Wenyi Wang6927bf32016-08-15 18:31:24 -0700271 setVisible(menu, R.id.menu_add, isGroupEditable && !isSelectionMode);
272 setVisible(menu, R.id.menu_rename_group, !isGroupReadOnly && !isSelectionMode);
273 setVisible(menu, R.id.menu_delete_group, !isGroupReadOnly && !isSelectionMode);
274 setVisible(menu, R.id.menu_edit_group, isGroupEditable && !mIsEditMode && !isSelectionMode
275 && !isGroupEmpty());
276 setVisible(menu, R.id.menu_remove_from_group, isGroupEditable && isSelectionMode &&
277 !mIsEditMode);
278 }
279
280 private boolean isGroupEmpty() {
281 return getAdapter() != null && getAdapter().isEmpty();
282 }
283
284 private static void setVisible(Menu menu, int id, boolean visible) {
285 final MenuItem menuItem = menu.findItem(id);
286 if (menuItem != null) {
287 menuItem.setVisible(visible);
288 }
289 }
290
Sean Midfordff6f1bb2016-10-12 09:48:23 -0700291 /**
292 * Helper class for cp2 query used to look up all contact's emails and phone numbers.
293 */
Sean Midford9970f302016-11-07 12:23:45 -0800294 public static abstract class Query {
Sean Midfordff6f1bb2016-10-12 09:48:23 -0700295 public static final String EMAIL_SELECTION =
296 ContactsContract.Data.MIMETYPE + "='"
297 + ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE + "'";
298
299 public static final String PHONE_SELECTION =
300 ContactsContract.Data.MIMETYPE + "='"
301 + ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "'";
302
Sean Midford4b2ccd22016-10-14 13:03:49 -0700303 public static final String[] EMAIL_PROJECTION = {
Sean Midfordff6f1bb2016-10-12 09:48:23 -0700304 ContactsContract.Data.CONTACT_ID,
Sean Midford4b2ccd22016-10-14 13:03:49 -0700305 ContactsContract.CommonDataKinds.Email._ID,
306 ContactsContract.Data.IS_SUPER_PRIMARY,
Sean Midford009bb752016-10-27 14:18:22 -0700307 ContactsContract.Data.TIMES_USED,
Sean Midfordff6f1bb2016-10-12 09:48:23 -0700308 ContactsContract.Data.DATA1
309 };
310
Sean Midford4b2ccd22016-10-14 13:03:49 -0700311 public static final String[] PHONE_PROJECTION = {
312 ContactsContract.Data.CONTACT_ID,
313 ContactsContract.CommonDataKinds.Phone._ID,
314 ContactsContract.Data.IS_SUPER_PRIMARY,
Sean Midford009bb752016-10-27 14:18:22 -0700315 ContactsContract.Data.TIMES_USED,
Sean Midford4b2ccd22016-10-14 13:03:49 -0700316 ContactsContract.Data.DATA1
317 };
318
319 public static final int CONTACT_ID = 0;
320 public static final int ITEM_ID = 1;
321 public static final int PRIMARY = 2;
Sean Midford009bb752016-10-27 14:18:22 -0700322 public static final int TIMES_USED = 3;
323 public static final int DATA1 = 4;
324 }
325
326 /**
327 * Helper class for managing data related to contacts and emails/phone numbers.
328 */
329 private class ContactDataHelperClass {
330
331 private List<String> items = new ArrayList<>();
332 private String mostUsedItemId = null;
333 private int mostUsedTimes;
334 private String primaryItemId = null;
335
336 public void addItem(String item, int timesUsed, boolean primaryFlag) {
337 if (mostUsedItemId == null || timesUsed > mostUsedTimes) {
338 mostUsedItemId = item;
339 mostUsedTimes = timesUsed;
340 }
341 if (primaryFlag) {
342 primaryItemId = item;
343 }
344 items.add(item);
345 }
346
347 public boolean hasDefaultItem() {
348 return primaryItemId != null || items.size() == 1;
349 }
350
351 public String getDefaultSelectionItemId() {
352 return primaryItemId != null
353 ? primaryItemId
354 : mostUsedItemId;
355 }
Sean Midfordff6f1bb2016-10-12 09:48:23 -0700356 }
357
358 private void sendToGroup(long[] ids, String sendScheme, String title) {
Gary Mai4ac56292016-10-31 10:41:11 -0700359 if (ids == null || ids.length == 0) return;
Sean Midfordff6f1bb2016-10-12 09:48:23 -0700360
361 // Get emails or phone numbers
Sean Midford009bb752016-10-27 14:18:22 -0700362 // contactMap <contact_id, contact_data>
363 final Map<String, ContactDataHelperClass> contactMap = new HashMap<>();
Sean Midford4b2ccd22016-10-14 13:03:49 -0700364 // itemList <item_data>
365 final List<String> itemList = new ArrayList<>();
Sean Midfordff6f1bb2016-10-12 09:48:23 -0700366 final String sIds = GroupUtil.convertArrayToString(ids);
367 final String select = (ContactsUtils.SCHEME_MAILTO.equals(sendScheme)
Sean Midfordb460f442016-10-13 10:42:35 -0700368 ? Query.EMAIL_SELECTION
369 : Query.PHONE_SELECTION)
Sean Midfordff6f1bb2016-10-12 09:48:23 -0700370 + " AND " + ContactsContract.Data.CONTACT_ID + " IN (" + sIds + ")";
371 final ContentResolver contentResolver = getContext().getContentResolver();
372 final Cursor cursor = contentResolver.query(ContactsContract.Data.CONTENT_URI,
Sean Midford4b2ccd22016-10-14 13:03:49 -0700373 ContactsUtils.SCHEME_MAILTO.equals(sendScheme)
374 ? Query.EMAIL_PROJECTION
375 : Query.PHONE_PROJECTION,
376 select, null, null);
Sean Midfordff6f1bb2016-10-12 09:48:23 -0700377
378 if (cursor == null) {
379 return;
380 }
381
382 try {
383 cursor.moveToPosition(-1);
384 while (cursor.moveToNext()) {
Sean Midford4b2ccd22016-10-14 13:03:49 -0700385 final String contactId = cursor.getString(Query.CONTACT_ID);
386 final String itemId = cursor.getString(Query.ITEM_ID);
387 final boolean isPrimary = cursor.getInt(Query.PRIMARY) != 0;
Sean Midford009bb752016-10-27 14:18:22 -0700388 final int timesUsed = cursor.getInt(Query.TIMES_USED);
Sean Midfordb460f442016-10-13 10:42:35 -0700389 final String data = cursor.getString(Query.DATA1);
Sean Midfordff6f1bb2016-10-12 09:48:23 -0700390
Sean Midford4b2ccd22016-10-14 13:03:49 -0700391 if (!TextUtils.isEmpty(data)) {
Sean Midford009bb752016-10-27 14:18:22 -0700392 final ContactDataHelperClass contact;
393 if (!contactMap.containsKey(contactId)) {
394 contact = new ContactDataHelperClass();
395 contactMap.put(contactId, contact);
396 } else {
397 contact = contactMap.get(contactId);
398 }
399 contact.addItem(itemId, timesUsed, isPrimary);
Sean Midford4b2ccd22016-10-14 13:03:49 -0700400 itemList.add(data);
Sean Midfordff6f1bb2016-10-12 09:48:23 -0700401 }
402 }
403 } finally {
404 cursor.close();
405 }
406
Sean Midford009bb752016-10-27 14:18:22 -0700407 // Start picker if a contact does not have a default
408 for (ContactDataHelperClass i : contactMap.values()) {
409 if (!i.hasDefaultItem()) {
Sean Midford4b2ccd22016-10-14 13:03:49 -0700410 // Build list of default selected item ids
411 final List<Long> defaultSelection = new ArrayList<>();
Sean Midford009bb752016-10-27 14:18:22 -0700412 for (ContactDataHelperClass j : contactMap.values()) {
413 final String selectionItemId = j.getDefaultSelectionItemId();
414 if (selectionItemId != null) {
415 defaultSelection.add(Long.parseLong(selectionItemId));
Sean Midford4b2ccd22016-10-14 13:03:49 -0700416 }
417 }
418 final long[] defaultSelectionArray = Longs.toArray(defaultSelection);
419 startSendToSelectionPickerActivity(ids, defaultSelectionArray, sendScheme, title);
420 return;
421 }
422 }
423
Sean Midford009bb752016-10-27 14:18:22 -0700424 if (itemList.size() == 0 || contactMap.size() < ids.length) {
Sean Midfordff6f1bb2016-10-12 09:48:23 -0700425 Toast.makeText(getContext(), ContactsUtils.SCHEME_MAILTO.equals(sendScheme)
426 ? getString(R.string.groupSomeContactsNoEmailsToast)
427 : getString(R.string.groupSomeContactsNoPhonesToast),
428 Toast.LENGTH_LONG).show();
429 }
430
Sean Midford4b2ccd22016-10-14 13:03:49 -0700431 if (itemList.size() == 0) {
Sean Midfordff6f1bb2016-10-12 09:48:23 -0700432 return;
433 }
434
Sean Midford4b2ccd22016-10-14 13:03:49 -0700435 final String itemsString = TextUtils.join(",", itemList);
Sean Midford9970f302016-11-07 12:23:45 -0800436 GroupUtil.startSendToSelectionActivity(this, itemsString, sendScheme, title);
Sean Midfordff6f1bb2016-10-12 09:48:23 -0700437 }
438
Sean Midford4b2ccd22016-10-14 13:03:49 -0700439 private void startSendToSelectionPickerActivity(long[] ids, long[] defaultSelection,
440 String sendScheme, String title) {
Sean Midford9970f302016-11-07 12:23:45 -0800441 startActivity(GroupUtil.createSendToSelectionPickerIntent(getContext(), ids,
442 defaultSelection, sendScheme, title));
Sean Midfordff6f1bb2016-10-12 09:48:23 -0700443 }
444
Wenyi Wang6927bf32016-08-15 18:31:24 -0700445 private void startGroupAddMemberActivity() {
Walter Jang5a496962016-09-09 18:32:50 -0700446 startActivityForResult(GroupUtil.createPickMemberIntent(getContext(), mGroupMetaData,
Wenyi Wang6927bf32016-08-15 18:31:24 -0700447 getMemberContactIds()), RESULT_GROUP_ADD_MEMBER);
448 }
449
450 @Override
451 public boolean onOptionsItemSelected(MenuItem item) {
452 switch (item.getItemId()) {
453 case android.R.id.home: {
Wenyi Wang79675452016-08-17 10:43:28 -0700454 mActivity.onBackPressed();
Wenyi Wang6927bf32016-08-15 18:31:24 -0700455 return true;
456 }
457 case R.id.menu_add: {
458 startGroupAddMemberActivity();
459 return true;
460 }
Sean Midfordff6f1bb2016-10-12 09:48:23 -0700461 case R.id.menu_multi_send_email: {
462 final long[] ids = mActionBarAdapter.isSelectionMode()
463 ? getAdapter().getSelectedContactIdsArray()
464 : GroupUtil.convertStringSetToLongArray(mGroupMemberContactIds);
465 sendToGroup(ids, ContactsUtils.SCHEME_MAILTO,
466 getString(R.string.menu_sendEmailOption));
467 return true;
468 }
469 case R.id.menu_multi_send_message: {
470 final long[] ids = mActionBarAdapter.isSelectionMode()
471 ? getAdapter().getSelectedContactIdsArray()
472 : GroupUtil.convertStringSetToLongArray(mGroupMemberContactIds);
473 sendToGroup(ids, ContactsUtils.SCHEME_SMSTO,
474 getString(R.string.menu_sendMessageOption));
475 return true;
476 }
Wenyi Wang6927bf32016-08-15 18:31:24 -0700477 case R.id.menu_rename_group: {
478 GroupNameEditDialogFragment.newInstanceForUpdate(
Walter Jang5a496962016-09-09 18:32:50 -0700479 new AccountWithDataSet(mGroupMetaData.accountName,
480 mGroupMetaData.accountType, mGroupMetaData.dataSet),
481 GroupUtil.ACTION_UPDATE_GROUP, mGroupMetaData.groupId,
482 mGroupMetaData.groupName).show(getFragmentManager(),
Wenyi Wang6927bf32016-08-15 18:31:24 -0700483 TAG_GROUP_NAME_EDIT_DIALOG);
484 return true;
485 }
486 case R.id.menu_delete_group: {
487 deleteGroup();
488 return true;
489 }
490 case R.id.menu_edit_group: {
491 mIsEditMode = true;
492 mActionBarAdapter.setSelectionMode(true);
493 displayDeleteButtons(true);
494 return true;
495 }
496 case R.id.menu_remove_from_group: {
497 logListEvent();
498 removeSelectedContacts();
499 return true;
500 }
501 }
502 return super.onOptionsItemSelected(item);
503 }
504
505 private void removeSelectedContacts() {
506 final long[] contactIds = getAdapter().getSelectedContactIdsArray();
507 new UpdateGroupMembersAsyncTask(UpdateGroupMembersAsyncTask.TYPE_REMOVE,
Walter Jang5a496962016-09-09 18:32:50 -0700508 getContext(), contactIds, mGroupMetaData.groupId, mGroupMetaData.accountName,
Walter Jang792dae72016-09-14 13:04:00 -0700509 mGroupMetaData.accountType, mGroupMetaData.dataSet).execute();
Wenyi Wang6927bf32016-08-15 18:31:24 -0700510
511 mActionBarAdapter.setSelectionMode(false);
512 }
513
514 @Override
515 public void onActivityResult(int requestCode, int resultCode, Intent data) {
Sean Midford9970f302016-11-07 12:23:45 -0800516 if (resultCode != Activity.RESULT_OK || data == null
517 || requestCode != RESULT_GROUP_ADD_MEMBER) {
Sean Midfordb460f442016-10-13 10:42:35 -0700518 return;
519 }
Sean Midford9970f302016-11-07 12:23:45 -0800520
521 long[] contactIds = data.getLongArrayExtra(
522 UiIntentActions.TARGET_CONTACT_IDS_EXTRA_KEY);
523 if (contactIds == null) {
524 final long contactId = data.getLongExtra(
525 UiIntentActions.TARGET_CONTACT_ID_EXTRA_KEY, -1);
526 if (contactId > -1) {
527 contactIds = new long[1];
528 contactIds[0] = contactId;
Sean Midfordb460f442016-10-13 10:42:35 -0700529 }
Wenyi Wang6927bf32016-08-15 18:31:24 -0700530 }
Sean Midford9970f302016-11-07 12:23:45 -0800531 new UpdateGroupMembersAsyncTask(
532 UpdateGroupMembersAsyncTask.TYPE_ADD,
533 getContext(), contactIds, mGroupMetaData.groupId, mGroupMetaData.accountName,
534 mGroupMetaData.accountType, mGroupMetaData.dataSet).execute();
Wenyi Wang6927bf32016-08-15 18:31:24 -0700535 }
536
Wenyi Wang88a9f242016-08-25 16:07:15 -0700537 private final ActionBarAdapter.Listener mActionBarListener = new ActionBarAdapter.Listener() {
538 @Override
539 public void onAction(int action) {
540 switch (action) {
541 case ActionBarAdapter.Listener.Action.START_SELECTION_MODE:
542 if (mIsEditMode) {
543 displayDeleteButtons(true);
544 mActionBarAdapter.setActionBarTitle(getString(R.string.title_edit_group));
545 } else {
546 displayCheckBoxes(true);
547 }
Wenyi Wang79675452016-08-17 10:43:28 -0700548 mActivity.invalidateOptionsMenu();
Wenyi Wang88a9f242016-08-25 16:07:15 -0700549 break;
550 case ActionBarAdapter.Listener.Action.STOP_SEARCH_AND_SELECTION_MODE:
551 mActionBarAdapter.setSearchMode(false);
552 if (mIsEditMode) {
553 displayDeleteButtons(false);
554 } else {
555 displayCheckBoxes(false);
556 }
Wenyi Wang79675452016-08-17 10:43:28 -0700557 mActivity.invalidateOptionsMenu();
Wenyi Wang88a9f242016-08-25 16:07:15 -0700558 break;
559 case ActionBarAdapter.Listener.Action.BEGIN_STOPPING_SEARCH_AND_SELECTION_MODE:
560 break;
561 }
562 }
Wenyi Wang6927bf32016-08-15 18:31:24 -0700563
Wenyi Wang88a9f242016-08-25 16:07:15 -0700564 @Override
565 public void onUpButtonPressed() {
Wenyi Wang79675452016-08-17 10:43:28 -0700566 mActivity.onBackPressed();
Wenyi Wang88a9f242016-08-25 16:07:15 -0700567 }
568 };
569
570 private final OnCheckBoxListActionListener mCheckBoxListener =
571 new OnCheckBoxListActionListener() {
572 @Override
573 public void onStartDisplayingCheckBoxes() {
574 mActionBarAdapter.setSelectionMode(true);
Wenyi Wang6927bf32016-08-15 18:31:24 -0700575 }
Wenyi Wang88a9f242016-08-25 16:07:15 -0700576
577 @Override
578 public void onSelectedContactIdsChanged() {
579 if (mActionBarAdapter == null) {
580 return;
581 }
582 if (mIsEditMode) {
583 mActionBarAdapter.setActionBarTitle(getString(R.string.title_edit_group));
584 } else {
585 mActionBarAdapter.setSelectionCount(getSelectedContactIds().size());
586 }
Wenyi Wang6927bf32016-08-15 18:31:24 -0700587 }
Wenyi Wang6927bf32016-08-15 18:31:24 -0700588
Wenyi Wang88a9f242016-08-25 16:07:15 -0700589 @Override
590 public void onStopDisplayingCheckBoxes() {
591 mActionBarAdapter.setSelectionMode(false);
592 }
593 };
Wenyi Wang6927bf32016-08-15 18:31:24 -0700594
595 private void logListEvent() {
596 Logger.logListEvent(
597 ListEvent.ActionType.REMOVE_LABEL,
598 getListType(),
599 getAdapter().getCount(),
600 /* clickedIndex */ -1,
601 getAdapter().getSelectedContactIdsArray().length);
602 }
603
604 private void deleteGroup() {
605 if (getMemberCount() == 0) {
606 final Intent intent = ContactSaveService.createGroupDeletionIntent(
Walter Jang5a496962016-09-09 18:32:50 -0700607 getContext(), mGroupMetaData.groupId);
Wenyi Wang6927bf32016-08-15 18:31:24 -0700608 getContext().startService(intent);
Wenyi Wang79675452016-08-17 10:43:28 -0700609 mActivity.switchToAllContacts();
Wenyi Wang6927bf32016-08-15 18:31:24 -0700610 } else {
Walter Jang5a496962016-09-09 18:32:50 -0700611 GroupDeletionDialogFragment.show(getFragmentManager(), mGroupMetaData.groupId,
612 mGroupMetaData.groupName);
Wenyi Wang6927bf32016-08-15 18:31:24 -0700613 }
614 }
615
616 @Override
617 public void onActivityCreated(Bundle savedInstanceState) {
618 super.onActivityCreated(savedInstanceState);
Wenyi Wang79675452016-08-17 10:43:28 -0700619 mActivity = (ContactsDrawerActivity) getActivity();
620 mActionBarAdapter = new ActionBarAdapter(mActivity, mActionBarListener,
Wenyi Wangf6606072016-10-03 17:34:53 -0700621 mActivity.getSupportActionBar(), mActivity.getToolbar(),
622 R.string.enter_contact_name);
Wenyi Wang6927bf32016-08-15 18:31:24 -0700623 mActionBarAdapter.setShowHomeIcon(true);
624 final ContactsRequest contactsRequest = new ContactsRequest();
625 contactsRequest.setActionCode(ContactsRequest.ACTION_GROUP);
626 mActionBarAdapter.initialize(savedInstanceState, contactsRequest);
Walter Jang5a496962016-09-09 18:32:50 -0700627 if (mGroupMetaData != null) {
628 mActivity.setTitle(mGroupMetaData.groupName);
629 if (mGroupMetaData.editable) {
Wenyi Wang79675452016-08-17 10:43:28 -0700630 setCheckBoxListListener(mCheckBoxListener);
631 }
632 }
Wenyi Wang6927bf32016-08-15 18:31:24 -0700633 }
634
Wenyi Wang79675452016-08-17 10:43:28 -0700635 @Override
Wenyi Wang6927bf32016-08-15 18:31:24 -0700636 public ActionBarAdapter getActionBarAdapter() {
637 return mActionBarAdapter;
Walter Jang4715c042016-04-06 17:14:23 -0700638 }
639
Walter Jang05e71472016-06-23 19:00:10 -0700640 public void displayDeleteButtons(boolean displayDeleteButtons) {
641 getAdapter().setDisplayDeleteButtons(displayDeleteButtons);
642 }
643
Walter Jang2552c112016-06-17 14:29:09 -0700644 public ArrayList<String> getMemberContactIds() {
Wenyi Wang79675452016-08-17 10:43:28 -0700645 return new ArrayList<>(mGroupMemberContactIds);
Walter Jang2552c112016-06-17 14:29:09 -0700646 }
647
648 public int getMemberCount() {
649 return mGroupMemberContactIds.size();
650 }
651
Wenyi Wang6927bf32016-08-15 18:31:24 -0700652 public boolean isEditMode() {
653 return mIsEditMode;
654 }
655
Walter Jang4715c042016-04-06 17:14:23 -0700656 @Override
657 public void onCreate(Bundle savedState) {
658 super.onCreate(savedState);
Walter Jang0680a312016-05-18 13:09:01 -0700659 if (savedState == null) {
Walter Jang44e91b12016-05-22 12:37:00 -0700660 mGroupUri = getArguments().getParcelable(ARG_GROUP_URI);
Walter Jang0680a312016-05-18 13:09:01 -0700661 } else {
Wenyi Wang6927bf32016-08-15 18:31:24 -0700662 mIsEditMode = savedState.getBoolean(KEY_IS_EDIT_MODE);
Walter Jang44e91b12016-05-22 12:37:00 -0700663 mGroupUri = savedState.getParcelable(KEY_GROUP_URI);
Walter Jang428824e2016-09-09 13:18:35 -0700664 mGroupMetaData = savedState.getParcelable(KEY_GROUP_METADATA);
Walter Jang4715c042016-04-06 17:14:23 -0700665 }
Wenyi Wang88a9f242016-08-25 16:07:15 -0700666 maybeAttachCheckBoxListener();
667 }
668
669 @Override
670 public void onResume() {
671 super.onResume();
672 // Re-register the listener, which may have been cleared when onSaveInstanceState was
673 // called. See also: onSaveInstanceState
674 mActionBarAdapter.setListener(mActionBarListener);
Walter Jang0680a312016-05-18 13:09:01 -0700675 }
676
677 @Override
Walter Jang44e91b12016-05-22 12:37:00 -0700678 protected void startLoading() {
Walter Jang428824e2016-09-09 13:18:35 -0700679 if (mGroupMetaData == null || !mGroupMetaData.isValid()) {
Walter Jang5a496962016-09-09 18:32:50 -0700680 getLoaderManager().restartLoader(LOADER_GROUP_METADATA, null, mGroupMetaDataCallbacks);
Walter Jang44e91b12016-05-22 12:37:00 -0700681 } else {
682 onGroupMetadataLoaded();
683 }
Walter Jang4715c042016-04-06 17:14:23 -0700684 }
685
686 @Override
Walter Jang2552c112016-06-17 14:29:09 -0700687 public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
688 if (data != null) {
Walter Jangdebf9da2016-06-20 12:42:27 -0700689 // Wait until contacts are loaded before showing the scrollbar
690 setVisibleScrollbarEnabled(true);
691
Walter Jang2552c112016-06-17 14:29:09 -0700692 final FilterCursorWrapper cursorWrapper = new FilterCursorWrapper(data);
693 bindMembersCount(cursorWrapper.getCount());
694 super.onLoadFinished(loader, cursorWrapper);
Wenyi Wang35e6f742016-08-01 15:16:47 -0700695 // Update state of menu items (e.g. "Remove contacts") based on number of group members.
Wenyi Wang79675452016-08-17 10:43:28 -0700696 mActivity.invalidateOptionsMenu();
Walter Jang2552c112016-06-17 14:29:09 -0700697 }
698 }
699
700 private void bindMembersCount(int memberCount) {
701 final View accountFilterContainer = getView().findViewById(
702 R.id.account_filter_header_container);
yaolud8effeb2016-06-29 14:42:38 -0700703 final View emptyGroupView = getView().findViewById(R.id.empty_group);
704 if (memberCount > 0) {
Wenyi Wang1114fde2016-07-11 21:44:02 -0700705 final AccountWithDataSet accountWithDataSet = new AccountWithDataSet(
Walter Jang428824e2016-09-09 13:18:35 -0700706 mGroupMetaData.accountName, mGroupMetaData.accountType, mGroupMetaData.dataSet);
Wenyi Wang1114fde2016-07-11 21:44:02 -0700707 bindListHeader(getContext(), getListView(), accountFilterContainer,
708 accountWithDataSet, memberCount);
yaolud8effeb2016-06-29 14:42:38 -0700709 emptyGroupView.setVisibility(View.GONE);
Walter Jang2552c112016-06-17 14:29:09 -0700710 } else {
Wenyi Wang1114fde2016-07-11 21:44:02 -0700711 hideHeaderAndAddPadding(getContext(), getListView(), accountFilterContainer);
yaolud8effeb2016-06-29 14:42:38 -0700712 emptyGroupView.setVisibility(View.VISIBLE);
Walter Jang2552c112016-06-17 14:29:09 -0700713 }
714 }
715
716 @Override
Walter Jang4715c042016-04-06 17:14:23 -0700717 public void onSaveInstanceState(Bundle outState) {
718 super.onSaveInstanceState(outState);
Wenyi Wang6927bf32016-08-15 18:31:24 -0700719 if (mActionBarAdapter != null) {
Wenyi Wang88a9f242016-08-25 16:07:15 -0700720 mActionBarAdapter.setListener(null);
Wenyi Wang6927bf32016-08-15 18:31:24 -0700721 mActionBarAdapter.onSaveInstanceState(outState);
722 }
723 outState.putBoolean(KEY_IS_EDIT_MODE, mIsEditMode);
Walter Jang44e91b12016-05-22 12:37:00 -0700724 outState.putParcelable(KEY_GROUP_URI, mGroupUri);
Walter Jang428824e2016-09-09 13:18:35 -0700725 outState.putParcelable(KEY_GROUP_METADATA, mGroupMetaData);
Walter Jang4715c042016-04-06 17:14:23 -0700726 }
727
Walter Jang44e91b12016-05-22 12:37:00 -0700728 private void onGroupMetadataLoaded() {
Walter Jang428824e2016-09-09 13:18:35 -0700729 if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "Loaded " + mGroupMetaData);
Walter Jang44e91b12016-05-22 12:37:00 -0700730
731 maybeAttachCheckBoxListener();
732
Walter Jang5a496962016-09-09 18:32:50 -0700733 mActivity.setTitle(mGroupMetaData.groupName);
734 mActivity.updateGroupMenu(mGroupMetaData);
Wenyi Wang79675452016-08-17 10:43:28 -0700735 mActivity.invalidateOptionsMenu();
Walter Jang44e91b12016-05-22 12:37:00 -0700736
737 // Start loading the group members
738 super.startLoading();
739 }
740
741 private void maybeAttachCheckBoxListener() {
742 // Don't attach the multi select check box listener if we can't edit the group
Walter Jang428824e2016-09-09 13:18:35 -0700743 if (mGroupMetaData != null && mGroupMetaData.editable) {
Wenyi Wang88a9f242016-08-25 16:07:15 -0700744 setCheckBoxListListener(mCheckBoxListener);
Walter Jang44e91b12016-05-22 12:37:00 -0700745 }
Walter Jang4715c042016-04-06 17:14:23 -0700746 }
747
748 @Override
Walter Jang90f2fe52016-06-17 16:38:43 -0700749 protected GroupMembersAdapter createListAdapter() {
750 final GroupMembersAdapter adapter = new GroupMembersAdapter(getContext());
Walter Jangdebf9da2016-06-20 12:42:27 -0700751 adapter.setSectionHeaderDisplayEnabled(true);
Walter Jang4715c042016-04-06 17:14:23 -0700752 adapter.setDisplayPhotos(true);
Wenyi Wang88a9f242016-08-25 16:07:15 -0700753 adapter.setDeleteContactListener(new DeletionListener());
Walter Jang4715c042016-04-06 17:14:23 -0700754 return adapter;
755 }
756
757 @Override
Walter Jang4715c042016-04-06 17:14:23 -0700758 protected void configureAdapter() {
759 super.configureAdapter();
Walter Jang428824e2016-09-09 13:18:35 -0700760 if (mGroupMetaData != null) {
761 getAdapter().setGroupId(mGroupMetaData.groupId);
Walter Jang44e91b12016-05-22 12:37:00 -0700762 }
Walter Jang4715c042016-04-06 17:14:23 -0700763 }
764
765 @Override
766 protected View inflateView(LayoutInflater inflater, ViewGroup container) {
yaolud8effeb2016-06-29 14:42:38 -0700767 final View view = inflater.inflate(R.layout.contact_list_content, /* root */ null);
768 final View emptyGroupView = inflater.inflate(R.layout.empty_group_view, null);
yaolub5046052016-07-28 15:34:02 -0700769
yaolud8effeb2016-06-29 14:42:38 -0700770 final ImageView image = (ImageView) emptyGroupView.findViewById(R.id.empty_group_image);
771 final LinearLayout.LayoutParams params =
772 (LinearLayout.LayoutParams) image.getLayoutParams();
yaolub5046052016-07-28 15:34:02 -0700773 final int screenHeight = getResources().getDisplayMetrics().heightPixels;
774 params.setMargins(0, screenHeight /
775 getResources().getInteger(R.integer.empty_group_view_image_margin_divisor), 0, 0);
yaolud8effeb2016-06-29 14:42:38 -0700776 params.gravity = Gravity.CENTER_HORIZONTAL;
777 image.setLayoutParams(params);
778
779 final FrameLayout contactListLayout = (FrameLayout) view.findViewById(R.id.contact_list);
780 contactListLayout.addView(emptyGroupView);
781
782 final Button addContactsButton =
783 (Button) emptyGroupView.findViewById(R.id.add_member_button);
784 addContactsButton.setOnClickListener(new View.OnClickListener() {
785 @Override
786 public void onClick(View v) {
Wenyi Wang6927bf32016-08-15 18:31:24 -0700787 startActivityForResult(GroupUtil.createPickMemberIntent(getContext(),
Walter Jang5a496962016-09-09 18:32:50 -0700788 mGroupMetaData, getMemberContactIds()), RESULT_GROUP_ADD_MEMBER);
yaolud8effeb2016-06-29 14:42:38 -0700789 }
790 });
791 return view;
Walter Jang4715c042016-04-06 17:14:23 -0700792 }
793
794 @Override
795 protected void onItemClick(int position, long id) {
Walter Jang8b8b30c2016-05-12 19:07:13 -0700796 final Uri uri = getAdapter().getContactUri(position);
797 if (uri == null) {
798 return;
799 }
800 if (getAdapter().isDisplayingCheckBoxes()) {
801 super.onItemClick(position, id);
802 return;
803 }
Wenyi Wang6927bf32016-08-15 18:31:24 -0700804 final int count = getAdapter().getCount();
805 Logger.logListEvent(ListEvent.ActionType.CLICK, ListEvent.ListType.GROUP, count,
806 /* clickedIndex */ position, /* numSelected */ 0);
Walter Jang0396cf72016-09-21 13:23:29 -0700807 ImplicitIntentsUtil.startQuickContact(
808 getActivity(), uri, ScreenEvent.ScreenType.LIST_GROUP);
Walter Jang4715c042016-04-06 17:14:23 -0700809 }
Walter Jangec807e12016-06-27 12:10:40 -0700810
811 @Override
812 protected boolean onItemLongClick(int position, long id) {
Wenyi Wang79675452016-08-17 10:43:28 -0700813 if (mActivity != null && mIsEditMode) {
814 return true;
Walter Jangec807e12016-06-27 12:10:40 -0700815 }
816 return super.onItemLongClick(position, id);
817 }
Tingting Wang4e2656f2016-06-28 22:58:43 -0700818
Wenyi Wang88a9f242016-08-25 16:07:15 -0700819 private final class DeletionListener implements DeleteContactListener {
820 @Override
821 public void onContactDeleteClicked(int position) {
822 final long contactId = getAdapter().getContactId(position);
823 final long[] contactIds = new long[1];
824 contactIds[0] = contactId;
825 new UpdateGroupMembersAsyncTask(UpdateGroupMembersAsyncTask.TYPE_REMOVE,
Walter Jang5a496962016-09-09 18:32:50 -0700826 getContext(), contactIds, mGroupMetaData.groupId, mGroupMetaData.accountName,
Walter Jang792dae72016-09-14 13:04:00 -0700827 mGroupMetaData.accountType, mGroupMetaData.dataSet).execute();
Wenyi Wang88a9f242016-08-25 16:07:15 -0700828 }
Wenyi Wang6927bf32016-08-15 18:31:24 -0700829 }
830
Walter Jang5a496962016-09-09 18:32:50 -0700831 public GroupMetaData getGroupMetaData() {
832 return mGroupMetaData;
Tingting Wang4e2656f2016-06-28 22:58:43 -0700833 }
Wenyi Wang88a9f242016-08-25 16:07:15 -0700834
Wenyi Wang79675452016-08-17 10:43:28 -0700835 public boolean isCurrentGroup(long groupId) {
Walter Jang5a496962016-09-09 18:32:50 -0700836 return mGroupMetaData != null && mGroupMetaData.groupId == groupId;
Wenyi Wang79675452016-08-17 10:43:28 -0700837 }
838
Wenyi Wang17fe7982016-10-05 13:54:09 -0700839 /**
840 * Return true if the fragment is not yet added, being removed, or detached.
841 */
842 public boolean isInactive() {
843 return !isAdded() || isRemoving() || isDetached();
844 }
845
Wenyi Wang88a9f242016-08-25 16:07:15 -0700846 @Override
847 public void onDestroy() {
848 if (mActionBarAdapter != null) {
849 mActionBarAdapter.setListener(null);
850 }
851 super.onDestroy();
852 }
Wenyi Wangcc8f2722016-09-07 14:52:32 -0700853
Wenyi Wangf6606072016-10-03 17:34:53 -0700854 public void updateExistingGroupFragment(Uri newGroupUri, String action) {
James Laskey1387e782016-10-26 13:34:23 -0700855 toastForSaveAction(action);
Wenyi Wangcc8f2722016-09-07 14:52:32 -0700856
857 if (isEditMode() && getGroupCount() == 1) {
858 // If we're deleting the last group member, exit edit mode
859 exitEditMode();
860 } else if (!GroupUtil.ACTION_REMOVE_FROM_GROUP.equals(action)) {
861 mGroupUri = newGroupUri;
Walter Jang5a496962016-09-09 18:32:50 -0700862 mGroupMetaData = null; // Clear mGroupMetaData to trigger a new load.
Wenyi Wangcc8f2722016-09-07 14:52:32 -0700863 reloadData();
864 mActivity.invalidateOptionsMenu();
865 }
866 }
867
James Laskey1387e782016-10-26 13:34:23 -0700868 public void toastForSaveAction(String action) {
869 int id = -1;
Wenyi Wangcc8f2722016-09-07 14:52:32 -0700870 switch(action) {
871 case GroupUtil.ACTION_UPDATE_GROUP:
James Laskey1387e782016-10-26 13:34:23 -0700872 id = R.string.groupUpdatedToast;
873 break;
Wenyi Wangcc8f2722016-09-07 14:52:32 -0700874 case GroupUtil.ACTION_REMOVE_FROM_GROUP:
James Laskey1387e782016-10-26 13:34:23 -0700875 id = R.string.groupMembersRemovedToast;
876 break;
Wenyi Wangcc8f2722016-09-07 14:52:32 -0700877 case GroupUtil.ACTION_CREATE_GROUP:
James Laskey1387e782016-10-26 13:34:23 -0700878 id = R.string.groupCreatedToast;
879 break;
880 case GroupUtil.ACTION_ADD_TO_GROUP:
881 id = R.string.groupMembersAddedToast;
882 break;
883 case GroupUtil.ACTION_SWITCH_GROUP:
884 // No toast associated with this action.
885 break;
Wenyi Wangcc8f2722016-09-07 14:52:32 -0700886 default:
James Laskey1387e782016-10-26 13:34:23 -0700887 FeedbackHelper.sendFeedback(getContext(), TAG,
888 "toastForSaveAction passed unknown action: " + action,
889 new IllegalArgumentException("Unhandled contact save action " + action));
Wenyi Wangcc8f2722016-09-07 14:52:32 -0700890 }
James Laskey1387e782016-10-26 13:34:23 -0700891 toast(id);
Wenyi Wangcc8f2722016-09-07 14:52:32 -0700892 }
893
894 private void toast(int resId) {
895 if (resId >= 0) {
896 Toast.makeText(getContext(), resId, Toast.LENGTH_SHORT).show();
897 }
898 }
899
900 private int getGroupCount() {
901 return getAdapter() != null ? getAdapter().getCount() : -1;
902 }
903
904 public void exitEditMode() {
905 mIsEditMode = false;
906 mActionBarAdapter.setSelectionMode(false);
907 displayDeleteButtons(false);
908 }
Walter Jang4715c042016-04-06 17:14:23 -0700909}