summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzachh <zachh@google.com>2018-01-29 13:45:58 -0800
committerCopybara-Service <copybara-piper@google.com>2018-01-29 15:36:05 -0800
commit75a8d5170399b37d33bced7825a9f6d88a5ec233 (patch)
tree35a7e6ae0b6dbdae5ba84388a55853af78ac875f
parentadd7d143419d8ada612eb3e0bb2807b0e97dff35 (diff)
Added is_valid and post_dial_portion fields to DialerPhoneNumber.
These are frequently used attributes of numbers that we can compute once at parse-time. Also did some general cleanup of DialerPhoneNumberUtil: -Removed unused Future version of parse() -Remove formatToValidE164 now that the new fields are available -Inlined normalizeNumber() Bug: 72563861 Test: existing PiperOrigin-RevId: 183720128 Change-Id: I702dc265360e590439c5352c493ae8a858f36812
-rw-r--r--java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java22
-rw-r--r--java/com/android/dialer/calllog/ui/RealtimeRowProcessor.java8
-rw-r--r--java/com/android/dialer/phonelookup/cp2/Cp2LocalPhoneLookup.java41
-rw-r--r--java/com/android/dialer/phonelookup/cp2/Cp2RemotePhoneLookup.java7
-rw-r--r--java/com/android/dialer/phonenumberproto/DialerPhoneNumberUtil.java100
-rw-r--r--java/com/android/dialer/phonenumberproto/PartitionedNumbers.java35
-rw-r--r--java/com/android/dialer/phonenumberproto/dialer_phone_number.proto16
7 files changed, 87 insertions, 142 deletions
diff --git a/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java b/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java
index 565a2a333..8fa6b67cc 100644
--- a/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java
+++ b/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java
@@ -42,14 +42,12 @@ import com.android.dialer.phonelookup.PhoneLookupInfo;
import com.android.dialer.phonelookup.consolidator.PhoneLookupInfoConsolidator;
import com.android.dialer.phonelookup.database.contract.PhoneLookupHistoryContract;
import com.android.dialer.phonelookup.database.contract.PhoneLookupHistoryContract.PhoneLookupHistory;
-import com.android.dialer.phonenumberproto.DialerPhoneNumberUtil;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.protobuf.InvalidProtocolBufferException;
import java.util.ArrayList;
import java.util.Arrays;
@@ -192,11 +190,8 @@ public final class PhoneLookupDataSource
populateInserts(originalPhoneLookupHistoryDataByAnnotatedCallLogId.build(), mutations);
// Compute and save the PhoneLookupHistory rows which can be deleted in onSuccessfulFill.
- DialerPhoneNumberUtil dialerPhoneNumberUtil =
- new DialerPhoneNumberUtil(PhoneNumberUtil.getInstance());
phoneLookupHistoryRowsToDelete.addAll(
- computePhoneLookupHistoryRowsToDelete(
- annotatedCallLogIdsByNumber, mutations, dialerPhoneNumberUtil));
+ computePhoneLookupHistoryRowsToDelete(annotatedCallLogIdsByNumber, mutations));
// Now compute the rows to update.
ImmutableMap.Builder<Long, PhoneLookupInfo> rowsToUpdate = ImmutableMap.builder();
@@ -209,7 +204,8 @@ public final class PhoneLookupDataSource
}
// Also save the updated information so that it can be written to PhoneLookupHistory
// in onSuccessfulFill.
- String normalizedNumber = dialerPhoneNumberUtil.normalizeNumber(dialerPhoneNumber);
+ // Note: This loses country info when number is not valid.
+ String normalizedNumber = dialerPhoneNumber.getNormalizedNumber();
phoneLookupHistoryRowsToUpdate.put(normalizedNumber, upToDateInfo);
}
}
@@ -417,10 +413,9 @@ public final class PhoneLookupDataSource
/** Returned map must have same keys as {@code uniqueDialerPhoneNumbers} */
private ImmutableMap<DialerPhoneNumber, PhoneLookupInfo> queryPhoneLookupHistoryForNumbers(
Context appContext, Set<DialerPhoneNumber> uniqueDialerPhoneNumbers) {
- DialerPhoneNumberUtil dialerPhoneNumberUtil =
- new DialerPhoneNumberUtil(PhoneNumberUtil.getInstance());
+ // Note: This loses country info when number is not valid.
Map<DialerPhoneNumber, String> dialerPhoneNumberToNormalizedNumbers =
- Maps.asMap(uniqueDialerPhoneNumbers, dialerPhoneNumberUtil::normalizeNumber);
+ Maps.asMap(uniqueDialerPhoneNumbers, DialerPhoneNumber::getNormalizedNumber);
// Convert values to a set to remove any duplicates that are the result of two
// DialerPhoneNumbers mapping to the same normalized number.
@@ -543,9 +538,7 @@ public final class PhoneLookupDataSource
}
private Set<String> computePhoneLookupHistoryRowsToDelete(
- Map<DialerPhoneNumber, Set<Long>> annotatedCallLogIdsByNumber,
- CallLogMutations mutations,
- DialerPhoneNumberUtil dialerPhoneNumberUtil) {
+ Map<DialerPhoneNumber, Set<Long>> annotatedCallLogIdsByNumber, CallLogMutations mutations) {
if (mutations.getDeletes().isEmpty()) {
return ImmutableSet.of();
}
@@ -555,7 +548,8 @@ public final class PhoneLookupDataSource
for (Entry<DialerPhoneNumber, Set<Long>> entry : annotatedCallLogIdsByNumber.entrySet()) {
DialerPhoneNumber dialerPhoneNumber = entry.getKey();
Set<Long> idsForDialerPhoneNumber = entry.getValue();
- String normalizedNumber = dialerPhoneNumberUtil.normalizeNumber(dialerPhoneNumber);
+ // Note: This loses country info when number is not valid.
+ String normalizedNumber = dialerPhoneNumber.getNormalizedNumber();
Set<Long> idsForNormalizedNumber = idsByNormalizedNumber.get(normalizedNumber);
if (idsForNormalizedNumber == null) {
idsForNormalizedNumber = new ArraySet<>();
diff --git a/java/com/android/dialer/calllog/ui/RealtimeRowProcessor.java b/java/com/android/dialer/calllog/ui/RealtimeRowProcessor.java
index f15c3136c..421c35f55 100644
--- a/java/com/android/dialer/calllog/ui/RealtimeRowProcessor.java
+++ b/java/com/android/dialer/calllog/ui/RealtimeRowProcessor.java
@@ -36,13 +36,11 @@ import com.android.dialer.phonelookup.PhoneLookupInfo;
import com.android.dialer.phonelookup.consolidator.PhoneLookupInfoConsolidator;
import com.android.dialer.phonelookup.database.contract.PhoneLookupHistoryContract;
import com.android.dialer.phonelookup.database.contract.PhoneLookupHistoryContract.PhoneLookupHistory;
-import com.android.dialer.phonenumberproto.DialerPhoneNumberUtil;
import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.i18n.phonenumbers.PhoneNumberUtil;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -151,9 +149,6 @@ public final class RealtimeRowProcessor {
ListenableFuture<Integer> applyBatchFuture =
backgroundExecutor.submit(
() -> {
- DialerPhoneNumberUtil dialerPhoneNumberUtil =
- new DialerPhoneNumberUtil(PhoneNumberUtil.getInstance());
-
ArrayList<ContentProviderOperation> operations = new ArrayList<>();
long currentTimestamp = System.currentTimeMillis();
for (Entry<DialerPhoneNumber, PhoneLookupInfo> entry : currentBatch.entrySet()) {
@@ -162,7 +157,8 @@ public final class RealtimeRowProcessor {
// Note: Multiple DialerPhoneNumbers can map to the same normalized number but we
// just write them all and the value for the last one will arbitrarily win.
- String normalizedNumber = dialerPhoneNumberUtil.normalizeNumber(dialerPhoneNumber);
+ // Note: This loses country info when number is not valid.
+ String normalizedNumber = dialerPhoneNumber.getNormalizedNumber();
ContentValues contentValues = new ContentValues();
contentValues.put(
diff --git a/java/com/android/dialer/phonelookup/cp2/Cp2LocalPhoneLookup.java b/java/com/android/dialer/phonelookup/cp2/Cp2LocalPhoneLookup.java
index 127569b9f..95b14a41d 100644
--- a/java/com/android/dialer/phonelookup/cp2/Cp2LocalPhoneLookup.java
+++ b/java/com/android/dialer/phonelookup/cp2/Cp2LocalPhoneLookup.java
@@ -39,18 +39,16 @@ import com.android.dialer.phonelookup.PhoneLookupInfo;
import com.android.dialer.phonelookup.PhoneLookupInfo.Cp2Info;
import com.android.dialer.phonelookup.PhoneLookupInfo.Cp2Info.Cp2ContactInfo;
import com.android.dialer.phonelookup.database.contract.PhoneLookupHistoryContract.PhoneLookupHistory;
-import com.android.dialer.phonenumberproto.DialerPhoneNumberUtil;
import com.android.dialer.phonenumberproto.PartitionedNumbers;
import com.android.dialer.storage.Unencrypted;
-import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
-import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.protobuf.InvalidProtocolBufferException;
import java.util.ArrayList;
import java.util.List;
@@ -96,21 +94,32 @@ public final class Cp2LocalPhoneLookup implements PhoneLookup<Cp2Info> {
}
private Cp2Info lookupInternal(DialerPhoneNumber dialerPhoneNumber) {
- DialerPhoneNumberUtil dialerPhoneNumberUtil =
- new DialerPhoneNumberUtil(PhoneNumberUtil.getInstance());
- String number = dialerPhoneNumberUtil.normalizeNumber(dialerPhoneNumber);
+ String number = dialerPhoneNumber.getNormalizedNumber();
if (TextUtils.isEmpty(number)) {
return Cp2Info.getDefaultInstance();
}
- Optional<String> validE164 = dialerPhoneNumberUtil.formatToValidE164(dialerPhoneNumber);
+
Set<Cp2ContactInfo> cp2ContactInfos = new ArraySet<>();
- // Note: It would make sense to use PHONE_LOOKUP for E164 numbers as well, but we use PHONE to
- // ensure consistency when the batch methods are used to update data.
- try (Cursor cursor =
- validE164.isPresent()
- ? queryPhoneTableBasedOnE164(
- Cp2Projections.getProjectionForPhoneTable(), ImmutableSet.of(validE164.get()))
- : queryPhoneLookup(Cp2Projections.getProjectionForPhoneLookupTable(), number)) {
+
+ // Even though this is only a single number, use PartitionedNumbers to mimic the logic used
+ // during getMostRecentInfo.
+ PartitionedNumbers partitionedNumbers =
+ new PartitionedNumbers(ImmutableSet.of(dialerPhoneNumber));
+
+ Cursor cursor = null;
+ try {
+ // Note: It would make sense to use PHONE_LOOKUP for valid numbers as well, but we use PHONE
+ // to ensure consistency when the batch methods are used to update data.
+ if (!partitionedNumbers.validE164Numbers().isEmpty()) {
+ cursor =
+ queryPhoneTableBasedOnE164(
+ Cp2Projections.getProjectionForPhoneTable(), partitionedNumbers.validE164Numbers());
+ } else {
+ cursor =
+ queryPhoneLookup(
+ Cp2Projections.getProjectionForPhoneLookupTable(),
+ Iterables.getOnlyElement(partitionedNumbers.invalidNumbers()));
+ }
if (cursor == null) {
LogUtil.w("Cp2LocalPhoneLookup.lookupInternal", "null cursor");
return Cp2Info.getDefaultInstance();
@@ -118,6 +127,10 @@ public final class Cp2LocalPhoneLookup implements PhoneLookup<Cp2Info> {
while (cursor.moveToNext()) {
cp2ContactInfos.add(Cp2Projections.buildCp2ContactInfoFromCursor(appContext, cursor));
}
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
}
return Cp2Info.newBuilder().addAllCp2ContactInfo(cp2ContactInfos).build();
}
diff --git a/java/com/android/dialer/phonelookup/cp2/Cp2RemotePhoneLookup.java b/java/com/android/dialer/phonelookup/cp2/Cp2RemotePhoneLookup.java
index 9596f15f7..cc4fbf19f 100644
--- a/java/com/android/dialer/phonelookup/cp2/Cp2RemotePhoneLookup.java
+++ b/java/com/android/dialer/phonelookup/cp2/Cp2RemotePhoneLookup.java
@@ -32,14 +32,12 @@ import com.android.dialer.inject.ApplicationContext;
import com.android.dialer.phonelookup.PhoneLookup;
import com.android.dialer.phonelookup.PhoneLookupInfo;
import com.android.dialer.phonelookup.PhoneLookupInfo.Cp2Info;
-import com.android.dialer.phonenumberproto.DialerPhoneNumberUtil;
import com.android.dialer.phonenumberutil.PhoneNumberHelper;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.i18n.phonenumbers.PhoneNumberUtil;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
@@ -114,9 +112,8 @@ public final class Cp2RemotePhoneLookup implements PhoneLookup<Cp2Info> {
return Futures.immediateFuture(Cp2Info.getDefaultInstance());
}
- DialerPhoneNumberUtil dialerPhoneNumberUtil =
- new DialerPhoneNumberUtil(PhoneNumberUtil.getInstance());
- String number = dialerPhoneNumberUtil.normalizeNumber(dialerPhoneNumber);
+ // Note: This loses country info when number is not valid.
+ String number = dialerPhoneNumber.getNormalizedNumber();
List<ListenableFuture<Cp2Info>> cp2InfoFutures = new ArrayList<>();
for (long remoteDirectoryId : remoteDirectoryIds) {
diff --git a/java/com/android/dialer/phonenumberproto/DialerPhoneNumberUtil.java b/java/com/android/dialer/phonenumberproto/DialerPhoneNumberUtil.java
index 319467ccc..a5b9520fd 100644
--- a/java/com/android/dialer/phonenumberproto/DialerPhoneNumberUtil.java
+++ b/java/com/android/dialer/phonenumberproto/DialerPhoneNumberUtil.java
@@ -16,7 +16,6 @@
package com.android.dialer.phonenumberproto;
-import android.support.annotation.AnyThread;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.WorkerThread;
@@ -25,9 +24,6 @@ import android.text.TextUtils;
import com.android.dialer.DialerPhoneNumber;
import com.android.dialer.common.Assert;
import com.android.dialer.common.LogUtil;
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.i18n.phonenumbers.NumberParseException;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.PhoneNumberUtil.MatchType;
@@ -59,58 +55,30 @@ public class DialerPhoneNumberUtil {
Assert.isWorkerThread();
DialerPhoneNumber.Builder dialerPhoneNumber = DialerPhoneNumber.newBuilder();
- // Numbers can be null or empty for incoming "unknown" calls.
- if (numberToParse != null) {
- dialerPhoneNumber.setNormalizedNumber(normalizeNumber(numberToParse, defaultRegion));
- }
+
if (defaultRegion != null) {
dialerPhoneNumber.setCountryIso(defaultRegion);
}
- return dialerPhoneNumber.build();
- }
-
- /**
- * Parses the provided raw phone number into a Future result of {@link DialerPhoneNumber}.
- *
- * <p>Work is run on the provided {@link ListeningExecutorService}.
- *
- * @see PhoneNumberUtil#parse(CharSequence, String)
- */
- @AnyThread
- public ListenableFuture<DialerPhoneNumber> parse(
- @Nullable String numberToParse,
- @Nullable String defaultRegion,
- @NonNull ListeningExecutorService service) {
- return service.submit(() -> parse(numberToParse, defaultRegion));
- }
- /**
- * Formats the provided number to E164 format or return a normalized version of the raw number if
- * the number is not valid according to {@link PhoneNumberUtil#isValidNumber(PhoneNumber)}.
- *
- * @see #formatToValidE164(DialerPhoneNumber)
- * @see PhoneNumberUtils#normalizeNumber(String)
- */
- public String normalizeNumber(DialerPhoneNumber number) {
- // TODO(zachh): Inline this method.
- // TODO(zachh): This loses country info when number is not valid.
- return number.getNormalizedNumber();
- }
-
- @WorkerThread
- private String normalizeNumber(@NonNull String rawNumber, @Nullable String defaultRegion) {
- Assert.isWorkerThread();
+ // Numbers can be null or empty for incoming "unknown" calls.
+ if (numberToParse == null) {
+ return dialerPhoneNumber.build();
+ }
// If the number is a service number, just store the raw number and don't bother trying to parse
// it. PhoneNumberUtil#parse ignores these characters which can lead to confusing behavior, such
// as the numbers "#123" and "123" being considered the same. The "#" can appear in the middle
// of a service number and the "*" can appear at the beginning (see a bug).
- if (isServiceNumber(rawNumber)) {
- return rawNumber;
+ if (isServiceNumber(numberToParse)) {
+ return dialerPhoneNumber.setNormalizedNumber(numberToParse).build();
}
- String postDialPortion = PhoneNumberUtils.extractPostDialPortion(rawNumber);
- String networkPortion = PhoneNumberUtils.extractNetworkPortion(rawNumber);
+ String postDialPortion = PhoneNumberUtils.extractPostDialPortion(numberToParse);
+ if (!postDialPortion.isEmpty()) {
+ dialerPhoneNumber.setPostDialPortion(postDialPortion);
+ }
+
+ String networkPortion = PhoneNumberUtils.extractNetworkPortion(numberToParse);
try {
PhoneNumber phoneNumber = phoneNumberUtil.parse(networkPortion, defaultRegion);
@@ -118,18 +86,18 @@ public class DialerPhoneNumberUtil {
String validNumber = phoneNumberUtil.format(phoneNumber, PhoneNumberFormat.E164);
if (TextUtils.isEmpty(validNumber)) {
throw new IllegalStateException(
- "e164 number should not be empty: " + LogUtil.sanitizePii(rawNumber));
+ "e164 number should not be empty: " + LogUtil.sanitizePii(numberToParse));
}
// The E164 representation doesn't contain post-dial digits, but we need to preserve them.
- if (postDialPortion != null) {
+ if (!postDialPortion.isEmpty()) {
validNumber += postDialPortion;
}
- return validNumber;
+ return dialerPhoneNumber.setNormalizedNumber(validNumber).setIsValid(true).build();
}
} catch (NumberParseException e) {
// fall through
}
- return networkPortion + postDialPortion;
+ return dialerPhoneNumber.setNormalizedNumber(networkPortion + postDialPortion).build();
}
/**
@@ -197,39 +165,7 @@ public class DialerPhoneNumberUtil {
return (matchType == MatchType.SHORT_NSN_MATCH
|| matchType == MatchType.NSN_MATCH
|| matchType == MatchType.EXACT_MATCH)
- && samePostDialPortion(firstNumberIn, secondNumberIn);
- }
-
- private static boolean samePostDialPortion(DialerPhoneNumber number1, DialerPhoneNumber number2) {
- return PhoneNumberUtils.extractPostDialPortion(number1.getNormalizedNumber())
- .equals(PhoneNumberUtils.extractPostDialPortion(number2.getNormalizedNumber()));
- }
-
- /**
- * If the provided number is "valid" (see {@link PhoneNumberUtil#isValidNumber(PhoneNumber)}),
- * formats it to E.164. Otherwise, returns {@link Optional#absent()}.
- *
- * <p>This method is analogous to {@link PhoneNumberUtils#formatNumberToE164(String, String)} (but
- * works with an already parsed {@link DialerPhoneNumber} object).
- *
- * @see PhoneNumberUtil#isValidNumber(PhoneNumber)
- * @see PhoneNumberUtil#format(PhoneNumber, PhoneNumberFormat)
- * @see PhoneNumberUtils#formatNumberToE164(String, String)
- */
- @WorkerThread
- public Optional<String> formatToValidE164(DialerPhoneNumber number) {
- // TODO(zachh): We could do something like store a "valid" bit in DialerPhoneNumber?
- Assert.isWorkerThread();
- PhoneNumber phoneNumber;
- try {
- phoneNumber = phoneNumberUtil.parse(number.getNormalizedNumber(), number.getCountryIso());
- } catch (NumberParseException e) {
- return Optional.absent();
- }
- if (phoneNumberUtil.isValidNumber(phoneNumber)) {
- return Optional.fromNullable(phoneNumberUtil.format(phoneNumber, PhoneNumberFormat.E164));
- }
- return Optional.absent();
+ && firstNumberIn.getPostDialPortion().equals(secondNumberIn.getPostDialPortion());
}
private boolean isServiceNumber(@NonNull String rawNumber) {
diff --git a/java/com/android/dialer/phonenumberproto/PartitionedNumbers.java b/java/com/android/dialer/phonenumberproto/PartitionedNumbers.java
index dbf99365c..2c19c1232 100644
--- a/java/com/android/dialer/phonenumberproto/PartitionedNumbers.java
+++ b/java/com/android/dialer/phonenumberproto/PartitionedNumbers.java
@@ -20,19 +20,19 @@ 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;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
-import com.google.i18n.phonenumbers.PhoneNumberUtil;
import java.util.Map;
import java.util.Set;
/**
* Divides a set of {@link DialerPhoneNumber DialerPhoneNumbers} according to those that are valid
* according to libphonenumber, and those that are not.
+ *
+ * <p>Numbers with post-dial portions are always considered invalid as most systems store E164
+ * numbers which do not support post-dial portions.
*/
public final class PartitionedNumbers {
private final ImmutableMap<String, ImmutableSet<DialerPhoneNumber>>
@@ -40,29 +40,27 @@ public final class PartitionedNumbers {
private final ImmutableMap<String, ImmutableSet<DialerPhoneNumber>>
invalidNumbersToDialerPhoneNumbers;
+ /**
+ * Divides a set of {@link DialerPhoneNumber DialerPhoneNumbers} according to those that are valid
+ * according to libphonenumber, and those that are not.
+ *
+ * <p>Numbers with post-dial portions are always considered invalid as most systems store E164
+ * numbers which do not support post-dial portions.
+ */
@WorkerThread
public PartitionedNumbers(@NonNull ImmutableSet<DialerPhoneNumber> dialerPhoneNumbers) {
Assert.isWorkerThread();
- DialerPhoneNumberUtil dialerPhoneNumberUtil =
- new DialerPhoneNumberUtil(PhoneNumberUtil.getInstance());
Map<String, Set<DialerPhoneNumber>> e164MapBuilder = new ArrayMap<>();
Map<String, Set<DialerPhoneNumber>> invalidMapBuilder = new ArrayMap<>();
for (DialerPhoneNumber dialerPhoneNumber : dialerPhoneNumbers) {
- Optional<String> optValidE164 = dialerPhoneNumberUtil.formatToValidE164(dialerPhoneNumber);
/*
* 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.
+ * post dial digits are lost in the process. For example, the normalized version of a number
+ * with a post-dial portion in the contacts database is stored without the post-dial portion.
*/
- if (optValidE164.isPresent() && !hasPostDialDigits(dialerPhoneNumber)) {
- String validE164 = optValidE164.get();
+ if (dialerPhoneNumber.getIsValid() && dialerPhoneNumber.getPostDialPortion().isEmpty()) {
+ String validE164 = dialerPhoneNumber.getNormalizedNumber();
Set<DialerPhoneNumber> currentNumbers = e164MapBuilder.get(validE164);
if (currentNumbers == null) {
currentNumbers = new ArraySet<>();
@@ -84,11 +82,6 @@ public final class PartitionedNumbers {
invalidNumbersToDialerPhoneNumbers = makeImmutable(invalidMapBuilder);
}
- private boolean hasPostDialDigits(DialerPhoneNumber dialerPhoneNumber) {
- return !PhoneNumberUtils.extractPostDialPortion(dialerPhoneNumber.getNormalizedNumber())
- .isEmpty();
- }
-
/** Returns the set of invalid numbers from the original DialerPhoneNumbers */
@NonNull
public ImmutableSet<String> invalidNumbers() {
diff --git a/java/com/android/dialer/phonenumberproto/dialer_phone_number.proto b/java/com/android/dialer/phonenumberproto/dialer_phone_number.proto
index 941de0428..ad8a8f9fa 100644
--- a/java/com/android/dialer/phonenumberproto/dialer_phone_number.proto
+++ b/java/com/android/dialer/phonenumberproto/dialer_phone_number.proto
@@ -40,6 +40,11 @@ message DialerPhoneNumber {
// number is a 7-digit US number (missing an area code) like "456-7890" which
// would be stored as "4567890".
//
+ // Note: Using this field without country_iso effectively loses country info
+ // when the number is not valid and no country prefix was prepended. This may
+ // cause numbers like {"456-7890", "US"} to be treated equivalently to
+ // {"456-7890", "DE"}, when they are not in fact equivalent.
+ //
// See DialerPhoneNumberUtil#parse.
optional string normalized_number = 1;
@@ -47,4 +52,15 @@ message DialerPhoneNumber {
// CallLog.Calls#COUNTRY: "The ISO 3166-1 two letters country code of the
// country where the user received or made the call."
optional string country_iso = 2;
+
+ // True if the number is valid according to libphonenumber.
+ optional bool is_valid = 3;
+
+ // The post dial portion of the number as described by
+ // PhoneNumberUtils#extractPostDialPortion. Note that this is also part of
+ // normalized_number, but this information is duplicated here for convenience.
+ //
+ // This includes pause and wait characters, but strips other characters, so
+ // for example would be ",123;456" given the raw input of "456-7890,123; 456".
+ optional string post_dial_portion = 4;
}