From 3e97f65b217c4b9e64c33e083b451ba83f239f6a Mon Sep 17 00:00:00 2001 From: Android Dialer Date: Mon, 19 Mar 2018 18:19:04 -0700 Subject: Show spam blocking promo after block spam dialog Test: SpamBlockingPromoHelperTest PiperOrigin-RevId: 189674918 Change-Id: I0b22eb9b8128125cc5b439674099820a01c3889f --- .../app/calllog/BlockReportSpamListener.java | 13 +++ .../android/dialer/app/calllog/CallLogAdapter.java | 1 + .../dialer/app/res/layout/call_log_fragment.xml | 1 + .../android/dialer/logging/dialer_impression.proto | 9 +- .../android/dialer/spam/promo/AndroidManifest.xml | 19 ++++ .../promo/SpamBlockingPromoDialogFragment.java | 69 ++++++++++++ .../dialer/spam/promo/SpamBlockingPromoHelper.java | 117 +++++++++++++++++++++ .../dialer/spam/promo/res/values/strings.xml | 39 +++++++ 8 files changed, 267 insertions(+), 1 deletion(-) create mode 100644 java/com/android/dialer/spam/promo/AndroidManifest.xml create mode 100644 java/com/android/dialer/spam/promo/SpamBlockingPromoDialogFragment.java create mode 100644 java/com/android/dialer/spam/promo/SpamBlockingPromoHelper.java create mode 100644 java/com/android/dialer/spam/promo/res/values/strings.xml (limited to 'java') diff --git a/java/com/android/dialer/app/calllog/BlockReportSpamListener.java b/java/com/android/dialer/app/calllog/BlockReportSpamListener.java index ecf629e14..5c7641c80 100644 --- a/java/com/android/dialer/app/calllog/BlockReportSpamListener.java +++ b/java/com/android/dialer/app/calllog/BlockReportSpamListener.java @@ -20,6 +20,7 @@ import android.app.FragmentManager; import android.content.Context; import android.support.annotation.NonNull; import android.support.v7.widget.RecyclerView; +import android.view.View; import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler; import com.android.dialer.blockreportspam.BlockReportSpamDialogs; import com.android.dialer.blockreportspam.BlockReportSpamDialogs.DialogFragmentForReportingNotSpam; @@ -31,26 +32,32 @@ import com.android.dialer.logging.Logger; import com.android.dialer.logging.ReportingLocation; import com.android.dialer.spam.Spam; import com.android.dialer.spam.SpamComponent; +import com.android.dialer.spam.promo.SpamBlockingPromoHelper; /** Listener to show dialogs for block and report spam actions. */ public class BlockReportSpamListener implements CallLogListItemViewHolder.OnClickListener { private final Context context; + private final View rootView; private final FragmentManager fragmentManager; private final RecyclerView.Adapter adapter; private final FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler; private final Spam spam; + private final SpamBlockingPromoHelper spamBlockingPromoHelper; public BlockReportSpamListener( Context context, + View rootView, FragmentManager fragmentManager, RecyclerView.Adapter adapter, FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler) { this.context = context; + this.rootView = rootView; this.fragmentManager = fragmentManager; this.adapter = adapter; this.filteredNumberAsyncQueryHandler = filteredNumberAsyncQueryHandler; spam = SpamComponent.get(context).spam(); + spamBlockingPromoHelper = new SpamBlockingPromoHelper(context, spam); } @Override @@ -85,6 +92,10 @@ public class BlockReportSpamListener implements CallLogListItemViewHolder.OnClic }, number, countryIso); + + if (isSpamChecked) { + spamBlockingPromoHelper.showSpamBlockingPromoDialog(rootView, fragmentManager); + } }, null) .show(fragmentManager, BlockReportSpamDialogs.BLOCK_REPORT_SPAM_DIALOG_TAG); @@ -122,6 +133,8 @@ public class BlockReportSpamListener implements CallLogListItemViewHolder.OnClic }, number, countryIso); + + spamBlockingPromoHelper.showSpamBlockingPromoDialog(rootView, fragmentManager); }, null) .show(fragmentManager, BlockReportSpamDialogs.BLOCK_DIALOG_TAG); diff --git a/java/com/android/dialer/app/calllog/CallLogAdapter.java b/java/com/android/dialer/app/calllog/CallLogAdapter.java index 7f8c889de..376057ff5 100644 --- a/java/com/android/dialer/app/calllog/CallLogAdapter.java +++ b/java/com/android/dialer/app/calllog/CallLogAdapter.java @@ -564,6 +564,7 @@ public class CallLogAdapter extends GroupingListAdapter blockReportSpamListener = new BlockReportSpamListener( this.activity, + this.activity.findViewById(R.id.call_log_fragment_root), ((Activity) this.activity).getFragmentManager(), this, this.filteredNumberAsyncQueryHandler); diff --git a/java/com/android/dialer/app/res/layout/call_log_fragment.xml b/java/com/android/dialer/app/res/layout/call_log_fragment.xml index efc08fbb4..f0563967c 100644 --- a/java/com/android/dialer/app/res/layout/call_log_fragment.xml +++ b/java/com/android/dialer/app/res/layout/call_log_fragment.xml @@ -16,6 +16,7 @@ diff --git a/java/com/android/dialer/logging/dialer_impression.proto b/java/com/android/dialer/logging/dialer_impression.proto index 96ca9c6be..16efd137c 100644 --- a/java/com/android/dialer/logging/dialer_impression.proto +++ b/java/com/android/dialer/logging/dialer_impression.proto @@ -12,7 +12,7 @@ message DialerImpression { // Event enums to be used for Impression Logging in Dialer. // It's perfectly acceptable for this enum to be large // Values should be from 1000 to 100000. - // Next Tag: 1366 + // Next Tag: 1369 enum Type { UNKNOWN_AOSP_EVENT_TYPE = 1000; @@ -719,5 +719,12 @@ message DialerImpression { VVM_USER_TURNED_TRANSCRIBE_OFF_FROM_SETTINGS = 1363; VVM_USER_TURNED_DONATION_ON_FROM_SETTINGS = 1364; VVM_USER_TURNED_DONATION_OFF_FROM_SETTINGS = 1365; + + // Spam blocking call log promo shown for user. + SPAM_BLOCKING_CALL_LOG_PROMO_SHOWN = 1366; + // User enabled spam blocking through call log promo. + SPAM_BLOCKING_ENABLED_THROUGH_CALL_LOG_PROMO = 1367; + // Failure happened while enabling spam blocking through call log promo. + SPAM_BLOCKING_MODIFY_FAILURE_THROUGH_CALL_LOG_PROMO = 1368; } } diff --git a/java/com/android/dialer/spam/promo/AndroidManifest.xml b/java/com/android/dialer/spam/promo/AndroidManifest.xml new file mode 100644 index 000000000..7d766b853 --- /dev/null +++ b/java/com/android/dialer/spam/promo/AndroidManifest.xml @@ -0,0 +1,19 @@ + + + + diff --git a/java/com/android/dialer/spam/promo/SpamBlockingPromoDialogFragment.java b/java/com/android/dialer/spam/promo/SpamBlockingPromoDialogFragment.java new file mode 100644 index 000000000..0ea17d395 --- /dev/null +++ b/java/com/android/dialer/spam/promo/SpamBlockingPromoDialogFragment.java @@ -0,0 +1,69 @@ +/* + * 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.spam.promo; + +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.DialogFragment; +import android.os.Bundle; + +/** Dialog for spam blocking on-boarding promotion. */ +public class SpamBlockingPromoDialogFragment extends DialogFragment { + + public static final String SPAM_BLOCKING_PROMO_DIALOG_TAG = "SpamBlockingPromoDialog"; + + /** Called when dialog positive button is pressed. */ + protected OnEnableListener positiveListener; + + public static DialogFragment newInstance(OnEnableListener positiveListener) { + SpamBlockingPromoDialogFragment fragment = new SpamBlockingPromoDialogFragment(); + fragment.positiveListener = positiveListener; + return fragment; + } + + @Override + public void onPause() { + // The dialog is dismissed onPause, i.e. rotation. + dismiss(); + super.onPause(); + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + super.onCreateDialog(savedInstanceState); + // Return the newly created dialog + return new AlertDialog.Builder(getActivity(), R.style.AlertDialogTheme) + .setCancelable(true) + .setTitle(R.string.spam_blocking_promo_title) + .setMessage(R.string.spam_blocking_promo_text) + .setNegativeButton( + R.string.spam_blocking_promo_action_dismiss, (dialog, which) -> dismiss()) + .setPositiveButton( + R.string.spam_blocking_promo_action_filter_spam, + (dialog, which) -> { + dismiss(); + positiveListener.onClick(); + }) + .create(); + } + + /** Positive listener for spam blocking promotion dialog. */ + public interface OnEnableListener { + /** Called when user clicks on positive button in the spam blocking promo dialog. */ + void onClick(); + } +} diff --git a/java/com/android/dialer/spam/promo/SpamBlockingPromoHelper.java b/java/com/android/dialer/spam/promo/SpamBlockingPromoHelper.java new file mode 100644 index 000000000..9349577c5 --- /dev/null +++ b/java/com/android/dialer/spam/promo/SpamBlockingPromoHelper.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.dialer.spam.promo; + +import android.app.FragmentManager; +import android.content.Context; +import android.preference.PreferenceManager; +import android.support.annotation.VisibleForTesting; +import android.support.design.widget.Snackbar; +import android.view.View; +import com.android.dialer.configprovider.ConfigProviderBindings; +import com.android.dialer.logging.DialerImpression; +import com.android.dialer.logging.Logger; +import com.android.dialer.spam.Spam; + +/** 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"; + + private final Context context; + private final Spam spam; + + public SpamBlockingPromoHelper(Context context, Spam spam) { + this.context = context; + this.spam = spam; + } + + /** Shows a spam blocking promo dialog with on complete snackbar if all the prerequisites meet. */ + public void showSpamBlockingPromoDialog(View view, FragmentManager fragmentManager) { + if (!shouldShowSpamBlockingPromo()) { + return; + } + + 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); + spam.modifySpamBlockingSetting( + true, success -> showModifySettingOnCompleteSnackbar(view, success)); + }) + .show(fragmentManager, SpamBlockingPromoDialogFragment.SPAM_BLOCKING_PROMO_DIALOG_TAG); + } + + /** + * Returns true if we should show a spam blocking promo. + * + *

Should show spam blocking promo only when all of the following criteria meet 1. Spam + * blocking setting is available. 2. Spam blocking setting is not yet enabled. 3. Time since last + * spam blocking promo exceeds the threshold. + * + * @return true if we should show a spam blocking promo. + */ + @VisibleForTesting + boolean shouldShowSpamBlockingPromo() { + if (!spam.isSpamEnabled() || !spam.isSpamBlockingAvailable() || spam.isSpamBlockingEnabled()) { + return false; + } + + long lastShowMillis = + PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext()) + .getLong(SPAM_BLOCKING_PROMO_LAST_SHOW_MILLIS, 0); + long showPeriodMillis = + ConfigProviderBindings.get(context) + .getLong(SPAM_BLOCKING_PROMO_PERIOD_MILLIS, Long.MAX_VALUE); + return lastShowMillis == 0 || System.currentTimeMillis() - lastShowMillis > showPeriodMillis; + } + + private void updateLastShowSpamTimestamp() { + PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext()) + .edit() + .putLong(SPAM_BLOCKING_PROMO_LAST_SHOW_MILLIS, System.currentTimeMillis()) + .commit(); + } + + /** + * Shows a modify setting on complete snackbar and a link to redirect to setting page + * + * @param view the view to attach on-complete notice snackbar + * @param success whether the modify setting operation succceeds + */ + private void showModifySettingOnCompleteSnackbar(View view, boolean success) { + if (!success) { + Logger.get(context) + .logImpression(DialerImpression.Type.SPAM_BLOCKING_MODIFY_FAILURE_THROUGH_CALL_LOG_PROMO); + } + String snackBarText = + success + ? context.getString(R.string.spam_blocking_settings_enable_complete_text) + : context.getString(R.string.spam_blocking_settings_enable_error_text); + Snackbar.make(view, snackBarText, Snackbar.LENGTH_LONG) + .setAction( + R.string.spam_blocking_setting_prompt, + v -> context.startActivity(spam.getSpamBlockingSettingIntent(context))) + .setActionTextColor( + context.getResources().getColor(R.color.dialer_snackbar_action_text_color)) + .show(); + } +} diff --git a/java/com/android/dialer/spam/promo/res/values/strings.xml b/java/com/android/dialer/spam/promo/res/values/strings.xml new file mode 100644 index 000000000..bef73812c --- /dev/null +++ b/java/com/android/dialer/spam/promo/res/values/strings.xml @@ -0,0 +1,39 @@ + + + + + + Filter suspected spam calls? + + Filtered spam calls will go straight to your voicemail + + Filter Spam + + Dismiss + + Settings + + + Problem turning on spam filtering + + Problem turning off spam filtering + + + Spam filtering turned on + + Spam filtering turned off + -- cgit v1.2.3