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