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.ContentValues;
19ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.content.Context;
20ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.database.Cursor;
21ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.database.sqlite.SQLiteFullException;
22ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.net.Uri;
23ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.os.Build.VERSION;
24ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.os.Build.VERSION_CODES;
25ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.provider.CallLog.Calls;
26ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.provider.ContactsContract;
27ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.provider.ContactsContract.CommonDataKinds.Phone;
28ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.provider.ContactsContract.Contacts;
29ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.provider.ContactsContract.Directory;
30ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.provider.ContactsContract.DisplayNameSources;
31ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.provider.ContactsContract.PhoneLookup;
32ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.support.annotation.Nullable;
33d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanianimport android.support.annotation.WorkerThread;
34ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.telephony.PhoneNumberUtils;
35ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.text.TextUtils;
36ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.ContactsUtils;
37ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.ContactsUtils.UserType;
38ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.util.Constants;
39d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanianimport com.android.dialer.common.Assert;
409779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanianimport com.android.dialer.common.LogUtil;
41c3d3c3dfbcf96f6db92b747463ac84ee244a0c85linyuhimport com.android.dialer.common.cp2.DirectoryCompat;
428369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanianimport com.android.dialer.logging.ContactSource;
439779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanianimport com.android.dialer.oem.CequintCallerIdManager;
449779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanianimport com.android.dialer.oem.CequintCallerIdManager.CequintCallerIdContact;
45ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.phonenumbercache.CachedNumberLookupService.CachedContactInfo;
46ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.phonenumberutil.PhoneNumberHelper;
47ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.telecom.TelecomUtil;
48ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.util.PermissionsUtil;
492ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanianimport com.android.dialer.util.UriUtils;
50ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.util.ArrayList;
51ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.util.List;
52ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport org.json.JSONException;
53ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport org.json.JSONObject;
54ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
55ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/** Utility class to look up the contact information for a given number. */
56ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian// This class uses Java 7 language features, so it must target M+
57ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian@TargetApi(VERSION_CODES.M)
58ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpublic class ContactInfoHelper {
59ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
60ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static final String TAG = ContactInfoHelper.class.getSimpleName();
61ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
62183cb71663320f16149d83eeebaff7795a4b55f2linyuh  private final Context context;
63183cb71663320f16149d83eeebaff7795a4b55f2linyuh  private final String currentCountryIso;
64183cb71663320f16149d83eeebaff7795a4b55f2linyuh  private final CachedNumberLookupService cachedNumberLookupService;
65ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
66ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public ContactInfoHelper(Context context, String currentCountryIso) {
67183cb71663320f16149d83eeebaff7795a4b55f2linyuh    this.context = context;
68183cb71663320f16149d83eeebaff7795a4b55f2linyuh    this.currentCountryIso = currentCountryIso;
69183cb71663320f16149d83eeebaff7795a4b55f2linyuh    cachedNumberLookupService = PhoneNumberCache.get(this.context).getCachedNumberLookupService();
70ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
71ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
72ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
73ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Creates a JSON-encoded lookup uri for a unknown number without an associated contact
74ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
75ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param number - Unknown phone number
76ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @return JSON-encoded URI that can be used to perform a lookup when clicking on the quick
77ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *     contact card.
78ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
79ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static Uri createTemporaryContactUri(String number) {
80ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    try {
81ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      final JSONObject contactRows =
82ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          new JSONObject()
83ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              .put(
84ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                  Phone.CONTENT_ITEM_TYPE,
85ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                  new JSONObject().put(Phone.NUMBER, number).put(Phone.TYPE, Phone.TYPE_CUSTOM));
86ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
87ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      final String jsonString =
88ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          new JSONObject()
89ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              .put(Contacts.DISPLAY_NAME, number)
90ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              .put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.PHONE)
91ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              .put(Contacts.CONTENT_ITEM_TYPE, contactRows)
92ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              .toString();
93ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
94ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return Contacts.CONTENT_LOOKUP_URI
95ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          .buildUpon()
96ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          .appendPath(Constants.LOOKUP_URI_ENCODED)
97ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          .appendQueryParameter(
98ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(Long.MAX_VALUE))
99ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          .encodedFragment(jsonString)
100ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          .build();
101ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } catch (JSONException e) {
102ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return null;
103ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
104ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
105ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
106ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public static String lookUpDisplayNameAlternative(
107ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      Context context, String lookupKey, @UserType long userType, @Nullable Long directoryId) {
108ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Query {@link Contacts#CONTENT_LOOKUP_URI} directly with work lookup key is not allowed.
109ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (lookupKey == null || userType == ContactsUtils.USER_TYPE_WORK) {
110ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return null;
111ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
112ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
113ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (directoryId != null) {
114ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Query {@link Contacts#CONTENT_LOOKUP_URI} with work lookup key is not allowed.
115ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (DirectoryCompat.isEnterpriseDirectoryId(directoryId)) {
116ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        return null;
117ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
118ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
119ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Skip this to avoid an extra remote network call for alternative name
120ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (DirectoryCompat.isRemoteDirectoryId(directoryId)) {
121ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        return null;
122ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
123ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
124ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
125ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    final Uri uri = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey);
126ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Cursor cursor = null;
127ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    try {
128ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      cursor =
129ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          context
130ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              .getContentResolver()
131ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              .query(uri, PhoneQuery.DISPLAY_NAME_ALTERNATIVE_PROJECTION, null, null, null);
132ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
133ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (cursor != null && cursor.moveToFirst()) {
134ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        return cursor.getString(PhoneQuery.NAME_ALTERNATIVE);
135ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
136ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } catch (IllegalArgumentException e) {
137ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Avoid dialer crash when lookup key is not valid
1389779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian      LogUtil.e(TAG, "IllegalArgumentException in lookUpDisplayNameAlternative", e);
139ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } finally {
140ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (cursor != null) {
141ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        cursor.close();
142ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
143ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
144ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
145ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return null;
146ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
147ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
148ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public static Uri getContactInfoLookupUri(String number) {
149ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return getContactInfoLookupUri(number, -1);
150ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
151ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
152ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public static Uri getContactInfoLookupUri(String number, long directoryId) {
153ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Get URI for the number in the PhoneLookup table, with a parameter to indicate whether
154ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // the number is a SIP number.
155ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Uri uri = PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI;
156ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (VERSION.SDK_INT < VERSION_CODES.N) {
157ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (directoryId != -1) {
158ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        // ENTERPRISE_CONTENT_FILTER_URI in M doesn't support directory lookup
159ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        uri = PhoneLookup.CONTENT_FILTER_URI;
160ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      } else {
161938468da6f5c225ebb161a68bd949c9cf3261892Eric Erfanian        // a bug in M. PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI, encodes twice.
162ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        number = Uri.encode(number);
163ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
164ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
165ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Uri.Builder builder =
166ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        uri.buildUpon()
167ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            .appendPath(number)
168ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            .appendQueryParameter(
169ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                PhoneLookup.QUERY_PARAMETER_SIP_ADDRESS,
170ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                String.valueOf(PhoneNumberHelper.isUriNumber(number)));
171ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (directoryId != -1) {
172ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      builder.appendQueryParameter(
173ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(directoryId));
174ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
175ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return builder.build();
176ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
177ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
178ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
179ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Returns the contact information stored in an entry of the call log.
180ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
181ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param c A cursor pointing to an entry in the call log.
182ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
183ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public static ContactInfo getContactInfo(Cursor c) {
184ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    ContactInfo info = new ContactInfo();
185ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.lookupUri = UriUtils.parseUriOrNull(c.getString(CallLogQuery.CACHED_LOOKUP_URI));
186ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.name = c.getString(CallLogQuery.CACHED_NAME);
187ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.type = c.getInt(CallLogQuery.CACHED_NUMBER_TYPE);
188ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.label = c.getString(CallLogQuery.CACHED_NUMBER_LABEL);
189ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    String matchedNumber = c.getString(CallLogQuery.CACHED_MATCHED_NUMBER);
190ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    String postDialDigits =
191ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        (VERSION.SDK_INT >= VERSION_CODES.N) ? c.getString(CallLogQuery.POST_DIAL_DIGITS) : "";
192ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.number =
193ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        (matchedNumber == null) ? c.getString(CallLogQuery.NUMBER) + postDialDigits : matchedNumber;
194ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
195ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.normalizedNumber = c.getString(CallLogQuery.CACHED_NORMALIZED_NUMBER);
196ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.photoId = c.getLong(CallLogQuery.CACHED_PHOTO_ID);
197ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.photoUri =
198ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        UriUtils.nullForNonContactsUri(
199ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            UriUtils.parseUriOrNull(c.getString(CallLogQuery.CACHED_PHOTO_URI)));
200ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.formattedNumber = c.getString(CallLogQuery.CACHED_FORMATTED_NUMBER);
201ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
202ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return info;
203ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
204ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
2052ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian  @Nullable
206ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public ContactInfo lookupNumber(String number, String countryIso) {
207ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return lookupNumber(number, countryIso, -1);
208ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
209ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
210ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
211ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Returns the contact information for the given number.
212ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
213ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * <p>If the number does not match any contact, returns a contact info containing only the number
214ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * and the formatted number.
215ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
216ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * <p>If an error occurs during the lookup, it returns null.
217ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
218ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param number the number to look up
219ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param countryIso the country associated with this number
220ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param directoryId the id of the directory to lookup
221ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
222ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Nullable
223ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @SuppressWarnings("ReferenceEquality")
224ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public ContactInfo lookupNumber(String number, String countryIso, long directoryId) {
225ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (TextUtils.isEmpty(number)) {
2262ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian      LogUtil.d("ContactInfoHelper.lookupNumber", "number is empty");
227ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return null;
228ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
229ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
230ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    ContactInfo info;
231ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
232ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (PhoneNumberHelper.isUriNumber(number)) {
2332ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian      LogUtil.d("ContactInfoHelper.lookupNumber", "number is sip");
234ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // The number is a SIP address..
235ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      info = lookupContactFromUri(getContactInfoLookupUri(number, directoryId));
236ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (info == null || info == ContactInfo.EMPTY) {
237ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        // If lookup failed, check if the "username" of the SIP address is a phone number.
238ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        String username = PhoneNumberHelper.getUsernameFromUriNumber(number);
239ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        if (PhoneNumberUtils.isGlobalPhoneNumber(username)) {
240ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          info = queryContactInfoForPhoneNumber(username, countryIso, directoryId);
241ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        }
242ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
243ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
244ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Look for a contact that has the given phone number.
245ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      info = queryContactInfoForPhoneNumber(number, countryIso, directoryId);
246ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
247ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
248ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    final ContactInfo updatedInfo;
249ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (info == null) {
250ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // The lookup failed.
2512ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian      LogUtil.d("ContactInfoHelper.lookupNumber", "lookup failed");
252ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      updatedInfo = null;
253ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
254ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // If we did not find a matching contact, generate an empty contact info for the number.
255ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (info == ContactInfo.EMPTY) {
256ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        // Did not find a matching contact.
257ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        updatedInfo = createEmptyContactInfoForNumber(number, countryIso);
258ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      } else {
259ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        updatedInfo = info;
260ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
261ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
262ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return updatedInfo;
263ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
264ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
265ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private ContactInfo createEmptyContactInfoForNumber(String number, String countryIso) {
266ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    ContactInfo contactInfo = new ContactInfo();
267ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    contactInfo.number = number;
268ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    contactInfo.formattedNumber = formatPhoneNumber(number, null, countryIso);
269ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    contactInfo.normalizedNumber = PhoneNumberUtils.formatNumberToE164(number, countryIso);
270ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    contactInfo.lookupUri = createTemporaryContactUri(contactInfo.formattedNumber);
271ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return contactInfo;
272ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
273ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
274ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
275ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Return the contact info object if the remote directory lookup succeeds, otherwise return an
276ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * empty contact info for the number.
277ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
278ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public ContactInfo lookupNumberInRemoteDirectory(String number, String countryIso) {
279183cb71663320f16149d83eeebaff7795a4b55f2linyuh    if (cachedNumberLookupService != null) {
280183cb71663320f16149d83eeebaff7795a4b55f2linyuh      List<Long> remoteDirectories = getRemoteDirectories(context);
281ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      for (long directoryId : remoteDirectories) {
282ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        ContactInfo contactInfo = lookupNumber(number, countryIso, directoryId);
283ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        if (hasName(contactInfo)) {
284ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          return contactInfo;
285ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        }
286ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
287ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
288ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return createEmptyContactInfoForNumber(number, countryIso);
289ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
290ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
291ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public boolean hasName(ContactInfo contactInfo) {
292ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return contactInfo != null && !TextUtils.isEmpty(contactInfo.name);
293ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
294ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
295ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private List<Long> getRemoteDirectories(Context context) {
296ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    List<Long> remoteDirectories = new ArrayList<>();
297ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Uri uri =
298ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        VERSION.SDK_INT >= VERSION_CODES.N
299ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            ? Directory.ENTERPRISE_CONTENT_URI
300ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            : Directory.CONTENT_URI;
301078a8340a1e7077c25a78698804cc3ed3d90051flinyuh    Cursor cursor =
302078a8340a1e7077c25a78698804cc3ed3d90051flinyuh        context.getContentResolver().query(uri, new String[] {Directory._ID}, null, null, null);
303ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (cursor == null) {
304ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return remoteDirectories;
305ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
306078a8340a1e7077c25a78698804cc3ed3d90051flinyuh    int idIndex = cursor.getColumnIndex(Directory._ID);
307ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    try {
308ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      while (cursor.moveToNext()) {
309ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        long directoryId = cursor.getLong(idIndex);
310ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        if (DirectoryCompat.isRemoteDirectoryId(directoryId)) {
311ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          remoteDirectories.add(directoryId);
312ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        }
313ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
314ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } finally {
315ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      cursor.close();
316ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
317ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return remoteDirectories;
318ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
319ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
320ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
321ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Looks up a contact using the given URI.
322ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
323ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * <p>It returns null if an error occurs, {@link ContactInfo#EMPTY} if no matching contact is
324ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * found, or the {@link ContactInfo} for the given contact.
325ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
326ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * <p>The {@link ContactInfo#formattedNumber} field is always set to {@code null} in the returned
327ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * value.
328ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
329ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  ContactInfo lookupContactFromUri(Uri uri) {
330ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (uri == null) {
3312ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian      LogUtil.d("ContactInfoHelper.lookupContactFromUri", "uri is null");
332ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return null;
333ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
334183cb71663320f16149d83eeebaff7795a4b55f2linyuh    if (!PermissionsUtil.hasContactsReadPermissions(context)) {
3352ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian      LogUtil.d("ContactInfoHelper.lookupContactFromUri", "no contact permission, return empty");
336ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return ContactInfo.EMPTY;
337ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
338ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
339e7ea93d5235c097151e40f8922a1efb000734904linyuh    try (Cursor phoneLookupCursor =
340183cb71663320f16149d83eeebaff7795a4b55f2linyuh        context
341e7ea93d5235c097151e40f8922a1efb000734904linyuh            .getContentResolver()
342e7ea93d5235c097151e40f8922a1efb000734904linyuh            .query(
343e7ea93d5235c097151e40f8922a1efb000734904linyuh                uri,
344e7ea93d5235c097151e40f8922a1efb000734904linyuh                PhoneQuery.getPhoneLookupProjection(uri),
345e7ea93d5235c097151e40f8922a1efb000734904linyuh                null /* selection */,
346e7ea93d5235c097151e40f8922a1efb000734904linyuh                null /* selectionArgs */,
347e7ea93d5235c097151e40f8922a1efb000734904linyuh                null /* sortOrder */)) {
348e7ea93d5235c097151e40f8922a1efb000734904linyuh      if (phoneLookupCursor == null) {
349e7ea93d5235c097151e40f8922a1efb000734904linyuh        LogUtil.d("ContactInfoHelper.lookupContactFromUri", "phoneLookupCursor is null");
350e7ea93d5235c097151e40f8922a1efb000734904linyuh        return null;
351e7ea93d5235c097151e40f8922a1efb000734904linyuh      }
352ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
353ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (!phoneLookupCursor.moveToFirst()) {
354ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        return ContactInfo.EMPTY;
355ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
356e7ea93d5235c097151e40f8922a1efb000734904linyuh
3572d5167b475d64b4bad0f0cde2508bca55c4b7643linyuh      // The Contacts provider ignores special characters in phone numbers when searching for a
3582d5167b475d64b4bad0f0cde2508bca55c4b7643linyuh      // contact. For example, number "123" is considered a match with a contact with number "#123".
3592d5167b475d64b4bad0f0cde2508bca55c4b7643linyuh      // We need to check whether the result contains a number that truly matches the query and move
3602d5167b475d64b4bad0f0cde2508bca55c4b7643linyuh      // the cursor to that position before building a ContactInfo.
3612d5167b475d64b4bad0f0cde2508bca55c4b7643linyuh      boolean hasNumberMatch =
3622d5167b475d64b4bad0f0cde2508bca55c4b7643linyuh          PhoneNumberHelper.updateCursorToMatchContactLookupUri(
3632d5167b475d64b4bad0f0cde2508bca55c4b7643linyuh              phoneLookupCursor, PhoneQuery.MATCHED_NUMBER, uri);
3642d5167b475d64b4bad0f0cde2508bca55c4b7643linyuh      if (!hasNumberMatch) {
3652d5167b475d64b4bad0f0cde2508bca55c4b7643linyuh        return ContactInfo.EMPTY;
3662d5167b475d64b4bad0f0cde2508bca55c4b7643linyuh      }
3672d5167b475d64b4bad0f0cde2508bca55c4b7643linyuh
368bdef88bb0c16889e7403c117ce90825f7ed7b9e4linyuh      String lookupKey = phoneLookupCursor.getString(PhoneQuery.LOOKUP_KEY);
369bdef88bb0c16889e7403c117ce90825f7ed7b9e4linyuh      ContactInfo contactInfo = createPhoneLookupContactInfo(phoneLookupCursor, lookupKey);
370183cb71663320f16149d83eeebaff7795a4b55f2linyuh      fillAdditionalContactInfo(context, contactInfo);
371ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return contactInfo;
372ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
373ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
374ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
375ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private ContactInfo createPhoneLookupContactInfo(Cursor phoneLookupCursor, String lookupKey) {
376ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    ContactInfo info = new ContactInfo();
377ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.lookupKey = lookupKey;
378ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.lookupUri =
379ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        Contacts.getLookupUri(phoneLookupCursor.getLong(PhoneQuery.PERSON_ID), lookupKey);
380ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.name = phoneLookupCursor.getString(PhoneQuery.NAME);
381ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.type = phoneLookupCursor.getInt(PhoneQuery.PHONE_TYPE);
382ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.label = phoneLookupCursor.getString(PhoneQuery.LABEL);
383ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.number = phoneLookupCursor.getString(PhoneQuery.MATCHED_NUMBER);
384ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.normalizedNumber = phoneLookupCursor.getString(PhoneQuery.NORMALIZED_NUMBER);
385ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.photoId = phoneLookupCursor.getLong(PhoneQuery.PHOTO_ID);
386ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.photoUri = UriUtils.parseUriOrNull(phoneLookupCursor.getString(PhoneQuery.PHOTO_URI));
387ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.formattedNumber = null;
388ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.userType =
389ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        ContactsUtils.determineUserType(null, phoneLookupCursor.getLong(PhoneQuery.PERSON_ID));
3908369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian    info.contactExists = true;
391ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
392ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return info;
393ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
394ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
395ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void fillAdditionalContactInfo(Context context, ContactInfo contactInfo) {
396ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (contactInfo.number == null) {
397ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
398ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
399ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Uri uri = Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, Uri.encode(contactInfo.number));
400ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    try (Cursor cursor =
401ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        context
402ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            .getContentResolver()
403ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            .query(uri, PhoneQuery.ADDITIONAL_CONTACT_INFO_PROJECTION, null, null, null)) {
404ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (cursor == null || !cursor.moveToFirst()) {
405ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        return;
406ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
407ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      contactInfo.nameAlternative =
408ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          cursor.getString(PhoneQuery.ADDITIONAL_CONTACT_INFO_DISPLAY_NAME_ALTERNATIVE);
409ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      contactInfo.carrierPresence =
410ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          cursor.getInt(PhoneQuery.ADDITIONAL_CONTACT_INFO_CARRIER_PRESENCE);
411ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
412ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
413ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
414ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
415ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Determines the contact information for the given phone number.
416ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
417ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * <p>It returns the contact info if found.
418ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
419ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * <p>If no contact corresponds to the given phone number, returns {@link ContactInfo#EMPTY}.
420ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
421ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * <p>If the lookup fails for some other reason, it returns null.
422ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
423ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @SuppressWarnings("ReferenceEquality")
424ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private ContactInfo queryContactInfoForPhoneNumber(
425ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      String number, String countryIso, long directoryId) {
426ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (TextUtils.isEmpty(number)) {
4272ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian      LogUtil.d("ContactInfoHelper.queryContactInfoForPhoneNumber", "number is empty");
428ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return null;
429ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
430ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
431ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    ContactInfo info = lookupContactFromUri(getContactInfoLookupUri(number, directoryId));
4322ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian    if (info == null) {
4332ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian      LogUtil.d("ContactInfoHelper.queryContactInfoForPhoneNumber", "info looked up is null");
4342ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian    }
435ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (info != null && info != ContactInfo.EMPTY) {
436ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      info.formattedNumber = formatPhoneNumber(number, null, countryIso);
4372ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian      if (directoryId == -1) {
4382ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian        // Contact found in the default directory
4392ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian        info.sourceType = ContactSource.Type.SOURCE_TYPE_DIRECTORY;
4402ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian      } else {
4412ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian        // Contact found in the extended directory specified by directoryId
4422ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian        info.sourceType = ContactSource.Type.SOURCE_TYPE_EXTENDED;
4432ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian      }
444183cb71663320f16149d83eeebaff7795a4b55f2linyuh    } else if (cachedNumberLookupService != null) {
445ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      CachedContactInfo cacheInfo =
446183cb71663320f16149d83eeebaff7795a4b55f2linyuh          cachedNumberLookupService.lookupCachedContactFromNumber(context, number);
447ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (cacheInfo != null) {
4482ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian        if (!cacheInfo.getContactInfo().isBadData) {
4492ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian          info = cacheInfo.getContactInfo();
4502ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian        } else {
4512ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian          LogUtil.i("ContactInfoHelper.queryContactInfoForPhoneNumber", "info is bad data");
4522ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian        }
453ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
454ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
455ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return info;
456ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
457ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
458ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
459ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Format the given phone number
460ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
461ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param number the number to be formatted.
462ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param normalizedNumber the normalized number of the given number.
463ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param countryIso the ISO 3166-1 two letters country code, the country's convention will be
464ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *     used to format the number if the normalized phone is null.
465ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @return the formatted number, or the given number if it was formatted.
466ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
467ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private String formatPhoneNumber(String number, String normalizedNumber, String countryIso) {
468ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (TextUtils.isEmpty(number)) {
469ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return "";
470ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
471ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // If "number" is really a SIP address, don't try to do any formatting at all.
472ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (PhoneNumberHelper.isUriNumber(number)) {
473ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return number;
474ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
475ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (TextUtils.isEmpty(countryIso)) {
476183cb71663320f16149d83eeebaff7795a4b55f2linyuh      countryIso = currentCountryIso;
477ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
478b06d00924123aa13086be564fee6404215fcc0d5linyuh    return PhoneNumberHelper.formatNumber(context, number, normalizedNumber, countryIso);
479ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
480ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
481ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
482ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Stores differences between the updated contact info and the current call log contact info.
483ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
484ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param number The number of the contact.
485ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param countryIso The country associated with this number.
486ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param updatedInfo The updated contact info.
487ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param callLogInfo The call log entry's current contact info.
488ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
489ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void updateCallLogContactInfo(
490ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      String number, String countryIso, ContactInfo updatedInfo, ContactInfo callLogInfo) {
491183cb71663320f16149d83eeebaff7795a4b55f2linyuh    if (!PermissionsUtil.hasPermission(context, android.Manifest.permission.WRITE_CALL_LOG)) {
492ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
493ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
494ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
495ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    final ContentValues values = new ContentValues();
496ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    boolean needsUpdate = false;
497ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
498ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (callLogInfo != null) {
499ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (!TextUtils.equals(updatedInfo.name, callLogInfo.name)) {
500ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        values.put(Calls.CACHED_NAME, updatedInfo.name);
501ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        needsUpdate = true;
502ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
503ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
504ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (updatedInfo.type != callLogInfo.type) {
505ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        values.put(Calls.CACHED_NUMBER_TYPE, updatedInfo.type);
506ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        needsUpdate = true;
507ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
508ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
509ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (!TextUtils.equals(updatedInfo.label, callLogInfo.label)) {
510ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        values.put(Calls.CACHED_NUMBER_LABEL, updatedInfo.label);
511ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        needsUpdate = true;
512ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
513ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
514ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (!UriUtils.areEqual(updatedInfo.lookupUri, callLogInfo.lookupUri)) {
515ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        values.put(Calls.CACHED_LOOKUP_URI, UriUtils.uriToString(updatedInfo.lookupUri));
516ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        needsUpdate = true;
517ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
518ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
519ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Only replace the normalized number if the new updated normalized number isn't empty.
520ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (!TextUtils.isEmpty(updatedInfo.normalizedNumber)
521ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          && !TextUtils.equals(updatedInfo.normalizedNumber, callLogInfo.normalizedNumber)) {
522ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        values.put(Calls.CACHED_NORMALIZED_NUMBER, updatedInfo.normalizedNumber);
523ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        needsUpdate = true;
524ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
525ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
526ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (!TextUtils.equals(updatedInfo.number, callLogInfo.number)) {
527ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        values.put(Calls.CACHED_MATCHED_NUMBER, updatedInfo.number);
528ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        needsUpdate = true;
529ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
530ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
531ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (updatedInfo.photoId != callLogInfo.photoId) {
532ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        values.put(Calls.CACHED_PHOTO_ID, updatedInfo.photoId);
533ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        needsUpdate = true;
534ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
535ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
536ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      final Uri updatedPhotoUriContactsOnly = UriUtils.nullForNonContactsUri(updatedInfo.photoUri);
537ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (!UriUtils.areEqual(updatedPhotoUriContactsOnly, callLogInfo.photoUri)) {
538ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        values.put(Calls.CACHED_PHOTO_URI, UriUtils.uriToString(updatedPhotoUriContactsOnly));
539ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        needsUpdate = true;
540ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
541ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
542ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (!TextUtils.equals(updatedInfo.formattedNumber, callLogInfo.formattedNumber)) {
543ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        values.put(Calls.CACHED_FORMATTED_NUMBER, updatedInfo.formattedNumber);
544ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        needsUpdate = true;
545ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
5469779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian
5479779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian      if (!TextUtils.equals(updatedInfo.geoDescription, callLogInfo.geoDescription)) {
5489779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian        values.put(Calls.GEOCODED_LOCATION, updatedInfo.geoDescription);
5499779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian        needsUpdate = true;
5509779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian      }
551ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
552ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // No previous values, store all of them.
553ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      values.put(Calls.CACHED_NAME, updatedInfo.name);
554ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      values.put(Calls.CACHED_NUMBER_TYPE, updatedInfo.type);
555ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      values.put(Calls.CACHED_NUMBER_LABEL, updatedInfo.label);
556ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      values.put(Calls.CACHED_LOOKUP_URI, UriUtils.uriToString(updatedInfo.lookupUri));
557ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      values.put(Calls.CACHED_MATCHED_NUMBER, updatedInfo.number);
558ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      values.put(Calls.CACHED_NORMALIZED_NUMBER, updatedInfo.normalizedNumber);
559ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      values.put(Calls.CACHED_PHOTO_ID, updatedInfo.photoId);
560ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      values.put(
561ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          Calls.CACHED_PHOTO_URI,
562ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          UriUtils.uriToString(UriUtils.nullForNonContactsUri(updatedInfo.photoUri)));
563ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      values.put(Calls.CACHED_FORMATTED_NUMBER, updatedInfo.formattedNumber);
5649779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian      values.put(Calls.GEOCODED_LOCATION, updatedInfo.geoDescription);
565ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      needsUpdate = true;
566ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
567ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
568ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (!needsUpdate) {
569ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
570ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
571ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
572ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    try {
573ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (countryIso == null) {
574183cb71663320f16149d83eeebaff7795a4b55f2linyuh        context
575ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            .getContentResolver()
576ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            .update(
577183cb71663320f16149d83eeebaff7795a4b55f2linyuh                TelecomUtil.getCallLogUri(context),
578ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                values,
579ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                Calls.NUMBER + " = ? AND " + Calls.COUNTRY_ISO + " IS NULL",
580ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                new String[] {number});
581ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      } else {
582183cb71663320f16149d83eeebaff7795a4b55f2linyuh        context
583ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            .getContentResolver()
584ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            .update(
585183cb71663320f16149d83eeebaff7795a4b55f2linyuh                TelecomUtil.getCallLogUri(context),
586ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                values,
587ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                Calls.NUMBER + " = ? AND " + Calls.COUNTRY_ISO + " = ?",
588ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                new String[] {number, countryIso});
589ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
590ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } catch (SQLiteFullException e) {
5919779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian      LogUtil.e(TAG, "Unable to update contact info in call log db", e);
592ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
593ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
594ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
595ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void updateCachedNumberLookupService(ContactInfo updatedInfo) {
596183cb71663320f16149d83eeebaff7795a4b55f2linyuh    if (cachedNumberLookupService != null) {
597ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (hasName(updatedInfo)) {
598ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        CachedContactInfo cachedContactInfo =
599183cb71663320f16149d83eeebaff7795a4b55f2linyuh            cachedNumberLookupService.buildCachedContactInfo(updatedInfo);
600183cb71663320f16149d83eeebaff7795a4b55f2linyuh        cachedNumberLookupService.addContact(context, cachedContactInfo);
601ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
602ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
603ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
604ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
605ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
606ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Given a contact's sourceType, return true if the contact is a business
607ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
608ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param sourceType sourceType of the contact. This is usually populated by {@link
609183cb71663320f16149d83eeebaff7795a4b55f2linyuh   *     #cachedNumberLookupService}.
610ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
6118369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian  public boolean isBusiness(ContactSource.Type sourceType) {
612183cb71663320f16149d83eeebaff7795a4b55f2linyuh    return cachedNumberLookupService != null && cachedNumberLookupService.isBusiness(sourceType);
613ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
614ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
615ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
616ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * This function looks at a contact's source and determines if the user can mark caller ids from
617ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * this source as invalid.
618ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
619ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param sourceType The source type to be checked
620ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param objectId The ID of the Contact object.
621ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @return true if contacts from this source can be marked with an invalid caller id
622ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
6238369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian  public boolean canReportAsInvalid(ContactSource.Type sourceType, String objectId) {
624183cb71663320f16149d83eeebaff7795a4b55f2linyuh    return cachedNumberLookupService != null
625183cb71663320f16149d83eeebaff7795a4b55f2linyuh        && cachedNumberLookupService.canReportAsInvalid(sourceType, objectId);
626ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
6279779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian
6289779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian  /**
6299779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian   * Update ContactInfo by querying to Cequint Caller ID. Only name, geoDescription and photo uri
6309779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian   * will be updated if available.
6319779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian   */
632d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian  @WorkerThread
6332ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian  public void updateFromCequintCallerId(
6342ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian      @Nullable CequintCallerIdManager cequintCallerIdManager, ContactInfo info, String number) {
635d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    Assert.isWorkerThread();
636183cb71663320f16149d83eeebaff7795a4b55f2linyuh    if (!CequintCallerIdManager.isCequintCallerIdEnabled(context)) {
6379779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian      return;
6389779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian    }
6392ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian    if (cequintCallerIdManager == null) {
6402ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian      return;
6412ca4318cc1ee57dda907ba2069bd61d162b1baefEric Erfanian    }
6429779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian    CequintCallerIdContact cequintCallerIdContact =
643183cb71663320f16149d83eeebaff7795a4b55f2linyuh        cequintCallerIdManager.getCequintCallerIdContact(context, number);
6449779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian    if (cequintCallerIdContact == null) {
6459779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian      return;
6469779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian    }
647d8046e520a866b9948ee9ba47cf642b441ca8e23Eric Erfanian    if (TextUtils.isEmpty(info.name) && !TextUtils.isEmpty(cequintCallerIdContact.name)) {
6489779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian      info.name = cequintCallerIdContact.name;
6499779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian    }
6509779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian    if (!TextUtils.isEmpty(cequintCallerIdContact.geoDescription)) {
6519779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian      info.geoDescription = cequintCallerIdContact.geoDescription;
6528369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian      info.sourceType = ContactSource.Type.SOURCE_TYPE_CEQUINT_CALLER_ID;
6539779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian    }
6548369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian    // Only update photo if local lookup has no result.
6558369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian    if (!info.contactExists && info.photoUri == null && cequintCallerIdContact.imageUrl != null) {
6569779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian      info.photoUri = UriUtils.parseUriOrNull(cequintCallerIdContact.imageUrl);
6579779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian    }
6589779f967ebb9512e5b19090b071572c9c4f0f2a6Eric Erfanian  }
659ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian}
660