1 /* 2 * Copyright (C) 2018 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 17 package com.android.dialer.phonelookup.cp2; 18 19 import android.content.Context; 20 import android.database.Cursor; 21 import android.provider.ContactsContract; 22 import android.provider.ContactsContract.CommonDataKinds.Phone; 23 import android.provider.ContactsContract.Contacts; 24 import android.provider.ContactsContract.PhoneLookup; 25 import android.text.TextUtils; 26 import com.android.dialer.phonelookup.PhoneLookupInfo.Cp2Info.Cp2ContactInfo; 27 28 /** 29 * A class providing projection-related functionality for {@link 30 * com.android.dialer.phonelookup.PhoneLookup} implementations for ContactsProvider2 (CP2). 31 */ 32 final class Cp2Projections { 33 34 // Projection for performing lookups using the PHONE table 35 private static final String[] PHONE_PROJECTION = 36 new String[] { 37 Phone.DISPLAY_NAME_PRIMARY, // 0 38 Phone.PHOTO_THUMBNAIL_URI, // 1 39 Phone.PHOTO_URI, // 2 40 Phone.PHOTO_ID, // 3 41 Phone.TYPE, // 4 42 Phone.LABEL, // 5 43 Phone.NORMALIZED_NUMBER, // 6 44 Phone.CONTACT_ID, // 7 45 Phone.LOOKUP_KEY, // 8 46 Phone.CARRIER_PRESENCE 47 }; 48 49 // Projection for performing lookups using the PHONE_LOOKUP table 50 private static final String[] PHONE_LOOKUP_PROJECTION = 51 new String[] { 52 PhoneLookup.DISPLAY_NAME_PRIMARY, // 0 53 PhoneLookup.PHOTO_THUMBNAIL_URI, // 1 54 PhoneLookup.PHOTO_URI, // 2 55 PhoneLookup.PHOTO_ID, // 3 56 PhoneLookup.TYPE, // 4 57 PhoneLookup.LABEL, // 5 58 PhoneLookup.NORMALIZED_NUMBER, // 6 59 PhoneLookup.CONTACT_ID, // 7 60 PhoneLookup.LOOKUP_KEY // 8 61 }; 62 63 // The following indexes should match the common columns in 64 // PHONE_PROJECTION and PHONE_LOOKUP_PROJECTION above. 65 private static final int CP2_INFO_NAME_INDEX = 0; 66 private static final int CP2_INFO_PHOTO_THUMBNAIL_URI_INDEX = 1; 67 private static final int CP2_INFO_PHOTO_URI_INDEX = 2; 68 private static final int CP2_INFO_PHOTO_ID_INDEX = 3; 69 private static final int CP2_INFO_TYPE_INDEX = 4; 70 private static final int CP2_INFO_LABEL_INDEX = 5; 71 private static final int CP2_INFO_NORMALIZED_NUMBER_INDEX = 6; 72 private static final int CP2_INFO_CONTACT_ID_INDEX = 7; 73 private static final int CP2_INFO_LOOKUP_KEY_INDEX = 8; 74 Cp2Projections()75 private Cp2Projections() {} 76 getProjectionForPhoneTable()77 static String[] getProjectionForPhoneTable() { 78 return PHONE_PROJECTION; 79 } 80 getProjectionForPhoneLookupTable()81 static String[] getProjectionForPhoneLookupTable() { 82 return PHONE_LOOKUP_PROJECTION; 83 } 84 85 /** 86 * Builds a {@link Cp2ContactInfo} based on the current row of {@code cursor}, of which the 87 * projection is either {@link #PHONE_PROJECTION} or {@link #PHONE_LOOKUP_PROJECTION}. 88 */ buildCp2ContactInfoFromCursor( Context appContext, Cursor cursor, long directoryId)89 static Cp2ContactInfo buildCp2ContactInfoFromCursor( 90 Context appContext, Cursor cursor, long directoryId) { 91 String displayName = cursor.getString(CP2_INFO_NAME_INDEX); 92 String photoThumbnailUri = cursor.getString(CP2_INFO_PHOTO_THUMBNAIL_URI_INDEX); 93 String photoUri = cursor.getString(CP2_INFO_PHOTO_URI_INDEX); 94 int photoId = cursor.getInt(CP2_INFO_PHOTO_ID_INDEX); 95 int type = cursor.getInt(CP2_INFO_TYPE_INDEX); 96 String label = cursor.getString(CP2_INFO_LABEL_INDEX); 97 int contactId = cursor.getInt(CP2_INFO_CONTACT_ID_INDEX); 98 String lookupKey = cursor.getString(CP2_INFO_LOOKUP_KEY_INDEX); 99 100 Cp2ContactInfo.Builder infoBuilder = Cp2ContactInfo.newBuilder(); 101 if (!TextUtils.isEmpty(displayName)) { 102 infoBuilder.setName(displayName); 103 } 104 if (!TextUtils.isEmpty(photoThumbnailUri)) { 105 infoBuilder.setPhotoThumbnailUri(photoThumbnailUri); 106 } 107 if (!TextUtils.isEmpty(photoUri)) { 108 infoBuilder.setPhotoUri(photoUri); 109 } 110 if (photoId > 0) { 111 infoBuilder.setPhotoId(photoId); 112 } 113 114 // Phone.getTypeLabel returns "Custom" if given (0, null) which is not of any use. Just 115 // omit setting the label if there's no information for it. 116 if (type != 0 || !TextUtils.isEmpty(label)) { 117 infoBuilder.setLabel(Phone.getTypeLabel(appContext.getResources(), type, label).toString()); 118 } 119 infoBuilder.setContactId(contactId); 120 if (!TextUtils.isEmpty(lookupKey)) { 121 infoBuilder.setLookupUri( 122 Contacts.getLookupUri(contactId, lookupKey) 123 .buildUpon() 124 .appendQueryParameter( 125 ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(directoryId)) 126 .build() 127 .toString()); 128 } 129 130 // Only PHONE_PROJECTION has a column containing carrier presence info. 131 int carrierPresenceColumn = cursor.getColumnIndex(Phone.CARRIER_PRESENCE); 132 if (carrierPresenceColumn != -1) { 133 int carrierPresenceInfo = cursor.getInt(carrierPresenceColumn); 134 infoBuilder.setCanSupportCarrierVideoCall( 135 (carrierPresenceInfo & Phone.CARRIER_PRESENCE_VT_CAPABLE) 136 == Phone.CARRIER_PRESENCE_VT_CAPABLE); 137 } 138 139 return infoBuilder.build(); 140 } 141 142 /** Returns the normalized number in the current row of {@code cursor}. */ getNormalizedNumberFromCursor(Cursor cursor)143 static String getNormalizedNumberFromCursor(Cursor cursor) { 144 return cursor.getString(CP2_INFO_NORMALIZED_NUMBER_INDEX); 145 } 146 } 147