diff options
6 files changed, 143 insertions, 233 deletions
diff --git a/java/com/android/dialer/phonenumbercache/ContactInfoHelper.java b/java/com/android/dialer/phonenumbercache/ContactInfoHelper.java index 8e08fb20d..c3f5b692f 100644 --- a/java/com/android/dialer/phonenumbercache/ContactInfoHelper.java +++ b/java/com/android/dialer/phonenumbercache/ContactInfoHelper.java @@ -337,30 +337,30 @@ public class ContactInfoHelper { return ContactInfo.EMPTY; } - try (Cursor phoneLookupCursor = - mContext - .getContentResolver() - .query(uri, PhoneQuery.getPhoneLookupProjection(uri), null, null, null)) { - if (phoneLookupCursor == null) { - LogUtil.d("ContactInfoHelper.lookupContactFromUri", "phoneLookupCursor is null"); - return null; - } + Cursor phoneLookupCursor = null; + try { + String[] projection = PhoneQuery.getPhoneLookupProjection(uri); + phoneLookupCursor = mContext.getContentResolver().query(uri, projection, null, null, null); + } catch (NullPointerException e) { + LogUtil.e("ContactInfoHelper.lookupContactFromUri", "phone lookup", e); + // Trap NPE from pre-N CP2 + return null; + } + if (phoneLookupCursor == null) { + LogUtil.d("ContactInfoHelper.lookupContactFromUri", "phoneLookupCursor is null"); + return null; + } + try { if (!phoneLookupCursor.moveToFirst()) { return ContactInfo.EMPTY; } - - Cursor matchedCursor = - PhoneNumberHelper.getCursorMatchForContactLookupUri( - phoneLookupCursor, PhoneQuery.MATCHED_NUMBER, uri); - if (matchedCursor == null) { - return ContactInfo.EMPTY; - } - - String lookupKey = matchedCursor.getString(PhoneQuery.LOOKUP_KEY); - ContactInfo contactInfo = createPhoneLookupContactInfo(matchedCursor, lookupKey); + String lookupKey = phoneLookupCursor.getString(PhoneQuery.LOOKUP_KEY); + ContactInfo contactInfo = createPhoneLookupContactInfo(phoneLookupCursor, lookupKey); fillAdditionalContactInfo(mContext, contactInfo); return contactInfo; + } finally { + phoneLookupCursor.close(); } } diff --git a/java/com/android/dialer/phonenumberutil/PhoneNumberHelper.java b/java/com/android/dialer/phonenumberutil/PhoneNumberHelper.java index e32ace59e..be1b0629a 100644 --- a/java/com/android/dialer/phonenumberutil/PhoneNumberHelper.java +++ b/java/com/android/dialer/phonenumberutil/PhoneNumberHelper.java @@ -17,8 +17,6 @@ package com.android.dialer.phonenumberutil; import android.content.Context; -import android.database.Cursor; -import android.net.Uri; import android.os.Trace; import android.provider.CallLog; import android.support.annotation.NonNull; @@ -29,7 +27,6 @@ import android.telephony.TelephonyManager; import android.text.BidiFormatter; import android.text.TextDirectionHeuristics; import android.text.TextUtils; -import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; import com.android.dialer.compat.CompatUtils; import com.android.dialer.compat.telephony.TelephonyManagerCompat; @@ -53,78 +50,6 @@ public class PhoneNumberHelper { } /** - * Find the cursor pointing to a number that matches the number in a contact lookup URI. - * - * <p>When determining whether two phone numbers are identical enough for caller ID purposes, the - * Contacts Provider uses {@link PhoneNumberUtils#compare(String, String)}, which ignores special - * dialable characters such as '#', '*', '+', etc. This makes it possible for the cursor returned - * by the Contacts Provider to have multiple rows even when the URI asks for a specific number. - * - * <p>For example, suppose the user has two contacts whose numbers are "#123" and "123", - * respectively. When the URI asks for number "123", both numbers will be returned. Therefore, the - * following strategy is employed to find a match. - * - * <p>If the cursor points to a global phone number (i.e., a number that can be accepted by {@link - * PhoneNumberUtils#isGlobalPhoneNumber(String)}) and the lookup number in the URI is a PARTIAL - * match, return the cursor. - * - * <p>If the cursor points to a number that is not a global phone number, return the cursor iff - * the lookup number in the URI is an EXACT match. - * - * <p>Return null in all other circumstances. - * - * @param cursor A cursor returned by the Contacts Provider. - * @param columnIndexForNumber The index of the column where phone numbers are stored. It is the - * caller's responsibility to pass the correct column index. - * @param contactLookupUri A URI used to retrieve a contact via the Contacts Provider. It is the - * caller's responsibility to ensure the URI is one that asks for a specific phone number. - * @return The cursor considered as a match by the description above or null if no such cursor can - * be found. - */ - public static Cursor getCursorMatchForContactLookupUri( - Cursor cursor, int columnIndexForNumber, Uri contactLookupUri) { - if (cursor == null || contactLookupUri == null) { - return null; - } - - if (!cursor.moveToFirst()) { - return null; - } - - Assert.checkArgument( - 0 <= columnIndexForNumber && columnIndexForNumber < cursor.getColumnCount()); - - String lookupNumber = contactLookupUri.getLastPathSegment(); - if (lookupNumber == null) { - return null; - } - - boolean isMatchFound; - do { - // All undialable characters should be converted/removed before comparing the lookup number - // and the existing contact number. - String rawExistingContactNumber = - PhoneNumberUtils.stripSeparators( - PhoneNumberUtils.convertKeypadLettersToDigits( - cursor.getString(columnIndexForNumber))); - String rawQueryNumber = - PhoneNumberUtils.stripSeparators( - PhoneNumberUtils.convertKeypadLettersToDigits(lookupNumber)); - - isMatchFound = - PhoneNumberUtils.isGlobalPhoneNumber(rawExistingContactNumber) - ? rawExistingContactNumber.contains(rawQueryNumber) - : rawExistingContactNumber.equals(rawQueryNumber); - - if (isMatchFound) { - return cursor; - } - } while (cursor.moveToNext()); - - return null; - } - - /** * Returns true if the given number is the number of the configured voicemail. To be able to * mock-out this, it is not a static method. */ diff --git a/java/com/android/incallui/CallerInfo.java b/java/com/android/incallui/CallerInfo.java index 4a9cf2181..6f8d1921e 100644 --- a/java/com/android/incallui/CallerInfo.java +++ b/java/com/android/incallui/CallerInfo.java @@ -192,145 +192,141 @@ public class CallerInfo { * * @param context the context used to retrieve string constants * @param contactRef the URI to attach to this CallerInfo object - * @param cursor the first matching object in the cursor is used to build the CallerInfo object. + * @param cursor the first object in the cursor is used to build the CallerInfo object. * @return the CallerInfo which contains the caller id for the given number. The returned * CallerInfo is null if no number is supplied. */ public static CallerInfo getCallerInfo(Context context, Uri contactRef, Cursor cursor) { CallerInfo info = new CallerInfo(); + info.photoResource = 0; + info.phoneLabel = null; + info.numberType = 0; + info.numberLabel = null; info.cachedPhoto = null; - info.contactExists = false; - info.contactRefUri = contactRef; info.isCachedPhotoCurrent = false; - info.name = null; - info.needUpdate = false; - info.numberLabel = null; - info.numberType = 0; - info.phoneLabel = null; - info.photoResource = 0; + info.contactExists = false; info.userType = ContactsUtils.USER_TYPE_CURRENT; Log.v(TAG, "getCallerInfo() based on cursor..."); - if (cursor == null || !cursor.moveToFirst()) { - return info; - } - - // TODO: photo_id is always available but not taken - // care of here. Maybe we should store it in the - // CallerInfo object as well. - - long contactId = 0L; - int columnIndex; - - // If the cursor has the phone number column, find the one that matches the lookup number in the - // URI. - columnIndex = cursor.getColumnIndex(PhoneLookup.NUMBER); - if (columnIndex != -1 && contactRef != null) { - cursor = PhoneNumberHelper.getCursorMatchForContactLookupUri(cursor, columnIndex, contactRef); - if (cursor != null) { - info.phoneNumber = cursor.getString(columnIndex); - } else { - return info; - } - } - - // Look for the name - columnIndex = cursor.getColumnIndex(PhoneLookup.DISPLAY_NAME); - if (columnIndex != -1) { - info.name = normalize(cursor.getString(columnIndex)); - } - - // Look for the normalized number - columnIndex = cursor.getColumnIndex(PhoneLookup.NORMALIZED_NUMBER); - if (columnIndex != -1) { - info.normalizedNumber = cursor.getString(columnIndex); - } - - // Look for the label/type combo - columnIndex = cursor.getColumnIndex(PhoneLookup.LABEL); - if (columnIndex != -1) { - int typeColumnIndex = cursor.getColumnIndex(PhoneLookup.TYPE); - if (typeColumnIndex != -1) { - info.numberType = cursor.getInt(typeColumnIndex); - info.numberLabel = cursor.getString(columnIndex); - info.phoneLabel = - Phone.getTypeLabel(context.getResources(), info.numberType, info.numberLabel) - .toString(); - } - } - - // cache the lookup key for later use to create lookup URIs - columnIndex = cursor.getColumnIndex(PhoneLookup.LOOKUP_KEY); - if (columnIndex != -1) { - info.lookupKeyOrNull = cursor.getString(columnIndex); - } - - // Look for the person_id. - columnIndex = getColumnIndexForPersonId(contactRef, cursor); - if (columnIndex != -1) { - contactId = cursor.getLong(columnIndex); - // QuickContacts in M doesn't support enterprise contact id - if (contactId != 0 - && (VERSION.SDK_INT >= VERSION_CODES.N || !Contacts.isEnterpriseContactId(contactId))) { - info.contactIdOrZero = contactId; - Log.v(TAG, "==> got info.contactIdOrZero: " + info.contactIdOrZero); - } - } else { - // No valid columnIndex, so we can't look up person_id. - Log.v(TAG, "Couldn't find contactId column for " + contactRef); - // Watch out: this means that anything that depends on - // person_id will be broken (like contact photo lookups in - // the in-call UI, for example.) - } - - // Display photo URI. - columnIndex = cursor.getColumnIndex(PhoneLookup.PHOTO_URI); - if ((columnIndex != -1) && (cursor.getString(columnIndex) != null)) { - info.contactDisplayPhotoUri = Uri.parse(cursor.getString(columnIndex)); - } else { - info.contactDisplayPhotoUri = null; - } - - // look for the custom ringtone, create from the string stored - // in the database. - columnIndex = cursor.getColumnIndex(PhoneLookup.CUSTOM_RINGTONE); - if ((columnIndex != -1) && (cursor.getString(columnIndex) != null)) { - if (TextUtils.isEmpty(cursor.getString(columnIndex))) { - // make it consistent with frameworks/base/.../CallerInfo.java - info.contactRingtoneUri = Uri.EMPTY; - } else { - info.contactRingtoneUri = Uri.parse(cursor.getString(columnIndex)); - } - } else { - info.contactRingtoneUri = null; - } - - // look for the send to voicemail flag, set it to true only - // under certain circumstances. - columnIndex = cursor.getColumnIndex(PhoneLookup.SEND_TO_VOICEMAIL); - info.shouldSendToVoicemail = (columnIndex != -1) && ((cursor.getInt(columnIndex)) == 1); - info.contactExists = true; - - // Determine userType by directoryId and contactId - final String directory = - contactRef == null - ? null - : contactRef.getQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY); - Long directoryId = null; - if (directory != null) { - try { - directoryId = Long.parseLong(directory); - } catch (NumberFormatException e) { - // do nothing + if (cursor != null) { + if (cursor.moveToFirst()) { + // TODO: photo_id is always available but not taken + // care of here. Maybe we should store it in the + // CallerInfo object as well. + + long contactId = 0L; + int columnIndex; + + // Look for the name + columnIndex = cursor.getColumnIndex(PhoneLookup.DISPLAY_NAME); + if (columnIndex != -1) { + info.name = cursor.getString(columnIndex); + } + + // Look for the number + columnIndex = cursor.getColumnIndex(PhoneLookup.NUMBER); + if (columnIndex != -1) { + info.phoneNumber = cursor.getString(columnIndex); + } + + // Look for the normalized number + columnIndex = cursor.getColumnIndex(PhoneLookup.NORMALIZED_NUMBER); + if (columnIndex != -1) { + info.normalizedNumber = cursor.getString(columnIndex); + } + + // Look for the label/type combo + columnIndex = cursor.getColumnIndex(PhoneLookup.LABEL); + if (columnIndex != -1) { + int typeColumnIndex = cursor.getColumnIndex(PhoneLookup.TYPE); + if (typeColumnIndex != -1) { + info.numberType = cursor.getInt(typeColumnIndex); + info.numberLabel = cursor.getString(columnIndex); + info.phoneLabel = + Phone.getTypeLabel(context.getResources(), info.numberType, info.numberLabel) + .toString(); + } + } + + // cache the lookup key for later use to create lookup URIs + columnIndex = cursor.getColumnIndex(PhoneLookup.LOOKUP_KEY); + if (columnIndex != -1) { + info.lookupKeyOrNull = cursor.getString(columnIndex); + } + + // Look for the person_id. + columnIndex = getColumnIndexForPersonId(contactRef, cursor); + if (columnIndex != -1) { + contactId = cursor.getLong(columnIndex); + // QuickContacts in M doesn't support enterprise contact id + if (contactId != 0 + && (VERSION.SDK_INT >= VERSION_CODES.N + || !Contacts.isEnterpriseContactId(contactId))) { + info.contactIdOrZero = contactId; + Log.v(TAG, "==> got info.contactIdOrZero: " + info.contactIdOrZero); + } + } else { + // No valid columnIndex, so we can't look up person_id. + Log.v(TAG, "Couldn't find contactId column for " + contactRef); + // Watch out: this means that anything that depends on + // person_id will be broken (like contact photo lookups in + // the in-call UI, for example.) + } + + // Display photo URI. + columnIndex = cursor.getColumnIndex(PhoneLookup.PHOTO_URI); + if ((columnIndex != -1) && (cursor.getString(columnIndex) != null)) { + info.contactDisplayPhotoUri = Uri.parse(cursor.getString(columnIndex)); + } else { + info.contactDisplayPhotoUri = null; + } + + // look for the custom ringtone, create from the string stored + // in the database. + columnIndex = cursor.getColumnIndex(PhoneLookup.CUSTOM_RINGTONE); + if ((columnIndex != -1) && (cursor.getString(columnIndex) != null)) { + if (TextUtils.isEmpty(cursor.getString(columnIndex))) { + // make it consistent with frameworks/base/.../CallerInfo.java + info.contactRingtoneUri = Uri.EMPTY; + } else { + info.contactRingtoneUri = Uri.parse(cursor.getString(columnIndex)); + } + } else { + info.contactRingtoneUri = null; + } + + // look for the send to voicemail flag, set it to true only + // under certain circumstances. + columnIndex = cursor.getColumnIndex(PhoneLookup.SEND_TO_VOICEMAIL); + info.shouldSendToVoicemail = (columnIndex != -1) && ((cursor.getInt(columnIndex)) == 1); + info.contactExists = true; + + // Determine userType by directoryId and contactId + final String directory = + contactRef == null + ? null + : contactRef.getQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY); + Long directoryId = null; + if (directory != null) { + try { + directoryId = Long.parseLong(directory); + } catch (NumberFormatException e) { + // do nothing + } + } + info.userType = ContactsUtils.determineUserType(directoryId, contactId); + + info.nameAlternative = + ContactInfoHelper.lookUpDisplayNameAlternative( + context, info.lookupKeyOrNull, info.userType, directoryId); } + cursor.close(); } - info.userType = ContactsUtils.determineUserType(directoryId, contactId); - info.nameAlternative = - ContactInfoHelper.lookUpDisplayNameAlternative( - context, info.lookupKeyOrNull, info.userType, directoryId); - cursor.close(); + info.needUpdate = false; + info.name = normalize(info.name); + info.contactRefUri = contactRef; return info; } @@ -510,7 +506,6 @@ public class CallerInfo { Log.e(TAG, "Cannot access VoiceMail.", se); } // TODO: There is no voicemail picture? - // photoResource = android.R.drawable.badge_voicemail; return this; } diff --git a/java/com/android/incallui/DialpadFragment.java b/java/com/android/incallui/DialpadFragment.java index 2f3a68cda..b2aacf71d 100644 --- a/java/com/android/incallui/DialpadFragment.java +++ b/java/com/android/incallui/DialpadFragment.java @@ -202,15 +202,6 @@ public class DialpadFragment extends BaseFragment<DialpadPresenter, DialpadUi> mDtmfDialerField.setText(PhoneNumberUtilsCompat.createTtsSpannable(text)); } - @Override - public void setVisible(boolean on) { - if (on) { - getView().setVisibility(View.VISIBLE); - } else { - getView().setVisibility(View.INVISIBLE); - } - } - /** Starts the slide up animation for the Dialpad keys when the Dialpad is revealed. */ public void animateShowDialpad() { final DialpadView dialpadView = (DialpadView) getView().findViewById(R.id.dialpad_view); diff --git a/java/com/android/incallui/DialpadPresenter.java b/java/com/android/incallui/DialpadPresenter.java index 7a784c279..002fefce7 100644 --- a/java/com/android/incallui/DialpadPresenter.java +++ b/java/com/android/incallui/DialpadPresenter.java @@ -84,8 +84,6 @@ public class DialpadPresenter extends Presenter<DialpadUi> public interface DialpadUi extends Ui { - void setVisible(boolean on); - void appendDigitsToField(char digit); } } diff --git a/java/com/android/incallui/InCallActivity.java b/java/com/android/incallui/InCallActivity.java index 28ff7da60..47b5986a0 100644 --- a/java/com/android/incallui/InCallActivity.java +++ b/java/com/android/incallui/InCallActivity.java @@ -35,7 +35,6 @@ import android.support.annotation.IntDef; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.VisibleForTesting; -import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.support.v4.content.res.ResourcesCompat; @@ -787,6 +786,7 @@ public class InCallActivity extends TransactionSafeFragmentActivity transaction.add(getDialpadContainerId(), new DialpadFragment(), Tags.DIALPAD_FRAGMENT); } else { transaction.show(dialpadFragment); + dialpadFragment.setUserVisibleHint(true); } transaction.commitAllowingStateLoss(); dialpadFragmentManager.executePendingTransactions(); @@ -801,19 +801,20 @@ public class InCallActivity extends TransactionSafeFragmentActivity return; } - Fragment dialpadFragment = dialpadFragmentManager.findFragmentByTag(Tags.DIALPAD_FRAGMENT); + DialpadFragment dialpadFragment = getDialpadFragment(); if (dialpadFragment != null) { FragmentTransaction transaction = dialpadFragmentManager.beginTransaction(); transaction.hide(dialpadFragment); transaction.commitAllowingStateLoss(); dialpadFragmentManager.executePendingTransactions(); + dialpadFragment.setUserVisibleHint(false); } updateNavigationBar(false /* isDialpadVisible */); } public boolean isDialpadVisible() { DialpadFragment dialpadFragment = getDialpadFragment(); - return dialpadFragment != null && dialpadFragment.isVisible(); + return dialpadFragment != null && dialpadFragment.getUserVisibleHint(); } /** Returns the {@link DialpadFragment} that's shown by this activity, or {@code null} */ |