summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Erfanian <erfanian@google.com>2018-04-27 15:32:24 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2018-04-27 15:32:24 +0000
commitc28ed7444c25d52fd3996f8edf076a1d740d4e05 (patch)
tree78f3eaa9f7fcd5ff7cdd5cead74b651d3636e618
parent52a161148b057ebd4b0c86228b82cba305f1102d (diff)
parente7d83218d752f677c859a6c88181d24dc36a8c83 (diff)
Merge changes I706802c0,I59f9b334,Ica9301f4,I78e0e0fc,I1d574287, ...
* changes: Show Cequint info in the new call log. Implement CequintPhoneLookup Fix impression logging for spam blocking promo dialog shown in after call notification. Build out the bottom sheet for suggested contacts in Speed Dial. Fix bug that title of RTT call is not centered. Add advisory text to RTT call about transcript storage.
-rw-r--r--assets/quantum/res/drawable/quantum_ic_question_answer_vd_theme_24.xml25
-rw-r--r--java/com/android/dialer/app/calllog/BlockReportSpamListener.java27
-rw-r--r--java/com/android/dialer/app/calllog/CallLogFragment.java2
-rw-r--r--java/com/android/dialer/callintent/CallIntentBuilder.java1
-rw-r--r--java/com/android/dialer/calllog/database/contract/number_attributes.proto6
-rw-r--r--java/com/android/dialer/calllogutils/CallLogEntryText.java7
-rw-r--r--java/com/android/dialer/calllogutils/NumberAttributesConverter.java3
-rw-r--r--java/com/android/dialer/historyitemactions/HistoryItemActionBottomSheet.java8
-rw-r--r--java/com/android/dialer/historyitemactions/HistoryItemActionModule.java5
-rw-r--r--java/com/android/dialer/historyitemactions/res/layout/module_layout.xml1
-rw-r--r--java/com/android/dialer/oem/CequintCallerIdManager.java113
-rw-r--r--java/com/android/dialer/phonelookup/cequint/CequintPhoneLookup.java90
-rw-r--r--java/com/android/dialer/phonelookup/consolidator/PhoneLookupInfoConsolidator.java45
-rw-r--r--java/com/android/dialer/phonenumbercache/ContactInfoHelper.java2
-rw-r--r--java/com/android/dialer/spam/promo/SpamBlockingPromoHelper.java28
-rw-r--r--java/com/android/dialer/speeddial/SpeedDialFragment.java114
-rw-r--r--java/com/android/dialer/speeddial/SuggestionViewHolder.java35
-rw-r--r--java/com/android/dialer/speeddial/loader/SpeedDialUiItem.java12
-rw-r--r--java/com/android/dialer/speeddial/res/layout/suggestion_row_layout.xml5
-rw-r--r--java/com/android/incallui/ContactInfoCache.java2
-rw-r--r--java/com/android/incallui/rtt/impl/AdvisoryViewHolder.java29
-rw-r--r--java/com/android/incallui/rtt/impl/RttChatAdapter.java107
-rw-r--r--java/com/android/incallui/rtt/impl/RttChatFragment.java1
-rw-r--r--java/com/android/incallui/rtt/impl/res/layout/frag_rtt_chat.xml2
-rw-r--r--java/com/android/incallui/rtt/impl/res/layout/rtt_banner.xml33
-rw-r--r--java/com/android/incallui/rtt/impl/res/layout/rtt_transcript_advisory.xml41
-rw-r--r--java/com/android/incallui/rtt/impl/res/values/dimens.xml3
-rw-r--r--java/com/android/incallui/rtt/impl/res/values/strings.xml3
-rw-r--r--java/com/android/incallui/spam/SpamNotificationActivity.java45
29 files changed, 640 insertions, 155 deletions
diff --git a/assets/quantum/res/drawable/quantum_ic_question_answer_vd_theme_24.xml b/assets/quantum/res/drawable/quantum_ic_question_answer_vd_theme_24.xml
new file mode 100644
index 000000000..f607d5312
--- /dev/null
+++ b/assets/quantum/res/drawable/quantum_ic_question_answer_vd_theme_24.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ 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
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"
+ android:tint="?attr/colorControlNormal">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M21,6h-2v9L6,15v2c0,0.55 0.45,1 1,1h11l4,4L22,7c0,-0.55 -0.45,-1 -1,-1zM17,12L17,3c0,-0.55 -0.45,-1 -1,-1L3,2c-0.55,0 -1,0.45 -1,1v14l4,-4h10c0.55,0 1,-0.45 1,-1z"/>
+</vector>
diff --git a/java/com/android/dialer/app/calllog/BlockReportSpamListener.java b/java/com/android/dialer/app/calllog/BlockReportSpamListener.java
index 551791850..987615f5f 100644
--- a/java/com/android/dialer/app/calllog/BlockReportSpamListener.java
+++ b/java/com/android/dialer/app/calllog/BlockReportSpamListener.java
@@ -206,11 +206,28 @@ public class BlockReportSpamListener implements CallLogListItemViewHolder.OnClic
}
private void showSpamBlockingPromoDialog() {
- if (spamBlockingPromoHelper.shouldShowSpamBlockingPromo()) {
- spamBlockingPromoHelper.showSpamBlockingPromoDialog(
- fragmentManager,
- success -> spamBlockingPromoHelper.showModifySettingOnCompleteSnackbar(rootView, success),
- null /* onDissmissListener */);
+ if (!spamBlockingPromoHelper.shouldShowSpamBlockingPromo()) {
+ return;
}
+
+ Logger.get(context).logImpression(DialerImpression.Type.SPAM_BLOCKING_CALL_LOG_PROMO_SHOWN);
+ spamBlockingPromoHelper.showSpamBlockingPromoDialog(
+ fragmentManager,
+ () -> {
+ Logger.get(context)
+ .logImpression(DialerImpression.Type.SPAM_BLOCKING_ENABLED_THROUGH_CALL_LOG_PROMO);
+ spamSettings.modifySpamBlockingSetting(
+ true,
+ success -> {
+ if (!success) {
+ Logger.get(context)
+ .logImpression(
+ DialerImpression.Type
+ .SPAM_BLOCKING_MODIFY_FAILURE_THROUGH_CALL_LOG_PROMO);
+ }
+ spamBlockingPromoHelper.showModifySettingOnCompleteSnackbar(rootView, success);
+ });
+ },
+ null /* onDismissListener */);
}
}
diff --git a/java/com/android/dialer/app/calllog/CallLogFragment.java b/java/com/android/dialer/app/calllog/CallLogFragment.java
index 4e968f095..1e55c6358 100644
--- a/java/com/android/dialer/app/calllog/CallLogFragment.java
+++ b/java/com/android/dialer/app/calllog/CallLogFragment.java
@@ -449,7 +449,7 @@ public class CallLogFragment extends Fragment
super.onStart();
CequintCallerIdManager cequintCallerIdManager = null;
if (CequintCallerIdManager.isCequintCallerIdEnabled(getContext())) {
- cequintCallerIdManager = CequintCallerIdManager.createInstanceForCallLog();
+ cequintCallerIdManager = new CequintCallerIdManager();
}
contactInfoCache.setCequintCallerIdManager(cequintCallerIdManager);
}
diff --git a/java/com/android/dialer/callintent/CallIntentBuilder.java b/java/com/android/dialer/callintent/CallIntentBuilder.java
index 0f9f8905d..92efd392b 100644
--- a/java/com/android/dialer/callintent/CallIntentBuilder.java
+++ b/java/com/android/dialer/callintent/CallIntentBuilder.java
@@ -152,6 +152,7 @@ public class CallIntentBuilder implements Parcelable {
return isVideoCall;
}
+ /** Default false. Should only be set to true if the number has a lookup URI. */
public CallIntentBuilder setAllowAssistedDial(boolean allowAssistedDial) {
this.allowAssistedDial = allowAssistedDial;
return this;
diff --git a/java/com/android/dialer/calllog/database/contract/number_attributes.proto b/java/com/android/dialer/calllog/database/contract/number_attributes.proto
index f99693d4e..f42974d36 100644
--- a/java/com/android/dialer/calllog/database/contract/number_attributes.proto
+++ b/java/com/android/dialer/calllog/database/contract/number_attributes.proto
@@ -24,7 +24,7 @@ package com.android.dialer;
import "java/com/android/dialer/logging/contact_source.proto";
// Information related to the phone number of the call.
-// Next ID: 13
+// Next ID: 14
message NumberAttributes {
// The name (which may be a person's name or business name, but not a number)
// formatted exactly as it should appear to the user. If the user's locale or
@@ -70,4 +70,8 @@ message NumberAttributes {
// Whether the number can be reached via a carrier video call.
optional bool can_support_carrier_video_call = 12;
+
+ // Description of the number's geolocation (e.g., "Mountain View, CA").
+ // This string is for display purpose only.
+ optional string geolocation = 13;
} \ No newline at end of file
diff --git a/java/com/android/dialer/calllogutils/CallLogEntryText.java b/java/com/android/dialer/calllogutils/CallLogEntryText.java
index e346de011..a1a2a3b48 100644
--- a/java/com/android/dialer/calllogutils/CallLogEntryText.java
+++ b/java/com/android/dialer/calllogutils/CallLogEntryText.java
@@ -214,7 +214,12 @@ public final class CallLogEntryText {
// (1) there is no number type label, and
// (2) the number is not spam.
if (TextUtils.isEmpty(numberTypeLabel) && !row.getNumberAttributes().getIsSpam()) {
- String location = row.getGeocodedLocation();
+ // If number attributes contain a location (obtained from a PhoneLookup), use it instead
+ // of the one from the annotated call log.
+ String location =
+ !TextUtils.isEmpty(row.getNumberAttributes().getGeolocation())
+ ? row.getNumberAttributes().getGeolocation()
+ : row.getGeocodedLocation();
if (!TextUtils.isEmpty(location)) {
if (secondaryText.length() > 0) {
secondaryText.append(", ");
diff --git a/java/com/android/dialer/calllogutils/NumberAttributesConverter.java b/java/com/android/dialer/calllogutils/NumberAttributesConverter.java
index f4fab8405..9f07fdac5 100644
--- a/java/com/android/dialer/calllogutils/NumberAttributesConverter.java
+++ b/java/com/android/dialer/calllogutils/NumberAttributesConverter.java
@@ -56,6 +56,7 @@ public final class NumberAttributesConverter {
.setCanReportAsInvalidNumber(phoneLookupInfoConsolidator.canReportAsInvalidNumber())
.setIsCp2InfoIncomplete(phoneLookupInfoConsolidator.isDefaultCp2InfoIncomplete())
.setContactSource(phoneLookupInfoConsolidator.getContactSource())
- .setCanSupportCarrierVideoCall(phoneLookupInfoConsolidator.canSupportCarrierVideoCall());
+ .setCanSupportCarrierVideoCall(phoneLookupInfoConsolidator.canSupportCarrierVideoCall())
+ .setGeolocation(phoneLookupInfoConsolidator.getGeolocation());
}
}
diff --git a/java/com/android/dialer/historyitemactions/HistoryItemActionBottomSheet.java b/java/com/android/dialer/historyitemactions/HistoryItemActionBottomSheet.java
index 79205a7d9..28663c17d 100644
--- a/java/com/android/dialer/historyitemactions/HistoryItemActionBottomSheet.java
+++ b/java/com/android/dialer/historyitemactions/HistoryItemActionBottomSheet.java
@@ -17,8 +17,10 @@
package com.android.dialer.historyitemactions;
import android.content.Context;
+import android.content.res.ColorStateList;
import android.os.Bundle;
import android.support.design.widget.BottomSheetDialog;
+import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
@@ -109,6 +111,12 @@ public class HistoryItemActionBottomSheet extends BottomSheetDialog implements O
((TextView) moduleView.findViewById(R.id.module_text)).setText(module.getStringId());
((ImageView) moduleView.findViewById(R.id.module_image))
.setImageResource(module.getDrawableId());
+ if (module.tintDrawable()) {
+ ((ImageView) moduleView.findViewById(R.id.module_image))
+ .setImageTintList(
+ ColorStateList.valueOf(
+ ContextCompat.getColor(getContext(), R.color.secondary_text_color)));
+ }
moduleView.setOnClickListener(this);
moduleView.setTag(module);
return moduleView;
diff --git a/java/com/android/dialer/historyitemactions/HistoryItemActionModule.java b/java/com/android/dialer/historyitemactions/HistoryItemActionModule.java
index d64cbca53..e948924d7 100644
--- a/java/com/android/dialer/historyitemactions/HistoryItemActionModule.java
+++ b/java/com/android/dialer/historyitemactions/HistoryItemActionModule.java
@@ -32,6 +32,11 @@ public interface HistoryItemActionModule {
@DrawableRes
int getDrawableId();
+ /** Returns true if tint can be applied to the drawable. */
+ default boolean tintDrawable() {
+ return true;
+ }
+
/** @return true if the bottom sheet should close, false otherwise */
boolean onClick();
}
diff --git a/java/com/android/dialer/historyitemactions/res/layout/module_layout.xml b/java/com/android/dialer/historyitemactions/res/layout/module_layout.xml
index 9aee67937..063051947 100644
--- a/java/com/android/dialer/historyitemactions/res/layout/module_layout.xml
+++ b/java/com/android/dialer/historyitemactions/res/layout/module_layout.xml
@@ -28,7 +28,6 @@
android:layout_height="@dimen/contact_actions_image_size"
android:layout_marginStart="@dimen/contact_actions_image_margin"
android:layout_marginEnd="@dimen/contact_actions_image_margin"
- android:tint="@color/dialer_secondary_text_color"
android:scaleType="center"/>
<TextView
diff --git a/java/com/android/dialer/oem/CequintCallerIdManager.java b/java/com/android/dialer/oem/CequintCallerIdManager.java
index 55cafc15e..53f5352b2 100644
--- a/java/com/android/dialer/oem/CequintCallerIdManager.java
+++ b/java/com/android/dialer/oem/CequintCallerIdManager.java
@@ -24,6 +24,7 @@ import android.os.Build.VERSION_CODES;
import android.support.annotation.AnyThread;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
import android.support.annotation.WorkerThread;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
@@ -45,7 +46,8 @@ import java.util.concurrent.ConcurrentHashMap;
@TargetApi(VERSION_CODES.N)
public class CequintCallerIdManager {
- private static final String CONFIG_CALLER_ID_ENABLED = "config_caller_id_enabled";
+ @VisibleForTesting
+ public static final String CONFIG_CALLER_ID_ENABLED = "config_caller_id_enabled";
private static final int CALLER_ID_LOOKUP_USER_PROVIDED_CID = 0x0001;
private static final int CALLER_ID_LOOKUP_SYSTEM_PROVIDED_CID = 0x0002;
@@ -53,36 +55,43 @@ public class CequintCallerIdManager {
private static final String[] EMPTY_PROJECTION = new String[] {};
- // Column names in Cequint provider.
- private static final String CITY_NAME = "cid_pCityName";
- private static final String STATE_NAME = "cid_pStateName";
- private static final String STATE_ABBR = "cid_pStateAbbr";
- private static final String COUNTRY_NAME = "cid_pCountryName";
- private static final String COMPANY = "cid_pCompany";
- private static final String NAME = "cid_pName";
- private static final String FIRST_NAME = "cid_pFirstName";
- private static final String LAST_NAME = "cid_pLastName";
- private static final String IMAGE = "cid_pLogo";
- private static final String DISPLAY_NAME = "cid_pDisplayName";
+ /** Column names in Cequint content provider. */
+ @VisibleForTesting
+ public static final class CequintColumnNames {
+ public static final String CITY_NAME = "cid_pCityName";
+ public static final String STATE_NAME = "cid_pStateName";
+ public static final String STATE_ABBR = "cid_pStateAbbr";
+ public static final String COUNTRY_NAME = "cid_pCountryName";
+ public static final String COMPANY = "cid_pCompany";
+ public static final String NAME = "cid_pName";
+ public static final String FIRST_NAME = "cid_pFirstName";
+ public static final String LAST_NAME = "cid_pLastName";
+ public static final String PHOTO_URI = "cid_pLogo";
+ public static final String DISPLAY_NAME = "cid_pDisplayName";
+ }
private static boolean hasAlreadyCheckedCequintCallerIdPackage;
private static String cequintProviderAuthority;
- // TODO(wangqi): Revisit it and maybe remove it if it's not necessary.
- private final ConcurrentHashMap<String, CequintCallerIdContact> callLogCache;
+ // TODO(a bug): Revisit it and maybe remove it if it's not necessary.
+ private final ConcurrentHashMap<String, CequintCallerIdContact> callLogCache =
+ new ConcurrentHashMap<>();
/** Cequint caller ID contact information. */
@AutoValue
public abstract static class CequintCallerIdContact {
+ @Nullable
public abstract String name();
/**
* Description of the geolocation (e.g., "Mountain View, CA"), which is for display purpose
* only.
*/
+ @Nullable
public abstract String geolocation();
+ @Nullable
public abstract String photoUri();
static Builder builder() {
@@ -91,11 +100,11 @@ public class CequintCallerIdManager {
@AutoValue.Builder
abstract static class Builder {
- abstract Builder setName(String name);
+ abstract Builder setName(@Nullable String name);
- abstract Builder setGeolocation(String geolocation);
+ abstract Builder setGeolocation(@Nullable String geolocation);
- abstract Builder setPhotoUri(String photoUri);
+ abstract Builder setPhotoUri(@Nullable String photoUri);
abstract CequintCallerIdContact build();
}
@@ -125,17 +134,14 @@ public class CequintCallerIdManager {
return cequintProviderAuthority != null;
}
- public static CequintCallerIdManager createInstanceForCallLog() {
- return new CequintCallerIdManager();
- }
-
+ /** Returns a {@link CequintCallerIdContact} for a call. */
@WorkerThread
@Nullable
- public static CequintCallerIdContact getCequintCallerIdContactForInCall(
+ public static CequintCallerIdContact getCequintCallerIdContactForCall(
Context context, String number, String cnapName, boolean isIncoming) {
Assert.isWorkerThread();
LogUtil.d(
- "CequintCallerIdManager.getCequintCallerIdContactForInCall",
+ "CequintCallerIdManager.getCequintCallerIdContactForCall",
"number: %s, cnapName: %s, isIncoming: %b",
LogUtil.sanitizePhoneNumber(number),
LogUtil.sanitizePii(cnapName),
@@ -151,29 +157,51 @@ public class CequintCallerIdManager {
return lookup(context, getIncallLookupUri(), number, flags);
}
+ /**
+ * Returns a cached {@link CequintCallerIdContact} associated with the provided number. If no
+ * contact can be found in the cache, look up the number using the Cequint content provider.
+ *
+ * @deprecated This method is for the old call log only. New code should use {@link
+ * #getCequintCallerIdContactForNumber(Context, String)}.
+ */
+ @Deprecated
@WorkerThread
@Nullable
- public CequintCallerIdContact getCequintCallerIdContact(Context context, String number) {
+ public CequintCallerIdContact getCachedCequintCallerIdContact(Context context, String number) {
Assert.isWorkerThread();
LogUtil.d(
- "CequintCallerIdManager.getCequintCallerIdContact",
+ "CequintCallerIdManager.getCachedCequintCallerIdContact",
"number: %s",
LogUtil.sanitizePhoneNumber(number));
if (callLogCache.containsKey(number)) {
return callLogCache.get(number);
}
CequintCallerIdContact cequintCallerIdContact =
- lookup(
- context,
- getLookupUri(),
- PhoneNumberUtils.stripSeparators(number),
- new String[] {"system"});
+ getCequintCallerIdContactForNumber(context, number);
if (cequintCallerIdContact != null) {
callLogCache.put(number, cequintCallerIdContact);
}
return cequintCallerIdContact;
}
+ /**
+ * Returns a {@link CequintCallerIdContact} associated with the provided number by looking it up
+ * using the Cequint content provider.
+ */
+ @WorkerThread
+ @Nullable
+ public static CequintCallerIdContact getCequintCallerIdContactForNumber(
+ Context context, String number) {
+ Assert.isWorkerThread();
+ LogUtil.d(
+ "CequintCallerIdManager.getCequintCallerIdContactForNumber",
+ "number: %s",
+ LogUtil.sanitizePhoneNumber(number));
+
+ return lookup(
+ context, getLookupUri(), PhoneNumberUtils.stripSeparators(number), new String[] {"system"});
+ }
+
@WorkerThread
@Nullable
private static CequintCallerIdContact lookup(
@@ -185,16 +213,17 @@ public class CequintCallerIdManager {
try (Cursor cursor =
context.getContentResolver().query(uri, EMPTY_PROJECTION, number, flags, null)) {
if (cursor != null && cursor.moveToFirst()) {
- String city = getString(cursor, cursor.getColumnIndex(CITY_NAME));
- String state = getString(cursor, cursor.getColumnIndex(STATE_NAME));
- String stateAbbr = getString(cursor, cursor.getColumnIndex(STATE_ABBR));
- String country = getString(cursor, cursor.getColumnIndex(COUNTRY_NAME));
- String company = getString(cursor, cursor.getColumnIndex(COMPANY));
- String name = getString(cursor, cursor.getColumnIndex(NAME));
- String firstName = getString(cursor, cursor.getColumnIndex(FIRST_NAME));
- String lastName = getString(cursor, cursor.getColumnIndex(LAST_NAME));
- String photoUri = getString(cursor, cursor.getColumnIndex(IMAGE));
- String displayName = getString(cursor, cursor.getColumnIndex(DISPLAY_NAME));
+ String city = getString(cursor, cursor.getColumnIndex(CequintColumnNames.CITY_NAME));
+ String state = getString(cursor, cursor.getColumnIndex(CequintColumnNames.STATE_NAME));
+ String stateAbbr = getString(cursor, cursor.getColumnIndex(CequintColumnNames.STATE_ABBR));
+ String country = getString(cursor, cursor.getColumnIndex(CequintColumnNames.COUNTRY_NAME));
+ String company = getString(cursor, cursor.getColumnIndex(CequintColumnNames.COMPANY));
+ String name = getString(cursor, cursor.getColumnIndex(CequintColumnNames.NAME));
+ String firstName = getString(cursor, cursor.getColumnIndex(CequintColumnNames.FIRST_NAME));
+ String lastName = getString(cursor, cursor.getColumnIndex(CequintColumnNames.LAST_NAME));
+ String photoUri = getString(cursor, cursor.getColumnIndex(CequintColumnNames.PHOTO_URI));
+ String displayName =
+ getString(cursor, cursor.getColumnIndex(CequintColumnNames.DISPLAY_NAME));
String contactName =
TextUtils.isEmpty(displayName)
@@ -293,8 +322,4 @@ public class CequintCallerIdManager {
private static Uri getIncallLookupUri() {
return Uri.parse("content://" + cequintProviderAuthority + "/incalllookup");
}
-
- private CequintCallerIdManager() {
- callLogCache = new ConcurrentHashMap<>();
- }
}
diff --git a/java/com/android/dialer/phonelookup/cequint/CequintPhoneLookup.java b/java/com/android/dialer/phonelookup/cequint/CequintPhoneLookup.java
index ce2cd18ad..36d0be40f 100644
--- a/java/com/android/dialer/phonelookup/cequint/CequintPhoneLookup.java
+++ b/java/com/android/dialer/phonelookup/cequint/CequintPhoneLookup.java
@@ -18,33 +18,85 @@ package com.android.dialer.phonelookup.cequint;
import android.content.Context;
import android.telecom.Call;
+import android.text.TextUtils;
import com.android.dialer.DialerPhoneNumber;
+import com.android.dialer.common.Assert;
+import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor;
+import com.android.dialer.common.concurrent.Annotations.LightweightExecutor;
+import com.android.dialer.inject.ApplicationContext;
+import com.android.dialer.location.GeoUtil;
+import com.android.dialer.oem.CequintCallerIdManager;
+import com.android.dialer.oem.CequintCallerIdManager.CequintCallerIdContact;
import com.android.dialer.phonelookup.PhoneLookup;
import com.android.dialer.phonelookup.PhoneLookupInfo;
import com.android.dialer.phonelookup.PhoneLookupInfo.CequintInfo;
+import com.android.dialer.phonenumberproto.DialerPhoneNumberUtil;
+import com.android.dialer.telecom.TelecomCallUtil;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
import javax.inject.Inject;
/** PhoneLookup implementation for Cequint. */
public class CequintPhoneLookup implements PhoneLookup<CequintInfo> {
+ private final Context appContext;
+ private final ListeningExecutorService backgroundExecutorService;
+ private final ListeningExecutorService lightweightExecutorService;
+
@Inject
- CequintPhoneLookup() {}
+ CequintPhoneLookup(
+ @ApplicationContext Context appContext,
+ @BackgroundExecutor ListeningExecutorService backgroundExecutorService,
+ @LightweightExecutor ListeningExecutorService lightweightExecutorService) {
+ this.appContext = appContext;
+ this.backgroundExecutorService = backgroundExecutorService;
+ this.lightweightExecutorService = lightweightExecutorService;
+ }
@Override
public ListenableFuture<CequintInfo> lookup(Context appContext, Call call) {
- // TODO(a bug): Override the default implementation in the PhoneLookup interface
- // as a Cequint lookup requires info in the provided call.
- return Futures.immediateFuture(CequintInfo.getDefaultInstance());
+ if (!CequintCallerIdManager.isCequintCallerIdEnabled(appContext)) {
+ return Futures.immediateFuture(CequintInfo.getDefaultInstance());
+ }
+
+ ListenableFuture<DialerPhoneNumber> dialerPhoneNumberFuture =
+ backgroundExecutorService.submit(
+ () -> {
+ DialerPhoneNumberUtil dialerPhoneNumberUtil = new DialerPhoneNumberUtil();
+ return dialerPhoneNumberUtil.parse(
+ TelecomCallUtil.getNumber(call), GeoUtil.getCurrentCountryIso(appContext));
+ });
+ String callerDisplayName = call.getDetails().getCallerDisplayName();
+ boolean isIncomingCall = (call.getState() == Call.STATE_RINGING);
+
+ return Futures.transformAsync(
+ dialerPhoneNumberFuture,
+ dialerPhoneNumber ->
+ backgroundExecutorService.submit(
+ () ->
+ buildCequintInfo(
+ CequintCallerIdManager.getCequintCallerIdContactForCall(
+ appContext,
+ Assert.isNotNull(dialerPhoneNumber).getNormalizedNumber(),
+ callerDisplayName,
+ isIncomingCall))),
+ lightweightExecutorService);
}
@Override
public ListenableFuture<CequintInfo> lookup(DialerPhoneNumber dialerPhoneNumber) {
- // TODO(a bug): Implement this method.
- return Futures.immediateFuture(CequintInfo.getDefaultInstance());
+ if (!CequintCallerIdManager.isCequintCallerIdEnabled(appContext)) {
+ return Futures.immediateFuture(CequintInfo.getDefaultInstance());
+ }
+
+ return backgroundExecutorService.submit(
+ () ->
+ buildCequintInfo(
+ CequintCallerIdManager.getCequintCallerIdContactForNumber(
+ appContext, dialerPhoneNumber.getNormalizedNumber())));
}
@Override
@@ -75,16 +127,38 @@ public class CequintPhoneLookup implements PhoneLookup<CequintInfo> {
@Override
public void registerContentObservers() {
- // No content observers for Cequint info.
+ // No need to register a content observer as the Cequint content provider doesn't support batch
+ // queries.
}
@Override
public void unregisterContentObservers() {
- // No content observers for Cequint info.
+ // Nothing to be done as no content observer is registered.
}
@Override
public ListenableFuture<Void> clearData() {
return Futures.immediateFuture(null);
}
+
+ /**
+ * Builds a {@link CequintInfo} proto based on the given {@link CequintCallerIdContact} returned
+ * by {@link CequintCallerIdManager}.
+ */
+ private static CequintInfo buildCequintInfo(CequintCallerIdContact cequintCallerIdContact) {
+ CequintInfo.Builder cequintInfoBuilder = CequintInfo.newBuilder();
+
+ // Every field in CequintCallerIdContact can be null.
+ if (!TextUtils.isEmpty(cequintCallerIdContact.name())) {
+ cequintInfoBuilder.setName(cequintCallerIdContact.name());
+ }
+ if (!TextUtils.isEmpty(cequintCallerIdContact.geolocation())) {
+ cequintInfoBuilder.setGeolocation(cequintCallerIdContact.geolocation());
+ }
+ if (!TextUtils.isEmpty(cequintCallerIdContact.photoUri())) {
+ cequintInfoBuilder.setPhotoUri(cequintCallerIdContact.photoUri());
+ }
+
+ return cequintInfoBuilder.build();
+ }
}
diff --git a/java/com/android/dialer/phonelookup/consolidator/PhoneLookupInfoConsolidator.java b/java/com/android/dialer/phonelookup/consolidator/PhoneLookupInfoConsolidator.java
index 07aea749d..23ecc8301 100644
--- a/java/com/android/dialer/phonelookup/consolidator/PhoneLookupInfoConsolidator.java
+++ b/java/com/android/dialer/phonelookup/consolidator/PhoneLookupInfoConsolidator.java
@@ -46,6 +46,7 @@ public final class PhoneLookupInfoConsolidator {
NameSource.CP2_DEFAULT_DIRECTORY,
NameSource.CP2_EXTENDED_DIRECTORY,
NameSource.PEOPLE_API,
+ NameSource.CEQUINT,
NameSource.CNAP
})
@interface NameSource {
@@ -53,7 +54,8 @@ public final class PhoneLookupInfoConsolidator {
int CP2_DEFAULT_DIRECTORY = 1;
int CP2_EXTENDED_DIRECTORY = 2;
int PEOPLE_API = 3;
- int CNAP = 4;
+ int CEQUINT = 4;
+ int CNAP = 5;
}
/**
@@ -78,6 +80,7 @@ public final class PhoneLookupInfoConsolidator {
NameSource.CP2_DEFAULT_DIRECTORY,
NameSource.CP2_EXTENDED_DIRECTORY,
NameSource.PEOPLE_API,
+ NameSource.CEQUINT,
NameSource.CNAP);
private final @NameSource int nameSource;
@@ -106,6 +109,8 @@ public final class PhoneLookupInfoConsolidator {
return ContactSource.Type.SOURCE_TYPE_EXTENDED;
case NameSource.PEOPLE_API:
return getRefinedPeopleApiSource();
+ case NameSource.CEQUINT:
+ return ContactSource.Type.SOURCE_TYPE_CEQUINT_CALLER_ID;
case NameSource.CNAP:
return ContactSource.Type.SOURCE_TYPE_CNAP;
case NameSource.NONE:
@@ -146,6 +151,8 @@ public final class PhoneLookupInfoConsolidator {
return Assert.isNotNull(firstExtendedCp2Contact).getName();
case NameSource.PEOPLE_API:
return phoneLookupInfo.getPeopleApiInfo().getDisplayName();
+ case NameSource.CEQUINT:
+ return phoneLookupInfo.getCequintInfo().getName();
case NameSource.CNAP:
return phoneLookupInfo.getCnapInfo().getName();
case NameSource.NONE:
@@ -170,6 +177,7 @@ public final class PhoneLookupInfoConsolidator {
case NameSource.CP2_EXTENDED_DIRECTORY:
return Assert.isNotNull(firstExtendedCp2Contact).getPhotoThumbnailUri();
case NameSource.PEOPLE_API:
+ case NameSource.CEQUINT:
case NameSource.CNAP:
case NameSource.NONE:
return "";
@@ -192,6 +200,8 @@ public final class PhoneLookupInfoConsolidator {
return Assert.isNotNull(firstDefaultCp2Contact).getPhotoUri();
case NameSource.CP2_EXTENDED_DIRECTORY:
return Assert.isNotNull(firstExtendedCp2Contact).getPhotoUri();
+ case NameSource.CEQUINT:
+ return phoneLookupInfo.getCequintInfo().getPhotoUri();
case NameSource.PEOPLE_API:
case NameSource.CNAP:
case NameSource.NONE:
@@ -213,6 +223,7 @@ public final class PhoneLookupInfoConsolidator {
case NameSource.CP2_EXTENDED_DIRECTORY:
return Math.max(Assert.isNotNull(firstExtendedCp2Contact).getPhotoId(), 0);
case NameSource.PEOPLE_API:
+ case NameSource.CEQUINT:
case NameSource.CNAP:
case NameSource.NONE:
return 0;
@@ -235,6 +246,7 @@ public final class PhoneLookupInfoConsolidator {
return Assert.isNotNull(firstExtendedCp2Contact).getLookupUri();
case NameSource.PEOPLE_API:
return Assert.isNotNull(phoneLookupInfo.getPeopleApiInfo().getLookupUri());
+ case NameSource.CEQUINT:
case NameSource.CNAP:
case NameSource.NONE:
return "";
@@ -259,6 +271,30 @@ public final class PhoneLookupInfoConsolidator {
case NameSource.CP2_EXTENDED_DIRECTORY:
return Assert.isNotNull(firstExtendedCp2Contact).getLabel();
case NameSource.PEOPLE_API:
+ case NameSource.CEQUINT:
+ case NameSource.CNAP:
+ case NameSource.NONE:
+ return "";
+ default:
+ throw Assert.createUnsupportedOperationFailException(
+ String.format("Unsupported name source: %s", nameSource));
+ }
+ }
+
+ /**
+ * The {@link PhoneLookupInfo} passed to the constructor is associated with a number. This method
+ * returns the number's geolocation (which is for display purpose only).
+ *
+ * <p>If no geolocation can be obtained from the {@link PhoneLookupInfo}, an empty string will be
+ * returned.
+ */
+ public String getGeolocation() {
+ switch (nameSource) {
+ case NameSource.CEQUINT:
+ return phoneLookupInfo.getCequintInfo().getGeolocation();
+ case NameSource.CP2_DEFAULT_DIRECTORY:
+ case NameSource.CP2_EXTENDED_DIRECTORY:
+ case NameSource.PEOPLE_API:
case NameSource.CNAP:
case NameSource.NONE:
return "";
@@ -320,6 +356,7 @@ public final class PhoneLookupInfoConsolidator {
switch (nameSource) {
case NameSource.CP2_DEFAULT_DIRECTORY:
case NameSource.CP2_EXTENDED_DIRECTORY:
+ case NameSource.CEQUINT:
case NameSource.CNAP:
case NameSource.NONE:
return false;
@@ -343,6 +380,7 @@ public final class PhoneLookupInfoConsolidator {
return Assert.isNotNull(firstDefaultCp2Contact).getCanSupportCarrierVideoCall();
case NameSource.CP2_EXTENDED_DIRECTORY:
case NameSource.PEOPLE_API:
+ case NameSource.CEQUINT:
case NameSource.CNAP:
case NameSource.NONE:
return false;
@@ -396,6 +434,11 @@ public final class PhoneLookupInfoConsolidator {
return NameSource.PEOPLE_API;
}
break;
+ case NameSource.CEQUINT:
+ if (!phoneLookupInfo.getCequintInfo().getName().isEmpty()) {
+ return NameSource.CEQUINT;
+ }
+ break;
case NameSource.CNAP:
if (!phoneLookupInfo.getCnapInfo().getName().isEmpty()) {
return NameSource.CNAP;
diff --git a/java/com/android/dialer/phonenumbercache/ContactInfoHelper.java b/java/com/android/dialer/phonenumbercache/ContactInfoHelper.java
index 4302436a7..6179b5dcf 100644
--- a/java/com/android/dialer/phonenumbercache/ContactInfoHelper.java
+++ b/java/com/android/dialer/phonenumbercache/ContactInfoHelper.java
@@ -621,7 +621,7 @@ public class ContactInfoHelper {
return;
}
CequintCallerIdContact cequintCallerIdContact =
- cequintCallerIdManager.getCequintCallerIdContact(context, number);
+ cequintCallerIdManager.getCachedCequintCallerIdContact(context, number);
if (cequintCallerIdContact == null) {
return;
}
diff --git a/java/com/android/dialer/spam/promo/SpamBlockingPromoHelper.java b/java/com/android/dialer/spam/promo/SpamBlockingPromoHelper.java
index 891ac44ad..6a8cde864 100644
--- a/java/com/android/dialer/spam/promo/SpamBlockingPromoHelper.java
+++ b/java/com/android/dialer/spam/promo/SpamBlockingPromoHelper.java
@@ -34,14 +34,14 @@ import com.android.dialer.logging.Logger;
import com.android.dialer.notification.DialerNotificationManager;
import com.android.dialer.notification.NotificationChannelId;
import com.android.dialer.spam.SpamSettings;
-import com.android.dialer.spam.SpamSettings.ModifySettingListener;
+import com.android.dialer.spam.promo.SpamBlockingPromoDialogFragment.OnEnableListener;
/** Helper class for showing spam blocking on-boarding promotions. */
public class SpamBlockingPromoHelper {
static final String SPAM_BLOCKING_PROMO_PERIOD_MILLIS = "spam_blocking_promo_period_millis";
static final String SPAM_BLOCKING_PROMO_LAST_SHOW_MILLIS = "spam_blocking_promo_last_show_millis";
- static final String ENABLE_SPAM_BLOCKING_PROMO = "enable_spam_blocking_promo";
+ public static final String ENABLE_SPAM_BLOCKING_PROMO = "enable_spam_blocking_promo";
private final Context context;
private final SpamSettings spamSettings;
@@ -81,33 +81,15 @@ public class SpamBlockingPromoHelper {
* Shows a spam blocking promo dialog.
*
* @param fragmentManager the fragment manager to show the dialog.
- * @param modifySettingListener the listener called after spam blocking setting is modified.
+ * @param onEnableListener the listener called when enable button is clicked.
* @param onDismissListener the listener called when the dialog is dismissed.
*/
public void showSpamBlockingPromoDialog(
FragmentManager fragmentManager,
- ModifySettingListener modifySettingListener,
+ OnEnableListener onEnableListener,
OnDismissListener onDismissListener) {
updateLastShowSpamTimestamp();
- Logger.get(context).logImpression(DialerImpression.Type.SPAM_BLOCKING_CALL_LOG_PROMO_SHOWN);
- SpamBlockingPromoDialogFragment.newInstance(
- () -> {
- Logger.get(context)
- .logImpression(
- DialerImpression.Type.SPAM_BLOCKING_ENABLED_THROUGH_CALL_LOG_PROMO);
- spamSettings.modifySpamBlockingSetting(
- true,
- success -> {
- if (!success) {
- Logger.get(context)
- .logImpression(
- DialerImpression.Type
- .SPAM_BLOCKING_MODIFY_FAILURE_THROUGH_CALL_LOG_PROMO);
- }
- modifySettingListener.onComplete(success);
- });
- },
- onDismissListener)
+ SpamBlockingPromoDialogFragment.newInstance(onEnableListener, onDismissListener)
.show(fragmentManager, SpamBlockingPromoDialogFragment.SPAM_BLOCKING_PROMO_DIALOG_TAG);
}
diff --git a/java/com/android/dialer/speeddial/SpeedDialFragment.java b/java/com/android/dialer/speeddial/SpeedDialFragment.java
index b76db1cf3..018f97888 100644
--- a/java/com/android/dialer/speeddial/SpeedDialFragment.java
+++ b/java/com/android/dialer/speeddial/SpeedDialFragment.java
@@ -16,6 +16,7 @@
package com.android.dialer.speeddial;
+import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
@@ -41,6 +42,12 @@ import com.android.dialer.common.concurrent.DialerExecutorComponent;
import com.android.dialer.common.concurrent.SupportUiListener;
import com.android.dialer.constants.ActivityRequestCodes;
import com.android.dialer.duo.DuoComponent;
+import com.android.dialer.historyitemactions.DividerModule;
+import com.android.dialer.historyitemactions.HistoryItemActionBottomSheet;
+import com.android.dialer.historyitemactions.HistoryItemActionModule;
+import com.android.dialer.historyitemactions.HistoryItemBottomSheetHeaderInfo;
+import com.android.dialer.historyitemactions.IntentModule;
+import com.android.dialer.historyitemactions.SharedModules;
import com.android.dialer.logging.DialerImpression;
import com.android.dialer.logging.Logger;
import com.android.dialer.precall.PreCall;
@@ -54,8 +61,11 @@ import com.android.dialer.speeddial.draghelper.SpeedDialLayoutManager;
import com.android.dialer.speeddial.loader.SpeedDialUiItem;
import com.android.dialer.speeddial.loader.UiItemLoaderComponent;
import com.android.dialer.util.IntentUtil;
+import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.Futures;
+import java.util.ArrayList;
+import java.util.List;
/**
* Fragment for displaying:
@@ -301,8 +311,61 @@ public class SpeedDialFragment extends Fragment {
private final class SpeedDialSuggestedListener implements SuggestedContactsListener {
@Override
- public void onOverFlowMenuClicked(SpeedDialUiItem speedDialUiItem) {
- // TODO(calderwoodra) show overflow menu for suggested contacts
+ public void onOverFlowMenuClicked(
+ SpeedDialUiItem speedDialUiItem, HistoryItemBottomSheetHeaderInfo headerInfo) {
+ List<HistoryItemActionModule> modules = new ArrayList<>();
+ Channel defaultChannel = speedDialUiItem.defaultChannel();
+
+ // Add voice call module
+ Channel voiceChannel = speedDialUiItem.getDeterministicVoiceChannel();
+ if (voiceChannel != null) {
+ modules.add(
+ IntentModule.newCallModule(
+ getContext(),
+ new CallIntentBuilder(voiceChannel.number(), CallInitiationType.Type.SPEED_DIAL)
+ .setAllowAssistedDial(true)));
+ } else {
+ modules.add(new DisambigDialogModule(speedDialUiItem, /* isVideo = */ false));
+ }
+
+ // Add video if we can determine the correct channel
+ Channel videoChannel = speedDialUiItem.getDeterministicVideoChannel();
+ if (videoChannel != null) {
+ modules.add(
+ IntentModule.newCallModule(
+ getContext(),
+ new CallIntentBuilder(videoChannel.number(), CallInitiationType.Type.SPEED_DIAL)
+ .setIsVideoCall(true)
+ .setAllowAssistedDial(true)));
+ } else if (speedDialUiItem.hasVideoChannels()) {
+ modules.add(new DisambigDialogModule(speedDialUiItem, /* isVideo = */ true));
+ }
+
+ // Add sms module
+ Optional<HistoryItemActionModule> smsModule =
+ SharedModules.createModuleForSendingTextMessage(
+ getContext(), defaultChannel.number(), false);
+ if (smsModule.isPresent()) {
+ modules.add(smsModule.get());
+ }
+
+ modules.add(new DividerModule());
+
+ // TODO(calderwoodra): add to favorites module
+ // TODO(calderwoodra): remove from strequent module
+
+ // Contact info module
+ modules.add(
+ new ContactInfoModule(
+ getContext(),
+ new Intent(
+ Intent.ACTION_VIEW,
+ Uri.withAppendedPath(
+ Contacts.CONTENT_URI, String.valueOf(speedDialUiItem.contactId()))),
+ R.string.contact_menu_contact_info,
+ R.drawable.context_menu_contact_icon));
+
+ HistoryItemActionBottomSheet.show(getContext(), headerInfo, modules);
}
@Override
@@ -321,6 +384,53 @@ public class SpeedDialFragment extends Fragment {
new CallIntentBuilder(channel.number(), CallInitiationType.Type.SPEED_DIAL)
.setIsVideoCall(channel.isVideoTechnology()));
}
+
+ private final class ContactInfoModule extends IntentModule {
+
+ public ContactInfoModule(Context context, Intent intent, int text, int image) {
+ super(context, intent, text, image);
+ }
+
+ @Override
+ public boolean tintDrawable() {
+ return false;
+ }
+ }
+
+ private final class DisambigDialogModule implements HistoryItemActionModule {
+
+ private final SpeedDialUiItem speedDialUiItem;
+ private final boolean isVideo;
+
+ DisambigDialogModule(SpeedDialUiItem speedDialUiItem, boolean isVideo) {
+ this.speedDialUiItem = speedDialUiItem;
+ this.isVideo = isVideo;
+ }
+
+ @Override
+ public int getStringId() {
+ if (isVideo) {
+ return R.string.contact_menu_video_call;
+ } else {
+ return R.string.contact_menu_voice_call;
+ }
+ }
+
+ @Override
+ public int getDrawableId() {
+ if (isVideo) {
+ return R.drawable.quantum_ic_videocam_vd_theme_24;
+ } else {
+ return R.drawable.quantum_ic_phone_vd_theme_24;
+ }
+ }
+
+ @Override
+ public boolean onClick() {
+ DisambigDialog.show(speedDialUiItem, getChildFragmentManager());
+ return true;
+ }
+ }
}
private static final class SpeedDialContextMenuItemListener implements ContextMenuItemListener {
diff --git a/java/com/android/dialer/speeddial/SuggestionViewHolder.java b/java/com/android/dialer/speeddial/SuggestionViewHolder.java
index 546ffbdff..578e0b328 100644
--- a/java/com/android/dialer/speeddial/SuggestionViewHolder.java
+++ b/java/com/android/dialer/speeddial/SuggestionViewHolder.java
@@ -17,27 +17,25 @@
package com.android.dialer.speeddial;
import android.content.Context;
-import android.provider.ContactsContract.Contacts;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
-import android.widget.QuickContactBadge;
import android.widget.TextView;
import com.android.dialer.common.Assert;
-import com.android.dialer.glidephotomanager.GlidePhotoManagerComponent;
-import com.android.dialer.glidephotomanager.PhotoInfo;
+import com.android.dialer.historyitemactions.HistoryItemBottomSheetHeaderInfo;
import com.android.dialer.location.GeoUtil;
import com.android.dialer.phonenumberutil.PhoneNumberHelper;
import com.android.dialer.speeddial.database.SpeedDialEntry.Channel;
import com.android.dialer.speeddial.loader.SpeedDialUiItem;
+import com.android.dialer.widget.ContactPhotoView;
/** ViewHolder for displaying suggested contacts in {@link SpeedDialFragment}. */
public class SuggestionViewHolder extends RecyclerView.ViewHolder implements OnClickListener {
private final SuggestedContactsListener listener;
- private final QuickContactBadge photoView;
+ private final ContactPhotoView photoView;
private final TextView nameOrNumberView;
private final TextView numberView;
@@ -71,34 +69,31 @@ public class SuggestionViewHolder extends RecyclerView.ViewHolder implements OnC
nameOrNumberView.setText(speedDialUiItem.name());
numberView.setText(secondaryInfo);
- GlidePhotoManagerComponent.get(context)
- .glidePhotoManager()
- .loadQuickContactBadge(
- photoView,
- PhotoInfo.newBuilder()
- .setPhotoId(speedDialUiItem.photoId())
- .setPhotoUri(speedDialUiItem.photoUri())
- .setName(speedDialUiItem.name())
- .setIsVideo(speedDialUiItem.defaultChannel().isVideoTechnology())
- .setLookupUri(
- Contacts.getLookupUri(speedDialUiItem.contactId(), speedDialUiItem.lookupKey())
- .toString())
- .build());
+ photoView.setPhoto(speedDialUiItem.getPhotoInfo());
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.overflow) {
- listener.onOverFlowMenuClicked(speedDialUiItem);
+ listener.onOverFlowMenuClicked(speedDialUiItem, getHeaderInfo());
} else {
listener.onRowClicked(speedDialUiItem.defaultChannel());
}
}
+ private HistoryItemBottomSheetHeaderInfo getHeaderInfo() {
+ return HistoryItemBottomSheetHeaderInfo.newBuilder()
+ .setPhotoInfo(speedDialUiItem.getPhotoInfo())
+ .setPrimaryText(nameOrNumberView.getText().toString())
+ .setSecondaryText(numberView.getText().toString())
+ .build();
+ }
+
/** Listener/Callback for {@link SuggestionViewHolder} parents. */
public interface SuggestedContactsListener {
- void onOverFlowMenuClicked(SpeedDialUiItem speedDialUiItem);
+ void onOverFlowMenuClicked(
+ SpeedDialUiItem speedDialUiItem, HistoryItemBottomSheetHeaderInfo headerInfo);
/** Called when a suggested contact is clicked. */
void onRowClicked(Channel channel);
diff --git a/java/com/android/dialer/speeddial/loader/SpeedDialUiItem.java b/java/com/android/dialer/speeddial/loader/SpeedDialUiItem.java
index a2bdfb89a..c5a3ea3ed 100644
--- a/java/com/android/dialer/speeddial/loader/SpeedDialUiItem.java
+++ b/java/com/android/dialer/speeddial/loader/SpeedDialUiItem.java
@@ -18,10 +18,12 @@ package com.android.dialer.speeddial.loader;
import android.database.Cursor;
import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import com.android.dialer.common.Assert;
+import com.android.dialer.glidephotomanager.PhotoInfo;
import com.android.dialer.speeddial.database.SpeedDialEntry;
import com.android.dialer.speeddial.database.SpeedDialEntry.Channel;
import com.google.auto.value.AutoValue;
@@ -139,6 +141,16 @@ public abstract class SpeedDialUiItem {
return builder.build();
}
+ public PhotoInfo getPhotoInfo() {
+ return PhotoInfo.newBuilder()
+ .setPhotoId(photoId())
+ .setPhotoUri(photoUri())
+ .setName(name())
+ .setIsVideo(defaultChannel() != null && defaultChannel().isVideoTechnology())
+ .setLookupUri(Contacts.getLookupUri(contactId(), lookupKey()).toString())
+ .build();
+ }
+
public SpeedDialEntry buildSpeedDialEntry() {
return SpeedDialEntry.builder()
.setId(speedDialEntryId())
diff --git a/java/com/android/dialer/speeddial/res/layout/suggestion_row_layout.xml b/java/com/android/dialer/speeddial/res/layout/suggestion_row_layout.xml
index ff95b5906..868606065 100644
--- a/java/com/android/dialer/speeddial/res/layout/suggestion_row_layout.xml
+++ b/java/com/android/dialer/speeddial/res/layout/suggestion_row_layout.xml
@@ -21,7 +21,7 @@
android:minHeight="72dp"
android:background="?android:attr/selectableItemBackground">
- <QuickContactBadge
+ <com.android.dialer.widget.ContactPhotoView
android:id="@+id/avatar"
android:layout_width="48dp"
android:layout_height="48dp"
@@ -59,5 +59,6 @@
android:scaleType="center"
android:tint="@color/secondary_text_color"
android:src="@drawable/quantum_ic_more_vert_white_24"
- android:background="?android:selectableItemBackgroundBorderless"/>
+ android:background="?android:selectableItemBackgroundBorderless"
+ android:contentDescription="@string/content_description_overflow"/>
</RelativeLayout> \ No newline at end of file
diff --git a/java/com/android/incallui/ContactInfoCache.java b/java/com/android/incallui/ContactInfoCache.java
index eefd4833c..81c7b724d 100644
--- a/java/com/android/incallui/ContactInfoCache.java
+++ b/java/com/android/incallui/ContactInfoCache.java
@@ -514,7 +514,7 @@ public class ContactInfoCache implements OnImageLoadCompleteListener {
return;
}
CequintCallerIdContact cequintCallerIdContact =
- CequintCallerIdManager.getCequintCallerIdContactForInCall(
+ CequintCallerIdManager.getCequintCallerIdContactForCall(
context, callerInfo.phoneNumber, cnapName, isIncoming);
if (cequintCallerIdContact == null) {
diff --git a/java/com/android/incallui/rtt/impl/AdvisoryViewHolder.java b/java/com/android/incallui/rtt/impl/AdvisoryViewHolder.java
new file mode 100644
index 000000000..8f081bebf
--- /dev/null
+++ b/java/com/android/incallui/rtt/impl/AdvisoryViewHolder.java
@@ -0,0 +1,29 @@
+/*
+ * 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.incallui.rtt.impl;
+
+import android.support.annotation.NonNull;
+import android.support.v7.widget.RecyclerView.ViewHolder;
+import android.view.View;
+
+/** ViewHolder class for RTT advisory text. */
+public class AdvisoryViewHolder extends ViewHolder {
+
+ public AdvisoryViewHolder(@NonNull View itemView) {
+ super(itemView);
+ }
+}
diff --git a/java/com/android/incallui/rtt/impl/RttChatAdapter.java b/java/com/android/incallui/rtt/impl/RttChatAdapter.java
index 692266335..f1cde759c 100644
--- a/java/com/android/incallui/rtt/impl/RttChatAdapter.java
+++ b/java/com/android/incallui/rtt/impl/RttChatAdapter.java
@@ -18,8 +18,10 @@ package com.android.incallui.rtt.impl;
import android.content.Context;
import android.graphics.drawable.Drawable;
+import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.ViewHolder;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
@@ -27,11 +29,29 @@ import android.view.ViewGroup;
import com.android.dialer.common.LogUtil;
import com.android.dialer.rtt.RttTranscript;
import com.android.dialer.rtt.RttTranscriptMessage;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
/** Adapter class for holding RTT chat data. */
-public class RttChatAdapter extends RecyclerView.Adapter<RttChatMessageViewHolder> {
+public class RttChatAdapter extends RecyclerView.Adapter<ViewHolder> {
+
+ /** IntDef for the different types of rows that can be shown in the call log. */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ RowType.ADVISORY,
+ RowType.MESSAGE,
+ })
+ @interface RowType {
+ /** The transcript advisory message. */
+ int ADVISORY = 1;
+
+ /** RTT chat message. */
+ int MESSAGE = 2;
+ }
+
+ private static final int POSITION_ADVISORY = 0;
private Drawable avatarDrawable;
@@ -45,6 +65,7 @@ public class RttChatAdapter extends RecyclerView.Adapter<RttChatMessageViewHolde
private List<RttChatMessage> rttMessages = new ArrayList<>();
private int lastIndexOfLocalMessage = -1;
private final MessageListener messageListener;
+ private boolean shouldShowAdvisory;
RttChatAdapter(Context context, MessageListener listener) {
this.context = context;
@@ -52,29 +73,54 @@ public class RttChatAdapter extends RecyclerView.Adapter<RttChatMessageViewHolde
}
@Override
- public RttChatMessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ public ViewHolder onCreateViewHolder(ViewGroup parent, @RowType int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(context);
- View view = layoutInflater.inflate(R.layout.rtt_chat_list_item, parent, false);
- return new RttChatMessageViewHolder(view);
+ switch (viewType) {
+ case RowType.ADVISORY:
+ View view = layoutInflater.inflate(R.layout.rtt_transcript_advisory, parent, false);
+ return new AdvisoryViewHolder(view);
+ case RowType.MESSAGE:
+ view = layoutInflater.inflate(R.layout.rtt_chat_list_item, parent, false);
+ return new RttChatMessageViewHolder(view);
+ default:
+ throw new RuntimeException("Unknown row type.");
+ }
}
@Override
public int getItemViewType(int position) {
- return super.getItemViewType(position);
+ if (shouldShowAdvisory && position == POSITION_ADVISORY) {
+ return RowType.ADVISORY;
+ } else {
+ return RowType.MESSAGE;
+ }
}
@Override
- public void onBindViewHolder(RttChatMessageViewHolder rttChatMessageViewHolder, int i) {
- boolean isSameGroup = false;
- if (i > 0) {
- isSameGroup = rttMessages.get(i).isRemote == rttMessages.get(i - 1).isRemote;
+ public void onBindViewHolder(ViewHolder viewHolder, int itemPosition) {
+ switch (getItemViewType(itemPosition)) {
+ case RowType.ADVISORY:
+ return;
+ case RowType.MESSAGE:
+ RttChatMessageViewHolder rttChatMessageViewHolder = (RttChatMessageViewHolder) viewHolder;
+ int messagePosition = toMessagePosition(itemPosition);
+ boolean isSameGroup = false;
+ if (messagePosition > 0) {
+ isSameGroup =
+ rttMessages.get(messagePosition).isRemote
+ == rttMessages.get(messagePosition - 1).isRemote;
+ }
+ rttChatMessageViewHolder.setMessage(
+ rttMessages.get(messagePosition), isSameGroup, avatarDrawable);
+ return;
+ default:
+ throw new RuntimeException("Unknown row type.");
}
- rttChatMessageViewHolder.setMessage(rttMessages.get(i), isSameGroup, avatarDrawable);
}
@Override
public int getItemCount() {
- return rttMessages.size();
+ return shouldShowAdvisory ? rttMessages.size() + 1 : rttMessages.size();
}
private void updateCurrentLocalMessage(String newMessage) {
@@ -96,11 +142,31 @@ public class RttChatAdapter extends RecyclerView.Adapter<RttChatMessageViewHolde
notifyItemRemoved(lastIndexOfLocalMessage);
lastIndexOfLocalMessage = -1;
} else {
- notifyItemChanged(lastIndexOfLocalMessage);
+ notifyItemChanged(toItemPosition(lastIndexOfLocalMessage));
}
}
}
+ private int toMessagePosition(int itemPosition) {
+ if (shouldShowAdvisory) {
+ return itemPosition - 1;
+ } else {
+ return itemPosition;
+ }
+ }
+
+ // Converts position in message list into item position in adapter.
+ private int toItemPosition(int messagePosition) {
+ if (messagePosition < 0) {
+ return messagePosition;
+ }
+ if (shouldShowAdvisory) {
+ return messagePosition + 1;
+ } else {
+ return messagePosition;
+ }
+ }
+
private void updateCurrentRemoteMessage(String newMessage) {
RttChatMessage.updateRemoteRttChatMessage(rttMessages, newMessage);
lastIndexOfLocalMessage = RttChatMessage.getLastIndexLocalMessage(rttMessages);
@@ -110,14 +176,14 @@ public class RttChatAdapter extends RecyclerView.Adapter<RttChatMessageViewHolde
void addLocalMessage(String message) {
updateCurrentLocalMessage(message);
if (messageListener != null) {
- messageListener.onUpdateLocalMessage(lastIndexOfLocalMessage);
+ messageListener.onUpdateLocalMessage(toItemPosition(lastIndexOfLocalMessage));
}
}
void submitLocalMessage() {
LogUtil.enterBlock("RttChatAdapater.submitLocalMessage");
rttMessages.get(lastIndexOfLocalMessage).finish();
- notifyItemChanged(lastIndexOfLocalMessage);
+ notifyItemChanged(toItemPosition(lastIndexOfLocalMessage));
lastIndexOfLocalMessage = -1;
}
@@ -139,10 +205,21 @@ public class RttChatAdapter extends RecyclerView.Adapter<RttChatMessageViewHolde
}
updateCurrentRemoteMessage(message);
if (messageListener != null) {
- messageListener.onUpdateRemoteMessage(RttChatMessage.getLastIndexRemoteMessage(rttMessages));
+ messageListener.onUpdateRemoteMessage(
+ toItemPosition(RttChatMessage.getLastIndexRemoteMessage(rttMessages)));
}
}
+ void hideAdvisory() {
+ shouldShowAdvisory = false;
+ notifyItemRemoved(POSITION_ADVISORY);
+ }
+
+ void showAdvisory() {
+ shouldShowAdvisory = true;
+ notifyItemInserted(POSITION_ADVISORY);
+ }
+
/**
* Retrieve last local message and update the index. This is used when deleting to previous
* message bubble.
diff --git a/java/com/android/incallui/rtt/impl/RttChatFragment.java b/java/com/android/incallui/rtt/impl/RttChatFragment.java
index 47036cd43..13e013fd3 100644
--- a/java/com/android/incallui/rtt/impl/RttChatFragment.java
+++ b/java/com/android/incallui/rtt/impl/RttChatFragment.java
@@ -467,6 +467,7 @@ public class RttChatFragment extends Fragment
if (editText.requestFocus()) {
UiUtil.openKeyboardFrom(getContext(), editText);
}
+ adapter.showAdvisory();
}
if (primaryCallState.state() == State.DIALING) {
showWaitingForJoinBanner();
diff --git a/java/com/android/incallui/rtt/impl/res/layout/frag_rtt_chat.xml b/java/com/android/incallui/rtt/impl/res/layout/frag_rtt_chat.xml
index f995185b1..cff2b3f38 100644
--- a/java/com/android/incallui/rtt/impl/res/layout/frag_rtt_chat.xml
+++ b/java/com/android/incallui/rtt/impl/res/layout/frag_rtt_chat.xml
@@ -23,7 +23,7 @@
android:id="@+id/rtt_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:paddingTop="70dp"
+ android:paddingTop="56dp"
android:paddingBottom="70dp"
android:clipToPadding="false"/>
diff --git a/java/com/android/incallui/rtt/impl/res/layout/rtt_banner.xml b/java/com/android/incallui/rtt/impl/res/layout/rtt_banner.xml
index 4b03ad8d5..8a5bba28d 100644
--- a/java/com/android/incallui/rtt/impl/res/layout/rtt_banner.xml
+++ b/java/com/android/incallui/rtt/impl/res/layout/rtt_banner.xml
@@ -19,30 +19,30 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
- <RelativeLayout
+ <LinearLayout
android:layout_width="match_parent"
- android:layout_height="?android:attr/actionBarSize"
+ android:layout_height="@dimen/rtt_banner_height"
android:background="#F305228F"
- android:elevation="3dp">
+ android:elevation="3dp"
+ android:orientation="horizontal">
<ImageButton
android:id="@+id/rtt_end_call_button"
- android:layout_width="32dp"
- android:layout_height="32dp"
- android:layout_marginStart="16dp"
- android:layout_alignParentStart="true"
- android:layout_centerVertical="true"
+ android:layout_width="@dimen/rtt_banner_height"
+ android:layout_height="@dimen/rtt_banner_height"
+ android:layout_marginStart="4dp"
+ android:layout_marginEnd="4dp"
+ android:padding="@dimen/rtt_banner_button_padding"
android:background="@android:color/transparent"
android:contentDescription="@string/incall_content_description_end_call"
android:scaleType="fitXY"
android:src="@drawable/quantum_ic_call_end_vd_theme_24"
android:tint="#FFDF0000"/>
<LinearLayout
- android:layout_width="260dp"
+ android:layout_width="0dp"
android:layout_height="match_parent"
+ android:layout_weight="1"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
- android:layout_marginStart="32dp"
- android:layout_toEndOf="@id/rtt_end_call_button"
android:orientation="vertical">
<TextView
android:id="@+id/rtt_name_or_number"
@@ -67,18 +67,17 @@
</LinearLayout>
<ImageButton
android:id="@+id/rtt_overflow_button"
- android:layout_width="32dp"
- android:layout_height="32dp"
- android:layout_marginEnd="12dp"
- android:layout_alignParentEnd="true"
- android:layout_centerVertical="true"
+ android:layout_width="@dimen/rtt_banner_height"
+ android:layout_height="@dimen/rtt_banner_height"
+ android:layout_marginStart="8dp"
+ android:padding="@dimen/rtt_banner_button_padding"
android:background="@android:color/transparent"
android:contentDescription="@string/content_description_overflow"
android:scaleType="fitXY"
android:src="@drawable/quantum_ic_more_vert_vd_theme_24"
android:tint="#FFFFFF"/>
- </RelativeLayout>
+ </LinearLayout>
<FrameLayout
android:id="@id/rtt_on_hold_banner"
android:layout_width="match_parent"
diff --git a/java/com/android/incallui/rtt/impl/res/layout/rtt_transcript_advisory.xml b/java/com/android/incallui/rtt/impl/res/layout/rtt_transcript_advisory.xml
new file mode 100644
index 000000000..a2cf3e74f
--- /dev/null
+++ b/java/com/android/incallui/rtt/impl/res/layout/rtt_transcript_advisory.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="24dp"
+ android:paddingBottom="16dp"
+ android:orientation="vertical">
+ <ImageView
+ android:layout_width="16dp"
+ android:layout_height="16dp"
+ android:layout_gravity="center_horizontal"
+ android:src="@drawable/quantum_ic_question_answer_vd_theme_24"
+ android:tint="#DEFFFFFF"
+ android:tintMode="src_in"/>
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="4dp"
+ android:paddingBottom="9dp"
+ android:paddingStart="64dp"
+ android:paddingEnd="64dp"
+ android:gravity="center_horizontal"
+ android:text="@string/rtt_transcript_advisory"
+ android:textColor="#FFFFFF"
+ android:textSize="12sp"/>
+</LinearLayout> \ No newline at end of file
diff --git a/java/com/android/incallui/rtt/impl/res/values/dimens.xml b/java/com/android/incallui/rtt/impl/res/values/dimens.xml
index c3d28da77..cab9da00c 100644
--- a/java/com/android/incallui/rtt/impl/res/values/dimens.xml
+++ b/java/com/android/incallui/rtt/impl/res/values/dimens.xml
@@ -20,4 +20,7 @@
<dimen name="rtt_overflow_menu_width">180dp</dimen>
<dimen name="rtt_overflow_menu_elevation">8dp</dimen>
<dimen name="rtt_avatar_size">40dp</dimen>
+ <dimen name="rtt_banner_height">56dp</dimen>
+ <!-- This is used to control image size inside the button. -->
+ <dimen name="rtt_banner_button_padding">12dp</dimen>
</resources>
diff --git a/java/com/android/incallui/rtt/impl/res/values/strings.xml b/java/com/android/incallui/rtt/impl/res/values/strings.xml
index 1d09f5446..462eea563 100644
--- a/java/com/android/incallui/rtt/impl/res/values/strings.xml
+++ b/java/com/android/incallui/rtt/impl/res/values/strings.xml
@@ -30,4 +30,7 @@
<!-- Text for status banner. [CHAR LIMIT=100] -->
<string name="rtt_status_banner_text">Waiting for <xliff:g id="name">%s</xliff:g> to join RTT call&#8230;</string>
+ <!-- Text for RTT transcript advisory. [CHAR LIMIT=NONE] -->
+ <string name="rtt_transcript_advisory">The other party can see you typing. Transcripts stored on your device in the call history.</string>
+
</resources> \ No newline at end of file
diff --git a/java/com/android/incallui/spam/SpamNotificationActivity.java b/java/com/android/incallui/spam/SpamNotificationActivity.java
index c04a071a1..e10dea381 100644
--- a/java/com/android/incallui/spam/SpamNotificationActivity.java
+++ b/java/com/android/incallui/spam/SpamNotificationActivity.java
@@ -43,6 +43,7 @@ import com.android.dialer.logging.ReportingLocation;
import com.android.dialer.notification.DialerNotificationManager;
import com.android.dialer.phonenumberutil.PhoneNumberHelper;
import com.android.dialer.spam.SpamComponent;
+import com.android.dialer.spam.SpamSettings;
import com.android.dialer.spam.promo.SpamBlockingPromoHelper;
import com.android.incallui.call.DialerCall;
@@ -86,6 +87,8 @@ public class SpamNotificationActivity extends FragmentActivity {
}
};
private FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler;
+ private SpamSettings spamSettings;
+ private SpamBlockingPromoHelper spamBlockingPromoHelper;
/**
* Creates an intent to start this activity.
@@ -160,6 +163,8 @@ public class SpamNotificationActivity extends FragmentActivity {
super.onCreate(savedInstanceState);
setFinishOnTouchOutside(true);
filteredNumberAsyncQueryHandler = new FilteredNumberAsyncQueryHandler(this);
+ spamSettings = SpamComponent.get(this).spamSettings();
+ spamBlockingPromoHelper = new SpamBlockingPromoHelper(getApplicationContext(), spamSettings);
cancelNotification();
}
@@ -417,7 +422,7 @@ public class SpamNotificationActivity extends FragmentActivity {
dismiss();
spamNotificationActivity.maybeShowBlockReportSpamDialog(
number, contactLookupResultType);
- spamNotificationActivity.showSpamBlockingPromoDialog();
+ spamNotificationActivity.maybeShowSpamBlockingPromoAndFinish();
}
})
.setNegativeButton(
@@ -515,23 +520,43 @@ public class SpamNotificationActivity extends FragmentActivity {
dismiss();
spamNotificationActivity.maybeShowBlockReportSpamDialog(
number, contactLookupResultType);
+ spamNotificationActivity.maybeShowSpamBlockingPromoAndFinish();
}
})
.create();
}
}
- private void showSpamBlockingPromoDialog() {
- SpamBlockingPromoHelper spamBlockingPromoHelper =
- new SpamBlockingPromoHelper(
- getApplicationContext(), SpamComponent.get(this).spamSettings());
+ private void maybeShowSpamBlockingPromoAndFinish() {
if (!spamBlockingPromoHelper.shouldShowSpamBlockingPromo()) {
finish();
- } else {
- spamBlockingPromoHelper.showSpamBlockingPromoDialog(
- getFragmentManager(),
- success -> spamBlockingPromoHelper.showModifySettingOnCompleteToast(success),
- dialog -> finish());
+ return;
}
+ Logger.get(this)
+ .logImpression(DialerImpression.Type.SPAM_BLOCKING_AFTER_CALL_NOTIFICATION_PROMO_SHOWN);
+ showSpamBlockingPromoDialog();
+ }
+
+ private void showSpamBlockingPromoDialog() {
+ spamBlockingPromoHelper.showSpamBlockingPromoDialog(
+ getFragmentManager(),
+ () -> {
+ Logger.get(this)
+ .logImpression(
+ DialerImpression.Type
+ .SPAM_BLOCKING_ENABLED_THROUGH_AFTER_CALL_NOTIFICATION_PROMO);
+ spamSettings.modifySpamBlockingSetting(
+ true,
+ success -> {
+ if (!success) {
+ Logger.get(this)
+ .logImpression(
+ DialerImpression.Type
+ .SPAM_BLOCKING_MODIFY_FAILURE_THROUGH_AFTER_CALL_NOTIFICATION_PROMO);
+ }
+ spamBlockingPromoHelper.showModifySettingOnCompleteToast(success);
+ });
+ },
+ dialog -> finish());
}
}