194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng/*
294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Copyright (C) 2011 The Android Open Source Project
394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng *
456cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
556cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee * in compliance with the License. You may obtain a copy of the License at
694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng *
756cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee * http://www.apache.org/licenses/LICENSE-2.0
894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng *
956cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee * Unless required by applicable law or agreed to in writing, software distributed under the License
1056cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
1156cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee * or implied. See the License for the specific language governing permissions and limitations under
1256cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee * the License.
1394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */
1494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng
1594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengpackage com.android.dialer.calllog;
1694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng
1794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.content.Context;
1894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.database.Cursor;
1994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.net.Uri;
2058ebe5d3fac837625b69fe1565427f17025bd780Yorke Leeimport android.provider.ContactsContract;
2158ebe5d3fac837625b69fe1565427f17025bd780Yorke Leeimport android.provider.ContactsContract.CommonDataKinds.Phone;
2294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.provider.ContactsContract.Contacts;
2358ebe5d3fac837625b69fe1565427f17025bd780Yorke Leeimport android.provider.ContactsContract.DisplayNameSources;
2494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.provider.ContactsContract.PhoneLookup;
2594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.telephony.PhoneNumberUtils;
2694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.text.TextUtils;
2794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng
2858ebe5d3fac837625b69fe1565427f17025bd780Yorke Leeimport com.android.contacts.common.util.Constants;
2937d29854313ca0a7807ac4fd5d10d154b79ee2ebYorke Leeimport com.android.contacts.common.util.PhoneNumberHelper;
3035071c06d1587942f5a66c8f12e6247e8f904d26Chiao Chengimport com.android.contacts.common.util.UriUtils;
31034a2b329e469bf6888fbbcf91992f974015c2a8Yorke Leeimport com.android.dialer.service.CachedNumberLookupService;
32c089b0d2b1bf1bd511cd54dc51d9186b6ce41681Jay Shraunerimport com.android.dialer.service.CachedNumberLookupService.CachedContactInfo;
33704acc087ce359295475a46695c2821c55778344Chiao Chengimport com.android.dialerbind.ObjectFactory;
3494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng
3558ebe5d3fac837625b69fe1565427f17025bd780Yorke Leeimport org.json.JSONException;
3658ebe5d3fac837625b69fe1565427f17025bd780Yorke Leeimport org.json.JSONObject;
3758ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee
3856cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Leeimport java.util.List;
3956cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee
4094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng/**
4194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Utility class to look up the contact information for a given number.
4294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */
4394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengpublic class ContactInfoHelper {
4494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng    private final Context mContext;
4594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng    private final String mCurrentCountryIso;
4694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng
47034a2b329e469bf6888fbbcf91992f974015c2a8Yorke Lee    private static final CachedNumberLookupService mCachedNumberLookupService =
48704acc087ce359295475a46695c2821c55778344Chiao Cheng            ObjectFactory.newCachedNumberLookupService();
49034a2b329e469bf6888fbbcf91992f974015c2a8Yorke Lee
5094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng    public ContactInfoHelper(Context context, String currentCountryIso) {
5194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        mContext = context;
5294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        mCurrentCountryIso = currentCountryIso;
5394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng    }
5494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng
5594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng    /**
5694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * Returns the contact information for the given number.
5794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * <p>
5894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * If the number does not match any contact, returns a contact info containing only the number
5994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * and the formatted number.
6094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * <p>
6194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * If an error occurs during the lookup, it returns null.
6294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     *
6394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * @param number the number to look up
6494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * @param countryIso the country associated with this number
6594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     */
6694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng    public ContactInfo lookupNumber(String number, String countryIso) {
6794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        final ContactInfo info;
6894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng
6994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        // Determine the contact info.
7037d29854313ca0a7807ac4fd5d10d154b79ee2ebYorke Lee        if (PhoneNumberHelper.isUriNumber(number)) {
7194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            // This "number" is really a SIP address.
7294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            ContactInfo sipInfo = queryContactInfoForSipAddress(number);
7394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            if (sipInfo == null || sipInfo == ContactInfo.EMPTY) {
7494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                // Check whether the "username" part of the SIP address is
7594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                // actually the phone number of a contact.
7637d29854313ca0a7807ac4fd5d10d154b79ee2ebYorke Lee                String username = PhoneNumberHelper.getUsernameFromUriNumber(number);
7794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                if (PhoneNumberUtils.isGlobalPhoneNumber(username)) {
7894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                    sipInfo = queryContactInfoForPhoneNumber(username, countryIso);
7994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                }
8094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            }
8194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            info = sipInfo;
8294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        } else {
8394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            // Look for a contact that has the given phone number.
8494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            ContactInfo phoneInfo = queryContactInfoForPhoneNumber(number, countryIso);
8594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng
8694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            if (phoneInfo == null || phoneInfo == ContactInfo.EMPTY) {
8794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                // Check whether the phone number has been saved as an "Internet call" number.
8894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                phoneInfo = queryContactInfoForSipAddress(number);
8994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            }
9094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            info = phoneInfo;
9194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        }
9294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng
9394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        final ContactInfo updatedInfo;
9494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        if (info == null) {
9594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            // The lookup failed.
9694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            updatedInfo = null;
9794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        } else {
9894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            // If we did not find a matching contact, generate an empty contact info for the number.
9994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            if (info == ContactInfo.EMPTY) {
10094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                // Did not find a matching contact.
10194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                updatedInfo = new ContactInfo();
10294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                updatedInfo.number = number;
10394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                updatedInfo.formattedNumber = formatPhoneNumber(number, null, countryIso);
104746dba885dc50c9f723456b01cfc7dbfcc9a49b0Tyler Gunn                updatedInfo.normalizedNumber = PhoneNumberUtils.formatNumberToE164(
105746dba885dc50c9f723456b01cfc7dbfcc9a49b0Tyler Gunn                        number, countryIso);
10656cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee                updatedInfo.lookupUri = createTemporaryContactUri(updatedInfo.formattedNumber);
10794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            } else {
10894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                updatedInfo = info;
10994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            }
11094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        }
11194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        return updatedInfo;
11294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng    }
11394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng
11494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng    /**
11558ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee     * Creates a JSON-encoded lookup uri for a unknown number without an associated contact
11658ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee     *
11758ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee     * @param number - Unknown phone number
11856cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee     * @return JSON-encoded URI that can be used to perform a lookup when clicking on the quick
11956cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee     *         contact card.
12058ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee     */
12158ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee    private static Uri createTemporaryContactUri(String number) {
12258ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee        try {
12356cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee            final JSONObject contactRows = new JSONObject().put(Phone.CONTENT_ITEM_TYPE,
12456cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee                    new JSONObject().put(Phone.NUMBER, number).put(Phone.TYPE, Phone.TYPE_CUSTOM));
12558ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee
12656cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee            final String jsonString = new JSONObject().put(Contacts.DISPLAY_NAME, number)
12756cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee                    .put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.PHONE)
12856cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee                    .put(Contacts.CONTENT_ITEM_TYPE, contactRows).toString();
12958ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee
13056cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee            return Contacts.CONTENT_LOOKUP_URI
13156cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee                    .buildUpon()
13258ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee                    .appendPath(Constants.LOOKUP_URI_ENCODED)
13358ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee                    .appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY,
13458ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee                            String.valueOf(Long.MAX_VALUE))
13595b2537946f2af718122a796662b025206cffd91Yorke Lee                    .encodedFragment(jsonString)
13658ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee                    .build();
13758ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee        } catch (JSONException e) {
13858ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee            return null;
13958ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee        }
14058ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee    }
14158ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee
14258ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee    /**
14394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * Looks up a contact using the given URI.
14494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * <p>
14594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * It returns null if an error occurs, {@link ContactInfo#EMPTY} if no matching contact is
14694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * found, or the {@link ContactInfo} for the given contact.
14794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * <p>
14894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * The {@link ContactInfo#formattedNumber} field is always set to {@code null} in the returned
14994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * value.
15094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     */
15194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng    private ContactInfo lookupContactFromUri(Uri uri) {
15294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        final ContactInfo info;
15394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        Cursor phonesCursor =
15456cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee                mContext.getContentResolver().query(uri, PhoneQuery._PROJECTION, null, null, null);
15594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng
15694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        if (phonesCursor != null) {
15794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            try {
15894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                if (phonesCursor.moveToFirst()) {
15994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                    info = new ContactInfo();
16094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                    long contactId = phonesCursor.getLong(PhoneQuery.PERSON_ID);
16194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                    String lookupKey = phonesCursor.getString(PhoneQuery.LOOKUP_KEY);
16256cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee                    info.lookupKey = lookupKey;
16394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                    info.lookupUri = Contacts.getLookupUri(contactId, lookupKey);
16494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                    info.name = phonesCursor.getString(PhoneQuery.NAME);
16594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                    info.type = phonesCursor.getInt(PhoneQuery.PHONE_TYPE);
16694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                    info.label = phonesCursor.getString(PhoneQuery.LABEL);
16794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                    info.number = phonesCursor.getString(PhoneQuery.MATCHED_NUMBER);
16894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                    info.normalizedNumber = phonesCursor.getString(PhoneQuery.NORMALIZED_NUMBER);
16994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                    info.photoId = phonesCursor.getLong(PhoneQuery.PHOTO_ID);
17094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                    info.photoUri =
17194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                            UriUtils.parseUriOrNull(phonesCursor.getString(PhoneQuery.PHOTO_URI));
17294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                    info.formattedNumber = null;
17394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                } else {
17494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                    info = ContactInfo.EMPTY;
17594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                }
17694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            } finally {
17794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                phonesCursor.close();
17894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            }
17994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        } else {
18094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            // Failed to fetch the data, ignore this request.
18194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            info = null;
18294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        }
18394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        return info;
18494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng    }
18594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng
18694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng    /**
18794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * Determines the contact information for the given SIP address.
18894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * <p>
18994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * It returns the contact info if found.
19094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * <p>
19194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * If no contact corresponds to the given SIP address, returns {@link ContactInfo#EMPTY}.
19294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * <p>
19394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * If the lookup fails for some other reason, it returns null.
19494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     */
19594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng    private ContactInfo queryContactInfoForSipAddress(String sipAddress) {
19694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        final ContactInfo info;
19794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng
19894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        // "contactNumber" is a SIP address, so use the PhoneLookup table with the SIP parameter.
19994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        Uri.Builder uriBuilder = PhoneLookup.CONTENT_FILTER_URI.buildUpon();
20094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        uriBuilder.appendPath(Uri.encode(sipAddress));
20194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        uriBuilder.appendQueryParameter(PhoneLookup.QUERY_PARAMETER_SIP_ADDRESS, "1");
20294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        return lookupContactFromUri(uriBuilder.build());
20394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng    }
20494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng
20594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng    /**
20694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * Determines the contact information for the given phone number.
20794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * <p>
20894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * It returns the contact info if found.
20994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * <p>
21094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * If no contact corresponds to the given phone number, returns {@link ContactInfo#EMPTY}.
21194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * <p>
21294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * If the lookup fails for some other reason, it returns null.
21394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     */
21494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng    private ContactInfo queryContactInfoForPhoneNumber(String number, String countryIso) {
21594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        String contactNumber = number;
21694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        if (!TextUtils.isEmpty(countryIso)) {
21794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            // Normalize the number: this is needed because the PhoneLookup query below does not
21894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            // accept a country code as an input.
21994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            String numberE164 = PhoneNumberUtils.formatNumberToE164(number, countryIso);
22094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            if (!TextUtils.isEmpty(numberE164)) {
22194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                // Only use it if the number could be formatted to E164.
22294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng                contactNumber = numberE164;
22394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            }
22494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        }
22594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng
22694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        // The "contactNumber" is a regular phone number, so use the PhoneLookup table.
22794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(contactNumber));
22894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        ContactInfo info = lookupContactFromUri(uri);
22994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        if (info != null && info != ContactInfo.EMPTY) {
23094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            info.formattedNumber = formatPhoneNumber(number, null, countryIso);
231034a2b329e469bf6888fbbcf91992f974015c2a8Yorke Lee        } else if (mCachedNumberLookupService != null) {
23256cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee            CachedContactInfo cacheInfo =
23356cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee                    mCachedNumberLookupService.lookupCachedContactFromNumber(mContext, number);
234ffb26eef68f526926ca1cf8562cc9cf07a32a45cSai Cheemalapati            if (cacheInfo != null) {
235ffb26eef68f526926ca1cf8562cc9cf07a32a45cSai Cheemalapati                info = cacheInfo.getContactInfo().isBadData ? null : cacheInfo.getContactInfo();
236ffb26eef68f526926ca1cf8562cc9cf07a32a45cSai Cheemalapati            } else {
237ffb26eef68f526926ca1cf8562cc9cf07a32a45cSai Cheemalapati                info = null;
238ffb26eef68f526926ca1cf8562cc9cf07a32a45cSai Cheemalapati            }
23994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        }
24094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        return info;
24194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng    }
24294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng
24394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng    /**
24494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * Format the given phone number
24594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     *
24694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * @param number the number to be formatted.
24794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * @param normalizedNumber the normalized number of the given number.
24856cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee     * @param countryIso the ISO 3166-1 two letters country code, the country's convention will be
24956cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee     *        used to format the number if the normalized phone is null.
25094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     *
25194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     * @return the formatted number, or the given number if it was formatted.
25294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng     */
25356cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee    private String formatPhoneNumber(String number, String normalizedNumber, String countryIso) {
25494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        if (TextUtils.isEmpty(number)) {
25594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            return "";
25694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        }
25794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        // If "number" is really a SIP address, don't try to do any formatting at all.
25837d29854313ca0a7807ac4fd5d10d154b79ee2ebYorke Lee        if (PhoneNumberHelper.isUriNumber(number)) {
25994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            return number;
26094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        }
26194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        if (TextUtils.isEmpty(countryIso)) {
26294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng            countryIso = mCurrentCountryIso;
26394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        }
26494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng        return PhoneNumberUtils.formatNumber(number, normalizedNumber, countryIso);
26594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng    }
26656cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee
26756cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee    /**
26856cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee     * Parses the given URI to determine the original lookup key of the contact.
26956cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee     */
27056cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee    public static String getLookupKeyFromUri(Uri lookupUri) {
27156cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee        // Would be nice to be able to persist the lookup key somehow to avoid having to parse
27256cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee        // the uri entirely just to retrieve the lookup key, but every uri is already parsed
27356cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee        // once anyway to check if it is an encoded JSON uri, so this has negligible effect
27456cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee        // on performance.
27556cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee        if (lookupUri != null && !UriUtils.isEncodedContactUri(lookupUri)) {
27656cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee            final List<String> segments = lookupUri.getPathSegments();
27756cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee            // This returns the third path segment of the uri, where the lookup key is located.
27856cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee            // See {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI}.
279774c0a924d00544e40a61a6d3bd13e967c5fd428Yorke Lee            return (segments.size() < 3) ? null : Uri.encode(segments.get(2));
28056cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee        } else {
28156cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee            return null;
28256cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee        }
28356cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee    }
28456cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee
28556cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee    /**
28656cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee     * Given a contact's sourceType, return true if the contact is a business
28756cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee     *
28856cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee     * @param sourceType sourceType of the contact. This is usually populated by
28956cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee     *        {@link #mCachedNumberLookupService}.
29056cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee     */
29156cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee    public boolean isBusiness(int sourceType) {
292b98da724ee52d0ff63739998c8d72d0fc9cabfa6Yorke Lee        return mCachedNumberLookupService != null
293b98da724ee52d0ff63739998c8d72d0fc9cabfa6Yorke Lee                && mCachedNumberLookupService.isBusiness(sourceType);
29456cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee    }
295b77bf5df2b866dd40e330b7c2dedee4a1d51fc78Sai Cheemalapati
296b77bf5df2b866dd40e330b7c2dedee4a1d51fc78Sai Cheemalapati    /**
29755733814f213809baaa8eaa8984ff026bdb08b4eAnthony Lee     * This function looks at a contact's source and determines if the user can
29855733814f213809baaa8eaa8984ff026bdb08b4eAnthony Lee     * mark caller ids from this source as invalid.
299b77bf5df2b866dd40e330b7c2dedee4a1d51fc78Sai Cheemalapati     *
30055733814f213809baaa8eaa8984ff026bdb08b4eAnthony Lee     * @param sourceType The source type to be checked
30155733814f213809baaa8eaa8984ff026bdb08b4eAnthony Lee     * @param objectId The ID of the Contact object.
30255733814f213809baaa8eaa8984ff026bdb08b4eAnthony Lee     * @return true if contacts from this source can be marked with an invalid caller id
303b77bf5df2b866dd40e330b7c2dedee4a1d51fc78Sai Cheemalapati     */
30455733814f213809baaa8eaa8984ff026bdb08b4eAnthony Lee    public boolean canReportAsInvalid(int sourceType, String objectId) {
305b77bf5df2b866dd40e330b7c2dedee4a1d51fc78Sai Cheemalapati        return mCachedNumberLookupService != null
30655733814f213809baaa8eaa8984ff026bdb08b4eAnthony Lee                && mCachedNumberLookupService.canReportAsInvalid(sourceType, objectId);
307b77bf5df2b866dd40e330b7c2dedee4a1d51fc78Sai Cheemalapati    }
30855733814f213809baaa8eaa8984ff026bdb08b4eAnthony Lee
30955733814f213809baaa8eaa8984ff026bdb08b4eAnthony Lee
31094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng}
311