1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.dialer.spam.promo; 18 19 import android.annotation.SuppressLint; 20 import android.app.Notification; 21 import android.app.Notification.Builder; 22 import android.app.PendingIntent; 23 import android.content.Context; 24 import android.content.DialogInterface.OnDismissListener; 25 import android.graphics.drawable.Icon; 26 import android.support.design.widget.Snackbar; 27 import android.support.v4.app.FragmentManager; 28 import android.support.v4.os.BuildCompat; 29 import android.view.View; 30 import android.widget.Toast; 31 import com.android.dialer.configprovider.ConfigProviderComponent; 32 import com.android.dialer.logging.DialerImpression; 33 import com.android.dialer.logging.Logger; 34 import com.android.dialer.notification.DialerNotificationManager; 35 import com.android.dialer.notification.NotificationChannelId; 36 import com.android.dialer.spam.SpamSettings; 37 import com.android.dialer.spam.promo.SpamBlockingPromoDialogFragment.OnEnableListener; 38 import com.android.dialer.storage.StorageComponent; 39 import com.android.dialer.theme.base.ThemeComponent; 40 41 /** Helper class for showing spam blocking on-boarding promotions. */ 42 public class SpamBlockingPromoHelper { 43 44 static final String SPAM_BLOCKING_PROMO_PERIOD_MILLIS = "spam_blocking_promo_period_millis"; 45 static final String SPAM_BLOCKING_PROMO_LAST_SHOW_MILLIS = "spam_blocking_promo_last_show_millis"; 46 public static final String ENABLE_SPAM_BLOCKING_PROMO = "enable_spam_blocking_promo"; 47 public static final String ENABLE_AFTER_CALL_SPAM_BLOCKING_PROMO = 48 "enable_after_call_spam_blocking_promo"; 49 50 private final Context context; 51 private final SpamSettings spamSettings; 52 SpamBlockingPromoHelper(Context context, SpamSettings spamSettings)53 public SpamBlockingPromoHelper(Context context, SpamSettings spamSettings) { 54 this.context = context; 55 this.spamSettings = spamSettings; 56 } 57 58 /** 59 * Returns true if we should show a spam blocking promo. 60 * 61 * <p>Should show spam blocking promo only when all of the following criteria meet 1. Spam 62 * blocking promo is enabled by flag. 2. Spam blocking setting is available. 3. Spam blocking 63 * setting is not yet enabled. 4. Time since last spam blocking promo exceeds the threshold. 64 * 65 * @return true if we should show a spam blocking promo. 66 */ shouldShowSpamBlockingPromo()67 public boolean shouldShowSpamBlockingPromo() { 68 if (!ConfigProviderComponent.get(context) 69 .getConfigProvider() 70 .getBoolean(ENABLE_SPAM_BLOCKING_PROMO, false) 71 || !spamSettings.isSpamEnabled() 72 || !spamSettings.isSpamBlockingEnabledByFlag() 73 || spamSettings.isSpamBlockingEnabledByUser()) { 74 return false; 75 } 76 77 long lastShowMillis = 78 StorageComponent.get(context) 79 .unencryptedSharedPrefs() 80 .getLong(SPAM_BLOCKING_PROMO_LAST_SHOW_MILLIS, 0); 81 long showPeriodMillis = 82 ConfigProviderComponent.get(context) 83 .getConfigProvider() 84 .getLong(SPAM_BLOCKING_PROMO_PERIOD_MILLIS, Long.MAX_VALUE); 85 return lastShowMillis == 0 || System.currentTimeMillis() - lastShowMillis > showPeriodMillis; 86 } 87 88 /* Returns true if we should show a spam blocking promo in after call notification scenario. */ shouldShowAfterCallSpamBlockingPromo()89 public boolean shouldShowAfterCallSpamBlockingPromo() { 90 return shouldShowSpamBlockingPromo() 91 && ConfigProviderComponent.get(context) 92 .getConfigProvider() 93 .getBoolean(ENABLE_AFTER_CALL_SPAM_BLOCKING_PROMO, false); 94 } 95 96 /** 97 * Shows a spam blocking promo dialog. 98 * 99 * @param fragmentManager the fragment manager to show the dialog. 100 * @param onEnableListener the listener called when enable button is clicked. 101 * @param onDismissListener the listener called when the dialog is dismissed. 102 */ showSpamBlockingPromoDialog( FragmentManager fragmentManager, OnEnableListener onEnableListener, OnDismissListener onDismissListener)103 public void showSpamBlockingPromoDialog( 104 FragmentManager fragmentManager, 105 OnEnableListener onEnableListener, 106 OnDismissListener onDismissListener) { 107 updateLastShowSpamTimestamp(); 108 SpamBlockingPromoDialogFragment.newInstance(onEnableListener, onDismissListener) 109 .show(fragmentManager, SpamBlockingPromoDialogFragment.SPAM_BLOCKING_PROMO_DIALOG_TAG); 110 } 111 updateLastShowSpamTimestamp()112 private void updateLastShowSpamTimestamp() { 113 StorageComponent.get(context) 114 .unencryptedSharedPrefs() 115 .edit() 116 .putLong(SPAM_BLOCKING_PROMO_LAST_SHOW_MILLIS, System.currentTimeMillis()) 117 .apply(); 118 } 119 120 /** 121 * Shows a modify setting on complete snackbar and a link to redirect to setting page. 122 * 123 * @param view the view to attach on-complete notice snackbar. 124 * @param success whether the modify setting operation succceeds. 125 */ showModifySettingOnCompleteSnackbar(View view, boolean success)126 public void showModifySettingOnCompleteSnackbar(View view, boolean success) { 127 String snackBarText = 128 success 129 ? context.getString(R.string.spam_blocking_settings_enable_complete_text) 130 : context.getString(R.string.spam_blocking_settings_enable_error_text); 131 Snackbar.make(view, snackBarText, Snackbar.LENGTH_LONG) 132 .setAction( 133 R.string.spam_blocking_setting_prompt, 134 v -> context.startActivity(spamSettings.getSpamBlockingSettingIntent(context))) 135 .setActionTextColor( 136 context.getResources().getColor(R.color.dialer_snackbar_action_text_color)) 137 .show(); 138 } 139 140 /** Shows a modify setting on complete toast message. */ showModifySettingOnCompleteToast(boolean success)141 public void showModifySettingOnCompleteToast(boolean success) { 142 String toastText = 143 success 144 ? context.getString(R.string.spam_blocking_settings_enable_complete_text) 145 : context.getString(R.string.spam_blocking_settings_enable_error_text); 146 Toast.makeText(context, toastText, Toast.LENGTH_LONG).show(); 147 } 148 149 /** 150 * Shows a spam blocking promo notification. 151 * 152 * @param notificationTag a string identifier for this notification. 153 * @param notificationId an identifier for this notification. 154 * @param contentIntent pending intent to be sent when notification is clicked. 155 * @param actionIntent pending intent to be sent when enable-spam-blocking button is clicked. 156 */ showSpamBlockingPromoNotification( String notificationTag, int notificationId, PendingIntent contentIntent, PendingIntent actionIntent)157 public void showSpamBlockingPromoNotification( 158 String notificationTag, 159 int notificationId, 160 PendingIntent contentIntent, 161 PendingIntent actionIntent) { 162 updateLastShowSpamTimestamp(); 163 Logger.get(context) 164 .logImpression(DialerImpression.Type.SPAM_BLOCKING_AFTER_CALL_NOTIFICATION_PROMO_SHOWN); 165 DialerNotificationManager.notify( 166 context, 167 notificationTag, 168 notificationId, 169 getSpamBlockingPromoNotification(contentIntent, actionIntent)); 170 } 171 172 /** 173 * Builds a spam blocking promo notification with given intents. 174 * 175 * @param contentIntent pending intent to be sent when notification is clicked. 176 * @param actionIntent pending intent to be sent when enable-spam-blocking button is clicked. 177 */ 178 @SuppressLint("NewApi") getSpamBlockingPromoNotification( PendingIntent contentIntent, PendingIntent actionIntent)179 private Notification getSpamBlockingPromoNotification( 180 PendingIntent contentIntent, PendingIntent actionIntent) { 181 Notification.Builder builder = 182 new Builder(context) 183 .setContentIntent(contentIntent) 184 .setCategory(Notification.CATEGORY_STATUS) 185 .setPriority(Notification.PRIORITY_DEFAULT) 186 .setColor(ThemeComponent.get(context).theme().getColorPrimary()) 187 .setSmallIcon(R.drawable.quantum_ic_call_vd_theme_24) 188 .setLargeIcon(Icon.createWithResource(context, R.drawable.spam_blocking_promo_icon)) 189 .setContentText(context.getString(R.string.spam_blocking_promo_text)) 190 .setStyle( 191 new Notification.BigTextStyle() 192 .bigText(context.getString(R.string.spam_blocking_promo_text))) 193 .addAction( 194 new Notification.Action.Builder( 195 R.drawable.quantum_ic_block_vd_theme_24, 196 context.getString(R.string.spam_blocking_promo_action_filter_spam), 197 actionIntent) 198 .build()) 199 .setContentTitle(context.getString(R.string.spam_blocking_promo_title)); 200 201 if (BuildCompat.isAtLeastO()) { 202 builder.setChannelId(NotificationChannelId.DEFAULT); 203 } 204 return builder.build(); 205 } 206 } 207 208