summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortwyen <twyen@google.com>2018-01-22 16:08:08 -0800
committerCopybara-Service <copybara-piper@google.com>2018-01-22 16:12:39 -0800
commit0e00f578d641440c5ddc4da48ab86eabbc21d403 (patch)
tree9ae99486deaf71b55a3f2a635ff95581d703c90b
parenta2c2d5c65ec2aad3ba198ab645e01f51331c8e83 (diff)
Implement System blocked number
This CL implements looking up blocked number in the Android system blocked number provider, which is available after N. Dialer and system blocked number will return empty if requirements are not made (N+ and migration completed is needed for system, otherwise dialer should not be used). Bug: 70989543 Test: Unit tests PiperOrigin-RevId: 182852672 Change-Id: I1360b7eed7c18f459292d769529ffcfceb61a7ed
-rw-r--r--java/com/android/dialer/phonelookup/PhoneLookupModule.java9
-rw-r--r--java/com/android/dialer/phonelookup/blockednumber/DialerBlockedNumberPhoneLookup.java39
-rw-r--r--java/com/android/dialer/phonelookup/blockednumber/MarkDirtyObserver.java47
-rw-r--r--java/com/android/dialer/phonelookup/blockednumber/SystemBlockedNumberPhoneLookup.java181
-rw-r--r--java/com/android/dialer/phonelookup/consolidator/PhoneLookupInfoConsolidator.java21
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.