From 49c5dcd4e6f09f3931a7df808db5562eb92ed14d Mon Sep 17 00:00:00 2001 From: twyen Date: Fri, 30 Mar 2018 10:56:48 -0700 Subject: Implement new blocking Old blocking is deprecated. Bug: 70989544 Test: TAP PiperOrigin-RevId: 191086875 Change-Id: Icde4963fce603fc4e16e486b78c070bd439e26e4 --- .../dialer/blocking/BlockNumberDialogFragment.java | 1 + .../blocking/BlockedNumbersAutoMigrator.java | 1 + .../dialer/blocking/BlockedNumbersMigrator.java | 1 + java/com/android/dialer/blocking/Blocking.java | 117 ++++++++++++++++ .../blocking/FilteredNumberAsyncQueryHandler.java | 1 + .../dialer/blocking/FilteredNumberCompat.java | 1 + .../dialer/blocking/FilteredNumberProvider.java | 1 + .../dialer/blocking/FilteredNumbersUtil.java | 1 + .../MigrateBlockedNumbersDialogFragment.java | 1 + .../ShowBlockReportSpamDialogReceiver.java | 151 ++++++++------------- .../dialer/blockreportspam/res/values/strings.xml | 5 + .../dialer/commandline/CommandLineModule.java | 14 +- .../android/dialer/commandline/impl/Blocking.java | 96 ------------- .../dialer/commandline/impl/BlockingCommand.java | 111 +++++++++++++++ .../android/dialer/logging/dialer_impression.proto | 10 +- 15 files changed, 317 insertions(+), 195 deletions(-) create mode 100644 java/com/android/dialer/blocking/Blocking.java delete mode 100644 java/com/android/dialer/commandline/impl/Blocking.java create mode 100644 java/com/android/dialer/commandline/impl/BlockingCommand.java diff --git a/java/com/android/dialer/blocking/BlockNumberDialogFragment.java b/java/com/android/dialer/blocking/BlockNumberDialogFragment.java index 621287f6c..de974cbec 100644 --- a/java/com/android/dialer/blocking/BlockNumberDialogFragment.java +++ b/java/com/android/dialer/blocking/BlockNumberDialogFragment.java @@ -41,6 +41,7 @@ import com.android.dialer.voicemailstatus.VisualVoicemailEnabledChecker; * Fragment for confirming and enacting blocking/unblocking a number. Also invokes snackbar * providing undo functionality. */ +@Deprecated public class BlockNumberDialogFragment extends DialogFragment { private static final String BLOCK_DIALOG_FRAGMENT = "BlockNumberDialog"; diff --git a/java/com/android/dialer/blocking/BlockedNumbersAutoMigrator.java b/java/com/android/dialer/blocking/BlockedNumbersAutoMigrator.java index 6e9fe1315..8a57f29e7 100644 --- a/java/com/android/dialer/blocking/BlockedNumbersAutoMigrator.java +++ b/java/com/android/dialer/blocking/BlockedNumbersAutoMigrator.java @@ -33,6 +33,7 @@ import com.android.dialer.common.concurrent.DialerExecutorFactory; * android.provider.BlockedNumberContract} blocking. In order for this to happen, the user cannot * have any numbers that are blocked in the Dialer solution. */ +@Deprecated public class BlockedNumbersAutoMigrator { static final String HAS_CHECKED_AUTO_MIGRATE_KEY = "checkedAutoMigrate"; diff --git a/java/com/android/dialer/blocking/BlockedNumbersMigrator.java b/java/com/android/dialer/blocking/BlockedNumbersMigrator.java index 61ebf2f56..101a04b2f 100644 --- a/java/com/android/dialer/blocking/BlockedNumbersMigrator.java +++ b/java/com/android/dialer/blocking/BlockedNumbersMigrator.java @@ -36,6 +36,7 @@ import java.util.Objects; * {@link android.provider.BlockedNumberContract} blocking. */ @TargetApi(VERSION_CODES.N) +@Deprecated public class BlockedNumbersMigrator { private final Context context; diff --git a/java/com/android/dialer/blocking/Blocking.java b/java/com/android/dialer/blocking/Blocking.java new file mode 100644 index 000000000..e86d0a6ac --- /dev/null +++ b/java/com/android/dialer/blocking/Blocking.java @@ -0,0 +1,117 @@ +/* + * 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.blocking; + +import android.content.ContentValues; +import android.content.Context; +import android.provider.BlockedNumberContract.BlockedNumbers; +import android.support.annotation.Nullable; +import android.telephony.PhoneNumberUtils; +import com.android.dialer.common.database.Selection; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; + +/** Blocks and unblocks number. */ +public final class Blocking { + + private Blocking() {} + + /** + * Thrown when blocking cannot be performed because dialer is not the default dialer, or the + * current user is not a primary user. + * + *

Blocking is only allowed on the primary user (the first user added). Primary user cannot be + * easily checked because {@link + * android.provider.BlockedNumberContract#canCurrentUserBlockNumbers(Context)} is a slow IPC, and + * UserManager.isPrimaryUser() is a system API. Since secondary users are rare cases this class + * choose to ignore the check and let callers handle the failure later. + */ + public static final class BlockingFailedException extends Exception { + BlockingFailedException(Throwable cause) { + super(cause); + } + } + + /** + * Block a number. + * + * @param countryIso the current location used to guess the country code of the number if not + * available. If {@code null} and {@code number} does not have a country code, only the + * original number will be blocked. + * @throws BlockingFailedException in the returned future if the operation failed. + */ + public static ListenableFuture block( + Context context, + ListeningExecutorService executorService, + String number, + @Nullable String countryIso) { + return executorService.submit( + () -> { + ContentValues values = new ContentValues(); + values.put(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, number); + String e164Number = PhoneNumberUtils.formatNumberToE164(number, countryIso); + if (e164Number != null) { + values.put(BlockedNumbers.COLUMN_E164_NUMBER, e164Number); + } + try { + context.getContentResolver().insert(BlockedNumbers.CONTENT_URI, values); + } catch (SecurityException e) { + throw new BlockingFailedException(e); + } + return null; + }); + } + + /** + * Unblock a number. + * + * @param countryIso the current location used to guess the country code of the number if not + * available. If {@code null} and {@code number} does not have a country code, only the + * original number will be unblocked. + * @throws BlockingFailedException in the returned future if the operation failed. + */ + public static ListenableFuture unblock( + Context context, + ListeningExecutorService executorService, + String number, + @Nullable String countryIso) { + return executorService.submit( + () -> { + Selection selection = + Selection.column(BlockedNumbers.COLUMN_ORIGINAL_NUMBER).is("=", number); + String e164Number = PhoneNumberUtils.formatNumberToE164(number, countryIso); + if (e164Number != null) { + selection = + selection + .buildUpon() + .or(Selection.column(BlockedNumbers.COLUMN_E164_NUMBER).is("=", e164Number)) + .build(); + } + try { + context + .getContentResolver() + .delete( + BlockedNumbers.CONTENT_URI, + selection.getSelection(), + selection.getSelectionArgs()); + } catch (SecurityException e) { + throw new BlockingFailedException(e); + } + return null; + }); + } +} diff --git a/java/com/android/dialer/blocking/FilteredNumberAsyncQueryHandler.java b/java/com/android/dialer/blocking/FilteredNumberAsyncQueryHandler.java index 8be479c99..b41759259 100644 --- a/java/com/android/dialer/blocking/FilteredNumberAsyncQueryHandler.java +++ b/java/com/android/dialer/blocking/FilteredNumberAsyncQueryHandler.java @@ -38,6 +38,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** TODO(calderwoodra): documentation */ +@Deprecated public class FilteredNumberAsyncQueryHandler extends AsyncQueryHandler { public static final int INVALID_ID = -1; diff --git a/java/com/android/dialer/blocking/FilteredNumberCompat.java b/java/com/android/dialer/blocking/FilteredNumberCompat.java index b0af45c97..d263d212c 100644 --- a/java/com/android/dialer/blocking/FilteredNumberCompat.java +++ b/java/com/android/dialer/blocking/FilteredNumberCompat.java @@ -48,6 +48,7 @@ import java.util.Objects; * referencing columns from either contract class in situations where both blocking solutions may be * used. */ +@Deprecated public class FilteredNumberCompat { private static Boolean canAttemptBlockOperationsForTest; diff --git a/java/com/android/dialer/blocking/FilteredNumberProvider.java b/java/com/android/dialer/blocking/FilteredNumberProvider.java index 3fad4e24f..547892b41 100644 --- a/java/com/android/dialer/blocking/FilteredNumberProvider.java +++ b/java/com/android/dialer/blocking/FilteredNumberProvider.java @@ -34,6 +34,7 @@ import com.android.dialer.database.FilteredNumberContract.FilteredNumberColumns; import com.android.dialer.location.GeoUtil; /** Filtered number content provider. */ +@Deprecated public class FilteredNumberProvider extends ContentProvider { private static final int FILTERED_NUMBERS_TABLE = 1; diff --git a/java/com/android/dialer/blocking/FilteredNumbersUtil.java b/java/com/android/dialer/blocking/FilteredNumbersUtil.java index 6433355fd..d839ef5da 100644 --- a/java/com/android/dialer/blocking/FilteredNumbersUtil.java +++ b/java/com/android/dialer/blocking/FilteredNumbersUtil.java @@ -42,6 +42,7 @@ import com.android.dialer.util.PermissionsUtil; import java.util.concurrent.TimeUnit; /** Utility to help with tasks related to filtered numbers. */ +@Deprecated public class FilteredNumbersUtil { public static final String CALL_BLOCKING_NOTIFICATION_TAG = "call_blocking"; diff --git a/java/com/android/dialer/blocking/MigrateBlockedNumbersDialogFragment.java b/java/com/android/dialer/blocking/MigrateBlockedNumbersDialogFragment.java index 9b416ff5e..9a3b647d2 100644 --- a/java/com/android/dialer/blocking/MigrateBlockedNumbersDialogFragment.java +++ b/java/com/android/dialer/blocking/MigrateBlockedNumbersDialogFragment.java @@ -30,6 +30,7 @@ import java.util.Objects; * Dialog fragment shown to users when they need to migrate to use {@link * android.provider.BlockedNumberContract} for blocking. */ +@Deprecated public class MigrateBlockedNumbersDialogFragment extends DialogFragment { private BlockedNumbersMigrator blockedNumbersMigrator; diff --git a/java/com/android/dialer/blockreportspam/ShowBlockReportSpamDialogReceiver.java b/java/com/android/dialer/blockreportspam/ShowBlockReportSpamDialogReceiver.java index cc307b6b9..fd26ab537 100644 --- a/java/com/android/dialer/blockreportspam/ShowBlockReportSpamDialogReceiver.java +++ b/java/com/android/dialer/blockreportspam/ShowBlockReportSpamDialogReceiver.java @@ -21,8 +21,9 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.support.annotation.Nullable; -import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler; +import android.widget.Toast; +import com.android.dialer.blocking.Blocking; +import com.android.dialer.blocking.Blocking.BlockingFailedException; import com.android.dialer.blockreportspam.BlockReportSpamDialogs.DialogFragmentForBlockingNumber; import com.android.dialer.blockreportspam.BlockReportSpamDialogs.DialogFragmentForBlockingNumberAndOptionallyReportingAsSpam; import com.android.dialer.blockreportspam.BlockReportSpamDialogs.DialogFragmentForReportingNotSpam; @@ -31,15 +32,16 @@ import com.android.dialer.blockreportspam.BlockReportSpamDialogs.OnConfirmListen import com.android.dialer.blockreportspam.BlockReportSpamDialogs.OnSpamDialogClickListener; import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; -import com.android.dialer.common.concurrent.DialerExecutor.Worker; import com.android.dialer.common.concurrent.DialerExecutorComponent; import com.android.dialer.logging.DialerImpression; +import com.android.dialer.logging.DialerImpression.Type; import com.android.dialer.logging.Logger; import com.android.dialer.protos.ProtoParsers; import com.android.dialer.spam.Spam; import com.android.dialer.spam.SpamComponent; import com.android.dialer.spam.SpamSettings; -import com.google.auto.value.AutoValue; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; /** * A {@link BroadcastReceiver} that shows an appropriate dialog upon receiving notifications from @@ -106,8 +108,6 @@ public final class ShowBlockReportSpamDialogReceiver extends BroadcastReceiver { Spam spam = SpamComponent.get(context).spam(); SpamSettings spamSettings = SpamComponent.get(context).spamSettings(); - FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler = - new FilteredNumberAsyncQueryHandler(context); // Set up the positive listener for the dialog. OnSpamDialogClickListener onSpamDialogClickListener = @@ -132,12 +132,7 @@ public final class ShowBlockReportSpamDialogReceiver extends BroadcastReceiver { dialogInfo.getContactSource()); } - filteredNumberAsyncQueryHandler.blockNumber( - unused -> - Logger.get(context) - .logImpression(DialerImpression.Type.USER_ACTION_BLOCKED_NUMBER), - dialogInfo.getNormalizedNumber(), - dialogInfo.getCountryIso()); + blockNumber(context, dialogInfo); }; // Create and show the dialog. @@ -157,19 +152,11 @@ public final class ShowBlockReportSpamDialogReceiver extends BroadcastReceiver { ProtoParsers.getTrusted( intent, EXTRA_DIALOG_INFO, BlockReportSpamDialogInfo.getDefaultInstance()); - FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler = - new FilteredNumberAsyncQueryHandler(context); - // Set up the positive listener for the dialog. OnConfirmListener onConfirmListener = () -> { LogUtil.i("ShowBlockReportSpamDialogReceiver.showDialogToBlockNumber", "block number"); - filteredNumberAsyncQueryHandler.blockNumber( - unused -> - Logger.get(context) - .logImpression(DialerImpression.Type.USER_ACTION_BLOCKED_NUMBER), - dialogInfo.getNormalizedNumber(), - dialogInfo.getCountryIso()); + blockNumber(context, dialogInfo); }; // Create and show the dialog. @@ -219,46 +206,12 @@ public final class ShowBlockReportSpamDialogReceiver extends BroadcastReceiver { ProtoParsers.getTrusted( intent, EXTRA_DIALOG_INFO, BlockReportSpamDialogInfo.getDefaultInstance()); - FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler = - new FilteredNumberAsyncQueryHandler(context); - // Set up the positive listener for the dialog. OnConfirmListener onConfirmListener = () -> { LogUtil.i("ShowBlockReportSpamDialogReceiver.showDialogToUnblockNumber", "confirmed"); - DialerExecutorComponent.get(context) - .dialerExecutorFactory() - .createNonUiTaskBuilder( - new GetIdForBlockedNumberWorker(filteredNumberAsyncQueryHandler)) - .onSuccess( - idForBlockedNumber -> { - LogUtil.i( - "ShowBlockReportSpamDialogReceiver.showDialogToUnblockNumber", - "ID for the blocked number retrieved"); - if (idForBlockedNumber == null) { - throw new IllegalStateException("ID for a blocked number is null."); - } - - LogUtil.i( - "ShowBlockReportSpamDialogReceiver.showDialogToUnblockNumber", - "unblocking number"); - filteredNumberAsyncQueryHandler.unblock( - (rows, values) -> - Logger.get(context) - .logImpression(DialerImpression.Type.USER_ACTION_UNBLOCKED_NUMBER), - idForBlockedNumber); - }) - .onFailure( - throwable -> { - throw new RuntimeException(throwable); - }) - .build() - .executeSerial( - NumberInfo.newBuilder() - .setNormalizedNumber(dialogInfo.getNormalizedNumber()) - .setCountryIso(dialogInfo.getCountryIso()) - .build()); + unblockNumber(context, dialogInfo); }; // Create & show the dialog. @@ -267,46 +220,58 @@ public final class ShowBlockReportSpamDialogReceiver extends BroadcastReceiver { .show(fragmentManager, BlockReportSpamDialogs.UNBLOCK_DIALOG_TAG); } - /** A {@link Worker} that retrieves the ID of a blocked number from the database. */ - private static final class GetIdForBlockedNumberWorker implements Worker { - - private final FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler; - - GetIdForBlockedNumberWorker(FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler) { - this.filteredNumberAsyncQueryHandler = filteredNumberAsyncQueryHandler; - } - - @Nullable - @Override - public Integer doInBackground(NumberInfo input) throws Throwable { - LogUtil.enterBlock("GetIdForBlockedNumberWorker.doInBackground"); + private static void blockNumber(Context context, BlockReportSpamDialogInfo dialogInfo) { + Logger.get(context).logImpression(Type.USER_ACTION_BLOCKED_NUMBER); + Futures.addCallback( + Blocking.block( + context, + DialerExecutorComponent.get(context).backgroundExecutor(), + dialogInfo.getNormalizedNumber(), + dialogInfo.getCountryIso()), + new FutureCallback() { + @Override + public void onSuccess(Void unused) { + // Do nothing + } - return filteredNumberAsyncQueryHandler.getBlockedIdSynchronous( - input.getNormalizedNumber(), input.getCountryIso()); - } + @Override + public void onFailure(Throwable throwable) { + if (throwable instanceof BlockingFailedException) { + Logger.get(context).logImpression(Type.USER_ACTION_BLOCK_NUMBER_FAILED); + Toast.makeText(context, R.string.block_number_failed_toast, Toast.LENGTH_LONG).show(); + } else { + throw new RuntimeException(throwable); + } + } + }, + DialerExecutorComponent.get(context).uiExecutor()); } - /** - * Contains information about a number and serves as the input to {@link - * GetIdForBlockedNumberWorker}. - */ - @AutoValue - abstract static class NumberInfo { - static Builder newBuilder() { - return new AutoValue_ShowBlockReportSpamDialogReceiver_NumberInfo.Builder(); - } - - abstract String getNormalizedNumber(); - - abstract String getCountryIso(); - - @AutoValue.Builder - abstract static class Builder { - abstract Builder setNormalizedNumber(String normalizedNumber); - - abstract Builder setCountryIso(String countryIso); + private static void unblockNumber(Context context, BlockReportSpamDialogInfo dialogInfo) { + Logger.get(context).logImpression(Type.USER_ACTION_UNBLOCKED_NUMBER); + Futures.addCallback( + Blocking.unblock( + context, + DialerExecutorComponent.get(context).backgroundExecutor(), + dialogInfo.getNormalizedNumber(), + dialogInfo.getCountryIso()), + new FutureCallback() { + @Override + public void onSuccess(Void unused) { + // Do nothing + } - abstract NumberInfo build(); - } + @Override + public void onFailure(Throwable throwable) { + if (throwable instanceof BlockingFailedException) { + Logger.get(context).logImpression(Type.USER_ACTION_UNBLOCK_NUMBER_FAILED); + Toast.makeText(context, R.string.unblock_number_failed_toast, Toast.LENGTH_LONG) + .show(); + } else { + throw new RuntimeException(throwable); + } + } + }, + DialerExecutorComponent.get(context).uiExecutor()); } } diff --git a/java/com/android/dialer/blockreportspam/res/values/strings.xml b/java/com/android/dialer/blockreportspam/res/values/strings.xml index aface9268..1537c2353 100644 --- a/java/com/android/dialer/blockreportspam/res/values/strings.xml +++ b/java/com/android/dialer/blockreportspam/res/values/strings.xml @@ -60,4 +60,9 @@ Report call as spam + + Problem blocking this number + + + Problem unblocking this number diff --git a/java/com/android/dialer/commandline/CommandLineModule.java b/java/com/android/dialer/commandline/CommandLineModule.java index 612155662..915578722 100644 --- a/java/com/android/dialer/commandline/CommandLineModule.java +++ b/java/com/android/dialer/commandline/CommandLineModule.java @@ -16,7 +16,7 @@ package com.android.dialer.commandline; -import com.android.dialer.commandline.impl.Blocking; +import com.android.dialer.commandline.impl.BlockingCommand; import com.android.dialer.commandline.impl.CallCommand; import com.android.dialer.commandline.impl.Echo; import com.android.dialer.commandline.impl.Help; @@ -43,16 +43,20 @@ public abstract class CommandLineModule { private final Help help; private final Version version; private final Echo echo; - private final Blocking blocking; + private final BlockingCommand blockingCommand; private final CallCommand callCommand; @Inject AospCommandInjector( - Help help, Version version, Echo echo, Blocking blocking, CallCommand callCommand) { + Help help, + Version version, + Echo echo, + BlockingCommand blockingCommand, + CallCommand callCommand) { this.help = help; this.version = version; this.echo = echo; - this.blocking = blocking; + this.blockingCommand = blockingCommand; this.callCommand = callCommand; } @@ -60,7 +64,7 @@ public abstract class CommandLineModule { builder.addCommand("help", help); builder.addCommand("version", version); builder.addCommand("echo", echo); - builder.addCommand("blocking", blocking); + builder.addCommand("blocking", blockingCommand); builder.addCommand("call", callCommand); return builder; } diff --git a/java/com/android/dialer/commandline/impl/Blocking.java b/java/com/android/dialer/commandline/impl/Blocking.java deleted file mode 100644 index 2afd16522..000000000 --- a/java/com/android/dialer/commandline/impl/Blocking.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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.commandline.impl; - -import android.content.Context; -import android.support.annotation.NonNull; -import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler; -import com.android.dialer.commandline.Arguments; -import com.android.dialer.commandline.Command; -import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor; -import com.android.dialer.inject.ApplicationContext; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.ListeningExecutorService; -import javax.inject.Inject; - -/** Block or unblock a number. */ -public class Blocking implements Command { - - @NonNull - @Override - public String getShortDescription() { - return "block or unblock numbers"; - } - - @NonNull - @Override - public String getUsage() { - return "blocking block|unblock|isblocked number\n\n" + "number should be e.164 formatted"; - } - - private final Context appContext; - private final ListeningExecutorService executorService; - - @Inject - Blocking( - @ApplicationContext Context context, - @BackgroundExecutor ListeningExecutorService executorService) { - this.appContext = context; - this.executorService = executorService; - } - - @Override - public ListenableFuture run(Arguments args) throws IllegalCommandLineArgumentException { - // AsyncQueryHandler must be created on a thread with looper. - // TODO(a bug): Use blocking version - FilteredNumberAsyncQueryHandler asyncQueryHandler = - new FilteredNumberAsyncQueryHandler(appContext); - return executorService.submit(() -> doInBackground(args, asyncQueryHandler)); - } - - private String doInBackground(Arguments args, FilteredNumberAsyncQueryHandler asyncQueryHandler) { - if (args.getPositionals().isEmpty()) { - return getUsage(); - } - - String command = args.getPositionals().get(0); - - if ("block".equals(command)) { - String number = args.getPositionals().get(1); - asyncQueryHandler.blockNumber((unused) -> {}, number, null); - return "blocked " + number; - } - - if ("unblock".equals(command)) { - String number = args.getPositionals().get(1); - Integer id = asyncQueryHandler.getBlockedIdSynchronous(number, null); - if (id == null) { - return number + " is not blocked"; - } - asyncQueryHandler.unblock((unusedRows, unusedValues) -> {}, id); - return "unblocked " + number; - } - - if ("isblocked".equals(command)) { - String number = args.getPositionals().get(1); - Integer id = asyncQueryHandler.getBlockedIdSynchronous(number, null); - return id == null ? "false" : "true"; - } - - return getUsage(); - } -} diff --git a/java/com/android/dialer/commandline/impl/BlockingCommand.java b/java/com/android/dialer/commandline/impl/BlockingCommand.java new file mode 100644 index 000000000..c8f893422 --- /dev/null +++ b/java/com/android/dialer/commandline/impl/BlockingCommand.java @@ -0,0 +1,111 @@ +/* + * 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.commandline.impl; + +import android.content.Context; +import android.support.annotation.NonNull; +import com.android.dialer.DialerPhoneNumber; +import com.android.dialer.blocking.Blocking; +import com.android.dialer.commandline.Arguments; +import com.android.dialer.commandline.Command; +import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor; +import com.android.dialer.inject.ApplicationContext; +import com.android.dialer.phonelookup.PhoneLookupComponent; +import com.android.dialer.phonelookup.PhoneLookupInfo; +import com.android.dialer.phonelookup.consolidator.PhoneLookupInfoConsolidator; +import com.android.dialer.phonenumberproto.DialerPhoneNumberUtil; +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 javax.inject.Inject; + +/** Block or unblock a number. */ +public class BlockingCommand implements Command { + + @NonNull + @Override + public String getShortDescription() { + return "block or unblock numbers"; + } + + @NonNull + @Override + public String getUsage() { + return "blocking block|unblock|isblocked number\n\n" + "number should be e.164 formatted"; + } + + private final Context appContext; + private final ListeningExecutorService executorService; + + @Inject + BlockingCommand( + @ApplicationContext Context context, + @BackgroundExecutor ListeningExecutorService executorService) { + this.appContext = context; + this.executorService = executorService; + } + + @Override + public ListenableFuture run(Arguments args) throws IllegalCommandLineArgumentException { + if (args.getPositionals().isEmpty()) { + return Futures.immediateFuture(getUsage()); + } + + String command = args.getPositionals().get(0); + + if ("block".equals(command)) { + String number = args.getPositionals().get(1); + return Futures.transform( + Blocking.block(appContext, executorService, number, null), + (unused) -> "blocked " + number, + MoreExecutors.directExecutor()); + } + + if ("unblock".equals(command)) { + String number = args.getPositionals().get(1); + return Futures.transform( + Blocking.unblock(appContext, executorService, number, null), + (unused) -> "unblocked " + number, + MoreExecutors.directExecutor()); + } + + if ("isblocked".equals(command)) { + String number = args.getPositionals().get(1); + ListenableFuture dialerPhoneNumberFuture = + executorService.submit( + () -> new DialerPhoneNumberUtil(PhoneNumberUtil.getInstance()).parse(number, null)); + + ListenableFuture lookupFuture = + Futures.transformAsync( + dialerPhoneNumberFuture, + (dialerPhoneNumber) -> + PhoneLookupComponent.get(appContext) + .compositePhoneLookup() + .lookup(dialerPhoneNumber), + executorService); + + return Futures.transform( + lookupFuture, + (info) -> new PhoneLookupInfoConsolidator(info).isBlocked() ? "true" : "false", + MoreExecutors.directExecutor()); + } + + return Futures.immediateFuture(getUsage()); + } +} diff --git a/java/com/android/dialer/logging/dialer_impression.proto b/java/com/android/dialer/logging/dialer_impression.proto index 16efd137c..96a7bb6f6 100644 --- a/java/com/android/dialer/logging/dialer_impression.proto +++ b/java/com/android/dialer/logging/dialer_impression.proto @@ -12,7 +12,7 @@ message DialerImpression { // Event enums to be used for Impression Logging in Dialer. // It's perfectly acceptable for this enum to be large // Values should be from 1000 to 100000. - // Next Tag: 1369 + // Next Tag: 1371 enum Type { UNKNOWN_AOSP_EVENT_TYPE = 1000; @@ -78,9 +78,17 @@ message DialerImpression { ; + // User made it to the last step but blocking failed because user is + // secondary or dialer is not default + USER_ACTION_BLOCK_NUMBER_FAILED = 1369; + // User made it to the last step and actually unblocked the number USER_ACTION_UNBLOCKED_NUMBER = 1013; + // User made it to the last step but unblocking failed because user is + // secondary or dialer is not default + USER_ACTION_UNBLOCK_NUMBER_FAILED = 1370; + // User blocked a number, does not guarantee if the number was reported as // spam or not To compute the number of blocked numbers that were reported // as not spam and yet blocked Subtract this value from -- cgit v1.2.3