ContactsIntentResolver.java revision 6e2009d58fdcf098cab033729d4a3b2444c2181c
1/*
2 * Copyright (C) 2010 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.list;
18
19import com.android.contacts.ContactsApplicationController;
20import com.android.contacts.ContactsSearchManager;
21import com.android.contacts.JoinContactActivity;
22import com.android.contacts.R;
23
24import android.app.Activity;
25import android.app.SearchManager;
26import android.content.ContentUris;
27import android.content.Intent;
28import android.content.UriMatcher;
29import android.database.Cursor;
30import android.net.Uri;
31import android.os.Bundle;
32import android.provider.ContactsContract;
33import android.provider.Contacts.ContactMethods;
34import android.provider.Contacts.People;
35import android.provider.Contacts.Phones;
36import android.provider.ContactsContract.Contacts;
37import android.provider.ContactsContract.Data;
38import android.provider.ContactsContract.Intents;
39import android.provider.ContactsContract.RawContacts;
40import android.provider.ContactsContract.CommonDataKinds.Phone;
41import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
42import android.provider.ContactsContract.Intents.Insert;
43import android.provider.ContactsContract.Intents.UI;
44import android.text.TextUtils;
45import android.util.Log;
46
47/**
48 * Maintains contact list configuration, which is a transient object that
49 * deals with intents, saved instance configuration etc.
50 */
51@SuppressWarnings("deprecation")
52public class ContactsIntentResolver {
53
54    private static final String TAG = "ContactsListActivity";
55
56    private static final String SHORTCUT_ACTION_KEY = "shortcutAction";
57
58    /**
59     * The action for the join contact activity.
60     * <p>
61     * Input: extra field {@link #EXTRA_AGGREGATE_ID} is the aggregate ID.
62     *
63     * TODO: move to {@link ContactsContract}.
64     */
65    public static final String JOIN_AGGREGATE =
66            "com.android.contacts.action.JOIN_AGGREGATE";
67
68    /**
69     * Used with {@link #JOIN_AGGREGATE} to give it the target for aggregation.
70     * <p>
71     * Type: LONG
72     */
73    public static final String EXTRA_AGGREGATE_ID =
74            "com.android.contacts.action.AGGREGATE_ID";
75
76    /** Mask for picker mode */
77    static final int MODE_MASK_PICKER = 0x80000000;
78    /** Mask for no presence mode */
79    static final int MODE_MASK_NO_PRESENCE = 0x40000000;
80    /** Mask for enabling list filtering */
81    static final int MODE_MASK_NO_FILTER = 0x20000000;
82    /** Mask for having a "create new contact" header in the list */
83    static final int MODE_MASK_CREATE_NEW = 0x10000000;
84    /** Mask for showing photos in the list */
85    static final int MODE_MASK_SHOW_PHOTOS = 0x08000000;
86    /** Mask for hiding additional information e.g. primary phone number in the list */
87    static final int MODE_MASK_NO_DATA = 0x04000000;
88    /** Mask for showing a call button in the list */
89    static final int MODE_MASK_SHOW_CALL_BUTTON = 0x02000000;
90    /** Mask to disable quickcontact (images will show as normal images) */
91    static final int MODE_MASK_DISABLE_QUIKCCONTACT = 0x01000000;
92    /** Mask to show the total number of contacts at the top */
93    static final int MODE_MASK_SHOW_NUMBER_OF_CONTACTS = 0x00800000;
94
95    /** Unknown mode */
96    static final int MODE_UNKNOWN = 0;
97    /** Default mode */
98    static final int MODE_DEFAULT = 4 | MODE_MASK_SHOW_PHOTOS | MODE_MASK_SHOW_NUMBER_OF_CONTACTS;
99    /** Custom mode */
100    static final int MODE_CUSTOM = 8;
101    /** Show all starred contacts */
102    static final int MODE_STARRED = 20 | MODE_MASK_SHOW_PHOTOS;
103    /** Show frequently contacted contacts */
104    static final int MODE_FREQUENT = 30 | MODE_MASK_SHOW_PHOTOS;
105    /** Show starred and the frequent */
106    static final int MODE_STREQUENT = 35 | MODE_MASK_SHOW_PHOTOS | MODE_MASK_SHOW_CALL_BUTTON;
107    /** Show all contacts and pick them when clicking */
108    static final int MODE_PICK_CONTACT = 40 | MODE_MASK_PICKER | MODE_MASK_SHOW_PHOTOS
109            | MODE_MASK_DISABLE_QUIKCCONTACT;
110    /** Show all contacts as well as the option to create a new one */
111    static final int MODE_PICK_OR_CREATE_CONTACT = 42 | MODE_MASK_PICKER | MODE_MASK_CREATE_NEW
112            | MODE_MASK_SHOW_PHOTOS | MODE_MASK_DISABLE_QUIKCCONTACT;
113    /** Show all people through the legacy provider and pick them when clicking */
114    static final int MODE_LEGACY_PICK_PERSON = 43 | MODE_MASK_PICKER
115            | MODE_MASK_DISABLE_QUIKCCONTACT;
116    /** Show all people through the legacy provider as well as the option to create a new one */
117    static final int MODE_LEGACY_PICK_OR_CREATE_PERSON = 44 | MODE_MASK_PICKER
118            | MODE_MASK_CREATE_NEW | MODE_MASK_DISABLE_QUIKCCONTACT;
119    /** Show all contacts and pick them when clicking, and allow creating a new contact */
120    static final int MODE_INSERT_OR_EDIT_CONTACT = 45 | MODE_MASK_PICKER | MODE_MASK_CREATE_NEW
121            | MODE_MASK_SHOW_PHOTOS | MODE_MASK_DISABLE_QUIKCCONTACT;
122    /** Show all phone numbers and pick them when clicking */
123    static final int MODE_PICK_PHONE = 50 | MODE_MASK_PICKER | MODE_MASK_NO_PRESENCE;
124    /** Show all phone numbers through the legacy provider and pick them when clicking */
125    static final int MODE_LEGACY_PICK_PHONE =
126            51 | MODE_MASK_PICKER | MODE_MASK_NO_PRESENCE | MODE_MASK_NO_FILTER;
127    /** Show all postal addresses and pick them when clicking */
128    static final int MODE_PICK_POSTAL =
129            55 | MODE_MASK_PICKER | MODE_MASK_NO_PRESENCE | MODE_MASK_NO_FILTER;
130    /** Show all postal addresses and pick them when clicking */
131    static final int MODE_LEGACY_PICK_POSTAL =
132            56 | MODE_MASK_PICKER | MODE_MASK_NO_PRESENCE | MODE_MASK_NO_FILTER;
133    static final int MODE_GROUP = 57 | MODE_MASK_SHOW_PHOTOS;
134    /** Run a search query */
135    static final int MODE_QUERY = 60 | MODE_MASK_SHOW_PHOTOS | MODE_MASK_NO_FILTER
136            | MODE_MASK_SHOW_NUMBER_OF_CONTACTS;
137    /** Run a search query in PICK mode, but that still launches to VIEW */
138    static final int MODE_QUERY_PICK_TO_VIEW = 65 | MODE_MASK_SHOW_PHOTOS | MODE_MASK_PICKER
139            | MODE_MASK_SHOW_NUMBER_OF_CONTACTS;
140
141    /** Show join suggestions followed by an A-Z list */
142    static final int MODE_JOIN_CONTACT = 70 | MODE_MASK_PICKER | MODE_MASK_NO_PRESENCE
143            | MODE_MASK_NO_DATA | MODE_MASK_SHOW_PHOTOS | MODE_MASK_DISABLE_QUIKCCONTACT;
144
145    /** Run a search query in a PICK mode */
146    static final int MODE_QUERY_PICK = 75 | MODE_MASK_SHOW_PHOTOS | MODE_MASK_NO_FILTER
147            | MODE_MASK_PICKER | MODE_MASK_DISABLE_QUIKCCONTACT | MODE_MASK_SHOW_NUMBER_OF_CONTACTS;
148
149    /** Run a search query in a PICK_PHONE mode */
150    static final int MODE_QUERY_PICK_PHONE = 80 | MODE_MASK_NO_FILTER | MODE_MASK_PICKER
151            | MODE_MASK_SHOW_NUMBER_OF_CONTACTS;
152
153    /** Run a search query in PICK mode, but that still launches to EDIT */
154    static final int MODE_QUERY_PICK_TO_EDIT = 85 | MODE_MASK_NO_FILTER | MODE_MASK_SHOW_PHOTOS
155            | MODE_MASK_PICKER | MODE_MASK_SHOW_NUMBER_OF_CONTACTS;
156
157    /**
158     * Show all phone numbers and do multiple pick when clicking. This mode has phone filtering
159     * feature, but doesn't support 'search for all contacts'.
160     */
161    static final int MODE_PICK_MULTIPLE_PHONES = 80 | MODE_MASK_PICKER
162            | MODE_MASK_NO_PRESENCE | MODE_MASK_SHOW_PHOTOS | MODE_MASK_DISABLE_QUIKCCONTACT;
163
164    /**
165     * An action used to do perform search while in a contact picker.  It is initiated
166     * by the ContactListActivity itself.
167     */
168    private static final String ACTION_SEARCH_INTERNAL = "com.android.contacts.INTERNAL_SEARCH";
169
170    // Uri matcher for contact id
171    private static final int CONTACTS_ID = 1001;
172    private static final UriMatcher sContactsIdMatcher;
173    static {
174        sContactsIdMatcher = new UriMatcher(UriMatcher.NO_MATCH);
175        sContactsIdMatcher.addURI(ContactsContract.AUTHORITY, "contacts/#", CONTACTS_ID);
176    }
177
178    private final Activity mContext;
179    private boolean mValid = true;
180    private Intent mRedirectIntent;
181    private CharSequence mTitle;
182
183    // TODO: make all these fields private.  They should only remain public while we
184    // are refactoring ContactListActivity.
185    public int mMode = MODE_DEFAULT;
186    public int mQueryMode = QUERY_MODE_NONE;
187    public boolean mSearchMode;
188    public boolean mShowSearchSnippets;
189    public String mInitialFilter;
190    public boolean mDisplayOnlyPhones;
191    public String mShortcutAction;
192    public boolean mSearchResultsMode;
193    public boolean mShowNumberOfContacts;
194    public String mGroupName;
195
196    /**
197     * Internal query type when in mode {@link #MODE_QUERY_PICK_TO_VIEW}.
198     */
199    private static final int QUERY_MODE_NONE = -1;
200    private static final int QUERY_MODE_MAILTO = 1;
201    private static final int QUERY_MODE_TEL = 2;
202
203    private final ContactsApplicationController mAppController;
204
205    public ContactsIntentResolver(Activity context, ContactsApplicationController appController) {
206        this.mContext = context;
207        this.mAppController = appController;
208    }
209
210    public void setIntent(Intent intent) {
211        String action = intent.getAction();
212        String component = intent.getComponent().getClassName();
213
214        // Allow the title to be set to a custom String using an extra on the intent
215        String title = intent.getStringExtra(UI.TITLE_EXTRA_KEY);
216        if (title != null) {
217            mTitle = title;
218        }
219
220        String type = intent.getType();
221
222        // When we get a FILTER_CONTACTS_ACTION, it represents search in the context
223        // of some other action. Let's retrieve the original action to provide proper
224        // context for the search queries.
225        if (UI.FILTER_CONTACTS_ACTION.equals(action)) {
226            mSearchMode = true;
227            mShowSearchSnippets = true;
228            Bundle extras = intent.getExtras();
229            if (extras != null) {
230                mInitialFilter = extras.getString(UI.FILTER_TEXT_EXTRA_KEY);
231                String originalAction =
232                        extras.getString(ContactsSearchManager.ORIGINAL_ACTION_EXTRA_KEY);
233                if (originalAction != null) {
234                    action = originalAction;
235                }
236                String originalComponent =
237                        extras.getString(ContactsSearchManager.ORIGINAL_COMPONENT_EXTRA_KEY);
238                if (originalComponent != null) {
239                    component = originalComponent;
240                }
241                String originalType =
242                    extras.getString(ContactsSearchManager.ORIGINAL_TYPE_EXTRA_KEY);
243                if (originalType != null) {
244                    type = originalType;
245                }
246            } else {
247                mInitialFilter = null;
248            }
249        }
250
251        Log.i(TAG, "Called with action: " + action);
252        mMode = MODE_UNKNOWN;
253        if (UI.LIST_DEFAULT.equals(action) || UI.FILTER_CONTACTS_ACTION.equals(action)) {
254            mMode = MODE_DEFAULT;
255            // When mDefaultMode is true the mode is set in onResume(), since the preferneces
256            // activity may change it whenever this activity isn't running
257        } else if (UI.LIST_GROUP_ACTION.equals(action)) {
258            mMode = MODE_GROUP;
259            mGroupName = intent.getStringExtra(UI.GROUP_NAME_EXTRA_KEY);
260            if (TextUtils.isEmpty(mGroupName)) {
261                mValid = false;
262                return;
263            }
264        } else if (UI.LIST_ALL_CONTACTS_ACTION.equals(action)) {
265            mMode = MODE_CUSTOM;
266            mDisplayOnlyPhones = false;
267        } else if (UI.LIST_STARRED_ACTION.equals(action)) {
268            mMode = mSearchMode ? MODE_DEFAULT : MODE_STARRED;
269        } else if (UI.LIST_FREQUENT_ACTION.equals(action)) {
270            mMode = mSearchMode ? MODE_DEFAULT : MODE_FREQUENT;
271        } else if (UI.LIST_STREQUENT_ACTION.equals(action)) {
272            mMode = mSearchMode ? MODE_DEFAULT : MODE_STREQUENT;
273        } else if (UI.LIST_CONTACTS_WITH_PHONES_ACTION.equals(action)) {
274            mMode = MODE_CUSTOM;
275            mDisplayOnlyPhones = true;
276        } else if (Intent.ACTION_PICK.equals(action)) {
277            // XXX These should be showing the data from the URI given in
278            // the Intent.
279           // TODO : Does it work in mSearchMode?
280            final String resolvedType = intent.resolveType(mContext);
281            if (Contacts.CONTENT_TYPE.equals(resolvedType)) {
282                mMode = MODE_PICK_CONTACT;
283            } else if (People.CONTENT_TYPE.equals(resolvedType)) {
284                mMode = MODE_LEGACY_PICK_PERSON;
285            } else if (Phone.CONTENT_TYPE.equals(resolvedType)) {
286                mMode = MODE_PICK_PHONE;
287            } else if (Phones.CONTENT_TYPE.equals(resolvedType)) {
288                mMode = MODE_LEGACY_PICK_PHONE;
289            } else if (StructuredPostal.CONTENT_TYPE.equals(resolvedType)) {
290                mMode = MODE_PICK_POSTAL;
291            } else if (ContactMethods.CONTENT_POSTAL_TYPE.equals(resolvedType)) {
292                mMode = MODE_LEGACY_PICK_POSTAL;
293            }
294        } else if (Intent.ACTION_CREATE_SHORTCUT.equals(action)) {
295            if (component.equals("alias.DialShortcut")) {
296                mMode = MODE_PICK_PHONE;
297                mShortcutAction = Intent.ACTION_CALL;
298                mShowSearchSnippets = false;
299                mTitle = mContext.getString(R.string.callShortcutActivityTitle);
300            } else if (component.equals("alias.MessageShortcut")) {
301                mMode = MODE_PICK_PHONE;
302                mShortcutAction = Intent.ACTION_SENDTO;
303                mShowSearchSnippets = false;
304                mTitle = mContext.getString(R.string.messageShortcutActivityTitle);
305            } else if (mSearchMode) {
306                mMode = MODE_PICK_CONTACT;
307                mShortcutAction = Intent.ACTION_VIEW;
308                mTitle = mContext.getString(R.string.shortcutActivityTitle);
309            } else {
310                mMode = MODE_PICK_OR_CREATE_CONTACT;
311                mShortcutAction = Intent.ACTION_VIEW;
312                mTitle = mContext.getString(R.string.shortcutActivityTitle);
313            }
314        } else if (Intent.ACTION_GET_CONTENT.equals(action)) {
315            if (Contacts.CONTENT_ITEM_TYPE.equals(type)) {
316                if (mSearchMode) {
317                    mMode = MODE_PICK_CONTACT;
318                } else {
319                    mMode = MODE_PICK_OR_CREATE_CONTACT;
320                }
321            } else if (Phone.CONTENT_ITEM_TYPE.equals(type)) {
322                mMode = MODE_PICK_PHONE;
323            } else if (Phones.CONTENT_ITEM_TYPE.equals(type)) {
324                mMode = MODE_LEGACY_PICK_PHONE;
325            } else if (StructuredPostal.CONTENT_ITEM_TYPE.equals(type)) {
326                mMode = MODE_PICK_POSTAL;
327            } else if (ContactMethods.CONTENT_POSTAL_ITEM_TYPE.equals(type)) {
328                mMode = MODE_LEGACY_PICK_POSTAL;
329            }  else if (People.CONTENT_ITEM_TYPE.equals(type)) {
330                if (mSearchMode) {
331                    mMode = MODE_LEGACY_PICK_PERSON;
332                } else {
333                    mMode = MODE_LEGACY_PICK_OR_CREATE_PERSON;
334                }
335            }
336
337        } else if (Intent.ACTION_INSERT_OR_EDIT.equals(action)) {
338            mMode = MODE_INSERT_OR_EDIT_CONTACT;
339        } else if (Intent.ACTION_SEARCH.equals(action)) {
340            // See if the suggestion was clicked with a search action key (call button)
341            if ("call".equals(intent.getStringExtra(SearchManager.ACTION_MSG))) {
342                String query = intent.getStringExtra(SearchManager.QUERY);
343                if (!TextUtils.isEmpty(query)) {
344                    Intent newIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
345                            Uri.fromParts("tel", query, null));
346                    mRedirectIntent = newIntent;
347                }
348                return;
349            }
350
351            // See if search request has extras to specify query
352            if (intent.hasExtra(Insert.EMAIL)) {
353                mMode = MODE_QUERY_PICK_TO_VIEW;
354                mQueryMode = QUERY_MODE_MAILTO;
355                mInitialFilter = intent.getStringExtra(Insert.EMAIL);
356            } else if (intent.hasExtra(Insert.PHONE)) {
357                mMode = MODE_QUERY_PICK_TO_VIEW;
358                mQueryMode = QUERY_MODE_TEL;
359                mInitialFilter = intent.getStringExtra(Insert.PHONE);
360            } else {
361                // Otherwise handle the more normal search case
362                mMode = MODE_QUERY;
363                mShowSearchSnippets = true;
364                mInitialFilter = intent.getStringExtra(SearchManager.QUERY);
365            }
366            mSearchResultsMode = true;
367        } else if (ACTION_SEARCH_INTERNAL.equals(action)) {
368            String originalAction = null;
369            Bundle extras = intent.getExtras();
370            if (extras != null) {
371                originalAction = extras.getString(ContactsSearchManager.ORIGINAL_ACTION_EXTRA_KEY);
372            }
373            mShortcutAction = intent.getStringExtra(SHORTCUT_ACTION_KEY);
374
375            if (Intent.ACTION_INSERT_OR_EDIT.equals(originalAction)) {
376                mMode = MODE_QUERY_PICK_TO_EDIT;
377                mShowSearchSnippets = true;
378                mInitialFilter = intent.getStringExtra(SearchManager.QUERY);
379            } else if (mShortcutAction != null && intent.hasExtra(Insert.PHONE)) {
380                mMode = MODE_QUERY_PICK_PHONE;
381                mQueryMode = QUERY_MODE_TEL;
382                mInitialFilter = intent.getStringExtra(Insert.PHONE);
383            } else {
384                mMode = MODE_QUERY_PICK;
385                mQueryMode = QUERY_MODE_NONE;
386                mShowSearchSnippets = true;
387                mInitialFilter = intent.getStringExtra(SearchManager.QUERY);
388            }
389            mSearchResultsMode = true;
390        // Since this is the filter activity it receives all intents
391        // dispatched from the SearchManager for security reasons
392        // so we need to re-dispatch from here to the intended target.
393        } else if (Intents.SEARCH_SUGGESTION_CLICKED.equals(action)) {
394            Uri data = intent.getData();
395            Uri telUri = null;
396            if (sContactsIdMatcher.match(data) == CONTACTS_ID) {
397                long contactId = Long.valueOf(data.getLastPathSegment());
398                final Cursor cursor = queryPhoneNumbers(contactId);
399                if (cursor != null) {
400                    if (cursor.getCount() == 1 && cursor.moveToFirst()) {
401                        int phoneNumberIndex = cursor.getColumnIndex(Phone.NUMBER);
402                        String phoneNumber = cursor.getString(phoneNumberIndex);
403                        telUri = Uri.parse("tel:" + phoneNumber);
404                    }
405                    cursor.close();
406                }
407            }
408            // See if the suggestion was clicked with a search action key (call button)
409            Intent newIntent;
410            if ("call".equals(intent.getStringExtra(SearchManager.ACTION_MSG)) && telUri != null) {
411                newIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED, telUri);
412            } else {
413                newIntent = new Intent(Intent.ACTION_VIEW, data);
414            }
415            mRedirectIntent = newIntent;
416            return;
417        } else if (Intents.SEARCH_SUGGESTION_DIAL_NUMBER_CLICKED.equals(action)) {
418            Intent newIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED, intent.getData());
419            mRedirectIntent = newIntent;
420            return;
421        } else if (Intents.SEARCH_SUGGESTION_CREATE_CONTACT_CLICKED.equals(action)) {
422            // TODO actually support this in EditContactActivity.
423            String number = intent.getData().getSchemeSpecificPart();
424            Intent newIntent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
425            newIntent.putExtra(Intents.Insert.PHONE, number);
426            mRedirectIntent = newIntent;
427            return;
428        } else if (JoinContactActivity.JOIN_CONTACT.equals(action)) {
429            mMode = MODE_PICK_CONTACT;
430        } else if (Intents.ACTION_GET_MULTIPLE_PHONES.equals(action)) {
431            if (mSearchMode) {
432                mShowSearchSnippets = false;
433            }
434            if (Phone.CONTENT_TYPE.equals(type)) {
435                mMode = MODE_PICK_MULTIPLE_PHONES;
436            } else {
437                // TODO support other content types
438                Log.e(TAG, "Intent " + action + " is not supported for type " + type);
439                mValid = false;
440            }
441        }
442        if (mMode == MODE_UNKNOWN) {
443            mMode = MODE_DEFAULT;
444        }
445
446        if (((mMode & MODE_MASK_SHOW_NUMBER_OF_CONTACTS) != 0 || mSearchMode)
447                && !mSearchResultsMode) {
448            mShowNumberOfContacts = true;
449        }
450    }
451
452    public boolean isValid() {
453        return mValid;
454    }
455
456    public Intent getRedirectIntent() {
457        return mRedirectIntent;
458    }
459
460    public CharSequence getActivityTitle() {
461        return mTitle;
462    }
463
464    private Cursor queryPhoneNumbers(long contactId) {
465        Uri baseUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
466        Uri dataUri = Uri.withAppendedPath(baseUri, Contacts.Data.CONTENT_DIRECTORY);
467
468        Cursor c = mContext.getContentResolver().query(dataUri,
469                new String[] {Phone._ID, Phone.NUMBER, Phone.IS_SUPER_PRIMARY,
470                RawContacts.ACCOUNT_TYPE, Phone.TYPE, Phone.LABEL},
471                Data.MIMETYPE + "=?", new String[] {Phone.CONTENT_ITEM_TYPE}, null);
472        if (c != null && c.moveToFirst()) {
473            return c;
474        }
475        return null;
476    }
477
478    public ContactEntryListConfiguration getConfiguration() {
479        ContactEntryListConfiguration config;
480        switch (mMode) {
481            case MODE_LEGACY_PICK_POSTAL:
482            case MODE_PICK_POSTAL:
483            case MODE_LEGACY_PICK_PHONE:
484            case MODE_PICK_PHONE:
485            case MODE_STREQUENT:
486            case MODE_FREQUENT: {
487                config = new DefaultContactListConfiguration(mContext, mAppController);
488                break;
489            }
490            case MODE_PICK_MULTIPLE_PHONES: {
491                config = new MultiplePhonePickerConfiguration(mContext, mAppController);
492                break;
493            }
494            default: {
495                config = new DefaultContactListConfiguration(mContext, mAppController);
496                if (!mSearchMode) {
497                    config.setSectionHeaderDisplayEnabled(true);
498                }
499            }
500        }
501
502        if ((mMode & MODE_MASK_SHOW_PHOTOS) == MODE_MASK_SHOW_PHOTOS) {
503            config.setPhotoLoaderEnabled(true);
504        }
505
506        return config;
507    }
508}
509