ContactInfoHelper.java revision e7ea93d5235c097151e40f8922a1efb000734904
1ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/*
2ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Copyright (C) 2011 The Android Open Source Project
3ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
4ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * in compliance with the License. You may obtain a copy of the License at
6ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
7ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * http://www.apache.org/licenses/LICENSE-2.0
8ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
9ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Unless required by applicable law or agreed to in writing, software distributed under the License
10ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * or implied. See the License for the specific language governing permissions and limitations under
12ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * the License.
13ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */
14ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
15ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpackage com.android.dialer.phonenumbercache;
16ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
17ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.annotation.TargetApi;
18ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.content.ContentResolver;
19ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.content.ContentValues;
20ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.content.Context;
21ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.database.Cursor;
22ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.database.sqlite.SQLiteFullException;
23ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.net.Uri;
24ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.os.Build.VERSION;
25ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.os.Build.VERSION_CODES;
26ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.provider.CallLog.Calls;
27ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.provider.ContactsContract;
28ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.provider.ContactsContract.CommonDataKinds.Phone;
29ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.provider.ContactsContract.Contacts;
30ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.provider.ContactsContract.Directory;
31ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.provider.ContactsContract.DisplayNameSources;
32ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.provider.ContactsContract.PhoneLookup;
33ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.support.annotation.Nullable;
34d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanianimport android.support.annotation.WorkerThread;
35ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.telephony.PhoneNumberUtils;
36ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.text.TextUtils;
37ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.ContactsUtils;
38ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.ContactsUtils.UserType;
39ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.compat.DirectoryCompat;
40ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.util.Constants;
41d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanianimport com.android.dialer.common.Assert;
429779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanianimport com.android.dialer.common.LogUtil;
438369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanianimport com.android.dialer.logging.ContactSource;
449779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanianimport com.android.dialer.oem.CequintCallerIdManager;
459779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanianimport com.android.dialer.oem.CequintCallerIdManager.CequintCallerIdContact;
46ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.phonenumbercache.CachedNumberLookupService.CachedContactInfo;
47ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.phonenumberutil.PhoneNumberHelper;
48ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.telecom.TelecomUtil;
49ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.util.PermissionsUtil;
502ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport com.android.dialer.util.UriUtils;
51ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.util.ArrayList;
52ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.util.List;
53ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport org.json.JSONException;
54ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport org.json.JSONObject;
55ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
56ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/** Utility class to look up the contact information for a given number. */
57ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian// This class uses Java 7 language features, so it must target M+
58ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian@TargetApi(VERSION_CODES.M)
59ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpublic class ContactInfoHelper {
60ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
61ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static final String TAG = ContactInfoHelper.class.getSimpleName();
62ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
63ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private final Context mContext;
64ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private final String mCurrentCountryIso;
65ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private final CachedNumberLookupService mCachedNumberLookupService;
66ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
67ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public ContactInfoHelper(Context context, String currentCountryIso) {
68ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mContext = context;
69ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mCurrentCountryIso = currentCountryIso;
70ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mCachedNumberLookupService = PhoneNumberCache.get(mContext).getCachedNumberLookupService();
71ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
72ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
73ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
74ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Creates a JSON-encoded lookup uri for a unknown number without an associated contact
75ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
76ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param number - Unknown phone number
77ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @return JSON-encoded URI that can be used to perform a lookup when clicking on the quick
78ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *     contact card.
79ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
80ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static Uri createTemporaryContactUri(String number) {
81ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    try {
82ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      final JSONObject contactRows =
83ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          new JSONObject()
84ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              .put(
85ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                  Phone.CONTENT_ITEM_TYPE,
86ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                  new JSONObject().put(Phone.NUMBER, number).put(Phone.TYPE, Phone.TYPE_CUSTOM));
87ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
88ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      final String jsonString =
89ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          new JSONObject()
90ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              .put(Contacts.DISPLAY_NAME, number)
91ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              .put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.PHONE)
92ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              .put(Contacts.CONTENT_ITEM_TYPE, contactRows)
93ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              .toString();
94ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
95ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return Contacts.CONTENT_LOOKUP_URI
96ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          .buildUpon()
97ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          .appendPath(Constants.LOOKUP_URI_ENCODED)
98ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          .appendQueryParameter(
99ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(Long.MAX_VALUE))
100ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          .encodedFragment(jsonString)
101ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          .build();
102ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } catch (JSONException e) {
103ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return null;
104ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
105ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
106ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
107ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public static String lookUpDisplayNameAlternative(
108ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      Context context, String lookupKey, @UserType long userType, @Nullable Long directoryId) {
109ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Query {@link Contacts#CONTENT_LOOKUP_URI} directly with work lookup key is not allowed.
110ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (lookupKey == null || userType == ContactsUtils.USER_TYPE_WORK) {
111ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return null;
112ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
113ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
114ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (directoryId != null) {
115ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Query {@link Contacts#CONTENT_LOOKUP_URI} with work lookup key is not allowed.
116ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (DirectoryCompat.isEnterpriseDirectoryId(directoryId)) {
117ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        return null;
118ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
119ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
120ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Skip this to avoid an extra remote network call for alternative name
121ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (DirectoryCompat.isRemoteDirectoryId(directoryId)) {
122ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        return null;
123ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
124ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
125ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
126ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    final Uri uri = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey);
127ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Cursor cursor = null;
128ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    try {
129ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      cursor =
130ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          context
131ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              .getContentResolver()
132ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              .query(uri, PhoneQuery.DISPLAY_NAME_ALTERNATIVE_PROJECTION, null, null, null);
133ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
134ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (cursor != null && cursor.moveToFirst()) {
135ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        return cursor.getString(PhoneQuery.NAME_ALTERNATIVE);
136ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
137ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } catch (IllegalArgumentException e) {
138ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Avoid dialer crash when lookup key is not valid
1399779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian      LogUtil.e(TAG, "IllegalArgumentException in lookUpDisplayNameAlternative", e);
140ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } finally {
141ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (cursor != null) {
142ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        cursor.close();
143ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
144ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
145ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
146ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return null;
147ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
148ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
149ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public static Uri getContactInfoLookupUri(String number) {
150ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return getContactInfoLookupUri(number, -1);
151ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
152ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
153ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public static Uri getContactInfoLookupUri(String number, long directoryId) {
154ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Get URI for the number in the PhoneLookup table, with a parameter to indicate whether
155ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // the number is a SIP number.
156ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Uri uri = PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI;
157ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (VERSION.SDK_INT < VERSION_CODES.N) {
158ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (directoryId != -1) {
159ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        // ENTERPRISE_CONTENT_FILTER_URI in M doesn't support directory lookup
160ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        uri = PhoneLookup.CONTENT_FILTER_URI;
161ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      } else {
162938468da6f5c225ebb161a68bd949c9cf3261892Eric Erfanian        // a bug in M. PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI, encodes twice.
163ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        number = Uri.encode(number);
164ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
165ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
166ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Uri.Builder builder =
167ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        uri.buildUpon()
168ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            .appendPath(number)
169ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            .appendQueryParameter(
170ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                PhoneLookup.QUERY_PARAMETER_SIP_ADDRESS,
171ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                String.valueOf(PhoneNumberHelper.isUriNumber(number)));
172ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (directoryId != -1) {
173ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      builder.appendQueryParameter(
174ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(directoryId));
175ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
176ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return builder.build();
177ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
178ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
179ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
180ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Returns the contact information stored in an entry of the call log.
181ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
182ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param c A cursor pointing to an entry in the call log.
183ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
184ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public static ContactInfo getContactInfo(Cursor c) {
185ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    ContactInfo info = new ContactInfo();
186ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.lookupUri = UriUtils.parseUriOrNull(c.getString(CallLogQuery.CACHED_LOOKUP_URI));
187ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.name = c.getString(CallLogQuery.CACHED_NAME);
188ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.type = c.getInt(CallLogQuery.CACHED_NUMBER_TYPE);
189ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.label = c.getString(CallLogQuery.CACHED_NUMBER_LABEL);
190ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    String matchedNumber = c.getString(CallLogQuery.CACHED_MATCHED_NUMBER);
191ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    String postDialDigits =
192ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        (VERSION.SDK_INT >= VERSION_CODES.N) ? c.getString(CallLogQuery.POST_DIAL_DIGITS) : "";
193ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.number =
194ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        (matchedNumber == null) ? c.getString(CallLogQuery.NUMBER) + postDialDigits : matchedNumber;
195ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
196ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.normalizedNumber = c.getString(CallLogQuery.CACHED_NORMALIZED_NUMBER);
197ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.photoId = c.getLong(CallLogQuery.CACHED_PHOTO_ID);
198ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.photoUri =
199ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        UriUtils.nullForNonContactsUri(
200ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            UriUtils.parseUriOrNull(c.getString(CallLogQuery.CACHED_PHOTO_URI)));
201ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.formattedNumber = c.getString(CallLogQuery.CACHED_FORMATTED_NUMBER);
202ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
203ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return info;
204ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
205ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
2062ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian  @Nullable
207ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public ContactInfo lookupNumber(String number, String countryIso) {
208ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return lookupNumber(number, countryIso, -1);
209ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
210ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
211ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
212ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Returns the contact information for the given number.
213ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
214ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * <p>If the number does not match any contact, returns a contact info containing only the number
215ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * and the formatted number.
216ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
217ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * <p>If an error occurs during the lookup, it returns null.
218ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
219ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param number the number to look up
220ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param countryIso the country associated with this number
221ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param directoryId the id of the directory to lookup
222ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
223ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Nullable
224ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @SuppressWarnings("ReferenceEquality")
225ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public ContactInfo lookupNumber(String number, String countryIso, long directoryId) {
226ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (TextUtils.isEmpty(number)) {
2272ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian      LogUtil.d("ContactInfoHelper.lookupNumber", "number is empty");
228ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return null;
229ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
230ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
231ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    ContactInfo info;
232ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
233ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (PhoneNumberHelper.isUriNumber(number)) {
2342ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian      LogUtil.d("ContactInfoHelper.lookupNumber", "number is sip");
235ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // The number is a SIP address..
236ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      info = lookupContactFromUri(getContactInfoLookupUri(number, directoryId));
237ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (info == null || info == ContactInfo.EMPTY) {
238ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        // If lookup failed, check if the "username" of the SIP address is a phone number.
239ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        String username = PhoneNumberHelper.getUsernameFromUriNumber(number);
240ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        if (PhoneNumberUtils.isGlobalPhoneNumber(username)) {
241ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          info = queryContactInfoForPhoneNumber(username, countryIso, directoryId);
242ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        }
243ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
244ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
245ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Look for a contact that has the given phone number.
246ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      info = queryContactInfoForPhoneNumber(number, countryIso, directoryId);
247ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
248ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
249ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    final ContactInfo updatedInfo;
250ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (info == null) {
251ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // The lookup failed.
2522ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian      LogUtil.d("ContactInfoHelper.lookupNumber", "lookup failed");
253ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      updatedInfo = null;
254ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
255ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // If we did not find a matching contact, generate an empty contact info for the number.
256ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (info == ContactInfo.EMPTY) {
257ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        // Did not find a matching contact.
258ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        updatedInfo = createEmptyContactInfoForNumber(number, countryIso);
259ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      } else {
260ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        updatedInfo = info;
261ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
262ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
263ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return updatedInfo;
264ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
265ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
266ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private ContactInfo createEmptyContactInfoForNumber(String number, String countryIso) {
267ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    ContactInfo contactInfo = new ContactInfo();
268ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    contactInfo.number = number;
269ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    contactInfo.formattedNumber = formatPhoneNumber(number, null, countryIso);
270ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    contactInfo.normalizedNumber = PhoneNumberUtils.formatNumberToE164(number, countryIso);
271ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    contactInfo.lookupUri = createTemporaryContactUri(contactInfo.formattedNumber);
272ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return contactInfo;
273ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
274ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
275ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
276ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Return the contact info object if the remote directory lookup succeeds, otherwise return an
277ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * empty contact info for the number.
278ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
279ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public ContactInfo lookupNumberInRemoteDirectory(String number, String countryIso) {
280ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mCachedNumberLookupService != null) {
281ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      List<Long> remoteDirectories = getRemoteDirectories(mContext);
282ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      for (long directoryId : remoteDirectories) {
283ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        ContactInfo contactInfo = lookupNumber(number, countryIso, directoryId);
284ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        if (hasName(contactInfo)) {
285ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          return contactInfo;
286ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        }
287ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
288ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
289ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return createEmptyContactInfoForNumber(number, countryIso);
290ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
291ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
292ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public boolean hasName(ContactInfo contactInfo) {
293ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return contactInfo != null && !TextUtils.isEmpty(contactInfo.name);
294ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
295ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
296ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private List<Long> getRemoteDirectories(Context context) {
297ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    List<Long> remoteDirectories = new ArrayList<>();
298ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Uri uri =
299ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        VERSION.SDK_INT >= VERSION_CODES.N
300ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            ? Directory.ENTERPRISE_CONTENT_URI
301ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            : Directory.CONTENT_URI;
302ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    ContentResolver cr = context.getContentResolver();
303ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Cursor cursor = cr.query(uri, new String[] {Directory._ID}, null, null, null);
304ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    int idIndex = cursor.getColumnIndex(Directory._ID);
305ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (cursor == null) {
306ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return remoteDirectories;
307ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
308ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    try {
309ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      while (cursor.moveToNext()) {
310ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        long directoryId = cursor.getLong(idIndex);
311ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        if (DirectoryCompat.isRemoteDirectoryId(directoryId)) {
312ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          remoteDirectories.add(directoryId);
313ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        }
314ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
315ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } finally {
316ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      cursor.close();
317ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
318ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return remoteDirectories;
319ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
320ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
321ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
322ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Looks up a contact using the given URI.
323ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
324ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * <p>It returns null if an error occurs, {@link ContactInfo#EMPTY} if no matching contact is
325ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * found, or the {@link ContactInfo} for the given contact.
326ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
327ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * <p>The {@link ContactInfo#formattedNumber} field is always set to {@code null} in the returned
328ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * value.
329ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
330ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  ContactInfo lookupContactFromUri(Uri uri) {
331ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (uri == null) {
3322ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian      LogUtil.d("ContactInfoHelper.lookupContactFromUri", "uri is null");
333ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return null;
334ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
335c857f90590e7d7fcffa89511982eb33afd34805fEric Erfanian    if (!PermissionsUtil.hasContactsReadPermissions(mContext)) {
3362ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian      LogUtil.d("ContactInfoHelper.lookupContactFromUri", "no contact permission, return empty");
337ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return ContactInfo.EMPTY;
338ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
339ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
340e7ea93d5235c097151e40f8922a1efb000734904linyuh    try (Cursor phoneLookupCursor =
341e7ea93d5235c097151e40f8922a1efb000734904linyuh        mContext
342e7ea93d5235c097151e40f8922a1efb000734904linyuh            .getContentResolver()
343e7ea93d5235c097151e40f8922a1efb000734904linyuh            .query(
344e7ea93d5235c097151e40f8922a1efb000734904linyuh                uri,
345e7ea93d5235c097151e40f8922a1efb000734904linyuh                PhoneQuery.getPhoneLookupProjection(uri),
346e7ea93d5235c097151e40f8922a1efb000734904linyuh                null /* selection */,
347e7ea93d5235c097151e40f8922a1efb000734904linyuh                null /* selectionArgs */,
348e7ea93d5235c097151e40f8922a1efb000734904linyuh                null /* sortOrder */)) {
349e7ea93d5235c097151e40f8922a1efb000734904linyuh      if (phoneLookupCursor == null) {
350e7ea93d5235c097151e40f8922a1efb000734904linyuh        LogUtil.d("ContactInfoHelper.lookupContactFromUri", "phoneLookupCursor is null");
351e7ea93d5235c097151e40f8922a1efb000734904linyuh        return null;
352e7ea93d5235c097151e40f8922a1efb000734904linyuh      }
353ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
354ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (!phoneLookupCursor.moveToFirst()) {
355ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        return ContactInfo.EMPTY;
356ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
357e7ea93d5235c097151e40f8922a1efb000734904linyuh
358bdef88bb0c16889e7403c117ce90825f7ed7b9e4linyuh      String lookupKey = phoneLookupCursor.getString(PhoneQuery.LOOKUP_KEY);
359bdef88bb0c16889e7403c117ce90825f7ed7b9e4linyuh      ContactInfo contactInfo = createPhoneLookupContactInfo(phoneLookupCursor, lookupKey);
360ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      fillAdditionalContactInfo(mContext, contactInfo);
361ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return contactInfo;
362ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
363ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
364ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
365ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private ContactInfo createPhoneLookupContactInfo(Cursor phoneLookupCursor, String lookupKey) {
366ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    ContactInfo info = new ContactInfo();
367ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.lookupKey = lookupKey;
368ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.lookupUri =
369ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        Contacts.getLookupUri(phoneLookupCursor.getLong(PhoneQuery.PERSON_ID), lookupKey);
370ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.name = phoneLookupCursor.getString(PhoneQuery.NAME);
371ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.type = phoneLookupCursor.getInt(PhoneQuery.PHONE_TYPE);
372ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.label = phoneLookupCursor.getString(PhoneQuery.LABEL);
373ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.number = phoneLookupCursor.getString(PhoneQuery.MATCHED_NUMBER);
374ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.normalizedNumber = phoneLookupCursor.getString(PhoneQuery.NORMALIZED_NUMBER);
375ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.photoId = phoneLookupCursor.getLong(PhoneQuery.PHOTO_ID);
376ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.photoUri = UriUtils.parseUriOrNull(phoneLookupCursor.getString(PhoneQuery.PHOTO_URI));
377ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.formattedNumber = null;
378ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.userType =
379ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        ContactsUtils.determineUserType(null, phoneLookupCursor.getLong(PhoneQuery.PERSON_ID));
3808369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian    info.contactExists = true;
381ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
382ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return info;
383ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
384ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
385ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void fillAdditionalContactInfo(Context context, ContactInfo contactInfo) {
386ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (contactInfo.number == null) {
387ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
388ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
389ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Uri uri = Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, Uri.encode(contactInfo.number));
390ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    try (Cursor cursor =
391ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        context
392ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            .getContentResolver()
393ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            .query(uri, PhoneQuery.ADDITIONAL_CONTACT_INFO_PROJECTION, null, null, null)) {
394ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (cursor == null || !cursor.moveToFirst()) {
395ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        return;
396ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
397ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      contactInfo.nameAlternative =
398ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          cursor.getString(PhoneQuery.ADDITIONAL_CONTACT_INFO_DISPLAY_NAME_ALTERNATIVE);
399ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      contactInfo.carrierPresence =
400ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          cursor.getInt(PhoneQuery.ADDITIONAL_CONTACT_INFO_CARRIER_PRESENCE);
401ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
402ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
403ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
404ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
405ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Determines the contact information for the given phone number.
406ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
407ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * <p>It returns the contact info if found.
408ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
409ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * <p>If no contact corresponds to the given phone number, returns {@link ContactInfo#EMPTY}.
410ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
411ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * <p>If the lookup fails for some other reason, it returns null.
412ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
413ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @SuppressWarnings("ReferenceEquality")
414ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private ContactInfo queryContactInfoForPhoneNumber(
415ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      String number, String countryIso, long directoryId) {
416ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (TextUtils.isEmpty(number)) {
4172ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian      LogUtil.d("ContactInfoHelper.queryContactInfoForPhoneNumber", "number is empty");
418ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return null;
419ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
420ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
421ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    ContactInfo info = lookupContactFromUri(getContactInfoLookupUri(number, directoryId));
4222ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian    if (info == null) {
4232ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian      LogUtil.d("ContactInfoHelper.queryContactInfoForPhoneNumber", "info looked up is null");
4242ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian    }
425ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (info != null && info != ContactInfo.EMPTY) {
426ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      info.formattedNumber = formatPhoneNumber(number, null, countryIso);
4272ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian      if (directoryId == -1) {
4282ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian        // Contact found in the default directory
4292ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian        info.sourceType = ContactSource.Type.SOURCE_TYPE_DIRECTORY;
4302ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian      } else {
4312ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian        // Contact found in the extended directory specified by directoryId
4322ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian        info.sourceType = ContactSource.Type.SOURCE_TYPE_EXTENDED;
4332ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian      }
434ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else if (mCachedNumberLookupService != null) {
435ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      CachedContactInfo cacheInfo =
436ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          mCachedNumberLookupService.lookupCachedContactFromNumber(mContext, number);
437ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (cacheInfo != null) {
4382ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian        if (!cacheInfo.getContactInfo().isBadData) {
4392ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian          info = cacheInfo.getContactInfo();
4402ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian        } else {
4412ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian          LogUtil.i("ContactInfoHelper.queryContactInfoForPhoneNumber", "info is bad data");
4422ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian        }
443ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
444ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
445ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return info;
446ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
447ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
448ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
449ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Format the given phone number
450ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
451ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param number the number to be formatted.
452ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param normalizedNumber the normalized number of the given number.
453ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param countryIso the ISO 3166-1 two letters country code, the country's convention will be
454ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *     used to format the number if the normalized phone is null.
455ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @return the formatted number, or the given number if it was formatted.
456ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
457ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private String formatPhoneNumber(String number, String normalizedNumber, String countryIso) {
458ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (TextUtils.isEmpty(number)) {
459ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return "";
460ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
461ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // If "number" is really a SIP address, don't try to do any formatting at all.
462ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (PhoneNumberHelper.isUriNumber(number)) {
463ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return number;
464ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
465ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (TextUtils.isEmpty(countryIso)) {
466ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      countryIso = mCurrentCountryIso;
467ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
468ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return PhoneNumberUtils.formatNumber(number, normalizedNumber, countryIso);
469ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
470ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
471ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
472ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Stores differences between the updated contact info and the current call log contact info.
473ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
474ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param number The number of the contact.
475ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param countryIso The country associated with this number.
476ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param updatedInfo The updated contact info.
477ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param callLogInfo The call log entry's current contact info.
478ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
479ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void updateCallLogContactInfo(
480ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      String number, String countryIso, ContactInfo updatedInfo, ContactInfo callLogInfo) {
481ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (!PermissionsUtil.hasPermission(mContext, android.Manifest.permission.WRITE_CALL_LOG)) {
482ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
483ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
484ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
485ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    final ContentValues values = new ContentValues();
486ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    boolean needsUpdate = false;
487ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
488ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (callLogInfo != null) {
489ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (!TextUtils.equals(updatedInfo.name, callLogInfo.name)) {
490ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        values.put(Calls.CACHED_NAME, updatedInfo.name);
491ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        needsUpdate = true;
492ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
493ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
494ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (updatedInfo.type != callLogInfo.type) {
495ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        values.put(Calls.CACHED_NUMBER_TYPE, updatedInfo.type);
496ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        needsUpdate = true;
497ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
498ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
499ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (!TextUtils.equals(updatedInfo.label, callLogInfo.label)) {
500ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        values.put(Calls.CACHED_NUMBER_LABEL, updatedInfo.label);
501ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        needsUpdate = true;
502ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
503ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
504ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (!UriUtils.areEqual(updatedInfo.lookupUri, callLogInfo.lookupUri)) {
505ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        values.put(Calls.CACHED_LOOKUP_URI, UriUtils.uriToString(updatedInfo.lookupUri));
506ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        needsUpdate = true;
507ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
508ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
509ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Only replace the normalized number if the new updated normalized number isn't empty.
510ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (!TextUtils.isEmpty(updatedInfo.normalizedNumber)
511ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          && !TextUtils.equals(updatedInfo.normalizedNumber, callLogInfo.normalizedNumber)) {
512ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        values.put(Calls.CACHED_NORMALIZED_NUMBER, updatedInfo.normalizedNumber);
513ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        needsUpdate = true;
514ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
515ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
516ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (!TextUtils.equals(updatedInfo.number, callLogInfo.number)) {
517ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        values.put(Calls.CACHED_MATCHED_NUMBER, updatedInfo.number);
518ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        needsUpdate = true;
519ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
520ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
521ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (updatedInfo.photoId != callLogInfo.photoId) {
522ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        values.put(Calls.CACHED_PHOTO_ID, updatedInfo.photoId);
523ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        needsUpdate = true;
524ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
525ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
526ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      final Uri updatedPhotoUriContactsOnly = UriUtils.nullForNonContactsUri(updatedInfo.photoUri);
527ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (!UriUtils.areEqual(updatedPhotoUriContactsOnly, callLogInfo.photoUri)) {
528ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        values.put(Calls.CACHED_PHOTO_URI, UriUtils.uriToString(updatedPhotoUriContactsOnly));
529ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        needsUpdate = true;
530ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
531ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
532ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (!TextUtils.equals(updatedInfo.formattedNumber, callLogInfo.formattedNumber)) {
533ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        values.put(Calls.CACHED_FORMATTED_NUMBER, updatedInfo.formattedNumber);
534ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        needsUpdate = true;
535ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
5369779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian
5379779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian      if (!TextUtils.equals(updatedInfo.geoDescription, callLogInfo.geoDescription)) {
5389779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian        values.put(Calls.GEOCODED_LOCATION, updatedInfo.geoDescription);
5399779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian        needsUpdate = true;
5409779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian      }
541ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
542ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // No previous values, store all of them.
543ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      values.put(Calls.CACHED_NAME, updatedInfo.name);
544ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      values.put(Calls.CACHED_NUMBER_TYPE, updatedInfo.type);
545ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      values.put(Calls.CACHED_NUMBER_LABEL, updatedInfo.label);
546ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      values.put(Calls.CACHED_LOOKUP_URI, UriUtils.uriToString(updatedInfo.lookupUri));
547ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      values.put(Calls.CACHED_MATCHED_NUMBER, updatedInfo.number);
548ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      values.put(Calls.CACHED_NORMALIZED_NUMBER, updatedInfo.normalizedNumber);
549ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      values.put(Calls.CACHED_PHOTO_ID, updatedInfo.photoId);
550ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      values.put(
551ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          Calls.CACHED_PHOTO_URI,
552ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          UriUtils.uriToString(UriUtils.nullForNonContactsUri(updatedInfo.photoUri)));
553ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      values.put(Calls.CACHED_FORMATTED_NUMBER, updatedInfo.formattedNumber);
5549779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian      values.put(Calls.GEOCODED_LOCATION, updatedInfo.geoDescription);
555ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      needsUpdate = true;
556ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
557ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
558ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (!needsUpdate) {
559ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
560ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
561ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
562ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    try {
563ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (countryIso == null) {
564ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        mContext
565ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            .getContentResolver()
566ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            .update(
567ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                TelecomUtil.getCallLogUri(mContext),
568ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                values,
569ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                Calls.NUMBER + " = ? AND " + Calls.COUNTRY_ISO + " IS NULL",
570ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                new String[] {number});
571ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      } else {
572ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        mContext
573ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            .getContentResolver()
574ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            .update(
575ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                TelecomUtil.getCallLogUri(mContext),
576ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                values,
577ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                Calls.NUMBER + " = ? AND " + Calls.COUNTRY_ISO + " = ?",
578ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                new String[] {number, countryIso});
579ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
580ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } catch (SQLiteFullException e) {
5819779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian      LogUtil.e(TAG, "Unable to update contact info in call log db", e);
582ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
583ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
584ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
585ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void updateCachedNumberLookupService(ContactInfo updatedInfo) {
586ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mCachedNumberLookupService != null) {
587ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (hasName(updatedInfo)) {
588ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        CachedContactInfo cachedContactInfo =
589ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            mCachedNumberLookupService.buildCachedContactInfo(updatedInfo);
590ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        mCachedNumberLookupService.addContact(mContext, cachedContactInfo);
591ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
592ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
593ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
594ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
595ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
596ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Given a contact's sourceType, return true if the contact is a business
597ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
598ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param sourceType sourceType of the contact. This is usually populated by {@link
599ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *     #mCachedNumberLookupService}.
600ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
6018369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian  public boolean isBusiness(ContactSource.Type sourceType) {
602ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return mCachedNumberLookupService != null && mCachedNumberLookupService.isBusiness(sourceType);
603ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
604ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
605ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
606ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * This function looks at a contact's source and determines if the user can mark caller ids from
607ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * this source as invalid.
608ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
609ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param sourceType The source type to be checked
610ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param objectId The ID of the Contact object.
611ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @return true if contacts from this source can be marked with an invalid caller id
612ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
6138369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian  public boolean canReportAsInvalid(ContactSource.Type sourceType, String objectId) {
614ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return mCachedNumberLookupService != null
615ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        && mCachedNumberLookupService.canReportAsInvalid(sourceType, objectId);
616ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
6179779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian
6189779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian  /**
6199779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian   * Update ContactInfo by querying to Cequint Caller ID. Only name, geoDescription and photo uri
6209779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian   * will be updated if available.
6219779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian   */
622d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian  @WorkerThread
6232ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian  public void updateFromCequintCallerId(
6242ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian      @Nullable CequintCallerIdManager cequintCallerIdManager, ContactInfo info, String number) {
625d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    Assert.isWorkerThread();
6269779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian    if (!CequintCallerIdManager.isCequintCallerIdEnabled(mContext)) {
6279779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian      return;
6289779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian    }
6292ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian    if (cequintCallerIdManager == null) {
6302ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian      return;
6312ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian    }
6329779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian    CequintCallerIdContact cequintCallerIdContact =
6332ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian        cequintCallerIdManager.getCequintCallerIdContact(mContext, number);
6349779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian    if (cequintCallerIdContact == null) {
6359779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian      return;
6369779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian    }
637d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    if (TextUtils.isEmpty(info.name) && !TextUtils.isEmpty(cequintCallerIdContact.name)) {
6389779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian      info.name = cequintCallerIdContact.name;
6399779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian    }
6409779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian    if (!TextUtils.isEmpty(cequintCallerIdContact.geoDescription)) {
6419779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian      info.geoDescription = cequintCallerIdContact.geoDescription;
6428369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian      info.sourceType = ContactSource.Type.SOURCE_TYPE_CEQUINT_CALLER_ID;
6439779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian    }
6448369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian    // Only update photo if local lookup has no result.
6458369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian    if (!info.contactExists && info.photoUri == null && cequintCallerIdContact.imageUrl != null) {
6469779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian      info.photoUri = UriUtils.parseUriOrNull(cequintCallerIdContact.imageUrl);
6479779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian    }
6489779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian  }
649ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian}
650