diff options
Diffstat (limited to 'java/com/android/dialer/phonelookup')
5 files changed, 260 insertions, 37 deletions
diff --git a/java/com/android/dialer/phonelookup/PhoneLookupModule.java b/java/com/android/dialer/phonelookup/PhoneLookupModule.java index e93ca0f77..8a78ba038 100644 --- a/java/com/android/dialer/phonelookup/PhoneLookupModule.java +++ b/java/com/android/dialer/phonelookup/PhoneLookupModule.java @@ -17,6 +17,7 @@ package com.android.dialer.phonelookup; import com.android.dialer.phonelookup.blockednumber.DialerBlockedNumberPhoneLookup; +import com.android.dialer.phonelookup.blockednumber.SystemBlockedNumberPhoneLookup; import com.android.dialer.phonelookup.composite.CompositePhoneLookup; import com.android.dialer.phonelookup.cp2.Cp2LocalPhoneLookup; import com.android.dialer.phonelookup.cp2.Cp2RemotePhoneLookup; @@ -33,9 +34,13 @@ public abstract class PhoneLookupModule { static ImmutableList<PhoneLookup> providePhoneLookupList( Cp2LocalPhoneLookup cp2LocalPhoneLookup, Cp2RemotePhoneLookup cp2RemotePhoneLookup, - DialerBlockedNumberPhoneLookup dialerBlockedNumberPhoneLookup) { + DialerBlockedNumberPhoneLookup dialerBlockedNumberPhoneLookup, + SystemBlockedNumberPhoneLookup systemBlockedNumberPhoneLookup) { return ImmutableList.of( - cp2LocalPhoneLookup, cp2RemotePhoneLookup, dialerBlockedNumberPhoneLookup); + cp2LocalPhoneLookup, + cp2RemotePhoneLookup, + dialerBlockedNumberPhoneLookup, + systemBlockedNumberPhoneLookup); } @Provides diff --git a/java/com/android/dialer/phonelookup/blockednumber/DialerBlockedNumberPhoneLookup.java b/java/com/android/dialer/phonelookup/blockednumber/DialerBlockedNumberPhoneLookup.java index ce1217751..2271c7580 100644 --- a/java/com/android/dialer/phonelookup/blockednumber/DialerBlockedNumberPhoneLookup.java +++ b/java/com/android/dialer/phonelookup/blockednumber/DialerBlockedNumberPhoneLookup.java @@ -17,17 +17,14 @@ 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.WorkerThread; import android.util.ArraySet; import com.android.dialer.DialerPhoneNumber; +import com.android.dialer.blocking.FilteredNumberCompat; 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.concurrent.ThreadUtil; import com.android.dialer.common.database.Selection; import com.android.dialer.database.FilteredNumberContract.FilteredNumber; import com.android.dialer.database.FilteredNumberContract.FilteredNumberColumns; @@ -65,6 +62,9 @@ public final class DialerBlockedNumberPhoneLookup implements PhoneLookup<DialerB @Override public ListenableFuture<DialerBlockedNumberInfo> lookup(DialerPhoneNumber dialerPhoneNumber) { + if (FilteredNumberCompat.useNewFiltering(appContext)) { + return Futures.immediateFuture(DialerBlockedNumberInfo.getDefaultInstance()); + } return executorService.submit( () -> queryNumbers(ImmutableSet.of(dialerPhoneNumber)).get(dialerPhoneNumber)); } @@ -79,6 +79,9 @@ public final class DialerBlockedNumberPhoneLookup implements PhoneLookup<DialerB @Override public ListenableFuture<ImmutableMap<DialerPhoneNumber, DialerBlockedNumberInfo>> getMostRecentInfo(ImmutableMap<DialerPhoneNumber, DialerBlockedNumberInfo> existingInfoMap) { + if (FilteredNumberCompat.useNewFiltering(appContext)) { + return Futures.immediateFuture(existingInfoMap); + } LogUtil.enterBlock("DialerBlockedNumberPhoneLookup.getMostRecentPhoneLookupInfo"); return executorService.submit(() -> queryNumbers(existingInfoMap.keySet())); } @@ -128,11 +131,7 @@ public final class DialerBlockedNumberPhoneLookup implements PhoneLookup<DialerB } Selection rawSelection = - Selection.column(FilteredNumberColumns.NUMBER) - .in( - partitionedNumbers - .invalidNumbers() - .toArray(new String[partitionedNumbers.invalidNumbers().size()])); + Selection.column(FilteredNumberColumns.NUMBER).in(partitionedNumbers.invalidNumbers()); try (Cursor cursor = appContext .getContentResolver() @@ -173,26 +172,6 @@ public final class DialerBlockedNumberPhoneLookup implements PhoneLookup<DialerB .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(ThreadUtil.getUiThreadHandler()); - 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); - } + new MarkDirtyObserver(appContext, contentObserverCallbacks)); } } diff --git a/java/com/android/dialer/phonelookup/blockednumber/MarkDirtyObserver.java b/java/com/android/dialer/phonelookup/blockednumber/MarkDirtyObserver.java new file mode 100644 index 000000000..1c41d8f7f --- /dev/null +++ b/java/com/android/dialer/phonelookup/blockednumber/MarkDirtyObserver.java @@ -0,0 +1,47 @@ +/* + * 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.net.Uri; +import android.support.annotation.MainThread; +import com.android.dialer.common.Assert; +import com.android.dialer.common.LogUtil; +import com.android.dialer.common.concurrent.ThreadUtil; +import com.android.dialer.phonelookup.PhoneLookup.ContentObserverCallbacks; + +/** Calls {@link ContentObserverCallbacks#markDirtyAndNotify(Context)} when the content changed */ +class MarkDirtyObserver extends ContentObserver { + + private final Context appContext; + private final ContentObserverCallbacks contentObserverCallbacks; + + MarkDirtyObserver(Context appContext, ContentObserverCallbacks contentObserverCallbacks) { + super(ThreadUtil.getUiThreadHandler()); + this.appContext = appContext; + this.contentObserverCallbacks = contentObserverCallbacks; + } + + @MainThread + @Override + public void onChange(boolean selfChange, Uri uri) { + Assert.isMainThread(); + LogUtil.enterBlock("SystemBlockedNumberPhoneLookup.FilteredNumberObserver.onChange"); + contentObserverCallbacks.markDirtyAndNotify(appContext); + } +} diff --git a/java/com/android/dialer/phonelookup/blockednumber/SystemBlockedNumberPhoneLookup.java b/java/com/android/dialer/phonelookup/blockednumber/SystemBlockedNumberPhoneLookup.java new file mode 100644 index 000000000..e0ff995e7 --- /dev/null +++ b/java/com/android/dialer/phonelookup/blockednumber/SystemBlockedNumberPhoneLookup.java @@ -0,0 +1,181 @@ +/* + * 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.annotation.TargetApi; +import android.content.Context; +import android.database.Cursor; +import android.os.Build.VERSION; +import android.os.Build.VERSION_CODES; +import android.provider.BlockedNumberContract.BlockedNumbers; +import android.support.annotation.NonNull; +import android.support.annotation.WorkerThread; +import android.util.ArraySet; +import com.android.dialer.DialerPhoneNumber; +import com.android.dialer.blocking.FilteredNumberCompat; +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.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.Builder; +import com.android.dialer.phonelookup.PhoneLookupInfo.SystemBlockedNumberInfo; +import com.android.dialer.phonenumberproto.PartitionedNumbers; +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 java.util.Set; +import javax.inject.Inject; + +/** + * Lookup blocked numbers in the system database. Requires N+ and migration from dialer database + * completed (need user consent to move data into system). + */ +public class SystemBlockedNumberPhoneLookup implements PhoneLookup<SystemBlockedNumberInfo> { + + private final Context appContext; + private final ListeningExecutorService executorService; + + @Inject + SystemBlockedNumberPhoneLookup( + @ApplicationContext Context appContext, + @BackgroundExecutor ListeningExecutorService executorService) { + this.appContext = appContext; + this.executorService = executorService; + } + + @Override + public ListenableFuture<SystemBlockedNumberInfo> lookup(@NonNull DialerPhoneNumber number) { + if (!FilteredNumberCompat.useNewFiltering(appContext)) { + return Futures.immediateFuture(SystemBlockedNumberInfo.getDefaultInstance()); + } + return executorService.submit( + () -> { + 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, SystemBlockedNumberInfo>> + getMostRecentInfo(ImmutableMap<DialerPhoneNumber, SystemBlockedNumberInfo> existingInfoMap) { + LogUtil.enterBlock("SystemBlockedNumberPhoneLookup.getMostRecentPhoneLookupInfo"); + if (!FilteredNumberCompat.useNewFiltering(appContext)) { + return Futures.immediateFuture(existingInfoMap); + } + return executorService.submit(() -> queryNumbers(existingInfoMap.keySet())); + } + + @WorkerThread + @TargetApi(VERSION_CODES.N) + private ImmutableMap<DialerPhoneNumber, SystemBlockedNumberInfo> queryNumbers( + ImmutableSet<DialerPhoneNumber> numbers) { + Assert.isWorkerThread(); + PartitionedNumbers partitionedNumbers = new PartitionedNumbers(numbers); + + Set<DialerPhoneNumber> blockedNumbers = new ArraySet<>(); + + Selection normalizedSelection = + Selection.column(BlockedNumbers.COLUMN_E164_NUMBER) + .in(partitionedNumbers.validE164Numbers()); + try (Cursor cursor = + appContext + .getContentResolver() + .query( + BlockedNumbers.CONTENT_URI, + new String[] {BlockedNumbers.COLUMN_E164_NUMBER}, + normalizedSelection.getSelection(), + normalizedSelection.getSelectionArgs(), + null)) { + while (cursor != null && cursor.moveToNext()) { + blockedNumbers.addAll( + partitionedNumbers.dialerPhoneNumbersForValidE164(cursor.getString(0))); + } + } + + Selection rawSelection = + Selection.column(BlockedNumbers.COLUMN_ORIGINAL_NUMBER) + .in(partitionedNumbers.invalidNumbers()); + try (Cursor cursor = + appContext + .getContentResolver() + .query( + BlockedNumbers.CONTENT_URI, + new String[] {BlockedNumbers.COLUMN_ORIGINAL_NUMBER}, + rawSelection.getSelection(), + rawSelection.getSelectionArgs(), + null)) { + while (cursor != null && cursor.moveToNext()) { + blockedNumbers.addAll(partitionedNumbers.dialerPhoneNumbersForInvalid(cursor.getString(0))); + } + } + + ImmutableMap.Builder<DialerPhoneNumber, SystemBlockedNumberInfo> result = + ImmutableMap.builder(); + + for (DialerPhoneNumber number : numbers) { + result.put( + number, + SystemBlockedNumberInfo.newBuilder() + .setBlockedState( + blockedNumbers.contains(number) ? BlockedState.BLOCKED : BlockedState.NOT_BLOCKED) + .build()); + } + + return result.build(); + } + + @Override + public void setSubMessage(Builder phoneLookupInfo, SystemBlockedNumberInfo subMessage) { + phoneLookupInfo.setSystemBlockedNumberInfo(subMessage); + } + + @Override + public SystemBlockedNumberInfo getSubMessage(PhoneLookupInfo phoneLookupInfo) { + return phoneLookupInfo.getSystemBlockedNumberInfo(); + } + + @Override + public ListenableFuture<Void> onSuccessfulBulkUpdate() { + return Futures.immediateFuture(null); + } + + @Override + public void registerContentObservers( + Context appContext, ContentObserverCallbacks contentObserverCallbacks) { + if (VERSION.SDK_INT < VERSION_CODES.N) { + return; + } + appContext + .getContentResolver() + .registerContentObserver( + BlockedNumbers.CONTENT_URI, + true, // BlockedNumbers notifies on the item + new MarkDirtyObserver(appContext, contentObserverCallbacks)); + } +} diff --git a/java/com/android/dialer/phonelookup/consolidator/PhoneLookupInfoConsolidator.java b/java/com/android/dialer/phonelookup/consolidator/PhoneLookupInfoConsolidator.java index ccad3e7bc..27f0d21ae 100644 --- a/java/com/android/dialer/phonelookup/consolidator/PhoneLookupInfoConsolidator.java +++ b/java/com/android/dialer/phonelookup/consolidator/PhoneLookupInfoConsolidator.java @@ -179,11 +179,7 @@ public final class PhoneLookupInfoConsolidator { * returned. */ public String getNumberLabel() { - if (phoneLookupInfo.hasDialerBlockedNumberInfo() - && phoneLookupInfo - .getDialerBlockedNumberInfo() - .getBlockedState() - .equals(BlockedState.BLOCKED)) { + if (isBlocked()) { return appContext.getString(R.string.blocked_number_new_call_log_label); } @@ -219,6 +215,21 @@ public final class PhoneLookupInfoConsolidator { return false; } + public boolean isBlocked() { + // If system blocking reported blocked state it always takes priority over the dialer blocking. + // It will be absent if dialer blocking should be used. + if (phoneLookupInfo.getSystemBlockedNumberInfo().hasBlockedState()) { + return phoneLookupInfo + .getSystemBlockedNumberInfo() + .getBlockedState() + .equals(BlockedState.BLOCKED); + } + return phoneLookupInfo + .getDialerBlockedNumberInfo() + .getBlockedState() + .equals(BlockedState.BLOCKED); + } + /** * Returns true if the {@link PhoneLookupInfo} passed to the constructor has incomplete CP2 local * info. |