From 89e3d1bb7941993206861fe9115778f816262c07 Mon Sep 17 00:00:00 2001 From: erfanian Date: Wed, 2 May 2018 18:50:59 -0700 Subject: More refactoring Test: unit PiperOrigin-RevId: 195188099 Change-Id: Ie2273229c257a9a767715831c15d90a6985fdda8 --- .../dialer/historyitemactions/HistoryItemActionBottomSheet.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'java/com/android/dialer/historyitemactions') diff --git a/java/com/android/dialer/historyitemactions/HistoryItemActionBottomSheet.java b/java/com/android/dialer/historyitemactions/HistoryItemActionBottomSheet.java index e3e9e7a64..f90effc4c 100644 --- a/java/com/android/dialer/historyitemactions/HistoryItemActionBottomSheet.java +++ b/java/com/android/dialer/historyitemactions/HistoryItemActionBottomSheet.java @@ -20,9 +20,9 @@ import android.content.Context; import android.content.res.ColorStateList; import android.os.Bundle; import android.support.annotation.NonNull; -import android.support.design.widget.BottomSheetBehavior; -import android.support.design.widget.BottomSheetBehavior.BottomSheetCallback; -import android.support.design.widget.BottomSheetDialog; +import android.support.design.bottomsheet.BottomSheetBehavior; +import android.support.design.bottomsheet.BottomSheetBehavior.BottomSheetCallback; +import android.support.design.bottomsheet.BottomSheetDialog; import android.support.v4.content.ContextCompat; import android.text.TextUtils; import android.view.LayoutInflater; -- cgit v1.2.3 From 253b4407c125acbb7add26592ba782144c4d0366 Mon Sep 17 00:00:00 2001 From: linyuh Date: Thu, 3 May 2018 12:42:04 -0700 Subject: Simplify how we build bottom sheet options (a.k.a. modules). Test: HistoryItemActionModulesBuilderTest, ModulesTest PiperOrigin-RevId: 195294876 Change-Id: Iac44f965a585975389da7dee758a94a8ad8311d3 --- .../historyitemactions/BlockReportSpamModules.java | 120 +++++++ .../HistoryItemActionModulesBuilder.java | 400 +++++++++++++++++++++ .../dialer/historyitemactions/IntentModule.java | 9 + .../dialer/historyitemactions/SharedModules.java | 247 ------------- .../history_item_action_module_info.proto | 69 ++++ 5 files changed, 598 insertions(+), 247 deletions(-) create mode 100644 java/com/android/dialer/historyitemactions/BlockReportSpamModules.java create mode 100644 java/com/android/dialer/historyitemactions/HistoryItemActionModulesBuilder.java delete mode 100644 java/com/android/dialer/historyitemactions/SharedModules.java create mode 100644 java/com/android/dialer/historyitemactions/history_item_action_module_info.proto (limited to 'java/com/android/dialer/historyitemactions') diff --git a/java/com/android/dialer/historyitemactions/BlockReportSpamModules.java b/java/com/android/dialer/historyitemactions/BlockReportSpamModules.java new file mode 100644 index 000000000..396c03376 --- /dev/null +++ b/java/com/android/dialer/historyitemactions/BlockReportSpamModules.java @@ -0,0 +1,120 @@ +/* + * 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.historyitemactions; + +import android.content.Context; +import com.android.dialer.blockreportspam.BlockReportSpamDialogInfo; +import com.android.dialer.blockreportspam.ShowBlockReportSpamDialogNotifier; + +/** Modules for blocking/unblocking a number and/or reporting it as spam/not spam. */ +final class BlockReportSpamModules { + + private BlockReportSpamModules() {} + + static HistoryItemActionModule moduleForMarkingNumberAsNotSpam( + Context context, BlockReportSpamDialogInfo blockReportSpamDialogInfo) { + + return new HistoryItemActionModule() { + @Override + public int getStringId() { + return R.string.not_spam; + } + + @Override + public int getDrawableId() { + return R.drawable.quantum_ic_report_off_vd_theme_24; + } + + @Override + public boolean onClick() { + ShowBlockReportSpamDialogNotifier.notifyShowDialogToReportNotSpam( + context, blockReportSpamDialogInfo); + return true; // Close the bottom sheet. + } + }; + } + + static HistoryItemActionModule moduleForBlockingNumber( + Context context, BlockReportSpamDialogInfo blockReportSpamDialogInfo) { + + return new HistoryItemActionModule() { + @Override + public int getStringId() { + return R.string.block_number; + } + + @Override + public int getDrawableId() { + return R.drawable.quantum_ic_block_vd_theme_24; + } + + @Override + public boolean onClick() { + ShowBlockReportSpamDialogNotifier.notifyShowDialogToBlockNumber( + context, blockReportSpamDialogInfo); + return true; // Close the bottom sheet. + } + }; + } + + static HistoryItemActionModule moduleForUnblockingNumber( + Context context, BlockReportSpamDialogInfo blockReportSpamDialogInfo) { + + return new HistoryItemActionModule() { + @Override + public int getStringId() { + return R.string.unblock_number; + } + + @Override + public int getDrawableId() { + return R.drawable.quantum_ic_unblock_vd_theme_24; + } + + @Override + public boolean onClick() { + ShowBlockReportSpamDialogNotifier.notifyShowDialogToUnblockNumber( + context, blockReportSpamDialogInfo); + + return true; // Close the bottom sheet. + } + }; + } + + static HistoryItemActionModule moduleForBlockingNumberAndOptionallyReportingSpam( + Context context, BlockReportSpamDialogInfo blockReportSpamDialogInfo) { + + return new HistoryItemActionModule() { + @Override + public int getStringId() { + return R.string.block_and_optionally_report_spam; + } + + @Override + public int getDrawableId() { + return R.drawable.quantum_ic_block_vd_theme_24; + } + + @Override + public boolean onClick() { + ShowBlockReportSpamDialogNotifier.notifyShowDialogToBlockNumberAndOptionallyReportSpam( + context, blockReportSpamDialogInfo); + return true; // Close the bottom sheet. + } + }; + } +} diff --git a/java/com/android/dialer/historyitemactions/HistoryItemActionModulesBuilder.java b/java/com/android/dialer/historyitemactions/HistoryItemActionModulesBuilder.java new file mode 100644 index 000000000..ca6d3f3e4 --- /dev/null +++ b/java/com/android/dialer/historyitemactions/HistoryItemActionModulesBuilder.java @@ -0,0 +1,400 @@ +/* + * 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.historyitemactions; + +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.provider.CallLog.Calls; +import android.provider.ContactsContract; +import android.text.TextUtils; +import com.android.dialer.blockreportspam.BlockReportSpamDialogInfo; +import com.android.dialer.callintent.CallInitiationType; +import com.android.dialer.callintent.CallIntentBuilder; +import com.android.dialer.clipboard.ClipboardUtils; +import com.android.dialer.common.Assert; +import com.android.dialer.duo.Duo; +import com.android.dialer.duo.DuoComponent; +import com.android.dialer.logging.ReportingLocation; +import com.android.dialer.util.CallUtil; +import com.android.dialer.util.UriUtils; +import java.util.ArrayList; +import java.util.List; + +/** + * Builds a list of {@link HistoryItemActionModule HistoryItemActionModules}. + * + *

Example usage: + * + *


+ *    // Create a HistoryItemActionModuleInfo proto with the information you have.
+ *    // You can simply skip a field if there is no information for it.
+ *    HistoryItemActionModuleInfo moduleInfo =
+ *        HistoryItemActionModuleInfo.newBuilder()
+ *            .setNormalizedNumber("+16502530000")
+ *            .setCountryIso("US")
+ *            .setName("Google")
+ *            .build();
+ *
+ *    // Initialize the builder using the module info above.
+ *    // Note that some modules require an activity context to work so it is preferred to pass one
+ *    // instead of an application context to the builder.
+ *    HistoryItemActionModulesBuilder modulesBuilder =
+ *        new HistoryItemActionModulesBuilder(activityContext, moduleInfo);
+ *
+ *    // Add all modules you want in the order you like.
+ *    // If a module shouldn't be added according to the module info, it won't be.
+ *    // For example, if the module info is not for a video call and doesn't indicate the presence
+ *    // of video calling capabilities, calling addModuleForVideoCall() is a no-op.
+ *    modulesBuilder
+ *        .addModuleForVoiceCall()
+ *        .addModuleForVideoCall()
+ *        .addModuleForSendingTextMessage()
+ *        .addModuleForDivider()
+ *        .addModuleForAddingToContacts()
+ *        .addModuleForBlockedOrSpamNumber()
+ *        .addModuleForCopyingNumber();
+ *
+ *    List modules = modulesBuilder.build();
+ * 
+ */ +public final class HistoryItemActionModulesBuilder { + + private final Context context; + private final HistoryItemActionModuleInfo moduleInfo; + private final List modules; + + public HistoryItemActionModulesBuilder(Context context, HistoryItemActionModuleInfo moduleInfo) { + Assert.checkArgument( + moduleInfo.getHost() != HistoryItemActionModuleInfo.Host.UNKNOWN, + "A host must be specified."); + + this.context = context; + this.moduleInfo = moduleInfo; + this.modules = new ArrayList<>(); + } + + public List build() { + return new ArrayList<>(modules); + } + + /** + * Adds a module for placing a voice call. + * + *

The method is a no-op if the number is blocked. + */ + public HistoryItemActionModulesBuilder addModuleForVoiceCall() { + if (moduleInfo.getIsBlocked()) { + return this; + } + + // TODO(zachh): Support post-dial digits; consider using DialerPhoneNumber. + // Do not set PhoneAccountHandle so that regular PreCall logic will be used. The account used to + // place or receive the call should be ignored for voice calls. + CallIntentBuilder callIntentBuilder = + new CallIntentBuilder(moduleInfo.getNormalizedNumber(), getCallInitiationType()) + .setAllowAssistedDial(moduleInfo.getCanSupportAssistedDialing()); + modules.add(IntentModule.newCallModule(context, callIntentBuilder)); + return this; + } + + /** + * Adds a module for a carrier video call *or* a Duo video call. + * + *

If the number is blocked or marked as spam, this method is a no-op. + * + *

If the provided module info is for a Duo video call and Duo is available, add a Duo video + * call module. + * + *

If the provided module info is for a Duo video call but Duo is unavailable, add a carrier + * video call module. + * + *

If the provided module info is for a carrier video call, add a carrier video call module. + * + *

If the provided module info is for a voice call and the device has carrier video call + * capability, add a carrier video call module. + * + *

If the provided module info is for a voice call, the device doesn't have carrier video call + * capability, and Duo is available, add a Duo video call module. + */ + public HistoryItemActionModulesBuilder addModuleForVideoCall() { + if (moduleInfo.getIsBlocked() || moduleInfo.getIsSpam()) { + return this; + } + + // Do not set PhoneAccountHandle so that regular PreCall logic will be used. The account used to + // place or receive the call should be ignored for carrier video calls. + // TODO(a bug): figure out the correct video call behavior + HistoryItemActionModule carrierVideoCallModule = + IntentModule.newCallModule( + context, + new CallIntentBuilder(moduleInfo.getNormalizedNumber(), getCallInitiationType()) + .setAllowAssistedDial(moduleInfo.getCanSupportAssistedDialing()) + .setIsVideoCall(true)); + HistoryItemActionModule duoVideoCallModule = + new DuoCallModule(context, moduleInfo.getNormalizedNumber()); + + // If the module info is for a video call, add an appropriate video call module. + if ((moduleInfo.getFeatures() & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO) { + modules.add(isDuoCall() && canPlaceDuoCall() ? duoVideoCallModule : carrierVideoCallModule); + return this; + } + + // At this point, the module info is for an audio call. We will also add a video call module if + // the video capability is present. + // + // The carrier video call module takes precedence over the Duo module. + if (canPlaceCarrierVideoCall()) { + modules.add(carrierVideoCallModule); + } else if (canPlaceDuoCall()) { + modules.add(duoVideoCallModule); + } + return this; + } + + /** + * Adds a module for sending text messages. + * + *

The method is a no-op if the number is blocked or empty. + */ + public HistoryItemActionModulesBuilder addModuleForSendingTextMessage() { + // TODO(zachh): There are other conditions where this module should not be shown; consider + // voicemail, business numbers, etc. + if (moduleInfo.getIsBlocked() || TextUtils.isEmpty(moduleInfo.getNormalizedNumber())) { + return this; + } + + modules.add( + IntentModule.newModuleForSendingTextMessage(context, moduleInfo.getNormalizedNumber())); + return this; + } + + /** + * Adds a module for a divider. + * + *

The method is a no-op if the divider module will be the first module. + */ + public HistoryItemActionModulesBuilder addModuleForDivider() { + if (modules.isEmpty()) { + return this; + } + + modules.add(new DividerModule()); + return this; + } + + /** + * Adds a module for adding a number to Contacts. + * + *

The method is a no-op if + * + *

    + *
  • the number is blocked, + *
  • the number is marked as spam, + *
  • the number is empty, or + *
  • the number belongs to an existing contact. + *
+ */ + public HistoryItemActionModulesBuilder addModuleForAddingToContacts() { + if (moduleInfo.getIsBlocked() + || moduleInfo.getIsSpam() + || isExistingContact() + || TextUtils.isEmpty(moduleInfo.getNormalizedNumber())) { + return this; + } + + Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT); + intent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE); + intent.putExtra(ContactsContract.Intents.Insert.PHONE, moduleInfo.getNormalizedNumber()); + + if (!TextUtils.isEmpty(moduleInfo.getName())) { + intent.putExtra(ContactsContract.Intents.Insert.NAME, moduleInfo.getName()); + } + + modules.add( + new IntentModule( + context, + intent, + R.string.add_to_contacts, + R.drawable.quantum_ic_person_add_vd_theme_24)); + return this; + } + + /** + * Add modules for blocking/unblocking a number and/or marking it as spam/not spam. + * + *

If a number is marked as spam, add two modules: + * + *

    + *
  • "Not spam" and "Block", or + *
  • "Not spam" and "Unblock". + *
+ * + *

If a number is blocked but not marked as spam, add the "Unblock" module. + * + *

If a number is not blocked or marked as spam, add the "Block/Report spam" module. + */ + public HistoryItemActionModulesBuilder addModuleForBlockedOrSpamNumber() { + BlockReportSpamDialogInfo blockReportSpamDialogInfo = + BlockReportSpamDialogInfo.newBuilder() + .setNormalizedNumber(moduleInfo.getNormalizedNumber()) + .setCountryIso(moduleInfo.getCountryIso()) + .setCallType(moduleInfo.getCallType()) + .setReportingLocation(getReportingLocation()) + .setContactSource(moduleInfo.getContactSource()) + .build(); + + // For a spam number, add two modules: + // (1) "Not spam" and "Block", or + // (2) "Not spam" and "Unblock". + if (moduleInfo.getIsSpam()) { + modules.add( + BlockReportSpamModules.moduleForMarkingNumberAsNotSpam( + context, blockReportSpamDialogInfo)); + modules.add( + moduleInfo.getIsBlocked() + ? BlockReportSpamModules.moduleForUnblockingNumber(context, blockReportSpamDialogInfo) + : BlockReportSpamModules.moduleForBlockingNumber(context, blockReportSpamDialogInfo)); + return this; + } + + // For a blocked non-spam number, add the "Unblock" module. + if (moduleInfo.getIsBlocked()) { + modules.add( + BlockReportSpamModules.moduleForUnblockingNumber(context, blockReportSpamDialogInfo)); + return this; + } + + // For a number that is neither a spam number nor blocked, add the "Block/Report spam" module. + modules.add( + BlockReportSpamModules.moduleForBlockingNumberAndOptionallyReportingSpam( + context, blockReportSpamDialogInfo)); + return this; + } + + /** + * Adds a module for copying a number. + * + *

The method is a no-op if the number is empty. + */ + public HistoryItemActionModulesBuilder addModuleForCopyingNumber() { + if (TextUtils.isEmpty(moduleInfo.getNormalizedNumber())) { + return this; + } + + modules.add( + new HistoryItemActionModule() { + @Override + public int getStringId() { + return R.string.copy_number; + } + + @Override + public int getDrawableId() { + return R.drawable.quantum_ic_content_copy_vd_theme_24; + } + + @Override + public boolean onClick() { + ClipboardUtils.copyText( + context, + /* label = */ null, + moduleInfo.getNormalizedNumber(), + /* showToast = */ true); + return false; + } + }); + return this; + } + + private boolean canPlaceCarrierVideoCall() { + int carrierVideoAvailability = CallUtil.getVideoCallingAvailability(context); + boolean isCarrierVideoCallingEnabled = + ((carrierVideoAvailability & CallUtil.VIDEO_CALLING_ENABLED) + == CallUtil.VIDEO_CALLING_ENABLED); + boolean canRelyOnCarrierVideoPresence = + ((carrierVideoAvailability & CallUtil.VIDEO_CALLING_PRESENCE) + == CallUtil.VIDEO_CALLING_PRESENCE); + + return isCarrierVideoCallingEnabled + && canRelyOnCarrierVideoPresence + && moduleInfo.getCanSupportCarrierVideoCall(); + } + + private boolean isDuoCall() { + return DuoComponent.get(context) + .getDuo() + .isDuoAccount(moduleInfo.getPhoneAccountComponentName()); + } + + private boolean canPlaceDuoCall() { + Duo duo = DuoComponent.get(context).getDuo(); + + return duo.isInstalled(context) + && duo.isEnabled(context) + && duo.isActivated(context) + && duo.isReachable(context, moduleInfo.getNormalizedNumber()); + } + + /** + * Lookup URIs are currently fetched from the cached column of the system call log. This URI + * contains encoded information for non-contacts for the purposes of populating contact cards. + * + *

We infer whether a contact is existing or not by checking if the lookup URI is "encoded" or + * not. + * + *

TODO(zachh): We should revisit this once the contact URI is no longer being read from the + * cached column in the system database, in case we decide not to overload the column. + */ + private boolean isExistingContact() { + return !TextUtils.isEmpty(moduleInfo.getLookupUri()) + && !UriUtils.isEncodedContactUri(Uri.parse(moduleInfo.getLookupUri())); + } + + /** + * Maps the value of {@link HistoryItemActionModuleInfo#getHost()} to {@link + * CallInitiationType.Type}, which is required by {@link CallIntentBuilder} to build a call + * intent. + */ + private CallInitiationType.Type getCallInitiationType() { + switch (moduleInfo.getHost()) { + case CALL_LOG: + return CallInitiationType.Type.CALL_LOG; + case VOICEMAIL: + return CallInitiationType.Type.VOICEMAIL_LOG; + default: + throw Assert.createUnsupportedOperationFailException( + String.format("Unsupported host: %s", moduleInfo.getHost())); + } + } + + /** + * Maps the value of {@link HistoryItemActionModuleInfo#getHost()} to {@link + * ReportingLocation.Type}, which is for logging where a spam number is reported. + */ + private ReportingLocation.Type getReportingLocation() { + switch (moduleInfo.getHost()) { + case CALL_LOG: + return ReportingLocation.Type.CALL_LOG_HISTORY; + case VOICEMAIL: + return ReportingLocation.Type.VOICEMAIL_HISTORY; + default: + throw Assert.createUnsupportedOperationFailException( + String.format("Unsupported host: %s", moduleInfo.getHost())); + } + } +} diff --git a/java/com/android/dialer/historyitemactions/IntentModule.java b/java/com/android/dialer/historyitemactions/IntentModule.java index f73d4c951..dc53064af 100644 --- a/java/com/android/dialer/historyitemactions/IntentModule.java +++ b/java/com/android/dialer/historyitemactions/IntentModule.java @@ -23,6 +23,7 @@ import android.support.annotation.StringRes; import com.android.dialer.callintent.CallIntentBuilder; import com.android.dialer.precall.PreCall; import com.android.dialer.util.DialerUtils; +import com.android.dialer.util.IntentUtil; /** * {@link HistoryItemActionModule} useful for making easy to build modules based on starting an @@ -73,4 +74,12 @@ public class IntentModule implements HistoryItemActionModule { return new IntentModule(context, PreCall.getIntent(context, callIntentBuilder), text, image); } + + public static IntentModule newModuleForSendingTextMessage(Context context, String number) { + return new IntentModule( + context, + IntentUtil.getSendSmsIntent(number), + R.string.send_a_message, + R.drawable.quantum_ic_message_vd_theme_24); + } } diff --git a/java/com/android/dialer/historyitemactions/SharedModules.java b/java/com/android/dialer/historyitemactions/SharedModules.java deleted file mode 100644 index 8604bed1d..000000000 --- a/java/com/android/dialer/historyitemactions/SharedModules.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (C) 2017 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.historyitemactions; - -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.provider.ContactsContract; -import android.support.annotation.Nullable; -import android.text.TextUtils; -import com.android.dialer.DialerPhoneNumber; -import com.android.dialer.blockreportspam.BlockReportSpamDialogInfo; -import com.android.dialer.blockreportspam.ShowBlockReportSpamDialogNotifier; -import com.android.dialer.clipboard.ClipboardUtils; -import com.android.dialer.util.IntentUtil; -import com.android.dialer.util.UriUtils; -import com.google.common.base.Optional; -import java.util.ArrayList; -import java.util.List; - -/** - * Modules for the bottom sheet that are shared between NewVoicemailFragment and NewCallLogFragment - */ -@SuppressWarnings("Guava") -public class SharedModules { - - public static Optional createModuleForAddingToContacts( - Context context, - DialerPhoneNumber dialerPhoneNumber, - String name, - String lookupUri, - boolean isBlocked, - boolean isSpam) { - // Skip showing the menu item for a spam/blocked number. - if (isBlocked || isSpam) { - return Optional.absent(); - } - - // Skip showing the menu item for existing contacts. - if (isExistingContact(lookupUri)) { - return Optional.absent(); - } - - // Skip showing the menu item if there is no number. - String normalizedNumber = dialerPhoneNumber.getNormalizedNumber(); - if (TextUtils.isEmpty(normalizedNumber)) { - return Optional.absent(); - } - - Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT); - intent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE); - intent.putExtra(ContactsContract.Intents.Insert.PHONE, normalizedNumber); - - if (!TextUtils.isEmpty(name)) { - intent.putExtra(ContactsContract.Intents.Insert.NAME, name); - } - - return Optional.of( - new IntentModule( - context, - intent, - R.string.add_to_contacts, - R.drawable.quantum_ic_person_add_vd_theme_24)); - } - - /** - * Lookup URIs are currently fetched from the cached column of the system call log. This URI - * contains encoded information for non-contacts for the purposes of populating contact cards. - * - *

We infer whether a contact is existing or not by checking if the lookup URI is "encoded" or - * not. - * - *

TODO(zachh): We should revisit this once the contact URI is no longer being read from the - * cached column in the system database, in case we decide not to overload the column. - */ - private static boolean isExistingContact(@Nullable String lookupUri) { - return !TextUtils.isEmpty(lookupUri) && !UriUtils.isEncodedContactUri(Uri.parse(lookupUri)); - } - - public static Optional createModuleForSendingTextMessage( - Context context, String normalizedNumber, boolean isBlocked) { - // Don't show the option to send a text message if the number is blocked. - if (isBlocked) { - return Optional.absent(); - } - - // TODO(zachh): There are some conditions where this module should not be shown; consider - // voicemail, business numbers, etc. - - return !TextUtils.isEmpty(normalizedNumber) - ? Optional.of( - new IntentModule( - context, - IntentUtil.getSendSmsIntent(normalizedNumber), - R.string.send_a_message, - R.drawable.quantum_ic_message_vd_theme_24)) - : Optional.absent(); - } - - /** - * Create modules related to blocking/unblocking a number and/or reporting it as spam/not spam. - */ - public static List createModulesHandlingBlockedOrSpamNumber( - Context context, - BlockReportSpamDialogInfo blockReportSpamDialogInfo, - boolean isBlocked, - boolean isSpam) { - List modules = new ArrayList<>(); - - // For a spam number, add two options: - // (1) "Not spam" and "Block", or - // (2) "Not spam" and "Unblock". - if (isSpam) { - modules.add(createModuleForMarkingNumberAsNonSpam(context, blockReportSpamDialogInfo)); - modules.add( - createModuleForBlockingOrUnblockingNumber(context, blockReportSpamDialogInfo, isBlocked)); - return modules; - } - - // For a blocked non-spam number, add "Unblock" option. - if (isBlocked) { - modules.add( - createModuleForBlockingOrUnblockingNumber(context, blockReportSpamDialogInfo, isBlocked)); - return modules; - } - - // For a number that is neither a spam number nor blocked, add "Block/Report spam" option. - modules.add( - createModuleForBlockingNumberAndOptionallyReportingSpam( - context, blockReportSpamDialogInfo)); - return modules; - } - - /** Create "Not spam" module. */ - private static HistoryItemActionModule createModuleForMarkingNumberAsNonSpam( - Context context, BlockReportSpamDialogInfo blockReportSpamDialogInfo) { - return new HistoryItemActionModule() { - @Override - public int getStringId() { - return R.string.not_spam; - } - - @Override - public int getDrawableId() { - return R.drawable.quantum_ic_report_off_vd_theme_24; - } - - @Override - public boolean onClick() { - ShowBlockReportSpamDialogNotifier.notifyShowDialogToReportNotSpam( - context, blockReportSpamDialogInfo); - return true; // Close the bottom sheet. - } - }; - } - - private static HistoryItemActionModule createModuleForBlockingOrUnblockingNumber( - Context context, BlockReportSpamDialogInfo blockReportSpamDialogInfo, boolean isBlocked) { - return new HistoryItemActionModule() { - @Override - public int getStringId() { - return isBlocked ? R.string.unblock_number : R.string.block_number; - } - - @Override - public int getDrawableId() { - return isBlocked - ? R.drawable.quantum_ic_unblock_vd_theme_24 - : R.drawable.quantum_ic_block_vd_theme_24; - } - - @Override - public boolean onClick() { - if (isBlocked) { - ShowBlockReportSpamDialogNotifier.notifyShowDialogToUnblockNumber( - context, blockReportSpamDialogInfo); - } else { - ShowBlockReportSpamDialogNotifier.notifyShowDialogToBlockNumber( - context, blockReportSpamDialogInfo); - } - return true; // Close the bottom sheet. - } - }; - } - - /** Create "Block/Report spam" module */ - private static HistoryItemActionModule createModuleForBlockingNumberAndOptionallyReportingSpam( - Context context, BlockReportSpamDialogInfo blockReportSpamDialogInfo) { - return new HistoryItemActionModule() { - @Override - public int getStringId() { - return R.string.block_and_optionally_report_spam; - } - - @Override - public int getDrawableId() { - return R.drawable.quantum_ic_block_vd_theme_24; - } - - @Override - public boolean onClick() { - ShowBlockReportSpamDialogNotifier.notifyShowDialogToBlockNumberAndOptionallyReportSpam( - context, blockReportSpamDialogInfo); - return true; // Close the bottom sheet. - } - }; - } - - public static Optional createModuleForCopyingNumber( - Context context, String normalizedNumber) { - if (TextUtils.isEmpty(normalizedNumber)) { - return Optional.absent(); - } - return Optional.of( - new HistoryItemActionModule() { - @Override - public int getStringId() { - return R.string.copy_number; - } - - @Override - public int getDrawableId() { - return R.drawable.quantum_ic_content_copy_vd_theme_24; - } - - @Override - public boolean onClick() { - ClipboardUtils.copyText(context, null, normalizedNumber, true); - return false; - } - }); - } -} diff --git a/java/com/android/dialer/historyitemactions/history_item_action_module_info.proto b/java/com/android/dialer/historyitemactions/history_item_action_module_info.proto new file mode 100644 index 000000000..99071a7cd --- /dev/null +++ b/java/com/android/dialer/historyitemactions/history_item_action_module_info.proto @@ -0,0 +1,69 @@ +syntax = "proto2"; + +option java_package = "com.android.dialer.historyitemactions"; +option java_multiple_files = true; +option optimize_for = LITE_RUNTIME; + + +package com.android.dialer.historyitemactions; + +import "java/com/android/dialer/logging/contact_source.proto"; + +// Contains information needed to construct items (modules) in a bottom sheet. +// Next ID: 16 +message HistoryItemActionModuleInfo { + // The dialer-normalized version of a phone number. + // See DialerPhoneNumber.normalized_number. + optional string normalized_number = 1; + + // The ISO 3166-1 two letters country code of the number. + optional string country_iso = 2; + + // The name associated with the number. + optional string name = 3; + + // The type of the call. + // See android.provider.CallLog.Calls.TYPE. + optional int32 call_type = 4; + + // Bit-mask describing features of the call. + // See android.provider.CallLog.Calls.FEATURES. + optional int32 features = 5; + + // The Contacts Provider lookup URI for the contact associated with the + // number. + optional string lookup_uri = 6; + + // The component name of the account used to place or receive the call. + // See android.provider.CallLog.Calls.PHONE_ACCOUNT_COMPONENT_NAME. + optional string phone_account_component_name = 7; + + // Whether the number can be reported as invalid through People API + optional bool can_report_as_invalid_number = 8; + + // Whether assisted dialing is supported. + optional bool can_support_assisted_dialing = 9; + + // Whether carrier video call is supported. + optional bool can_support_carrier_video_call = 10; + + // Whether the number is blocked. + optional bool is_blocked = 11; + + // Whether the number is spam. + optional bool is_spam = 12; + + // Whether the call is to the voicemail inbox. + optional bool is_voicemail_call = 13; + + // The source of the contact if there is one associated with the number. + optional com.android.dialer.logging.ContactSource.Type contact_source = 14; + + // Places that can host items (modules) in a bottom sheet + enum Host { + UNKNOWN = 0; + CALL_LOG = 1; + VOICEMAIL = 2; + } + optional Host host = 15; +} -- cgit v1.2.3 From 0f224557fa34a4b810fb1128cf35231668d6e583 Mon Sep 17 00:00:00 2001 From: calderwoodra Date: Thu, 3 May 2018 15:15:36 -0700 Subject: Aosp fix for v28-support-prelease bottom sheet. The bottomsheet in v28-prelease support library is no longer available. So revert back to the deprecated bottom sheet. Test: manual PiperOrigin-RevId: 195319010 Change-Id: I580ef4d979d50864ea385b01245dfbeb68b8579d --- .../dialer/historyitemactions/HistoryItemActionBottomSheet.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'java/com/android/dialer/historyitemactions') diff --git a/java/com/android/dialer/historyitemactions/HistoryItemActionBottomSheet.java b/java/com/android/dialer/historyitemactions/HistoryItemActionBottomSheet.java index f90effc4c..e3e9e7a64 100644 --- a/java/com/android/dialer/historyitemactions/HistoryItemActionBottomSheet.java +++ b/java/com/android/dialer/historyitemactions/HistoryItemActionBottomSheet.java @@ -20,9 +20,9 @@ import android.content.Context; import android.content.res.ColorStateList; import android.os.Bundle; import android.support.annotation.NonNull; -import android.support.design.bottomsheet.BottomSheetBehavior; -import android.support.design.bottomsheet.BottomSheetBehavior.BottomSheetCallback; -import android.support.design.bottomsheet.BottomSheetDialog; +import android.support.design.widget.BottomSheetBehavior; +import android.support.design.widget.BottomSheetBehavior.BottomSheetCallback; +import android.support.design.widget.BottomSheetDialog; import android.support.v4.content.ContextCompat; import android.text.TextUtils; import android.view.LayoutInflater; -- cgit v1.2.3 From e62700865987d7a46c8d51d7be1144282194c94f Mon Sep 17 00:00:00 2001 From: linyuh Date: Thu, 3 May 2018 15:18:04 -0700 Subject: Filter out unnecessary bottom sheet options for a call to a voicemail box. Bug: 78476115 Test: HistoryItemActionModulesBuilderTest PiperOrigin-RevId: 195319447 Change-Id: I7d431e74c2f4efe6ea3ce24b7d3ae42ebb4525b2 --- .../HistoryItemActionModulesBuilder.java | 36 +++++++++++++++++----- 1 file changed, 29 insertions(+), 7 deletions(-) (limited to 'java/com/android/dialer/historyitemactions') diff --git a/java/com/android/dialer/historyitemactions/HistoryItemActionModulesBuilder.java b/java/com/android/dialer/historyitemactions/HistoryItemActionModulesBuilder.java index ca6d3f3e4..9af08be50 100644 --- a/java/com/android/dialer/historyitemactions/HistoryItemActionModulesBuilder.java +++ b/java/com/android/dialer/historyitemactions/HistoryItemActionModulesBuilder.java @@ -115,7 +115,13 @@ public final class HistoryItemActionModulesBuilder { /** * Adds a module for a carrier video call *or* a Duo video call. * - *

If the number is blocked or marked as spam, this method is a no-op. + *

This method is a no-op if + * + *

    + *
  • the call is one made to a voicemail box, + *
  • the number is blocked, or + *
  • the number is marked as spam. + *
* *

If the provided module info is for a Duo video call and Duo is available, add a Duo video * call module. @@ -132,7 +138,7 @@ public final class HistoryItemActionModulesBuilder { * capability, and Duo is available, add a Duo video call module. */ public HistoryItemActionModulesBuilder addModuleForVideoCall() { - if (moduleInfo.getIsBlocked() || moduleInfo.getIsSpam()) { + if (moduleInfo.getIsVoicemailCall() || moduleInfo.getIsBlocked() || moduleInfo.getIsSpam()) { return this; } @@ -169,12 +175,20 @@ public final class HistoryItemActionModulesBuilder { /** * Adds a module for sending text messages. * - *

The method is a no-op if the number is blocked or empty. + *

The method is a no-op if + * + *

    + *
  • the call is one made to a voicemail box, + *
  • the number is blocked, or + *
  • the number is empty. + *
*/ public HistoryItemActionModulesBuilder addModuleForSendingTextMessage() { - // TODO(zachh): There are other conditions where this module should not be shown; consider - // voicemail, business numbers, etc. - if (moduleInfo.getIsBlocked() || TextUtils.isEmpty(moduleInfo.getNormalizedNumber())) { + // TODO(zachh): There are other conditions where this module should not be shown + // (e.g., business numbers). + if (moduleInfo.getIsVoicemailCall() + || moduleInfo.getIsBlocked() + || TextUtils.isEmpty(moduleInfo.getNormalizedNumber())) { return this; } @@ -203,6 +217,7 @@ public final class HistoryItemActionModulesBuilder { *

The method is a no-op if * *

    + *
  • the call is one made to a voicemail box, *
  • the number is blocked, *
  • the number is marked as spam, *
  • the number is empty, or @@ -210,7 +225,8 @@ public final class HistoryItemActionModulesBuilder { *
*/ public HistoryItemActionModulesBuilder addModuleForAddingToContacts() { - if (moduleInfo.getIsBlocked() + if (moduleInfo.getIsVoicemailCall() + || moduleInfo.getIsBlocked() || moduleInfo.getIsSpam() || isExistingContact() || TextUtils.isEmpty(moduleInfo.getNormalizedNumber())) { @@ -237,6 +253,8 @@ public final class HistoryItemActionModulesBuilder { /** * Add modules for blocking/unblocking a number and/or marking it as spam/not spam. * + *

The method is a no-op if the call is one made to a voicemail box. + * *

If a number is marked as spam, add two modules: * *

    @@ -249,6 +267,10 @@ public final class HistoryItemActionModulesBuilder { *

    If a number is not blocked or marked as spam, add the "Block/Report spam" module. */ public HistoryItemActionModulesBuilder addModuleForBlockedOrSpamNumber() { + if (moduleInfo.getIsVoicemailCall()) { + return this; + } + BlockReportSpamDialogInfo blockReportSpamDialogInfo = BlockReportSpamDialogInfo.newBuilder() .setNormalizedNumber(moduleInfo.getNormalizedNumber()) -- cgit v1.2.3 From 763ce4404ae8e4199da719359a1b01389884cec4 Mon Sep 17 00:00:00 2001 From: linyuh Date: Fri, 4 May 2018 10:54:12 -0700 Subject: Remove TODOs for showing SIM info in the bottom sheet & call details. Bug: 74522027 Test: None PiperOrigin-RevId: 195439124 Change-Id: Ibab0bc7e58bd1b23255d9af476c5b98ed89f13fa --- .../historyitemactions/history_item_bottom_sheet_header_info.proto | 2 -- 1 file changed, 2 deletions(-) (limited to 'java/com/android/dialer/historyitemactions') diff --git a/java/com/android/dialer/historyitemactions/history_item_bottom_sheet_header_info.proto b/java/com/android/dialer/historyitemactions/history_item_bottom_sheet_header_info.proto index ef71ecd7e..04d9f2259 100644 --- a/java/com/android/dialer/historyitemactions/history_item_bottom_sheet_header_info.proto +++ b/java/com/android/dialer/historyitemactions/history_item_bottom_sheet_header_info.proto @@ -36,6 +36,4 @@ message HistoryItemBottomSheetHeaderInfo { // "Blocked • Mobile • 555-1234", and // "Spam • Mobile • 555-1234". optional string secondary_text = 4; - - // TODO(a bug): Add SIM info. } -- cgit v1.2.3