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.voicemail.impl;
18
19import android.content.Context;
20import android.os.Bundle;
21import android.support.annotation.WorkerThread;
22import android.telecom.PhoneAccountHandle;
23import android.telephony.TelephonyManager;
24import android.text.TextUtils;
25import com.android.voicemail.impl.settings.VisualVoicemailSettingsUtil;
26import com.android.voicemail.impl.settings.VoicemailChangePinActivity;
27import java.lang.reflect.Method;
28
29/** Handles migration of data from the visual voicemail client in telephony before O. */
30public final class PreOMigrationHandler {
31
32  // Hidden system APIs to access pre O VVM data
33  // Bundle getVisualVoicemailSettings()
34  private static final String METHOD_GET_VISUAL_VOICEMAIL_SETTINGS = "getVisualVoicemailSettings";
35
36  /**
37   * Key in bundle returned by {@link #METHOD_GET_VISUAL_VOICEMAIL_SETTINGS}, indicating whether
38   * visual voicemail was enabled or disabled by the user. If the user never explicitly changed this
39   * setting, this key will not exist.
40   */
41  private static final String EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL =
42      "android.telephony.extra.VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL";
43
44  /**
45   * Key in bundle returned by {@link #METHOD_GET_VISUAL_VOICEMAIL_SETTINGS}, indicating the
46   * voicemail access PIN scrambled during the auto provisioning process. The user is expected to
47   * reset their PIN if this value is not {@code null}.
48   */
49  private static final String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING =
50      "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING";
51
52  private static final String PRE_O_MIGRATION_FINISHED = "pre_o_migration_finished";
53
54  @WorkerThread
55  public static void migrate(Context context, PhoneAccountHandle phoneAccountHandle) {
56    Assert.isNotMainThread();
57    VisualVoicemailPreferences preferences =
58        new VisualVoicemailPreferences(context, phoneAccountHandle);
59    if (preferences.getBoolean(PRE_O_MIGRATION_FINISHED, false)) {
60      VvmLog.i("PreOMigrationHandler", phoneAccountHandle + " already migrated");
61      return;
62    }
63    VvmLog.i("PreOMigrationHandler", "migrating " + phoneAccountHandle);
64    migrateSettings(context, phoneAccountHandle);
65
66    preferences.edit().putBoolean(PRE_O_MIGRATION_FINISHED, true).apply();
67  }
68
69  private static void migrateSettings(Context context, PhoneAccountHandle phoneAccountHandle) {
70    VvmLog.i("PreOMigrationHandler.migrateSettings", "migrating settings");
71    TelephonyManager telephonyManager =
72        context
73            .getSystemService(TelephonyManager.class)
74            .createForPhoneAccountHandle(phoneAccountHandle);
75    if (telephonyManager == null) {
76      VvmLog.e("PreOMigrationHandler.migrateSettings", "invalid PhoneAccountHandle");
77      return;
78    }
79    Bundle legacySettings;
80    try {
81      Method method = TelephonyManager.class.getMethod(METHOD_GET_VISUAL_VOICEMAIL_SETTINGS);
82      legacySettings = (Bundle) method.invoke(telephonyManager);
83    } catch (ReflectiveOperationException | ClassCastException e) {
84      VvmLog.i("PreOMigrationHandler.migrateSettings", "unable to retrieve settings from system");
85      return;
86    }
87
88    if (legacySettings.containsKey(EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL)) {
89      boolean enabled = legacySettings.getBoolean(EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL);
90      VvmLog.i("PreOMigrationHandler.migrateSettings", "setting VVM enabled to " + enabled);
91      VisualVoicemailSettingsUtil.setEnabled(context, phoneAccountHandle, enabled);
92    }
93
94    if (legacySettings.containsKey(EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING)) {
95      String scrambledPin = legacySettings.getString(EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING);
96      if (!TextUtils.isEmpty(scrambledPin)) {
97        VvmLog.i("PreOMigrationHandler.migrateSettings", "migrating scrambled PIN");
98        VoicemailChangePinActivity.setDefaultOldPIN(context, phoneAccountHandle, scrambledPin);
99      }
100    }
101  }
102}
103