From 17b8bd14b9cf67b7353f9287045fdc10fd1e93fb Mon Sep 17 00:00:00 2001 From: zachh Date: Fri, 19 Jan 2018 10:54:19 -0800 Subject: Improved support for post dial digits in new call log. -Don't ever coalesce rows with different post-dial digits -Made matching of unparsable numbers a little more intelligent by comparing national/postdial portions which have undialable characters removed (rather than exact string match) -Read and append the post-dial digits from the system call log when building DialerPhoneNumbers to place in the AnnotatedCallLog. Note: PhoneNumberUtil will parse numbers with exactly one post-dial character, but not more than one. -Use post-dial digits when building the AnnotatedCallLog's FORMATTED_NUMBER value -Display the formatted number in CallDetails when the name is missing, instead of the unformatted number -Don't set the displayNumber in CallDetails when the name is missing, because we are showing the (formatted) number via the nameOrNumber field. -Treat numbers with post-dial digits as invalid in PartitionedNumbers; batch operations are not possible with these numbers because their normalized representations strip the post-dial digits (and they are significant for contact matching) Bug: 70989632 Test: unit and manual PiperOrigin-RevId: 182557754 Change-Id: Idcdefce0946a189e5b350a53ec2a16a96a8d4552 --- .../phonenumberproto/DialerPhoneNumberUtil.java | 43 ++++++++++++++++++---- .../phonenumberproto/PartitionedNumbers.java | 19 +++++++++- 2 files changed, 54 insertions(+), 8 deletions(-) (limited to 'java/com/android/dialer/phonenumberproto') diff --git a/java/com/android/dialer/phonenumberproto/DialerPhoneNumberUtil.java b/java/com/android/dialer/phonenumberproto/DialerPhoneNumberUtil.java index d37f7fa1d..4e7d30031 100644 --- a/java/com/android/dialer/phonenumberproto/DialerPhoneNumberUtil.java +++ b/java/com/android/dialer/phonenumberproto/DialerPhoneNumberUtil.java @@ -103,9 +103,19 @@ public class DialerPhoneNumberUtil { } /** - * Returns true if the two numbers were parseable by libphonenumber and are a {@link - * MatchType#SHORT_NSN_MATCH} or {@link MatchType#NSN_MATCH} or {@link MatchType#EXACT_MATCH} or - * if they have the same raw input. + * Returns true if the two numbers: + * + * + * + *

If either number is not parseable, returns true if their raw inputs have the same network + * and post-dial portions. + * + *

An empty number is never considered to match another number. * * @see PhoneNumberUtil#isNumberMatch(PhoneNumber, PhoneNumber) */ @@ -115,15 +125,34 @@ public class DialerPhoneNumberUtil { Assert.isWorkerThread(); if (!Assert.isNotNull(firstNumberIn).hasDialerInternalPhoneNumber() || !Assert.isNotNull(secondNumberIn).hasDialerInternalPhoneNumber()) { - return firstNumberIn.getRawInput().equals(secondNumberIn.getRawInput()); + // An empty number should not be combined with any other number. + if (firstNumberIn.getRawInput().getNumber().isEmpty() + || secondNumberIn.getRawInput().getNumber().isEmpty()) { + return false; + } + // Both the network and post-dial portions of the number should match. + return sameNetworkPortion(firstNumberIn, secondNumberIn) + && samePostDialPortion(firstNumberIn, secondNumberIn); } MatchType matchType = isNumberMatch( firstNumberIn.getDialerInternalPhoneNumber(), secondNumberIn.getDialerInternalPhoneNumber()); - return matchType == MatchType.SHORT_NSN_MATCH - || matchType == MatchType.NSN_MATCH - || matchType == MatchType.EXACT_MATCH; + + return (matchType == MatchType.SHORT_NSN_MATCH + || matchType == MatchType.NSN_MATCH + || matchType == MatchType.EXACT_MATCH) + && samePostDialPortion(firstNumberIn, secondNumberIn); + } + + private static boolean sameNetworkPortion(DialerPhoneNumber number1, DialerPhoneNumber number2) { + return PhoneNumberUtils.extractNetworkPortion(number1.getRawInput().getNumber()) + .equals(PhoneNumberUtils.extractNetworkPortion(number2.getRawInput().getNumber())); + } + + private static boolean samePostDialPortion(DialerPhoneNumber number1, DialerPhoneNumber number2) { + return PhoneNumberUtils.extractPostDialPortion(number1.getRawInput().getNumber()) + .equals(PhoneNumberUtils.extractPostDialPortion(number2.getRawInput().getNumber())); } /** diff --git a/java/com/android/dialer/phonenumberproto/PartitionedNumbers.java b/java/com/android/dialer/phonenumberproto/PartitionedNumbers.java index 4c8ac2f21..0a4aafaf7 100644 --- a/java/com/android/dialer/phonenumberproto/PartitionedNumbers.java +++ b/java/com/android/dialer/phonenumberproto/PartitionedNumbers.java @@ -20,6 +20,7 @@ import android.support.annotation.NonNull; import android.support.annotation.WorkerThread; import android.support.v4.util.ArrayMap; import android.support.v4.util.ArraySet; +import android.telephony.PhoneNumberUtils; import com.android.dialer.DialerPhoneNumber; import com.android.dialer.common.Assert; import com.google.common.base.Optional; @@ -49,7 +50,18 @@ public final class PartitionedNumbers { for (DialerPhoneNumber dialerPhoneNumber : dialerPhoneNumbers) { Optional optValidE164 = dialerPhoneNumberUtil.formatToValidE164(dialerPhoneNumber); - if (optValidE164.isPresent()) { + /* + * Numbers with post-dial digits are considered valid and can be converted to E164, but their + * post dial digits are lost in the process. Similarly, if a contact's number has a post-dial + * digits, the normalized version of it stored in the contacts database does not include the + * post dial digits. + * + * A number with post-dial digits should not match a contact whose number does not have + * post-dial digits, which means that we cannot normalize such numbers for use in bulk lookup. + * Treat them as invalid which will cause them to be processed individually using + * ContactsContract.PHONE_LOOKUP. + */ + if (optValidE164.isPresent() && !hasPostDialDigits(dialerPhoneNumber)) { String validE164 = optValidE164.get(); Set currentNumbers = e164MapBuilder.get(validE164); if (currentNumbers == null) { @@ -72,6 +84,11 @@ public final class PartitionedNumbers { invalidNumbersToDialerPhoneNumbers = makeImmutable(invalidMapBuilder); } + private boolean hasPostDialDigits(DialerPhoneNumber dialerPhoneNumber) { + return !PhoneNumberUtils.extractPostDialPortion(dialerPhoneNumber.getRawInput().getNumber()) + .isEmpty(); + } + /** Returns the set of invalid numbers from the original DialerPhoneNumbers */ @NonNull public ImmutableSet invalidNumbers() { -- cgit v1.2.3