12ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian/* 22ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian * Copyright (C) 2017 The Android Open Source Project 32ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian * 42ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian * Licensed under the Apache License, Version 2.0 (the "License"); 52ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian * you may not use this file except in compliance with the License. 62ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian * You may obtain a copy of the License at 72ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian * 82ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian * http://www.apache.org/licenses/LICENSE-2.0 92ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian * 102ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian * Unless required by applicable law or agreed to in writing, software 112ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian * distributed under the License is distributed on an "AS IS" BASIS, 122ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian * See the License for the specific language governing permissions and 142ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian * limitations under the License 152ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian */ 162ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian 17844dcad13ad494256dddfdc44f7ad90a5f93c530linyuhpackage com.android.dialer.searchfragment.directories; 182ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian 192ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport android.content.Context; 202ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport android.content.res.Resources; 212ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport android.database.Cursor; 222ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport android.net.Uri; 232ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport android.provider.ContactsContract; 242ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport android.provider.ContactsContract.CommonDataKinds.Phone; 25dede7e703541f81af4533ce4a53f18f327090568calderwoodraimport android.provider.ContactsContract.Contacts; 262ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport android.support.v7.widget.RecyclerView; 272ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport android.text.TextUtils; 282ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport android.view.View; 29c266566db55647ac1e27f686b6f03440c5eee36bcalderwoodraimport android.widget.ImageView; 302ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport android.widget.QuickContactBadge; 312ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport android.widget.TextView; 322ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport com.android.dialer.callintent.CallInitiationType; 332ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport com.android.dialer.callintent.CallIntentBuilder; 34c3d3c3dfbcf96f6db92b747463ac84ee244a0c85linyuhimport com.android.dialer.common.cp2.DirectoryCompat; 352ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport com.android.dialer.contactphoto.ContactPhotoManager; 362ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport com.android.dialer.lettertile.LetterTileDrawable; 370efc840171da8739359b326249978d0a44df540btwyenimport com.android.dialer.precall.PreCall; 382ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport com.android.dialer.searchfragment.common.Projections; 392ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport com.android.dialer.searchfragment.common.QueryBoldingUtil; 402ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport com.android.dialer.searchfragment.common.R; 412ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport com.android.dialer.searchfragment.common.SearchCursor; 422ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian 43844dcad13ad494256dddfdc44f7ad90a5f93c530linyuh/** ViewHolder for a directory contact row. */ 44844dcad13ad494256dddfdc44f7ad90a5f93c530linyuhpublic final class DirectoryContactViewHolder extends RecyclerView.ViewHolder 452ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian implements View.OnClickListener { 462ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian 472ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian private final Context context; 482ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian private final TextView nameView; 492ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian private final TextView numberView; 502ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian private final QuickContactBadge photo; 51c266566db55647ac1e27f686b6f03440c5eee36bcalderwoodra private final ImageView workBadge; 522ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian 532ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian private String number; 542ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian 55844dcad13ad494256dddfdc44f7ad90a5f93c530linyuh public DirectoryContactViewHolder(View view) { 562ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian super(view); 572ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian view.setOnClickListener(this); 582ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian photo = view.findViewById(R.id.photo); 592ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian nameView = view.findViewById(R.id.primary); 602ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian numberView = view.findViewById(R.id.secondary); 61c266566db55647ac1e27f686b6f03440c5eee36bcalderwoodra workBadge = view.findViewById(R.id.work_icon); 622ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian context = view.getContext(); 632ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian } 642ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian 652ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian /** 66844dcad13ad494256dddfdc44f7ad90a5f93c530linyuh * Binds the ViewHolder with a cursor from {@link DirectoryContactsCursorLoader} with the data 67844dcad13ad494256dddfdc44f7ad90a5f93c530linyuh * found at the cursors current position. 682ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian */ 692ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian public void bind(SearchCursor cursor, String query) { 702ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian number = cursor.getString(Projections.PHONE_NUMBER); 71fe7e9e1d5a083bfe376df0d54bcf632f60012dcfcalderwoodra String name = cursor.getString(Projections.DISPLAY_NAME); 722ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian String label = getLabel(context.getResources(), cursor); 732ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian String secondaryInfo = 742ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian TextUtils.isEmpty(label) 752ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian ? number 76c3d3c3dfbcf96f6db92b747463ac84ee244a0c85linyuh : context.getString(R.string.call_subject_type_and_number, label, number); 772ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian 7882670fee34bfc922905f31d3904406eb0677b162linyuh nameView.setText(QueryBoldingUtil.getNameWithQueryBolded(query, name, context)); 7982670fee34bfc922905f31d3904406eb0677b162linyuh numberView.setText(QueryBoldingUtil.getNameWithQueryBolded(query, secondaryInfo, context)); 80c266566db55647ac1e27f686b6f03440c5eee36bcalderwoodra workBadge.setVisibility( 81c266566db55647ac1e27f686b6f03440c5eee36bcalderwoodra DirectoryCompat.isOnlyEnterpriseDirectoryId(cursor.getDirectoryId()) 82c266566db55647ac1e27f686b6f03440c5eee36bcalderwoodra ? View.VISIBLE 83c266566db55647ac1e27f686b6f03440c5eee36bcalderwoodra : View.GONE); 842ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian 852ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian if (shouldShowPhoto(cursor)) { 862ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian nameView.setVisibility(View.VISIBLE); 872ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian photo.setVisibility(View.VISIBLE); 88fe7e9e1d5a083bfe376df0d54bcf632f60012dcfcalderwoodra String photoUri = cursor.getString(Projections.PHOTO_URI); 892ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian ContactPhotoManager.getInstance(context) 902ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian .loadDialerThumbnailOrPhoto( 912ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian photo, 922ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian getContactUri(cursor), 93fe7e9e1d5a083bfe376df0d54bcf632f60012dcfcalderwoodra cursor.getLong(Projections.PHOTO_ID), 942ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian photoUri == null ? null : Uri.parse(photoUri), 952ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian name, 962ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian LetterTileDrawable.TYPE_DEFAULT); 972ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian } else { 982ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian nameView.setVisibility(View.GONE); 992ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian photo.setVisibility(View.INVISIBLE); 1002ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian } 1012ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian } 1022ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian 1032ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian // Show the contact photo next to only the first number if a contact has multiple numbers 1042ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian private boolean shouldShowPhoto(SearchCursor cursor) { 1052ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian int currentPosition = cursor.getPosition(); 106fe7e9e1d5a083bfe376df0d54bcf632f60012dcfcalderwoodra String currentLookupKey = cursor.getString(Projections.LOOKUP_KEY); 1072ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian cursor.moveToPosition(currentPosition - 1); 1082ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian 1092ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian if (!cursor.isHeader() && !cursor.isBeforeFirst()) { 110fe7e9e1d5a083bfe376df0d54bcf632f60012dcfcalderwoodra String previousLookupKey = cursor.getString(Projections.LOOKUP_KEY); 1112ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian cursor.moveToPosition(currentPosition); 1122ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian return !currentLookupKey.equals(previousLookupKey); 1132ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian } 1142ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian cursor.moveToPosition(currentPosition); 1152ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian return true; 1162ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian } 1172ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian 1182ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian // TODO(calderwoodra): unify this into a utility method with CallLogAdapter#getNumberType 1192ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian private static String getLabel(Resources resources, Cursor cursor) { 1202ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian int numberType = cursor.getInt(Projections.PHONE_TYPE); 1212ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian String numberLabel = cursor.getString(Projections.PHONE_LABEL); 1222ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian 1232ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian // Returns empty label instead of "custom" if the custom label is empty. 1242ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian if (numberType == Phone.TYPE_CUSTOM && TextUtils.isEmpty(numberLabel)) { 1252ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian return ""; 1262ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian } 1272ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian return (String) Phone.getTypeLabel(resources, numberType, numberLabel); 1282ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian } 1292ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian 130dede7e703541f81af4533ce4a53f18f327090568calderwoodra private static Uri getContactUri(SearchCursor cursor) { 131fe7e9e1d5a083bfe376df0d54bcf632f60012dcfcalderwoodra long contactId = cursor.getLong(Projections.ID); 132fe7e9e1d5a083bfe376df0d54bcf632f60012dcfcalderwoodra String lookupKey = cursor.getString(Projections.LOOKUP_KEY); 133dede7e703541f81af4533ce4a53f18f327090568calderwoodra return Contacts.getLookupUri(contactId, lookupKey) 134dede7e703541f81af4533ce4a53f18f327090568calderwoodra .buildUpon() 135dede7e703541f81af4533ce4a53f18f327090568calderwoodra .appendQueryParameter( 136dede7e703541f81af4533ce4a53f18f327090568calderwoodra ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(cursor.getDirectoryId())) 137dede7e703541f81af4533ce4a53f18f327090568calderwoodra .build(); 1382ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian } 1392ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian 1402ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian @Override 1412ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian public void onClick(View v) { 1420efc840171da8739359b326249978d0a44df540btwyen PreCall.start(context, new CallIntentBuilder(number, CallInitiationType.Type.REGULAR_SEARCH)); 1432ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian } 1442ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian} 145