Loading java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java +8 −14 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); Loading @@ -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); } } Loading Loading @@ -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. Loading Loading @@ -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(); } Loading @@ -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<>(); Loading java/com/android/dialer/calllog/ui/RealtimeRowProcessor.java +2 −6 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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()) { Loading @@ -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( Loading java/com/android/dialer/phonelookup/cp2/Cp2LocalPhoneLookup.java +27 −14 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); Loading @@ -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(); } Loading java/com/android/dialer/phonelookup/cp2/Cp2RemotePhoneLookup.java +2 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading java/com/android/dialer/phonenumberproto/DialerPhoneNumberUtil.java +18 −82 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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(); // Numbers can be null or empty for incoming "unknown" calls. if (numberToParse == null) { return dialerPhoneNumber.build(); } @WorkerThread private String normalizeNumber(@NonNull String rawNumber, @Nullable String defaultRegion) { Assert.isWorkerThread(); // 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(numberToParse); if (!postDialPortion.isEmpty()) { dialerPhoneNumber.setPostDialPortion(postDialPortion); } String postDialPortion = PhoneNumberUtils.extractPostDialPortion(rawNumber); String networkPortion = PhoneNumberUtils.extractNetworkPortion(rawNumber); String networkPortion = PhoneNumberUtils.extractNetworkPortion(numberToParse); try { PhoneNumber phoneNumber = phoneNumberUtil.parse(networkPortion, defaultRegion); Loading @@ -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(); } /** Loading Loading @@ -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) { Loading Loading
java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java +8 −14 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); Loading @@ -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); } } Loading Loading @@ -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. Loading Loading @@ -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(); } Loading @@ -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<>(); Loading
java/com/android/dialer/calllog/ui/RealtimeRowProcessor.java +2 −6 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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()) { Loading @@ -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( Loading
java/com/android/dialer/phonelookup/cp2/Cp2LocalPhoneLookup.java +27 −14 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); Loading @@ -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(); } Loading
java/com/android/dialer/phonelookup/cp2/Cp2RemotePhoneLookup.java +2 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading
java/com/android/dialer/phonenumberproto/DialerPhoneNumberUtil.java +18 −82 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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(); // Numbers can be null or empty for incoming "unknown" calls. if (numberToParse == null) { return dialerPhoneNumber.build(); } @WorkerThread private String normalizeNumber(@NonNull String rawNumber, @Nullable String defaultRegion) { Assert.isWorkerThread(); // 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(numberToParse); if (!postDialPortion.isEmpty()) { dialerPhoneNumber.setPostDialPortion(postDialPortion); } String postDialPortion = PhoneNumberUtils.extractPostDialPortion(rawNumber); String networkPortion = PhoneNumberUtils.extractNetworkPortion(rawNumber); String networkPortion = PhoneNumberUtils.extractNetworkPortion(numberToParse); try { PhoneNumber phoneNumber = phoneNumberUtil.parse(networkPortion, defaultRegion); Loading @@ -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(); } /** Loading Loading @@ -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) { Loading