1ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/* 2ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Copyright (C) 2010 The Android Open Source Project 3ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 4ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Licensed under the Apache License, Version 2.0 (the "License"); 5ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * you may not use this file except in compliance with the License. 6ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * You may obtain a copy of the License at 7ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 8ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * http://www.apache.org/licenses/LICENSE-2.0 9ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 10ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Unless required by applicable law or agreed to in writing, software 11ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * distributed under the License is distributed on an "AS IS" BASIS, 12ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * See the License for the specific language governing permissions and 14ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * limitations under the License. 15ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 16ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 17ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpackage com.android.contacts.common.list; 18ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 19ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.content.Context; 203331545bd3fb769ae3f9246c0bd92fe35c6308absailimport android.content.CursorLoader; 21ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.database.Cursor; 22ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.net.Uri; 23ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.net.Uri.Builder; 24ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.provider.ContactsContract; 25ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.provider.ContactsContract.CommonDataKinds.Callable; 26ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.provider.ContactsContract.CommonDataKinds.Phone; 27ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.provider.ContactsContract.CommonDataKinds.SipAddress; 28ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.provider.ContactsContract.Contacts; 29ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.provider.ContactsContract.Directory; 3010ae593a59aa50963e1d3159747da2d65ca79bedEric Erfanianimport android.support.annotation.VisibleForTesting; 31ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.text.TextUtils; 32ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.view.View; 33ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.view.ViewGroup; 34ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.ContactPhotoManager.DefaultImageRequest; 35ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.ContactsUtils; 36ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.R; 37ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.compat.CallableCompat; 38ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.compat.DirectoryCompat; 39ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.compat.PhoneCompat; 40ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.extensions.PhoneDirectoryExtenderAccessor; 412f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport com.android.contacts.common.lettertiles.LetterTileDrawable; 4210b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanianimport com.android.contacts.common.list.ContactListItemView.CallToAction; 43ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.preference.ContactsPreferences; 44ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.util.Constants; 4510b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanianimport com.android.dialer.common.LogUtil; 46ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.compat.CompatUtils; 472f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport com.android.dialer.dialercontact.DialerContact; 4810b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanianimport com.android.dialer.enrichedcall.EnrichedCallCapabilities; 4910b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanianimport com.android.dialer.enrichedcall.EnrichedCallComponent; 5010b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanianimport com.android.dialer.enrichedcall.EnrichedCallManager; 512f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport com.android.dialer.lightbringer.LightbringerComponent; 5210b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanianimport com.android.dialer.location.GeoUtil; 53ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.util.CallUtil; 54ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.util.ArrayList; 55ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.util.Arrays; 56ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.util.List; 57ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 58ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/** 59ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * A cursor adapter for the {@link Phone#CONTENT_ITEM_TYPE} and {@link 60ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * SipAddress#CONTENT_ITEM_TYPE}. 61ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 62ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * <p>By default this adapter just handles phone numbers. When {@link #setUseCallableUri(boolean)} 63ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * is called with "true", this adapter starts handling SIP addresses too, by using {@link Callable} 64ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * API instead of {@link Phone}. 65ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 66ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpublic class PhoneNumberListAdapter extends ContactEntryListAdapter { 67ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 68ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private static final String TAG = PhoneNumberListAdapter.class.getSimpleName(); 69ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private static final String IGNORE_NUMBER_TOO_LONG_CLAUSE = "length(" + Phone.NUMBER + ") < 1000"; 70ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // A list of extended directories to add to the directories from the database 71ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private final List<DirectoryPartition> mExtendedDirectories; 72ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private final CharSequence mUnknownNameText; 732f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian protected final boolean mIsImsVideoEnabled; 742f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian 75ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // Extended directories will have ID's that are higher than any of the id's from the database, 76ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // so that we can identify them and set them up properly. If no extended directories 77ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // exist, this will be Long.MAX_VALUE 78ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private long mFirstExtendedDirectoryId = Long.MAX_VALUE; 79ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private boolean mUseCallableUri; 80ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private Listener mListener; 81ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 82ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public PhoneNumberListAdapter(Context context) { 83ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian super(context); 84ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian setDefaultFilterHeaderText(R.string.list_filter_phones); 85ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mUnknownNameText = context.getText(android.R.string.unknownName); 86ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 87ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mExtendedDirectories = 88ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian PhoneDirectoryExtenderAccessor.get(mContext).getExtendedDirectories(mContext); 89ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 90ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian int videoCapabilities = CallUtil.getVideoCallingAvailability(context); 912f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian mIsImsVideoEnabled = 922f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian CallUtil.isVideoEnabled(context) 932f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian && (videoCapabilities & CallUtil.VIDEO_CALLING_PRESENCE) != 0; 94ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 95ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 96ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian @Override 97ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public void configureLoader(CursorLoader loader, long directoryId) { 98ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian String query = getQueryString(); 99ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (query == null) { 100ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian query = ""; 101ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 102ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (isExtendedDirectory(directoryId)) { 103ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final DirectoryPartition directory = getExtendedDirectoryFromId(directoryId); 104ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final String contentUri = directory.getContentUri(); 105ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (contentUri == null) { 106ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian throw new IllegalStateException("Extended directory must have a content URL: " + directory); 107ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 108ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final Builder builder = Uri.parse(contentUri).buildUpon(); 109ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian builder.appendPath(query); 110ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian builder.appendQueryParameter( 111ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian ContactsContract.LIMIT_PARAM_KEY, String.valueOf(getDirectoryResultLimit(directory))); 112ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian loader.setUri(builder.build()); 113ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian loader.setProjection(PhoneQuery.PROJECTION_PRIMARY); 114ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else { 115ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final boolean isRemoteDirectoryQuery = DirectoryCompat.isRemoteDirectoryId(directoryId); 116ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final Builder builder; 117ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (isSearchMode()) { 118ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final Uri baseUri; 119ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (isRemoteDirectoryQuery) { 120ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian baseUri = PhoneCompat.getContentFilterUri(); 121ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else if (mUseCallableUri) { 122ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian baseUri = CallableCompat.getContentFilterUri(); 123ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else { 124ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian baseUri = PhoneCompat.getContentFilterUri(); 125ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 126ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian builder = baseUri.buildUpon(); 127ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian builder.appendPath(query); // Builder will encode the query 128ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian builder.appendQueryParameter( 129ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(directoryId)); 130ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (isRemoteDirectoryQuery) { 131ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian builder.appendQueryParameter( 132ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian ContactsContract.LIMIT_PARAM_KEY, 133ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian String.valueOf(getDirectoryResultLimit(getDirectoryById(directoryId)))); 134ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 135ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else { 136ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian Uri baseUri = mUseCallableUri ? Callable.CONTENT_URI : Phone.CONTENT_URI; 137ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian builder = 138ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian baseUri 139ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian .buildUpon() 140ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian .appendQueryParameter( 141ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(Directory.DEFAULT)); 142ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (isSectionHeaderDisplayEnabled()) { 143ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian builder.appendQueryParameter(Phone.EXTRA_ADDRESS_BOOK_INDEX, "true"); 144ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 145ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian applyFilter(loader, builder, directoryId, getFilter()); 146ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 147ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 148ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // Ignore invalid phone numbers that are too long. These can potentially cause freezes 149ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // in the UI and there is no reason to display them. 150ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final String prevSelection = loader.getSelection(); 151ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final String newSelection; 152ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (!TextUtils.isEmpty(prevSelection)) { 153ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian newSelection = prevSelection + " AND " + IGNORE_NUMBER_TOO_LONG_CLAUSE; 154ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else { 155ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian newSelection = IGNORE_NUMBER_TOO_LONG_CLAUSE; 156ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 157ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian loader.setSelection(newSelection); 158ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 159ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // Remove duplicates when it is possible. 160ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian builder.appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true"); 161ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian loader.setUri(builder.build()); 162ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 163ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // TODO a projection that includes the search snippet 164ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (getContactNameDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_PRIMARY) { 165ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian loader.setProjection(PhoneQuery.PROJECTION_PRIMARY); 166ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else { 167ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian loader.setProjection(PhoneQuery.PROJECTION_ALTERNATIVE); 168ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 169ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 170ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (getSortOrder() == ContactsPreferences.SORT_ORDER_PRIMARY) { 171ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian loader.setSortOrder(Phone.SORT_KEY_PRIMARY); 172ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else { 173ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian loader.setSortOrder(Phone.SORT_KEY_ALTERNATIVE); 174ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 175ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 176ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 177ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 178ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian protected boolean isExtendedDirectory(long directoryId) { 179ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return directoryId >= mFirstExtendedDirectoryId; 180ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 181ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 182ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private DirectoryPartition getExtendedDirectoryFromId(long directoryId) { 183ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final int directoryIndex = (int) (directoryId - mFirstExtendedDirectoryId); 184ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return mExtendedDirectories.get(directoryIndex); 185ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 186ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 187ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** 188ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Configure {@code loader} and {@code uriBuilder} according to {@code directoryId} and {@code 189ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * filter}. 190ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 191ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian private void applyFilter( 192ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian CursorLoader loader, Uri.Builder uriBuilder, long directoryId, ContactListFilter filter) { 193ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (filter == null || directoryId != Directory.DEFAULT) { 194ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return; 195ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 196ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 197ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final StringBuilder selection = new StringBuilder(); 198ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final List<String> selectionArgs = new ArrayList<String>(); 199ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 200ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian switch (filter.filterType) { 201ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian case ContactListFilter.FILTER_TYPE_CUSTOM: 202ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian { 203ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian selection.append(Contacts.IN_VISIBLE_GROUP + "=1"); 204ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian selection.append(" AND " + Contacts.HAS_PHONE_NUMBER + "=1"); 205ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian break; 206ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 207ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian case ContactListFilter.FILTER_TYPE_ACCOUNT: 208ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian { 209ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian filter.addAccountQueryParameterToUrl(uriBuilder); 210ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian break; 211ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 212ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian case ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS: 213ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian case ContactListFilter.FILTER_TYPE_DEFAULT: 214ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian break; // No selection needed. 215ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian case ContactListFilter.FILTER_TYPE_WITH_PHONE_NUMBERS_ONLY: 216ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian break; // This adapter is always "phone only", so no selection needed either. 217ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian default: 21810b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian LogUtil.w( 219ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian TAG, 220ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian "Unsupported filter type came " 221ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian + "(type: " 222ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian + filter.filterType 223ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian + ", toString: " 224ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian + filter 225ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian + ")" 226ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian + " showing all contacts."); 227ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // No selection. 228ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian break; 229ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 230ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian loader.setSelection(selection.toString()); 231ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian loader.setSelectionArgs(selectionArgs.toArray(new String[0])); 232ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 233ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 234ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public String getPhoneNumber(int position) { 235ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final Cursor item = (Cursor) getItem(position); 236ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return item != null ? item.getString(PhoneQuery.PHONE_NUMBER) : null; 237ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 238ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 239ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** 240ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Retrieves the lookup key for the given cursor position. 241ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * 242ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * @param position The cursor position. 243ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * @return The lookup key. 244ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 245ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public String getLookupKey(int position) { 246ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final Cursor item = (Cursor) getItem(position); 247ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return item != null ? item.getString(PhoneQuery.LOOKUP_KEY) : null; 248ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 249ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 2502f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian public DialerContact getDialerContact(int position) { 25110b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian Cursor cursor = (Cursor) getItem(position); 25210b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian if (cursor == null) { 2532f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian LogUtil.e("PhoneNumberListAdapter.getDialerContact", "cursor was null."); 25410b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian return null; 25510b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian } 25610b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian 25710b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian String displayName = cursor.getString(PhoneQuery.DISPLAY_NAME); 25810b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian String number = cursor.getString(PhoneQuery.PHONE_NUMBER); 25910b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian String photoUri = cursor.getString(PhoneQuery.PHOTO_URI); 26010b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian Uri contactUri = 26110b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian Contacts.getLookupUri( 26210b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian cursor.getLong(PhoneQuery.CONTACT_ID), cursor.getString(PhoneQuery.LOOKUP_KEY)); 26310b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian 2642f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian DialerContact.Builder contact = DialerContact.newBuilder(); 26510b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian contact 26610b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian .setNumber(number) 26710b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian .setPhotoId(cursor.getLong(PhoneQuery.PHOTO_ID)) 2682f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian .setContactType(LetterTileDrawable.TYPE_DEFAULT) 26910b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian .setNameOrNumber(displayName) 27010b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian .setNumberLabel( 27110b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian Phone.getTypeLabel( 27210b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian mContext.getResources(), 27310b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian cursor.getInt(PhoneQuery.PHONE_TYPE), 27410b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian cursor.getString(PhoneQuery.PHONE_LABEL)) 27510b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian .toString()); 27610b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian 27710b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian if (photoUri != null) { 27810b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian contact.setPhotoUri(photoUri); 27910b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian } 28010b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian 28110b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian if (contactUri != null) { 28210b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian contact.setContactUri(contactUri.toString()); 28310b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian } 28410b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian 28510b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian if (!TextUtils.isEmpty(displayName)) { 28610b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian contact.setDisplayNumber(number); 28710b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian } 28810b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian 28910b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian return contact.build(); 29010b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian } 29110b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian 292ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian @Override 293ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian protected ContactListItemView newView( 294ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian Context context, int partition, Cursor cursor, int position, ViewGroup parent) { 295ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian ContactListItemView view = super.newView(context, partition, cursor, position, parent); 296ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian view.setUnknownNameText(mUnknownNameText); 297ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian view.setQuickContactEnabled(isQuickContactEnabled()); 298ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return view; 299ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 300ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 301ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian protected void setHighlight(ContactListItemView view, Cursor cursor) { 302ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian view.setHighlightedPrefix(isSearchMode() ? getUpperCaseQueryString() : null); 303ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 304ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 305ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian @Override 306ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian protected void bindView(View itemView, int partition, Cursor cursor, int position) { 307ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian super.bindView(itemView, partition, cursor, position); 308ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian ContactListItemView view = (ContactListItemView) itemView; 309ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 310ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian setHighlight(view, cursor); 311ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 312ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // Look at elements before and after this position, checking if contact IDs are same. 313ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // If they have one same contact ID, it means they can be grouped. 314ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // 315ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // In one group, only the first entry will show its photo and its name, and the other 316ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // entries in the group show just their data (e.g. phone number, email address). 317ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian cursor.moveToPosition(position); 318ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian boolean isFirstEntry = true; 319ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final long currentContactId = cursor.getLong(PhoneQuery.CONTACT_ID); 320ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (cursor.moveToPrevious() && !cursor.isBeforeFirst()) { 321ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final long previousContactId = cursor.getLong(PhoneQuery.CONTACT_ID); 322ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (currentContactId == previousContactId) { 323ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian isFirstEntry = false; 324ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 325ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 326ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian cursor.moveToPosition(position); 327ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 328ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian bindViewId(view, cursor, PhoneQuery.PHONE_ID); 329ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 330ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian bindSectionHeaderAndDivider(view, position); 331ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (isFirstEntry) { 332ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian bindName(view, cursor); 333ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (isQuickContactEnabled()) { 334ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian bindQuickContact( 335ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian view, 336ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian partition, 337ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian cursor, 338ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian PhoneQuery.PHOTO_ID, 339ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian PhoneQuery.PHOTO_URI, 340ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian PhoneQuery.CONTACT_ID, 341ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian PhoneQuery.LOOKUP_KEY, 342ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian PhoneQuery.DISPLAY_NAME); 343ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else { 344ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (getDisplayPhotos()) { 345ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian bindPhoto(view, partition, cursor); 346ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 347ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 348ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else { 349ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian unbindName(view); 350ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 351ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian view.removePhotoView(true, false); 352ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 353ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 354ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final DirectoryPartition directory = (DirectoryPartition) getPartition(partition); 3552f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian // All sections have headers, so scroll position is off by 1. 3562f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian position += getPositionForPartition(partition) + 1; 357ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 358ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian bindPhoneNumber(view, cursor, directory.isDisplayNumber(), position); 359ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 360ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 36110ae593a59aa50963e1d3159747da2d65ca79bedEric Erfanian @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED) 36210ae593a59aa50963e1d3159747da2d65ca79bedEric Erfanian public void bindPhoneNumber( 363ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian ContactListItemView view, Cursor cursor, boolean displayNumber, int position) { 364ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian CharSequence label = null; 365ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (displayNumber && !cursor.isNull(PhoneQuery.PHONE_TYPE)) { 366ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final int type = cursor.getInt(PhoneQuery.PHONE_TYPE); 367ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final String customLabel = cursor.getString(PhoneQuery.PHONE_LABEL); 368ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 369ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // TODO cache 37010b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian label = Phone.getTypeLabel(mContext.getResources(), type, customLabel); 371ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 372ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian view.setLabel(label); 373ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final String text; 37410b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian String number = cursor.getString(PhoneQuery.PHONE_NUMBER); 375ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (displayNumber) { 37610b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian text = number; 377ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else { 378ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // Display phone label. If that's null, display geocoded location for the number 379ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final String phoneLabel = cursor.getString(PhoneQuery.PHONE_LABEL); 380ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (phoneLabel != null) { 381ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian text = phoneLabel; 382ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else { 383ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final String phoneNumber = cursor.getString(PhoneQuery.PHONE_NUMBER); 384ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian text = GeoUtil.getGeocodedLocationFor(mContext, phoneNumber); 385ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 386ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 387ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian view.setPhoneNumber(text); 388ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 38910b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian @CallToAction int action = ContactListItemView.NONE; 39010b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian 391ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (CompatUtils.isVideoCompatible()) { 392ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // Determine if carrier presence indicates the number supports video calling. 393ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian int carrierPresence = cursor.getInt(PhoneQuery.CARRIER_PRESENCE); 394ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian boolean isPresent = (carrierPresence & Phone.CARRIER_PRESENCE_VT_CAPABLE) != 0; 395ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 3962f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian boolean showViewIcon = mIsImsVideoEnabled && isPresent; 3972f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian if (showViewIcon) { 39810b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian action = ContactListItemView.VIDEO; 39910b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian } 40010b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian } 40110b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian 40210ae593a59aa50963e1d3159747da2d65ca79bedEric Erfanian if (action == ContactListItemView.NONE 40310ae593a59aa50963e1d3159747da2d65ca79bedEric Erfanian && LightbringerComponent.get(mContext).getLightbringer().isReachable(mContext, number)) { 4042f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian action = ContactListItemView.LIGHTBRINGER; 4052f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian } 4062f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian 4072f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian if (action == ContactListItemView.NONE) { 40810b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian EnrichedCallManager manager = EnrichedCallComponent.get(mContext).getEnrichedCallManager(); 40910b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian EnrichedCallCapabilities capabilities = manager.getCapabilities(number); 41010b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian if (capabilities != null && capabilities.supportsCallComposer()) { 41110b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian action = ContactListItemView.CALL_AND_SHARE; 41210b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian } else if (capabilities == null 41310b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian && getQueryString() != null 41410b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian && getQueryString().length() >= 3) { 41510b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian manager.requestCapabilities(number); 41610b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian } 417ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 41810b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian 41910b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian view.setCallToAction(action, mListener, position); 420ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 421ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 422ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian protected void bindSectionHeaderAndDivider(final ContactListItemView view, int position) { 423ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (isSectionHeaderDisplayEnabled()) { 424ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian Placement placement = getItemPlacementInSection(position); 425ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian view.setSectionHeader(placement.firstInSection ? placement.sectionHeader : null); 426ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else { 427ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian view.setSectionHeader(null); 428ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 429ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 430ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 431ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian protected void bindName(final ContactListItemView view, Cursor cursor) { 432ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian view.showDisplayName(cursor, PhoneQuery.DISPLAY_NAME); 433ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // Note: we don't show phonetic names any more (see issue 5265330) 434ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 435ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 436ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian protected void unbindName(final ContactListItemView view) { 437ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian view.hideDisplayName(); 438ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 439ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 440ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian @Override 441ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian protected void bindWorkProfileIcon(final ContactListItemView view, int partition) { 442ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final DirectoryPartition directory = (DirectoryPartition) getPartition(partition); 443ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final long directoryId = directory.getDirectoryId(); 444ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final long userType = ContactsUtils.determineUserType(directoryId, null); 445ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // Work directory must not be a extended directory. An extended directory is custom 446ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // directory in the app, but not a directory provided by framework. So it can't be 447ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // USER_TYPE_WORK. 448ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian view.setWorkProfileIconEnabled( 449ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian !isExtendedDirectory(directoryId) && userType == ContactsUtils.USER_TYPE_WORK); 450ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 451ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 452ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian protected void bindPhoto(final ContactListItemView view, int partitionIndex, Cursor cursor) { 453ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (!isPhotoSupported(partitionIndex)) { 454ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian view.removePhotoView(); 455ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return; 456ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 457ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 458ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian long photoId = 0; 459ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (!cursor.isNull(PhoneQuery.PHOTO_ID)) { 460ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian photoId = cursor.getLong(PhoneQuery.PHOTO_ID); 461ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 462ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 463ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (photoId != 0) { 464ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian getPhotoLoader() 465ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian .loadThumbnail(view.getPhotoView(), photoId, false, getCircularPhotos(), null); 466ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } else { 467ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final String photoUriString = cursor.getString(PhoneQuery.PHOTO_URI); 468ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final Uri photoUri = photoUriString == null ? null : Uri.parse(photoUriString); 469ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 470ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian DefaultImageRequest request = null; 471ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (photoUri == null) { 472ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final String displayName = cursor.getString(PhoneQuery.DISPLAY_NAME); 473ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final String lookupKey = cursor.getString(PhoneQuery.LOOKUP_KEY); 474ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian request = new DefaultImageRequest(displayName, lookupKey, getCircularPhotos()); 475ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 476ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian getPhotoLoader() 477ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian .loadDirectoryPhoto(view.getPhotoView(), photoUri, false, getCircularPhotos(), request); 478ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 479ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 480ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 481ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public void setUseCallableUri(boolean useCallableUri) { 482ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mUseCallableUri = useCallableUri; 483ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 484ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 485ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** 486ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Override base implementation to inject extended directories between local & remote directories. 487ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * This is done in the following steps: 1. Call base implementation to add directories from the 488ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * cursor. 2. Iterate all base directories and establish the following information: a. The highest 489ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * directory id so that we can assign unused id's to the extended directories. b. The index of the 490ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * last non-remote directory. This is where we will insert extended directories. 3. Iterate the 491ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * extended directories and for each one, assign an ID and insert it in the proper location. 492ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 493ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian @Override 494ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public void changeDirectories(Cursor cursor) { 495ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian super.changeDirectories(cursor); 496ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (getDirectorySearchMode() == DirectoryListLoader.SEARCH_MODE_NONE) { 497ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return; 498ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 499ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final int numExtendedDirectories = mExtendedDirectories.size(); 500ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (getPartitionCount() == cursor.getCount() + numExtendedDirectories) { 501ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // already added all directories; 502ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return; 503ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 504ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // 505ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mFirstExtendedDirectoryId = Long.MAX_VALUE; 506ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (numExtendedDirectories > 0) { 507ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // The Directory.LOCAL_INVISIBLE is not in the cursor but we can't reuse it's 508ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // "special" ID. 509ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian long maxId = Directory.LOCAL_INVISIBLE; 510ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian int insertIndex = 0; 511ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian for (int i = 0, n = getPartitionCount(); i < n; i++) { 512ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final DirectoryPartition partition = (DirectoryPartition) getPartition(i); 513ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final long id = partition.getDirectoryId(); 514ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (id > maxId) { 515ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian maxId = id; 516ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 517ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (!DirectoryCompat.isRemoteDirectoryId(id)) { 518ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // assuming remote directories come after local, we will end up with the index 519ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // where we should insert extended directories. This also works if there are no 520ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // remote directories at all. 521ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian insertIndex = i + 1; 522ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 523ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 524ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian // Extended directories ID's cannot collide with base directories 525ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mFirstExtendedDirectoryId = maxId + 1; 526ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian for (int i = 0; i < numExtendedDirectories; i++) { 527ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final long id = mFirstExtendedDirectoryId + i; 528ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final DirectoryPartition directory = mExtendedDirectories.get(i); 529ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (getPartitionByDirectoryId(id) == -1) { 530ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian addPartition(insertIndex, directory); 531ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian directory.setDirectoryId(id); 532ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 533ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 534ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 535ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 536ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 537ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian @Override 538ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian protected Uri getContactUri( 539ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian int partitionIndex, Cursor cursor, int contactIdColumn, int lookUpKeyColumn) { 540ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final DirectoryPartition directory = (DirectoryPartition) getPartition(partitionIndex); 541ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final long directoryId = directory.getDirectoryId(); 542ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian if (!isExtendedDirectory(directoryId)) { 543ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return super.getContactUri(partitionIndex, cursor, contactIdColumn, lookUpKeyColumn); 544ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 545ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return Contacts.CONTENT_LOOKUP_URI 546ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian .buildUpon() 547ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian .appendPath(Constants.LOOKUP_URI_ENCODED) 548ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian .appendQueryParameter(Directory.DISPLAY_NAME, directory.getLabel()) 549ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian .appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(directoryId)) 550ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian .encodedFragment(cursor.getString(lookUpKeyColumn)) 551ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian .build(); 552ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 553ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 554ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public Listener getListener() { 555ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian return mListener; 556ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 557ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 558ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public void setListener(Listener listener) { 559ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian mListener = listener; 560ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 561ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 562ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public interface Listener { 563ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 564ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian void onVideoCallIconClicked(int position); 56510b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian 5662f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian void onLightbringerIconClicked(int position); 5672f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian 56810b34a5ebf12e97ecba0caf3c8e30b476b038a96Eric Erfanian void onCallAndShareIconClicked(int position); 569ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 570ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 571ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public static class PhoneQuery { 572ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 573ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** 574ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Optional key used as part of a JSON lookup key to specify an analytics category associated 575ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * with the row. 576ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 577ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public static final String ANALYTICS_CATEGORY = "analytics_category"; 578ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 579ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** 580ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Optional key used as part of a JSON lookup key to specify an analytics action associated with 581ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * the row. 582ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 583ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public static final String ANALYTICS_ACTION = "analytics_action"; 584ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 585ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian /** 586ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Optional key used as part of a JSON lookup key to specify an analytics value associated with 587ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * the row. 588ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */ 589ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public static final String ANALYTICS_VALUE = "analytics_value"; 590ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 591ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public static final String[] PROJECTION_PRIMARY_INTERNAL = 592ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian new String[] { 593ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian Phone._ID, // 0 594ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian Phone.TYPE, // 1 595ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian Phone.LABEL, // 2 596ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian Phone.NUMBER, // 3 597ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian Phone.CONTACT_ID, // 4 598ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian Phone.LOOKUP_KEY, // 5 599ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian Phone.PHOTO_ID, // 6 600ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian Phone.DISPLAY_NAME_PRIMARY, // 7 601ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian Phone.PHOTO_THUMBNAIL_URI, // 8 602ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian }; 603ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 604ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public static final String[] PROJECTION_PRIMARY; 605ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public static final String[] PROJECTION_ALTERNATIVE_INTERNAL = 606ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian new String[] { 607ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian Phone._ID, // 0 608ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian Phone.TYPE, // 1 609ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian Phone.LABEL, // 2 610ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian Phone.NUMBER, // 3 611ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian Phone.CONTACT_ID, // 4 612ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian Phone.LOOKUP_KEY, // 5 613ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian Phone.PHOTO_ID, // 6 614ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian Phone.DISPLAY_NAME_ALTERNATIVE, // 7 615ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian Phone.PHOTO_THUMBNAIL_URI, // 8 616ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian }; 617ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public static final String[] PROJECTION_ALTERNATIVE; 618ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public static final int PHONE_ID = 0; 619ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public static final int PHONE_TYPE = 1; 620ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public static final int PHONE_LABEL = 2; 621ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public static final int PHONE_NUMBER = 3; 622ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public static final int CONTACT_ID = 4; 623ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public static final int LOOKUP_KEY = 5; 624ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public static final int PHOTO_ID = 6; 625ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public static final int DISPLAY_NAME = 7; 626ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public static final int PHOTO_URI = 8; 627ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian public static final int CARRIER_PRESENCE = 9; 628ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 629ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian static { 630ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final List<String> projectionList = 631ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian new ArrayList<>(Arrays.asList(PROJECTION_PRIMARY_INTERNAL)); 6322f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian projectionList.add(Phone.CARRIER_PRESENCE); // 9 633ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian PROJECTION_PRIMARY = projectionList.toArray(new String[projectionList.size()]); 634ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 635ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian 636ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian static { 637ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian final List<String> projectionList = 638ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian new ArrayList<>(Arrays.asList(PROJECTION_ALTERNATIVE_INTERNAL)); 6392f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian projectionList.add(Phone.CARRIER_PRESENCE); // 9 640ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian PROJECTION_ALTERNATIVE = projectionList.toArray(new String[projectionList.size()]); 641ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 642ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian } 643ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian} 644