blob: ee4b7269a0b54c73f1d2329f2af16e3e6aa72cd5 [file] [log] [blame]
Dmitri Plotnikovb979b422010-07-01 15:29:15 -07001/*
2 * Copyright (C) 2007 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 */
16
17package com.android.contacts.activities;
18
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -070019import android.app.Fragment;
Jay Shrauner1d815e62014-01-31 10:37:31 -080020import android.content.ActivityNotFoundException;
Dmitri Plotnikovb979b422010-07-01 15:29:15 -070021import android.content.Intent;
John Shaobd9ef3c2016-12-15 12:42:03 -080022import android.graphics.PorterDuff;
23import android.graphics.drawable.Drawable;
Dmitri Plotnikovb979b422010-07-01 15:29:15 -070024import android.net.Uri;
25import android.os.Bundle;
26import android.provider.ContactsContract.Contacts;
John Shaobd9ef3c2016-12-15 12:42:03 -080027import android.support.v4.content.ContextCompat;
Walter Janga4897212016-06-21 19:02:23 -070028import android.support.v7.widget.Toolbar;
Dmitri Plotnikov4d174aa2010-10-25 15:38:54 -070029import android.text.TextUtils;
Daisuke Miyakawaa8729cd2011-10-12 12:27:16 -070030import android.util.Log;
Brian Attwell81cc3b32014-07-22 16:04:52 -070031import android.view.Menu;
32import android.view.MenuInflater;
Dmitri Plotnikovb979b422010-07-01 15:29:15 -070033import android.view.MenuItem;
34import android.view.View;
Dmitri Plotnikov63c311a2010-12-08 09:29:24 -080035import android.view.View.OnClickListener;
Daisuke Miyakawaa8729cd2011-10-12 12:27:16 -070036import android.view.View.OnFocusChangeListener;
Wenyi Wangf5493a62016-07-11 14:28:52 -070037import android.widget.TextView;
Jay Shrauner1d815e62014-01-31 10:37:31 -080038import android.widget.Toast;
Dmitri Plotnikovb979b422010-07-01 15:29:15 -070039
Walter Janga4897212016-06-21 19:02:23 -070040import com.android.contacts.AppCompatContactsActivity;
Chiao Chenge0b2f1e2012-06-12 13:07:56 -070041import com.android.contacts.R;
Walter Jangac679af2015-06-01 12:17:06 -070042import com.android.contacts.editor.EditorIntents;
Gary Mai0a49afa2016-12-05 15:53:58 -080043import com.android.contacts.list.ContactEntryListFragment;
Chiao Chenge0b2f1e2012-06-12 13:07:56 -070044import com.android.contacts.list.ContactPickerFragment;
45import com.android.contacts.list.ContactsIntentResolver;
46import com.android.contacts.list.ContactsRequest;
Gary Mai0a49afa2016-12-05 15:53:58 -080047import com.android.contacts.list.DirectoryListLoader;
Chiao Chenge0b2f1e2012-06-12 13:07:56 -070048import com.android.contacts.list.EmailAddressPickerFragment;
Walter Janga4897212016-06-21 19:02:23 -070049import com.android.contacts.list.GroupMemberPickerFragment;
Brian Attwell81cc3b32014-07-22 16:04:52 -070050import com.android.contacts.list.JoinContactListFragment;
Chiao Chenga953aa72012-12-04 17:04:48 -080051import com.android.contacts.list.LegacyPhoneNumberPickerFragment;
Walter Janga4897212016-06-21 19:02:23 -070052import com.android.contacts.list.MultiSelectContactsListFragment;
53import com.android.contacts.list.MultiSelectContactsListFragment.OnCheckBoxListActionListener;
Gary Mai0a49afa2016-12-05 15:53:58 -080054import com.android.contacts.list.MultiSelectEmailAddressesListFragment;
55import com.android.contacts.list.MultiSelectPhoneNumbersListFragment;
Chiao Chenge0b2f1e2012-06-12 13:07:56 -070056import com.android.contacts.list.OnContactPickerActionListener;
57import com.android.contacts.list.OnEmailAddressPickerActionListener;
Gary Mai0a49afa2016-12-05 15:53:58 -080058import com.android.contacts.list.OnPhoneNumberPickerActionListener;
Chiao Chenge0b2f1e2012-06-12 13:07:56 -070059import com.android.contacts.list.OnPostalAddressPickerActionListener;
Gary Mai0a49afa2016-12-05 15:53:58 -080060import com.android.contacts.list.PhoneNumberPickerFragment;
Chiao Chenge0b2f1e2012-06-12 13:07:56 -070061import com.android.contacts.list.PostalAddressPickerFragment;
Walter Janga4897212016-06-21 19:02:23 -070062import com.android.contacts.list.UiIntentActions;
Gary Mai0a49afa2016-12-05 15:53:58 -080063import com.android.contacts.logging.ListEvent;
64import com.android.contacts.util.ImplicitIntentsUtil;
65import com.android.contacts.util.ViewUtil;
Chiao Chenge0b2f1e2012-06-12 13:07:56 -070066
Walter Jangf9779ef2016-05-25 12:23:05 -070067import java.util.ArrayList;
Katherine Kuan37bddc22011-07-09 17:36:26 -070068
Dmitri Plotnikovb979b422010-07-01 15:29:15 -070069/**
70 * Displays a list of contacts (or phone numbers or postal addresses) for the
71 * purposes of selecting one.
72 */
Walter Janga4897212016-06-21 19:02:23 -070073public class ContactSelectionActivity extends AppCompatContactsActivity implements
74 View.OnCreateContextMenuListener, ActionBarAdapter.Listener, OnClickListener,
75 OnFocusChangeListener, OnCheckBoxListActionListener {
76 private static final String TAG = "ContactSelection";
Dmitri Plotnikovb979b422010-07-01 15:29:15 -070077
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -070078 private static final String KEY_ACTION_CODE = "actionCode";
Brian Attwell81cc3b32014-07-22 16:04:52 -070079 private static final String KEY_SEARCH_MODE = "searchMode";
Dmitri Plotnikov4d174aa2010-10-25 15:38:54 -070080 private static final int DEFAULT_DIRECTORY_RESULT_LIMIT = 20;
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -070081
Dmitri Plotnikovb979b422010-07-01 15:29:15 -070082 private ContactsIntentResolver mIntentResolver;
83 protected ContactEntryListFragment<?> mListFragment;
84
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -070085 private int mActionCode = -1;
Brian Attwell81cc3b32014-07-22 16:04:52 -070086 private boolean mIsSearchMode;
Brian Attwellfde48de2014-11-21 11:01:31 -080087 private boolean mIsSearchSupported;
Dmitri Plotnikovb979b422010-07-01 15:29:15 -070088
Dmitri Plotnikovb979b422010-07-01 15:29:15 -070089 private ContactsRequest mRequest;
Walter Janga4897212016-06-21 19:02:23 -070090
91 private ActionBarAdapter mActionBarAdapter;
92 private Toolbar mToolbar;
Dmitri Plotnikovb979b422010-07-01 15:29:15 -070093
94 public ContactSelectionActivity() {
95 mIntentResolver = new ContactsIntentResolver(this);
96 }
97
98 @Override
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -070099 public void onAttachFragment(Fragment fragment) {
100 if (fragment instanceof ContactEntryListFragment<?>) {
101 mListFragment = (ContactEntryListFragment<?>) fragment;
102 setupActionListener();
103 }
104 }
105
106 @Override
107 protected void onCreate(Bundle savedState) {
108 super.onCreate(savedState);
109
Brian Attwellbdd32642015-05-08 17:03:15 -0700110 if (RequestPermissionsActivity.startPermissionActivity(this)) {
111 return;
112 }
113
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700114 if (savedState != null) {
115 mActionCode = savedState.getInt(KEY_ACTION_CODE);
Brian Attwell81cc3b32014-07-22 16:04:52 -0700116 mIsSearchMode = savedState.getBoolean(KEY_SEARCH_MODE);
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700117 }
Katherine Kuanacd8e8b2011-10-21 12:35:55 -0700118
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700119 // Extract relevant information from the intent
120 mRequest = mIntentResolver.resolveIntent(getIntent());
121 if (!mRequest.isValid()) {
122 setResult(RESULT_CANCELED);
123 finish();
124 return;
125 }
126
Dmitri Plotnikov4d174aa2010-10-25 15:38:54 -0700127 setContentView(R.layout.contact_picker);
128
Daisuke Miyakawaa8729cd2011-10-12 12:27:16 -0700129 if (mActionCode != mRequest.getActionCode()) {
130 mActionCode = mRequest.getActionCode();
131 configureListFragment();
132 }
Dmitri Plotnikov4d174aa2010-10-25 15:38:54 -0700133
Walter Janga4897212016-06-21 19:02:23 -0700134 prepareSearchViewAndActionBar(savedState);
135 configureActivityTitle();
Daisuke Miyakawaa8729cd2011-10-12 12:27:16 -0700136 }
137
Walter Janga4897212016-06-21 19:02:23 -0700138 public boolean isSelectionMode() {
139 return mActionBarAdapter.isSelectionMode();
140 }
141
142 public boolean isSearchMode() {
143 return mActionBarAdapter.isSearchMode();
144 }
145
146 private void prepareSearchViewAndActionBar(Bundle savedState) {
147 mToolbar = getView(R.id.toolbar);
148 setSupportActionBar(mToolbar);
149
150 // Add a shadow under the toolbar.
151 ViewUtil.addRectangularOutlineProvider(findViewById(R.id.toolbar_parent), getResources());
152
Wenyi Wangca6018d2016-08-18 17:23:13 -0700153 mActionBarAdapter = new ActionBarAdapter(this, this, getSupportActionBar(), mToolbar,
Walter Janga4897212016-06-21 19:02:23 -0700154 R.string.enter_contact_name);
155 mActionBarAdapter.setShowHomeIcon(true);
156 mActionBarAdapter.setShowHomeAsUp(true);
Walter Janga4897212016-06-21 19:02:23 -0700157 mActionBarAdapter.initialize(savedState, mRequest);
Brian Attwellbbd22012014-07-16 15:59:10 -0700158
Walter Jang16c29592016-06-14 15:34:39 -0700159 // Postal address pickers (and legacy pickers) don't support search, so just show
Daniel Lehmannd1af8ad2011-11-08 17:19:51 -0800160 // "HomeAsUp" button and title.
Sean Midfordff6f1bb2016-10-12 09:48:23 -0700161 mIsSearchSupported = mRequest.getActionCode() != ContactsRequest.ACTION_PICK_POSTAL
162 && mRequest.getActionCode() != ContactsRequest.ACTION_PICK_EMAILS
163 && mRequest.getActionCode() != ContactsRequest.ACTION_PICK_PHONES
164 && !mRequest.isLegacyCompatibilityMode();
Brian Attwell81cc3b32014-07-22 16:04:52 -0700165 configureSearchMode();
166 }
167
168 private void configureSearchMode() {
Walter Janga4897212016-06-21 19:02:23 -0700169 mActionBarAdapter.setSearchMode(mIsSearchMode);
Brian Attwell81cc3b32014-07-22 16:04:52 -0700170 invalidateOptionsMenu();
Daisuke Miyakawaa8729cd2011-10-12 12:27:16 -0700171 }
Dmitri Plotnikov63c311a2010-12-08 09:29:24 -0800172
Daisuke Miyakawaa8729cd2011-10-12 12:27:16 -0700173 @Override
Daisuke Miyakawaa8729cd2011-10-12 12:27:16 -0700174 public boolean onOptionsItemSelected(MenuItem item) {
175 switch (item.getItemId()) {
176 case android.R.id.home:
177 // Go back to previous screen, intending "cancel"
178 setResult(RESULT_CANCELED);
Brian Attwell81cc3b32014-07-22 16:04:52 -0700179 onBackPressed();
180 return true;
181 case R.id.menu_search:
182 mIsSearchMode = !mIsSearchMode;
183 configureSearchMode();
Daisuke Miyakawaa8729cd2011-10-12 12:27:16 -0700184 return true;
Daisuke Miyakawaa8729cd2011-10-12 12:27:16 -0700185 }
186 return super.onOptionsItemSelected(item);
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700187 }
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700188
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700189 @Override
190 protected void onSaveInstanceState(Bundle outState) {
191 super.onSaveInstanceState(outState);
192 outState.putInt(KEY_ACTION_CODE, mActionCode);
Brian Attwell81cc3b32014-07-22 16:04:52 -0700193 outState.putBoolean(KEY_SEARCH_MODE, mIsSearchMode);
Walter Jang0ef05182016-06-23 15:34:15 -0700194 if (mActionBarAdapter != null) {
195 mActionBarAdapter.onSaveInstanceState(outState);
196 }
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700197 }
198
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700199 private void configureActivityTitle() {
Makoto Onukib7a1da62012-11-27 15:40:38 -0800200 if (!TextUtils.isEmpty(mRequest.getActivityTitle())) {
Walter Janga4897212016-06-21 19:02:23 -0700201 getSupportActionBar().setTitle(mRequest.getActivityTitle());
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700202 return;
203 }
Walter Janga4897212016-06-21 19:02:23 -0700204 int titleResId = -1;
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700205 int actionCode = mRequest.getActionCode();
206 switch (actionCode) {
207 case ContactsRequest.ACTION_INSERT_OR_EDIT_CONTACT: {
Walter Janga4897212016-06-21 19:02:23 -0700208 titleResId = R.string.contactInsertOrEditActivityTitle;
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700209 break;
210 }
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700211 case ContactsRequest.ACTION_PICK_CONTACT: {
Walter Janga4897212016-06-21 19:02:23 -0700212 titleResId = R.string.contactPickerActivityTitle;
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700213 break;
214 }
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700215 case ContactsRequest.ACTION_PICK_OR_CREATE_CONTACT: {
Walter Janga4897212016-06-21 19:02:23 -0700216 titleResId = R.string.contactPickerActivityTitle;
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700217 break;
218 }
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700219 case ContactsRequest.ACTION_CREATE_SHORTCUT_CONTACT: {
Walter Janga4897212016-06-21 19:02:23 -0700220 titleResId = R.string.shortcutActivityTitle;
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700221 break;
222 }
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700223 case ContactsRequest.ACTION_PICK_PHONE: {
Walter Janga4897212016-06-21 19:02:23 -0700224 titleResId = R.string.contactPickerActivityTitle;
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700225 break;
226 }
Daniel Lehmannc86ace72011-03-23 21:04:29 -0700227 case ContactsRequest.ACTION_PICK_EMAIL: {
Walter Janga4897212016-06-21 19:02:23 -0700228 titleResId = R.string.contactPickerActivityTitle;
Daniel Lehmannc86ace72011-03-23 21:04:29 -0700229 break;
230 }
Sean Midfordff6f1bb2016-10-12 09:48:23 -0700231 case ContactsRequest.ACTION_PICK_PHONES: {
232 titleResId = R.string.pickerSelectContactsActivityTitle;
233 break;
234 }
235 case ContactsRequest.ACTION_PICK_EMAILS: {
236 titleResId = R.string.pickerSelectContactsActivityTitle;
237 break;
238 }
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700239 case ContactsRequest.ACTION_CREATE_SHORTCUT_CALL: {
Walter Jangf5faebf2016-12-08 10:33:08 -0800240 titleResId = R.string.shortcutActivityTitle;
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700241 break;
242 }
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700243 case ContactsRequest.ACTION_CREATE_SHORTCUT_SMS: {
Walter Jangf5faebf2016-12-08 10:33:08 -0800244 titleResId = R.string.shortcutActivityTitle;
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700245 break;
246 }
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700247 case ContactsRequest.ACTION_PICK_POSTAL: {
Walter Janga4897212016-06-21 19:02:23 -0700248 titleResId = R.string.contactPickerActivityTitle;
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700249 break;
250 }
Brian Attwell81cc3b32014-07-22 16:04:52 -0700251 case ContactsRequest.ACTION_PICK_JOIN: {
Walter Janga4897212016-06-21 19:02:23 -0700252 titleResId = R.string.titleJoinContactDataWith;
Brian Attwell81cc3b32014-07-22 16:04:52 -0700253 break;
254 }
Walter Jangf9779ef2016-05-25 12:23:05 -0700255 case ContactsRequest.ACTION_PICK_GROUP_MEMBERS: {
Walter Jangec807e12016-06-27 12:10:40 -0700256 titleResId = R.string.groupMemberPickerActivityTitle;
Walter Jangf9779ef2016-05-25 12:23:05 -0700257 break;
258 }
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700259 }
Walter Janga4897212016-06-21 19:02:23 -0700260 if (titleResId > 0) {
261 getSupportActionBar().setTitle(titleResId);
262 }
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700263 }
264
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700265 /**
266 * Creates the fragment based on the current request.
267 */
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700268 public void configureListFragment() {
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700269 switch (mActionCode) {
270 case ContactsRequest.ACTION_INSERT_OR_EDIT_CONTACT: {
Dmitri Plotnikov86092522010-10-27 17:03:52 -0700271 ContactPickerFragment fragment = new ContactPickerFragment();
Dmitri Plotnikov86092522010-10-27 17:03:52 -0700272 fragment.setEditMode(true);
273 fragment.setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_NONE);
Brian Attwellbbd22012014-07-16 15:59:10 -0700274 fragment.setCreateContactEnabled(!mRequest.isSearchMode());
Walter Jang6158b812016-07-19 15:59:51 -0700275 fragment.setListType(ListEvent.ListType.PICK_CONTACT);
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700276 mListFragment = fragment;
277 break;
278 }
279
Jay Shrauner98609ec2014-01-10 11:26:14 -0800280 case ContactsRequest.ACTION_DEFAULT:
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700281 case ContactsRequest.ACTION_PICK_CONTACT: {
282 ContactPickerFragment fragment = new ContactPickerFragment();
Wenyi Wang7b6bb002016-04-11 12:40:28 -0700283 fragment.setIncludeFavorites(mRequest.shouldIncludeFavorites());
Walter Jang6158b812016-07-19 15:59:51 -0700284 fragment.setListType(ListEvent.ListType.PICK_CONTACT);
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700285 mListFragment = fragment;
286 break;
287 }
288
289 case ContactsRequest.ACTION_PICK_OR_CREATE_CONTACT: {
290 ContactPickerFragment fragment = new ContactPickerFragment();
Brian Attwellbbd22012014-07-16 15:59:10 -0700291 fragment.setCreateContactEnabled(!mRequest.isSearchMode());
Walter Jang6158b812016-07-19 15:59:51 -0700292 fragment.setListType(ListEvent.ListType.PICK_CONTACT);
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700293 mListFragment = fragment;
294 break;
295 }
296
297 case ContactsRequest.ACTION_CREATE_SHORTCUT_CONTACT: {
298 ContactPickerFragment fragment = new ContactPickerFragment();
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700299 fragment.setShortcutRequested(true);
Walter Jang6158b812016-07-19 15:59:51 -0700300 fragment.setListType(ListEvent.ListType.PICK_CONTACT_FOR_SHORTCUT);
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700301 mListFragment = fragment;
302 break;
303 }
304
305 case ContactsRequest.ACTION_PICK_PHONE: {
Chiao Chenga953aa72012-12-04 17:04:48 -0800306 PhoneNumberPickerFragment fragment = getPhoneNumberPickerFragment(mRequest);
Walter Jang6158b812016-07-19 15:59:51 -0700307 fragment.setListType(ListEvent.ListType.PICK_PHONE);
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700308 mListFragment = fragment;
309 break;
310 }
311
Daniel Lehmannc86ace72011-03-23 21:04:29 -0700312 case ContactsRequest.ACTION_PICK_EMAIL: {
313 mListFragment = new EmailAddressPickerFragment();
Walter Jang6158b812016-07-19 15:59:51 -0700314 mListFragment.setListType(ListEvent.ListType.PICK_EMAIL);
Daniel Lehmannc86ace72011-03-23 21:04:29 -0700315 break;
316 }
317
Sean Midfordff6f1bb2016-10-12 09:48:23 -0700318 case ContactsRequest.ACTION_PICK_PHONES: {
319 mListFragment = new MultiSelectPhoneNumbersListFragment();
320 mListFragment.setArguments(getIntent().getExtras());
321 break;
322 }
323
324 case ContactsRequest.ACTION_PICK_EMAILS: {
325 mListFragment = new MultiSelectEmailAddressesListFragment();
326 mListFragment.setArguments(getIntent().getExtras());
327 break;
328 }
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700329 case ContactsRequest.ACTION_CREATE_SHORTCUT_CALL: {
Chiao Chenga953aa72012-12-04 17:04:48 -0800330 PhoneNumberPickerFragment fragment = getPhoneNumberPickerFragment(mRequest);
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700331 fragment.setShortcutAction(Intent.ACTION_CALL);
Walter Jang6158b812016-07-19 15:59:51 -0700332 fragment.setListType(ListEvent.ListType.PICK_CONTACT_FOR_SHORTCUT);
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700333 mListFragment = fragment;
334 break;
335 }
336
337 case ContactsRequest.ACTION_CREATE_SHORTCUT_SMS: {
Chiao Chenga953aa72012-12-04 17:04:48 -0800338 PhoneNumberPickerFragment fragment = getPhoneNumberPickerFragment(mRequest);
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700339 fragment.setShortcutAction(Intent.ACTION_SENDTO);
Walter Jang6158b812016-07-19 15:59:51 -0700340 fragment.setListType(ListEvent.ListType.PICK_CONTACT_FOR_SHORTCUT);
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700341 mListFragment = fragment;
342 break;
343 }
344
345 case ContactsRequest.ACTION_PICK_POSTAL: {
346 PostalAddressPickerFragment fragment = new PostalAddressPickerFragment();
Walter Jang6158b812016-07-19 15:59:51 -0700347 fragment.setListType(ListEvent.ListType.PICK_POSTAL);
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700348 mListFragment = fragment;
349 break;
350 }
351
Brian Attwell81cc3b32014-07-22 16:04:52 -0700352 case ContactsRequest.ACTION_PICK_JOIN: {
353 JoinContactListFragment joinFragment = new JoinContactListFragment();
354 joinFragment.setTargetContactId(getTargetContactId());
Walter Jang6158b812016-07-19 15:59:51 -0700355 joinFragment.setListType(ListEvent.ListType.PICK_JOIN);
Brian Attwell81cc3b32014-07-22 16:04:52 -0700356 mListFragment = joinFragment;
357 break;
358 }
359
Walter Jangf9779ef2016-05-25 12:23:05 -0700360 case ContactsRequest.ACTION_PICK_GROUP_MEMBERS: {
Walter Jang6c5a5582016-06-16 11:26:53 -0700361 final String accountName = getIntent().getStringExtra(
362 UiIntentActions.GROUP_ACCOUNT_NAME);
363 final String accountType = getIntent().getStringExtra(
364 UiIntentActions.GROUP_ACCOUNT_TYPE);
365 final String accountDataSet = getIntent().getStringExtra(
366 UiIntentActions.GROUP_ACCOUNT_DATA_SET);
Walter Jang16c29592016-06-14 15:34:39 -0700367 final ArrayList<String> contactIds = getIntent().getStringArrayListExtra(
368 UiIntentActions.GROUP_CONTACT_IDS);
Walter Jang6c5a5582016-06-16 11:26:53 -0700369 mListFragment = GroupMemberPickerFragment.newInstance(
370 accountName, accountType, accountDataSet, contactIds);
Walter Jang6158b812016-07-19 15:59:51 -0700371 mListFragment.setListType(ListEvent.ListType.PICK_GROUP_MEMBERS);
Walter Jangf9779ef2016-05-25 12:23:05 -0700372 break;
373 }
374
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700375 default:
376 throw new IllegalStateException("Invalid action code: " + mActionCode);
377 }
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700378
Chiao Chenga953aa72012-12-04 17:04:48 -0800379 // Setting compatibility is no longer needed for PhoneNumberPickerFragment since that logic
380 // has been separated into LegacyPhoneNumberPickerFragment. But we still need to set
381 // compatibility for other fragments.
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700382 mListFragment.setLegacyCompatibilityMode(mRequest.isLegacyCompatibilityMode());
Dmitri Plotnikov4d174aa2010-10-25 15:38:54 -0700383 mListFragment.setDirectoryResultLimit(DEFAULT_DIRECTORY_RESULT_LIMIT);
384
Dianne Hackborn3ed426c2011-01-17 12:30:32 -0800385 getFragmentManager().beginTransaction()
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700386 .replace(R.id.list_container, mListFragment)
Minh Pham4b25da72011-08-25 13:50:38 -0700387 .commitAllowingStateLoss();
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700388 }
389
Chiao Chenga953aa72012-12-04 17:04:48 -0800390 private PhoneNumberPickerFragment getPhoneNumberPickerFragment(ContactsRequest request) {
391 if (mRequest.isLegacyCompatibilityMode()) {
392 return new LegacyPhoneNumberPickerFragment();
393 } else {
394 return new PhoneNumberPickerFragment();
395 }
396 }
397
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700398 public void setupActionListener() {
Dmitri Plotnikov6e850a02010-10-28 10:46:21 -0700399 if (mListFragment instanceof ContactPickerFragment) {
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700400 ((ContactPickerFragment) mListFragment).setOnContactPickerActionListener(
401 new ContactPickerActionListener());
402 } else if (mListFragment instanceof PhoneNumberPickerFragment) {
403 ((PhoneNumberPickerFragment) mListFragment).setOnPhoneNumberPickerActionListener(
404 new PhoneNumberPickerActionListener());
405 } else if (mListFragment instanceof PostalAddressPickerFragment) {
406 ((PostalAddressPickerFragment) mListFragment).setOnPostalAddressPickerActionListener(
407 new PostalAddressPickerActionListener());
Daniel Lehmannc86ace72011-03-23 21:04:29 -0700408 } else if (mListFragment instanceof EmailAddressPickerFragment) {
409 ((EmailAddressPickerFragment) mListFragment).setOnEmailAddressPickerActionListener(
410 new EmailAddressPickerActionListener());
Sean Midfordff6f1bb2016-10-12 09:48:23 -0700411 } else if (mListFragment instanceof MultiSelectEmailAddressesListFragment) {
412 ((MultiSelectEmailAddressesListFragment) mListFragment).setCheckBoxListListener(this);
413 } else if (mListFragment instanceof MultiSelectPhoneNumbersListFragment) {
414 ((MultiSelectPhoneNumbersListFragment) mListFragment).setCheckBoxListListener(this);
Brian Attwell81cc3b32014-07-22 16:04:52 -0700415 } else if (mListFragment instanceof JoinContactListFragment) {
416 ((JoinContactListFragment) mListFragment).setOnContactPickerActionListener(
417 new JoinContactActionListener());
Walter Jangf9779ef2016-05-25 12:23:05 -0700418 } else if (mListFragment instanceof GroupMemberPickerFragment) {
419 ((GroupMemberPickerFragment) mListFragment).setListener(
420 new GroupMemberPickerListener());
Walter Janga4897212016-06-21 19:02:23 -0700421 getMultiSelectListFragment().setCheckBoxListListener(this);
Dmitri Plotnikov84b3cc72010-10-11 18:19:51 -0700422 } else {
423 throw new IllegalStateException("Unsupported list fragment type: " + mListFragment);
424 }
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700425 }
426
Walter Janga4897212016-06-21 19:02:23 -0700427 private MultiSelectContactsListFragment getMultiSelectListFragment() {
428 if (mListFragment instanceof MultiSelectContactsListFragment) {
429 return (MultiSelectContactsListFragment) mListFragment;
430 }
431 return null;
432 }
433
434 @Override
435 public void onAction(int action) {
436 switch (action) {
437 case ActionBarAdapter.Listener.Action.START_SEARCH_MODE:
438 mIsSearchMode = true;
439 configureSearchMode();
440 break;
441 case ActionBarAdapter.Listener.Action.CHANGE_SEARCH_QUERY:
442 final String queryString = mActionBarAdapter.getQueryString();
443 mListFragment.setQueryString(queryString, /* delaySelection */ false);
444 break;
445 case ActionBarAdapter.Listener.Action.START_SELECTION_MODE:
446 if (getMultiSelectListFragment() != null) {
447 getMultiSelectListFragment().displayCheckBoxes(true);
448 }
449 invalidateOptionsMenu();
450 break;
451 case ActionBarAdapter.Listener.Action.STOP_SEARCH_AND_SELECTION_MODE:
Wenyi Wangb236b7c2016-06-23 08:59:19 -0700452 mListFragment.setQueryString("", /* delaySelection */ false);
Walter Janga4897212016-06-21 19:02:23 -0700453 mActionBarAdapter.setSearchMode(false);
454 if (getMultiSelectListFragment() != null) {
455 getMultiSelectListFragment().displayCheckBoxes(false);
456 }
457 invalidateOptionsMenu();
458 break;
459 }
460 }
461
462 @Override
Walter Janga4897212016-06-21 19:02:23 -0700463 public void onUpButtonPressed() {
464 onBackPressed();
465 }
466
467 @Override
468 public void onStartDisplayingCheckBoxes() {
469 mActionBarAdapter.setSelectionMode(true);
470 }
471
472 @Override
473 public void onSelectedContactIdsChanged() {
474 if (mListFragment instanceof MultiSelectContactsListFragment) {
Wenyi Wangf5493a62016-07-11 14:28:52 -0700475 final int count = getMultiSelectListFragment().getSelectedContactIds().size();
476 mActionBarAdapter.setSelectionCount(count);
477 updateAddContactsButton(count);
478
Walter Janga4897212016-06-21 19:02:23 -0700479 // Show or hide the multi select "Done" button
480 invalidateOptionsMenu();
481 }
482 }
483
Wenyi Wangf5493a62016-07-11 14:28:52 -0700484 private void updateAddContactsButton(int count) {
485 final TextView textView = (TextView) mActionBarAdapter.getSelectionContainer()
486 .findViewById(R.id.add_contacts);
487 if (count > 0) {
488 textView.setVisibility(View.VISIBLE);
489 textView.setAllCaps(true);
490 textView.setOnClickListener(new OnClickListener() {
491 @Override
492 public void onClick(View v) {
493 final long[] contactIds =
494 getMultiSelectListFragment().getSelectedContactIdsArray();
495 returnSelectedContacts(contactIds);
496 }
497 });
498 } else {
499 textView.setVisibility(View.GONE);
500 }
501 }
502
Walter Janga4897212016-06-21 19:02:23 -0700503 @Override
504 public void onStopDisplayingCheckBoxes() {
505 mActionBarAdapter.setSelectionMode(false);
506 }
507
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700508 private final class ContactPickerActionListener implements OnContactPickerActionListener {
Daniel Lehmanne20d3432010-10-10 18:37:51 -0700509 @Override
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700510 public void onCreateNewContactAction() {
Daisuke Miyakawaa8729cd2011-10-12 12:27:16 -0700511 startCreateNewContactActivity();
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700512 }
513
Daniel Lehmanne20d3432010-10-10 18:37:51 -0700514 @Override
Dmitri Plotnikov86092522010-10-27 17:03:52 -0700515 public void onEditContactAction(Uri contactLookupUri) {
Gary Mai363af602016-09-28 10:01:23 -0700516 startActivityAndForwardResult(EditorIntents.createEditContactIntent(
John Shao41c68862016-08-17 21:02:41 -0700517 ContactSelectionActivity.this, contactLookupUri, /* materialPalette =*/ null,
518 /* photoId =*/ -1));
Dmitri Plotnikov86092522010-10-27 17:03:52 -0700519 }
520
521 @Override
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700522 public void onPickContactAction(Uri contactUri) {
Dmitri Plotnikovd11bca22010-12-08 20:15:17 -0800523 returnPickerResult(contactUri);
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700524 }
525
Daniel Lehmanne20d3432010-10-10 18:37:51 -0700526 @Override
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700527 public void onShortcutIntentCreated(Intent intent) {
Dmitri Plotnikovd11bca22010-12-08 20:15:17 -0800528 returnPickerResult(intent);
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700529 }
530 }
531
532 private final class PhoneNumberPickerActionListener implements
533 OnPhoneNumberPickerActionListener {
Daniel Lehmanne20d3432010-10-10 18:37:51 -0700534 @Override
Tyler Gunn0a8f9732015-12-15 15:38:54 -0800535 public void onPickDataUri(Uri dataUri, boolean isVideoCall, int callInitiationType) {
Dmitri Plotnikovd11bca22010-12-08 20:15:17 -0800536 returnPickerResult(dataUri);
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700537 }
538
Daniel Lehmanne20d3432010-10-10 18:37:51 -0700539 @Override
Anne Ronga6e72302015-09-29 15:16:47 -0700540 public void onPickPhoneNumber(String phoneNumber, boolean isVideoCall,
541 int callInitiationType) {
Andrew Lee86c224e2014-07-02 11:09:28 -0700542 Log.w(TAG, "Unsupported call.");
543 }
544
545 @Override
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700546 public void onShortcutIntentCreated(Intent intent) {
Dmitri Plotnikovd11bca22010-12-08 20:15:17 -0800547 returnPickerResult(intent);
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700548 }
Daisuke Miyakawa88f70fc2011-07-01 12:47:10 -0700549
Yorke Leedd3d2a42015-09-15 13:52:08 -0700550 @Override
Daisuke Miyakawa88f70fc2011-07-01 12:47:10 -0700551 public void onHomeInActionBarSelected() {
552 ContactSelectionActivity.this.onBackPressed();
553 }
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700554 }
555
Brian Attwell81cc3b32014-07-22 16:04:52 -0700556 private final class JoinContactActionListener implements OnContactPickerActionListener {
557 @Override
558 public void onPickContactAction(Uri contactUri) {
559 Intent intent = new Intent(null, contactUri);
560 setResult(RESULT_OK, intent);
561 finish();
562 }
563
564 @Override
565 public void onShortcutIntentCreated(Intent intent) {
566 }
567
568 @Override
569 public void onCreateNewContactAction() {
570 }
571
572 @Override
573 public void onEditContactAction(Uri contactLookupUri) {
574 }
575 }
576
Walter Jangf9779ef2016-05-25 12:23:05 -0700577 private final class GroupMemberPickerListener implements GroupMemberPickerFragment.Listener {
578
579 @Override
Walter Jang16c29592016-06-14 15:34:39 -0700580 public void onGroupMemberClicked(long contactId) {
581 final Intent intent = new Intent();
582 intent.putExtra(UiIntentActions.TARGET_CONTACT_ID_EXTRA_KEY, contactId);
583 returnPickerResult(intent);
Walter Jangf9779ef2016-05-25 12:23:05 -0700584 }
Walter Janga4897212016-06-21 19:02:23 -0700585
586 @Override
Walter Janga4897212016-06-21 19:02:23 -0700587 public void onSelectGroupMembers() {
588 mActionBarAdapter.setSelectionMode(true);
589 }
Walter Jangf9779ef2016-05-25 12:23:05 -0700590 }
591
Wenyi Wangf5493a62016-07-11 14:28:52 -0700592 private void returnSelectedContacts(long[] contactIds) {
593 final Intent intent = new Intent();
594 intent.putExtra(UiIntentActions.TARGET_CONTACT_IDS_EXTRA_KEY, contactIds);
595 returnPickerResult(intent);
596 }
597
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700598 private final class PostalAddressPickerActionListener implements
599 OnPostalAddressPickerActionListener {
Daniel Lehmanne20d3432010-10-10 18:37:51 -0700600 @Override
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700601 public void onPickPostalAddressAction(Uri dataUri) {
Dmitri Plotnikovd11bca22010-12-08 20:15:17 -0800602 returnPickerResult(dataUri);
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700603 }
604 }
605
Daniel Lehmannc86ace72011-03-23 21:04:29 -0700606 private final class EmailAddressPickerActionListener implements
607 OnEmailAddressPickerActionListener {
608 @Override
609 public void onPickEmailAddressAction(Uri dataUri) {
610 returnPickerResult(dataUri);
611 }
612 }
613
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700614 public void startActivityAndForwardResult(final Intent intent) {
615 intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
616
617 // Forward extras to the new activity
618 Bundle extras = getIntent().getExtras();
619 if (extras != null) {
620 intent.putExtras(extras);
621 }
Jay Shrauner1d815e62014-01-31 10:37:31 -0800622 try {
John Shao41c68862016-08-17 21:02:41 -0700623 ImplicitIntentsUtil.startActivityInApp(ContactSelectionActivity.this, intent);
Jay Shrauner1d815e62014-01-31 10:37:31 -0800624 } catch (ActivityNotFoundException e) {
625 Log.e(TAG, "startActivity() failed: " + e);
626 Toast.makeText(ContactSelectionActivity.this, R.string.missing_app,
627 Toast.LENGTH_SHORT).show();
628 }
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700629 finish();
630 }
631
632 @Override
Daisuke Miyakawaa8729cd2011-10-12 12:27:16 -0700633 public void onFocusChange(View view, boolean hasFocus) {
634 switch (view.getId()) {
635 case R.id.search_view: {
636 if (hasFocus) {
Walter Janga4897212016-06-21 19:02:23 -0700637 mActionBarAdapter.setFocusOnSearchView();
Daisuke Miyakawaa8729cd2011-10-12 12:27:16 -0700638 }
639 }
640 }
641 }
642
Dmitri Plotnikovd11bca22010-12-08 20:15:17 -0800643 public void returnPickerResult(Uri data) {
644 Intent intent = new Intent();
645 intent.setData(data);
646 returnPickerResult(intent);
647 }
648
649 public void returnPickerResult(Intent intent) {
650 intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
651 setResult(RESULT_OK, intent);
652 finish();
653 }
654
Dmitri Plotnikov63c311a2010-12-08 09:29:24 -0800655 @Override
Daisuke Miyakawaa8729cd2011-10-12 12:27:16 -0700656 public void onClick(View view) {
657 switch (view.getId()) {
Brian Attwell89ee3952014-07-09 16:40:39 -0700658 case R.id.floating_action_button: {
Daisuke Miyakawaa8729cd2011-10-12 12:27:16 -0700659 startCreateNewContactActivity();
660 break;
661 }
662 }
663 }
664
Brian Attwell81cc3b32014-07-22 16:04:52 -0700665 private long getTargetContactId() {
666 Intent intent = getIntent();
Brian Attwellc3d202c2015-01-08 15:01:03 -0800667 final long targetContactId = intent.getLongExtra(
668 UiIntentActions.TARGET_CONTACT_ID_EXTRA_KEY, -1);
Brian Attwell81cc3b32014-07-22 16:04:52 -0700669 if (targetContactId == -1) {
670 Log.e(TAG, "Intent " + intent.getAction() + " is missing required extra: "
Brian Attwellc3d202c2015-01-08 15:01:03 -0800671 + UiIntentActions.TARGET_CONTACT_ID_EXTRA_KEY);
Brian Attwell81cc3b32014-07-22 16:04:52 -0700672 setResult(RESULT_CANCELED);
673 finish();
674 return -1;
675 }
676 return targetContactId;
677 }
678
Daisuke Miyakawaa8729cd2011-10-12 12:27:16 -0700679 private void startCreateNewContactActivity() {
680 Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
Gary Mai363af602016-09-28 10:01:23 -0700681 intent.putExtra(ContactEditorActivity.
Walter Jang8d45cdb2016-09-01 09:25:44 -0700682 INTENT_KEY_FINISH_ACTIVITY_ON_SAVE_COMPLETED, true);
Daisuke Miyakawaa8729cd2011-10-12 12:27:16 -0700683 startActivityAndForwardResult(intent);
684 }
685
Katherine Kuan37bddc22011-07-09 17:36:26 -0700686 @Override
Brian Attwell81cc3b32014-07-22 16:04:52 -0700687 public boolean onCreateOptionsMenu(Menu menu) {
688 super.onCreateOptionsMenu(menu);
689
690 final MenuInflater inflater = getMenuInflater();
691 inflater.inflate(R.menu.search_menu, menu);
692
693 final MenuItem searchItem = menu.findItem(R.id.menu_search);
Brian Attwellfde48de2014-11-21 11:01:31 -0800694 searchItem.setVisible(!mIsSearchMode && mIsSearchSupported);
John Shaobd9ef3c2016-12-15 12:42:03 -0800695
696 final Drawable searchIcon = searchItem.getIcon();
697 if (searchIcon != null) {
698 searchIcon.mutate().setColorFilter(ContextCompat.getColor(this,
699 R.color.actionbar_icon_color), PorterDuff.Mode.SRC_ATOP);
700 }
Brian Attwell81cc3b32014-07-22 16:04:52 -0700701 return true;
702 }
703
704 @Override
705 public void onBackPressed() {
Jay Shrauner7712aef2015-09-25 14:14:28 -0700706 if (!isSafeToCommitTransactions()) {
Jay Shrauner35e17452015-09-16 11:19:23 -0700707 return;
708 }
709
Walter Jang794dbd02016-07-28 13:53:13 -0700710 if (isSelectionMode()) {
711 mActionBarAdapter.setSelectionMode(false);
Wenyi Wang5a48cd92016-08-01 16:40:44 -0700712 if (getMultiSelectListFragment() != null) {
713 getMultiSelectListFragment().displayCheckBoxes(false);
714 }
Walter Jang794dbd02016-07-28 13:53:13 -0700715 } else if (mIsSearchMode) {
Brian Attwell81cc3b32014-07-22 16:04:52 -0700716 mIsSearchMode = false;
717 configureSearchMode();
718 } else {
719 super.onBackPressed();
720 }
721 }
Dmitri Plotnikovb979b422010-07-01 15:29:15 -0700722}