Home | History | Annotate | Download | only in error
      1 /*
      2  * Copyright (C) 2017 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.app.voicemail.error;
     18 
     19 import android.app.AlertDialog;
     20 import android.content.ComponentName;
     21 import android.content.Context;
     22 import android.content.DialogInterface;
     23 import android.content.Intent;
     24 import android.content.SharedPreferences;
     25 import android.graphics.Typeface;
     26 import android.preference.PreferenceManager;
     27 import android.support.annotation.Nullable;
     28 import android.telecom.PhoneAccountHandle;
     29 import android.telephony.TelephonyManager;
     30 import android.text.SpannableString;
     31 import android.text.style.StyleSpan;
     32 import android.view.View;
     33 import android.view.View.OnClickListener;
     34 import com.android.contacts.common.compat.TelephonyManagerCompat;
     35 import com.android.dialer.app.voicemail.error.VoicemailErrorMessage.Action;
     36 import com.android.dialer.common.LogUtil;
     37 import com.android.dialer.configprovider.ConfigProviderBindings;
     38 import com.android.dialer.logging.DialerImpression;
     39 import com.android.dialer.logging.Logger;
     40 import com.android.voicemail.VisualVoicemailTypeExtensions;
     41 import com.android.voicemail.VoicemailClient;
     42 import com.android.voicemail.VoicemailComponent;
     43 import java.util.Locale;
     44 
     45 /**
     46  * Create error message from {@link VoicemailStatus} for voicemail. This is will show different
     47  * terms of service for Verizon and for other carriers.
     48  */
     49 public class VoicemailTosMessageCreator {
     50   // Flag to check which version of the Verizon ToS that the user has accepted.
     51   public static final String VVM3_TOS_VERSION_ACCEPTED_KEY = "vvm3_tos_version_accepted";
     52 
     53   // Flag to check which version of the Google Dialer ToS that the user has accepted.
     54   public static final String DIALER_TOS_VERSION_ACCEPTED_KEY = "dialer_tos_version_accepted";
     55 
     56   public static final int CURRENT_VVM3_TOS_VERSION = 2;
     57   public static final int CURRENT_DIALER_TOS_VERSION = 1;
     58 
     59   private static final String ISO639_SPANISH = "es";
     60 
     61   private final Context context;
     62   private final VoicemailStatus status;
     63   private final VoicemailStatusReader statusReader;
     64   private final SharedPreferences preferences;
     65 
     66   VoicemailTosMessageCreator(
     67       final Context context,
     68       final VoicemailStatus status,
     69       final VoicemailStatusReader statusReader) {
     70     this.context = context;
     71     this.status = status;
     72     this.statusReader = statusReader;
     73     this.preferences = PreferenceManager.getDefaultSharedPreferences(context);
     74   }
     75 
     76   @Nullable
     77   VoicemailErrorMessage maybeCreateTosMessage() {
     78     // TODO: add filtering based on carrier
     79     if (hasAcceptedTos()) {
     80       return null;
     81     }
     82 
     83     if (!shouldShowTos()) {
     84       return null;
     85     }
     86 
     87     logTosCreatedImpression();
     88 
     89     return new VoicemailTosMessage(
     90             getTosTitle(),
     91             getTosMessage(),
     92             new Action(
     93                 getDeclineText(),
     94                 new OnClickListener() {
     95                   @Override
     96                   public void onClick(View v) {
     97                     LogUtil.i("VoicemailTosMessageCreator.maybeShowTosMessage", "decline clicked");
     98                     PhoneAccountHandle handle =
     99                         new PhoneAccountHandle(
    100                             ComponentName.unflattenFromString(status.phoneAccountComponentName),
    101                             status.phoneAccountId);
    102                     logTosDeclinedImpression();
    103                     showDeclineTosDialog(handle);
    104                   }
    105                 }),
    106             new Action(
    107                 getAcceptText(),
    108                 new OnClickListener() {
    109                   @Override
    110                   public void onClick(View v) {
    111                     LogUtil.i("VoicemailTosMessageCreator.maybeShowTosMessage", "accept clicked");
    112                     recordTosAcceptance();
    113                     logTosAcceptedImpression();
    114                     statusReader.refresh();
    115                   }
    116                 },
    117                 true /* raised */))
    118         .setModal(true)
    119         .setImageResourceId(getTosImageId());
    120   }
    121 
    122   private boolean shouldShowTos() {
    123     if (isVvm3()) {
    124       LogUtil.i("VoicemailTosMessageCreator.shouldShowTos", "showing TOS for verizon");
    125       return true;
    126     }
    127 
    128     if (isVoicemailTranscriptionEnabled()) {
    129       LogUtil.i(
    130           "VoicemailTosMessageCreator.shouldShowTos", "showing TOS for Google transcription users");
    131       return true;
    132     }
    133 
    134     return false;
    135   }
    136 
    137   private boolean isVoicemailTranscriptionEnabled() {
    138     return ConfigProviderBindings.get(context).getBoolean("voicemail_transcription_enabled", false);
    139   }
    140 
    141   private void showDeclineTosDialog(final PhoneAccountHandle handle) {
    142     if (isVvm3() && Vvm3VoicemailMessageCreator.PIN_NOT_SET == status.configurationState) {
    143       LogUtil.i(
    144           "VoicemailTosMessageCreator.showDeclineTosDialog", "PIN_NOT_SET, showing set PIN dialog");
    145       showSetPinBeforeDeclineDialog();
    146       return;
    147     }
    148     LogUtil.i(
    149         "VoicemailTosMessageCreator.showDeclineVerizonTosDialog",
    150         "showing decline ToS dialog, status=" + status);
    151     final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class);
    152     AlertDialog.Builder builder = new AlertDialog.Builder(context);
    153     builder.setMessage(getTosDeclinedDialogMessageId());
    154     builder.setPositiveButton(
    155         getTosDeclinedDialogDowngradeId(),
    156         new DialogInterface.OnClickListener() {
    157           @Override
    158           public void onClick(DialogInterface dialog, int which) {
    159             Logger.get(context).logImpression(DialerImpression.Type.VOICEMAIL_VVM3_TOS_DECLINED);
    160             VoicemailClient voicemailClient = VoicemailComponent.get(context).getVoicemailClient();
    161             if (voicemailClient.isVoicemailModuleEnabled()) {
    162               voicemailClient.setVoicemailEnabled(context, status.getPhoneAccountHandle(), false);
    163             } else {
    164               TelephonyManagerCompat.setVisualVoicemailEnabled(telephonyManager, handle, false);
    165             }
    166           }
    167         });
    168 
    169     builder.setNegativeButton(
    170         android.R.string.cancel,
    171         new DialogInterface.OnClickListener() {
    172           @Override
    173           public void onClick(DialogInterface dialog, int which) {
    174             dialog.dismiss();
    175           }
    176         });
    177 
    178     builder.setCancelable(true);
    179     builder.show();
    180   }
    181 
    182   private void showSetPinBeforeDeclineDialog() {
    183     AlertDialog.Builder builder = new AlertDialog.Builder(context);
    184     builder.setMessage(R.string.verizon_terms_and_conditions_decline_set_pin_dialog_message);
    185     builder.setPositiveButton(
    186         R.string.verizon_terms_and_conditions_decline_set_pin_dialog_set_pin,
    187         new DialogInterface.OnClickListener() {
    188           @Override
    189           public void onClick(DialogInterface dialog, int which) {
    190             Logger.get(context)
    191                 .logImpression(DialerImpression.Type.VOICEMAIL_VVM3_TOS_DECLINE_CHANGE_PIN_SHOWN);
    192             Intent intent = new Intent(TelephonyManager.ACTION_CONFIGURE_VOICEMAIL);
    193             context.startActivity(intent);
    194           }
    195         });
    196 
    197     builder.setNegativeButton(
    198         android.R.string.cancel,
    199         new DialogInterface.OnClickListener() {
    200           @Override
    201           public void onClick(DialogInterface dialog, int which) {
    202             dialog.dismiss();
    203           }
    204         });
    205 
    206     builder.setCancelable(true);
    207     builder.show();
    208   }
    209 
    210   private boolean isVvm3() {
    211     return VisualVoicemailTypeExtensions.VVM_TYPE_VVM3.equals(status.type);
    212   }
    213 
    214   private boolean useSpanish() {
    215     return Locale.getDefault().getLanguage().equals(new Locale(ISO639_SPANISH).getLanguage());
    216   }
    217 
    218   private boolean hasAcceptedTos() {
    219     if (isVvm3()) {
    220       return preferences.getInt(VVM3_TOS_VERSION_ACCEPTED_KEY, 0) >= CURRENT_VVM3_TOS_VERSION;
    221     } else {
    222       return preferences.getInt(DIALER_TOS_VERSION_ACCEPTED_KEY, 0) >= CURRENT_DIALER_TOS_VERSION;
    223     }
    224   }
    225 
    226   private void recordTosAcceptance() {
    227     if (isVvm3()) {
    228       preferences.edit().putInt(VVM3_TOS_VERSION_ACCEPTED_KEY, CURRENT_VVM3_TOS_VERSION).apply();
    229     } else {
    230       preferences
    231           .edit()
    232           .putInt(DIALER_TOS_VERSION_ACCEPTED_KEY, CURRENT_DIALER_TOS_VERSION)
    233           .apply();
    234     }
    235   }
    236 
    237   private void logTosCreatedImpression() {
    238     if (isVvm3()) {
    239       Logger.get(context).logImpression(DialerImpression.Type.VOICEMAIL_VVM3_TOS_V2_CREATED);
    240     } else {
    241       Logger.get(context).logImpression(DialerImpression.Type.VOICEMAIL_DIALER_TOS_CREATED);
    242     }
    243   }
    244 
    245   private void logTosDeclinedImpression() {
    246     if (isVvm3()) {
    247       Logger.get(context)
    248           .logImpression(DialerImpression.Type.VOICEMAIL_VVM3_TOS_V2_DECLINE_CLICKED);
    249     } else {
    250       Logger.get(context).logImpression(DialerImpression.Type.VOICEMAIL_DIALER_TOS_DECLINE_CLICKED);
    251     }
    252   }
    253 
    254   private void logTosAcceptedImpression() {
    255     if (isVvm3()) {
    256       Logger.get(context).logImpression(DialerImpression.Type.VOICEMAIL_VVM3_TOS_V2_ACCEPTED);
    257     } else {
    258       Logger.get(context).logImpression(DialerImpression.Type.VOICEMAIL_DIALER_TOS_ACCEPTED);
    259     }
    260   }
    261 
    262   private CharSequence getVvm3Tos() {
    263     return useSpanish()
    264         ? context.getString(R.string.verizon_terms_and_conditions_1_1_spanish)
    265         : context.getString(R.string.verizon_terms_and_conditions_1_1_english);
    266   }
    267 
    268   private CharSequence getDialerTos() {
    269     if (!isVoicemailTranscriptionEnabled()) {
    270       return "";
    271     }
    272 
    273     return useSpanish()
    274         ? context.getString(R.string.dialer_terms_and_conditions_1_0_spanish)
    275         : context.getString(R.string.dialer_terms_and_conditions_1_0_english);
    276   }
    277 
    278   private CharSequence getAcceptText() {
    279     if (isVvm3()) {
    280       return useSpanish()
    281           ? context.getString(R.string.verizon_terms_and_conditions_accept_spanish)
    282           : context.getString(R.string.verizon_terms_and_conditions_accept_english);
    283     } else {
    284       return useSpanish()
    285           ? context.getString(R.string.dialer_terms_and_conditions_accept_spanish)
    286           : context.getString(R.string.dialer_terms_and_conditions_accept_english);
    287     }
    288   }
    289 
    290   private CharSequence getDeclineText() {
    291     if (isVvm3()) {
    292       return useSpanish()
    293           ? context.getString(R.string.verizon_terms_and_conditions_decline_spanish)
    294           : context.getString(R.string.verizon_terms_and_conditions_decline_english);
    295     } else {
    296       return useSpanish()
    297           ? context.getString(R.string.dialer_terms_and_conditions_decline_spanish)
    298           : context.getString(R.string.dialer_terms_and_conditions_decline_english);
    299     }
    300   }
    301 
    302   private CharSequence getTosTitle() {
    303     return isVvm3()
    304         ? context.getString(R.string.verizon_terms_and_conditions_title)
    305         : context.getString(R.string.dialer_terms_and_conditions_title);
    306   }
    307 
    308   private CharSequence getTosMessage() {
    309     if (isVvm3()) {
    310       // For verizon the TOS consist of three pieces: google dialer TOS, Verizon TOS message and
    311       // Verizon TOS details.
    312       CharSequence vvm3Details = getVvm3Tos();
    313       CharSequence tos =
    314           context.getString(
    315               R.string.verizon_terms_and_conditions_message, getDialerTos(), vvm3Details);
    316       // Make all text bold except the details.
    317       SpannableString spannableTos = new SpannableString(tos);
    318       spannableTos.setSpan(new StyleSpan(Typeface.BOLD), 0, tos.length() - vvm3Details.length(), 0);
    319       return spannableTos;
    320     } else {
    321       // The TOS for everyone else there are no details, so just make everything bold.
    322       CharSequence tos =
    323           context.getString(R.string.dialer_terms_and_conditions_message, getDialerTos());
    324       SpannableString spannableTos = new SpannableString(tos);
    325       spannableTos.setSpan(new StyleSpan(Typeface.BOLD), 0, tos.length(), 0);
    326       return spannableTos;
    327     }
    328   }
    329 
    330   private int getTosDeclinedDialogMessageId() {
    331     return isVvm3()
    332         ? R.string.verizon_terms_and_conditions_decline_dialog_message
    333         : R.string.dialer_terms_and_conditions_decline_dialog_message;
    334   }
    335 
    336   private int getTosDeclinedDialogDowngradeId() {
    337     return isVvm3()
    338         ? R.string.verizon_terms_and_conditions_decline_dialog_downgrade
    339         : R.string.dialer_terms_and_conditions_decline_dialog_downgrade;
    340   }
    341 
    342   private Integer getTosImageId() {
    343     return isVvm3() ? null : R.drawable.voicemail_tos_image;
    344   }
    345 }
    346