diff options
Diffstat (limited to 'java/com/android/dialer/phonelookup')
-rw-r--r-- | java/com/android/dialer/phonelookup/PhoneLookup.java | 14 | ||||
-rw-r--r-- | java/com/android/dialer/phonelookup/PhoneLookupModule.java | 8 | ||||
-rw-r--r-- | java/com/android/dialer/phonelookup/blockednumber/DialerBlockedNumberPhoneLookup.java | 210 | ||||
-rw-r--r-- | java/com/android/dialer/phonelookup/composite/CompositePhoneLookup.java | 13 | ||||
-rw-r--r-- | java/com/android/dialer/phonelookup/cp2/Cp2PhoneLookup.java | 64 | ||||
-rw-r--r-- | java/com/android/dialer/phonelookup/phone_lookup_info.proto | 22 | ||||
-rw-r--r-- | java/com/android/dialer/phonelookup/selector/AndroidManifest.xml | 18 | ||||
-rw-r--r-- | java/com/android/dialer/phonelookup/selector/PhoneLookupSelector.java (renamed from java/com/android/dialer/phonelookup/PhoneLookupSelector.java) | 38 | ||||
-rw-r--r-- | java/com/android/dialer/phonelookup/selector/res/values/strings.xml | 22 |
9 files changed, 344 insertions, 65 deletions
diff --git a/java/com/android/dialer/phonelookup/PhoneLookup.java b/java/com/android/dialer/phonelookup/PhoneLookup.java index 859085e7b..118ae603e 100644 --- a/java/com/android/dialer/phonelookup/PhoneLookup.java +++ b/java/com/android/dialer/phonelookup/PhoneLookup.java @@ -16,6 +16,8 @@ package com.android.dialer.phonelookup; +import android.content.Context; +import android.support.annotation.MainThread; import android.support.annotation.NonNull; import android.telecom.Call; import com.android.dialer.DialerPhoneNumber; @@ -82,4 +84,16 @@ public interface PhoneLookup<T> { * be efficiently implemented. */ ListenableFuture<Void> onSuccessfulBulkUpdate(); + + @MainThread + void registerContentObservers( + Context appContext, ContentObserverCallbacks contentObserverCallbacks); + + /** + * Methods which may optionally be called as a result of a phone lookup's content observer firing. + */ + interface ContentObserverCallbacks { + @MainThread + void markDirtyAndNotify(Context appContext); + } } diff --git a/java/com/android/dialer/phonelookup/PhoneLookupModule.java b/java/com/android/dialer/phonelookup/PhoneLookupModule.java index 8a590052d..b4f37872e 100644 --- a/java/com/android/dialer/phonelookup/PhoneLookupModule.java +++ b/java/com/android/dialer/phonelookup/PhoneLookupModule.java @@ -16,6 +16,7 @@ package com.android.dialer.phonelookup; +import com.android.dialer.phonelookup.blockednumber.DialerBlockedNumberPhoneLookup; import com.android.dialer.phonelookup.composite.CompositePhoneLookup; import com.android.dialer.phonelookup.cp2.Cp2PhoneLookup; import com.google.common.collect.ImmutableList; @@ -27,8 +28,11 @@ import dagger.Provides; public abstract class PhoneLookupModule { @Provides - static ImmutableList<PhoneLookup> providePhoneLookupList(Cp2PhoneLookup cp2PhoneLookup) { - return ImmutableList.of(cp2PhoneLookup); + @SuppressWarnings({"unchecked", "rawtype"}) + static ImmutableList<PhoneLookup> providePhoneLookupList( + Cp2PhoneLookup cp2PhoneLookup, + DialerBlockedNumberPhoneLookup dialerBlockedNumberPhoneLookup) { + return ImmutableList.of(cp2PhoneLookup, dialerBlockedNumberPhoneLookup); } @Provides diff --git a/java/com/android/dialer/phonelookup/blockednumber/DialerBlockedNumberPhoneLookup.java b/java/com/android/dialer/phonelookup/blockednumber/DialerBlockedNumberPhoneLookup.java new file mode 100644 index 000000000..54df3995c --- /dev/null +++ b/java/com/android/dialer/phonelookup/blockednumber/DialerBlockedNumberPhoneLookup.java @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.dialer.phonelookup.blockednumber; + +import android.content.Context; +import android.database.ContentObserver; +import android.database.Cursor; +import android.net.Uri; +import android.support.annotation.MainThread; +import android.support.annotation.NonNull; +import android.support.annotation.WorkerThread; +import android.telecom.Call; +import android.util.ArraySet; +import com.android.dialer.DialerPhoneNumber; +import com.android.dialer.common.Assert; +import com.android.dialer.common.LogUtil; +import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor; +import com.android.dialer.common.database.Selection; +import com.android.dialer.database.FilteredNumberContract.FilteredNumber; +import com.android.dialer.database.FilteredNumberContract.FilteredNumberColumns; +import com.android.dialer.database.FilteredNumberContract.FilteredNumberTypes; +import com.android.dialer.inject.ApplicationContext; +import com.android.dialer.phonelookup.PhoneLookup; +import com.android.dialer.phonelookup.PhoneLookupInfo; +import com.android.dialer.phonelookup.PhoneLookupInfo.BlockedState; +import com.android.dialer.phonelookup.PhoneLookupInfo.DialerBlockedNumberInfo; +import com.android.dialer.phonenumberproto.DialerPhoneNumberUtil; +import com.android.dialer.phonenumberproto.PartitionedNumbers; +import com.android.dialer.telecom.TelecomCallUtil; +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.Set; +import javax.inject.Inject; + +/** + * Lookup blocked numbers in the dialer internal database. This is used when the system database is + * not yet available. + */ +public final class DialerBlockedNumberPhoneLookup implements PhoneLookup<DialerBlockedNumberInfo> { + + private final Context appContext; + private final ListeningExecutorService executorService; + + @Inject + DialerBlockedNumberPhoneLookup( + @ApplicationContext Context appContext, + @BackgroundExecutor ListeningExecutorService executorService) { + this.appContext = appContext; + this.executorService = executorService; + } + + @Override + public ListenableFuture<DialerBlockedNumberInfo> lookup(@NonNull Call call) { + return executorService.submit( + () -> { + DialerPhoneNumberUtil dialerPhoneNumberUtil = + new DialerPhoneNumberUtil(PhoneNumberUtil.getInstance()); + + DialerPhoneNumber number = + dialerPhoneNumberUtil.parse( + TelecomCallUtil.getNumber(call), + TelecomCallUtil.getCountryCode(appContext, call).orNull()); + return queryNumbers(ImmutableSet.of(number)).get(number); + }); + } + + @Override + public ListenableFuture<Boolean> isDirty(ImmutableSet<DialerPhoneNumber> phoneNumbers) { + // Dirty state is recorded with PhoneLookupDataSource.markDirtyAndNotify(), which will force + // rebuild with the CallLogFramework + return Futures.immediateFuture(false); + } + + @Override + public ListenableFuture<ImmutableMap<DialerPhoneNumber, DialerBlockedNumberInfo>> + getMostRecentInfo(ImmutableMap<DialerPhoneNumber, DialerBlockedNumberInfo> existingInfoMap) { + LogUtil.enterBlock("DialerBlockedNumberPhoneLookup.getMostRecentPhoneLookupInfo"); + return executorService.submit(() -> queryNumbers(existingInfoMap.keySet())); + } + + @Override + public void setSubMessage( + PhoneLookupInfo.Builder phoneLookupInfo, DialerBlockedNumberInfo subMessage) { + phoneLookupInfo.setDialerBlockedNumberInfo(subMessage); + } + + @Override + public DialerBlockedNumberInfo getSubMessage(PhoneLookupInfo phoneLookupInfo) { + return phoneLookupInfo.getDialerBlockedNumberInfo(); + } + + @Override + public ListenableFuture<Void> onSuccessfulBulkUpdate() { + return Futures.immediateFuture(null); + } + + @WorkerThread + private ImmutableMap<DialerPhoneNumber, DialerBlockedNumberInfo> queryNumbers( + ImmutableSet<DialerPhoneNumber> numbers) { + Assert.isWorkerThread(); + PartitionedNumbers partitionedNumbers = new PartitionedNumbers(numbers); + + Set<DialerPhoneNumber> blockedNumbers = new ArraySet<>(); + + Selection normalizedSelection = + Selection.column(FilteredNumberColumns.NORMALIZED_NUMBER) + .in(partitionedNumbers.validE164Numbers()); + try (Cursor cursor = + appContext + .getContentResolver() + .query( + FilteredNumber.CONTENT_URI, + new String[] {FilteredNumberColumns.NORMALIZED_NUMBER, FilteredNumberColumns.TYPE}, + normalizedSelection.getSelection(), + normalizedSelection.getSelectionArgs(), + null)) { + while (cursor != null && cursor.moveToNext()) { + if (cursor.getInt(1) == FilteredNumberTypes.BLOCKED_NUMBER) { + blockedNumbers.addAll(partitionedNumbers.dialerPhoneNumbersForE164(cursor.getString(0))); + } + } + } + + Selection rawSelection = + Selection.column(FilteredNumberColumns.NUMBER) + .in( + partitionedNumbers + .unformattableNumbers() + .toArray(new String[partitionedNumbers.unformattableNumbers().size()])); + try (Cursor cursor = + appContext + .getContentResolver() + .query( + FilteredNumber.CONTENT_URI, + new String[] {FilteredNumberColumns.NUMBER, FilteredNumberColumns.TYPE}, + rawSelection.getSelection(), + rawSelection.getSelectionArgs(), + null)) { + while (cursor != null && cursor.moveToNext()) { + if (cursor.getInt(1) == FilteredNumberTypes.BLOCKED_NUMBER) { + blockedNumbers.addAll( + partitionedNumbers.dialerPhoneNumbersForUnformattable(cursor.getString(0))); + } + } + } + + ImmutableMap.Builder<DialerPhoneNumber, DialerBlockedNumberInfo> result = + ImmutableMap.builder(); + + for (DialerPhoneNumber number : numbers) { + result.put( + number, + DialerBlockedNumberInfo.newBuilder() + .setBlockedState( + blockedNumbers.contains(number) ? BlockedState.BLOCKED : BlockedState.NOT_BLOCKED) + .build()); + } + + return result.build(); + } + + @Override + public void registerContentObservers( + Context appContext, ContentObserverCallbacks contentObserverCallbacks) { + appContext + .getContentResolver() + .registerContentObserver( + FilteredNumber.CONTENT_URI, + true, // FilteredNumberProvider notifies on the item + new FilteredNumberObserver(appContext, contentObserverCallbacks)); + } + + private static class FilteredNumberObserver extends ContentObserver { + private final Context appContext; + private final ContentObserverCallbacks contentObserverCallbacks; + + FilteredNumberObserver(Context appContext, ContentObserverCallbacks contentObserverCallbacks) { + super(null); + this.appContext = appContext; + this.contentObserverCallbacks = contentObserverCallbacks; + } + + @MainThread + @Override + @SuppressWarnings("FutureReturnValueIgnored") // never throws. + public void onChange(boolean selfChange, Uri uri) { + Assert.isMainThread(); + LogUtil.enterBlock("DialerBlockedNumberPhoneLookup.FilteredNumberObserver.onChange"); + contentObserverCallbacks.markDirtyAndNotify(appContext); + } + } +} diff --git a/java/com/android/dialer/phonelookup/composite/CompositePhoneLookup.java b/java/com/android/dialer/phonelookup/composite/CompositePhoneLookup.java index da4378bb7..34f35311f 100644 --- a/java/com/android/dialer/phonelookup/composite/CompositePhoneLookup.java +++ b/java/com/android/dialer/phonelookup/composite/CompositePhoneLookup.java @@ -16,6 +16,8 @@ package com.android.dialer.phonelookup.composite; +import android.content.Context; +import android.support.annotation.MainThread; import android.support.annotation.NonNull; import android.telecom.Call; import com.android.dialer.DialerPhoneNumber; @@ -60,7 +62,7 @@ public final class CompositePhoneLookup implements PhoneLookup<PhoneLookupInfo> * <p>Note: If any of the dependent lookups fails, the returned future will also fail. If any of * the dependent lookups does not complete, the returned future will also not complete. */ - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "rawtype"}) @Override public ListenableFuture<PhoneLookupInfo> lookup(@NonNull Call call) { // TODO(zachh): Add short-circuiting logic so that this call is not blocked on low-priority @@ -164,4 +166,13 @@ public final class CompositePhoneLookup implements PhoneLookup<PhoneLookupInfo> return Futures.transform( Futures.allAsList(futures), unused -> null, lightweightExecutorService); } + + @Override + @MainThread + public void registerContentObservers( + Context appContext, ContentObserverCallbacks contentObserverCallbacks) { + for (PhoneLookup phoneLookup : phoneLookups) { + phoneLookup.registerContentObservers(appContext, contentObserverCallbacks); + } + } } diff --git a/java/com/android/dialer/phonelookup/cp2/Cp2PhoneLookup.java b/java/com/android/dialer/phonelookup/cp2/Cp2PhoneLookup.java index 60c934ace..307e0a434 100644 --- a/java/com/android/dialer/phonelookup/cp2/Cp2PhoneLookup.java +++ b/java/com/android/dialer/phonelookup/cp2/Cp2PhoneLookup.java @@ -37,7 +37,7 @@ 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.android.dialer.telecom.TelecomCallUtil; import com.google.common.base.Optional; @@ -45,7 +45,6 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; 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.Map; import java.util.Map.Entry; @@ -392,6 +391,12 @@ public final class Cp2PhoneLookup implements PhoneLookup<Cp2Info> { }); } + @Override + public void registerContentObservers( + Context appContext, ContentObserverCallbacks contentObserverCallbacks) { + // Do nothing since CP2 changes are too noisy. + } + /** * 1. get all contact ids. if the id is unset, add the number to the list of contacts to look up. * 2. reduce our list of contact ids to those that were updated after lastModified. 3. Now we have @@ -475,7 +480,8 @@ public final class Cp2PhoneLookup implements PhoneLookup<Cp2Info> { // Divide the numbers into those we can format to E164 and those we can't. Then run separate // queries against the contacts table using the NORMALIZED_NUMBER and NUMBER columns. // TODO(zachh): These queries are inefficient without a lastModified column to filter on. - PartitionedNumbers partitionedNumbers = new PartitionedNumbers(updatedNumbers); + PartitionedNumbers partitionedNumbers = + new PartitionedNumbers(ImmutableSet.copyOf(updatedNumbers)); if (!partitionedNumbers.validE164Numbers().isEmpty()) { try (Cursor cursor = queryPhoneTableBasedOnE164(CP2_INFO_PROJECTION, partitionedNumbers.validE164Numbers())) { @@ -701,56 +707,4 @@ public final class Cp2PhoneLookup implements PhoneLookup<Cp2Info> { } return where.toString(); } - - /** - * Divides a set of {@link DialerPhoneNumber DialerPhoneNumbers} by those that can be formatted to - * E164 and those that cannot. - */ - private static class PartitionedNumbers { - private Map<String, Set<DialerPhoneNumber>> e164NumbersToDialerPhoneNumbers = new ArrayMap<>(); - private Map<String, Set<DialerPhoneNumber>> unformattableNumbersToDialerPhoneNumbers = - new ArrayMap<>(); - - PartitionedNumbers(Set<DialerPhoneNumber> dialerPhoneNumbers) { - DialerPhoneNumberUtil dialerPhoneNumberUtil = - new DialerPhoneNumberUtil(PhoneNumberUtil.getInstance()); - for (DialerPhoneNumber dialerPhoneNumber : dialerPhoneNumbers) { - Optional<String> e164 = dialerPhoneNumberUtil.formatToE164(dialerPhoneNumber); - if (e164.isPresent()) { - String validE164 = e164.get(); - Set<DialerPhoneNumber> currentNumbers = e164NumbersToDialerPhoneNumbers.get(validE164); - if (currentNumbers == null) { - currentNumbers = new ArraySet<>(); - e164NumbersToDialerPhoneNumbers.put(validE164, currentNumbers); - } - currentNumbers.add(dialerPhoneNumber); - } else { - String unformattableNumber = dialerPhoneNumber.getRawInput().getNumber(); - Set<DialerPhoneNumber> currentNumbers = - unformattableNumbersToDialerPhoneNumbers.get(unformattableNumber); - if (currentNumbers == null) { - currentNumbers = new ArraySet<>(); - unformattableNumbersToDialerPhoneNumbers.put(unformattableNumber, currentNumbers); - } - currentNumbers.add(dialerPhoneNumber); - } - } - } - - Set<String> unformattableNumbers() { - return unformattableNumbersToDialerPhoneNumbers.keySet(); - } - - Set<String> validE164Numbers() { - return e164NumbersToDialerPhoneNumbers.keySet(); - } - - Set<DialerPhoneNumber> dialerPhoneNumbersForE164(String e164) { - return e164NumbersToDialerPhoneNumbers.get(e164); - } - - Set<DialerPhoneNumber> dialerPhoneNumbersForUnformattable(String unformattableNumber) { - return unformattableNumbersToDialerPhoneNumbers.get(unformattableNumber); - } - } } diff --git a/java/com/android/dialer/phonelookup/phone_lookup_info.proto b/java/com/android/dialer/phonelookup/phone_lookup_info.proto index c42faf49d..75423b9ee 100644 --- a/java/com/android/dialer/phonelookup/phone_lookup_info.proto +++ b/java/com/android/dialer/phonelookup/phone_lookup_info.proto @@ -83,4 +83,26 @@ message PhoneLookupInfo { optional InfoType info_type = 6; } optional PeopleApiInfo people_api_info = 3; + + // Whether a number is blocked or not. Used by both the system blacklist and + // dialer fallback + enum BlockedState { + UNKNOWN = 0; + BLOCKED = 1; + NOT_BLOCKED = 2; + } + + // Message for the android system BlockedNumber lookup. Available starting in + // N. + message SystemBlockedNumberInfo { + optional BlockedState blocked_state = 1; + } + optional SystemBlockedNumberInfo system_blocked_number_info = 4; + + // Message for the dialer fallback for blocked number. Used in M or when the + // migration to the system has not been completed. + message DialerBlockedNumberInfo { + optional BlockedState blocked_state = 1; + } + optional DialerBlockedNumberInfo dialer_blocked_number_info = 5; }
\ No newline at end of file diff --git a/java/com/android/dialer/phonelookup/selector/AndroidManifest.xml b/java/com/android/dialer/phonelookup/selector/AndroidManifest.xml new file mode 100644 index 000000000..5d836c791 --- /dev/null +++ b/java/com/android/dialer/phonelookup/selector/AndroidManifest.xml @@ -0,0 +1,18 @@ +<!-- + ~ Copyright (C) 2018 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> +<manifest + package="com.android.dialer.phonelookup.selector"> +</manifest> diff --git a/java/com/android/dialer/phonelookup/PhoneLookupSelector.java b/java/com/android/dialer/phonelookup/selector/PhoneLookupSelector.java index c933af728..a960d4e96 100644 --- a/java/com/android/dialer/phonelookup/PhoneLookupSelector.java +++ b/java/com/android/dialer/phonelookup/selector/PhoneLookupSelector.java @@ -13,13 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License */ -package com.android.dialer.phonelookup; +package com.android.dialer.phonelookup.selector; +import android.content.Context; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.annotation.VisibleForTesting; +import com.android.dialer.inject.ApplicationContext; +import com.android.dialer.phonelookup.PhoneLookup; +import com.android.dialer.phonelookup.PhoneLookupInfo; +import com.android.dialer.phonelookup.PhoneLookupInfo.BlockedState; import com.android.dialer.phonelookup.PhoneLookupInfo.Cp2Info.Cp2ContactInfo; import com.android.dialer.phonelookup.PhoneLookupInfo.PeopleApiInfo; import com.android.dialer.phonelookup.PhoneLookupInfo.PeopleApiInfo.InfoType; +import javax.inject.Inject; /** * Prioritizes information from a {@link PhoneLookupInfo}. @@ -35,12 +42,20 @@ import com.android.dialer.phonelookup.PhoneLookupInfo.PeopleApiInfo.InfoType; */ public final class PhoneLookupSelector { + private final Context appContext; + + @Inject + @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) + public PhoneLookupSelector(@ApplicationContext Context appContext) { + this.appContext = appContext; + } + /** * Select the name associated with this number. Examples of this are a local contact's name or a * business name received from caller ID. */ @NonNull - public static String selectName(PhoneLookupInfo phoneLookupInfo) { + public String selectName(PhoneLookupInfo phoneLookupInfo) { Cp2ContactInfo firstLocalContact = firstLocalContact(phoneLookupInfo); if (firstLocalContact != null) { String name = firstLocalContact.getName(); @@ -56,7 +71,7 @@ public final class PhoneLookupSelector { /** Select the photo URI associated with this number. */ @NonNull - public static String selectPhotoUri(PhoneLookupInfo phoneLookupInfo) { + public String selectPhotoUri(PhoneLookupInfo phoneLookupInfo) { Cp2ContactInfo firstLocalContact = firstLocalContact(phoneLookupInfo); if (firstLocalContact != null) { String photoUri = firstLocalContact.getPhotoUri(); @@ -68,7 +83,7 @@ public final class PhoneLookupSelector { } /** Select the photo ID associated with this number, or 0 if there is none. */ - public static long selectPhotoId(PhoneLookupInfo phoneLookupInfo) { + public long selectPhotoId(PhoneLookupInfo phoneLookupInfo) { Cp2ContactInfo firstLocalContact = firstLocalContact(phoneLookupInfo); if (firstLocalContact != null) { long photoId = firstLocalContact.getPhotoId(); @@ -81,7 +96,7 @@ public final class PhoneLookupSelector { /** Select the lookup URI associated with this number. */ @NonNull - public static String selectLookupUri(PhoneLookupInfo phoneLookupInfo) { + public String selectLookupUri(PhoneLookupInfo phoneLookupInfo) { Cp2ContactInfo firstLocalContact = firstLocalContact(phoneLookupInfo); if (firstLocalContact != null) { String lookupUri = firstLocalContact.getLookupUri(); @@ -97,7 +112,11 @@ public final class PhoneLookupSelector { * set by the user. */ @NonNull - public static String selectNumberLabel(PhoneLookupInfo phoneLookupInfo) { + public String selectNumberLabel(PhoneLookupInfo phoneLookupInfo) { + if (isBlocked(phoneLookupInfo)) { + return appContext.getString(R.string.blocked_number_new_call_log_label); + } + Cp2ContactInfo firstLocalContact = firstLocalContact(phoneLookupInfo); if (firstLocalContact != null) { String label = firstLocalContact.getLabel(); @@ -135,10 +154,15 @@ public final class PhoneLookupSelector { * show a synthesized photo containing photos of both "Mom" and "Dad"). */ @Nullable - private static Cp2ContactInfo firstLocalContact(PhoneLookupInfo phoneLookupInfo) { + private Cp2ContactInfo firstLocalContact(PhoneLookupInfo phoneLookupInfo) { if (phoneLookupInfo.getCp2Info().getCp2ContactInfoCount() > 0) { return phoneLookupInfo.getCp2Info().getCp2ContactInfo(0); } return null; } + + private static boolean isBlocked(PhoneLookupInfo info) { + return info.hasDialerBlockedNumberInfo() + && info.getDialerBlockedNumberInfo().getBlockedState().equals(BlockedState.BLOCKED); + } } diff --git a/java/com/android/dialer/phonelookup/selector/res/values/strings.xml b/java/com/android/dialer/phonelookup/selector/res/values/strings.xml new file mode 100644 index 000000000..2080b3975 --- /dev/null +++ b/java/com/android/dialer/phonelookup/selector/res/values/strings.xml @@ -0,0 +1,22 @@ +<!-- + ~ Copyright (C) 2018 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> + +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + + <!-- Label under the name of a blocked number in the call log. [CHAR LIMIT=15] --> + <string name="blocked_number_new_call_log_label">Blocked</string> + +</resources> |