Move Voicemail notification settings into util.

This utility localizes related functions/constants in a class,
in preparation for adding more functionality to make both
voicemail ringtone and vibration settings MSIM-capable, and also
handle associated necessary migrations.

Besides fixing voicemail notifications (before it did not update when
the value is changed), there should be no change in functionality.

+ Add utility for settings related to voicemail notifications.
+ Handle get/set ringtone uri in new util.
+ Handle get/set vibrate in new util.
+ Make keys for shared preferences independent of preference names.
There was an implicit relationship between these before. I think
it is safer if the two are not correlated, and the shared preferences
key needs to be changed shortly to consider subscription id anyways.
+ Handle saving ringtone uri in VoicemailRingtonePreference. For now
this has no change in behavior, but in a subsequent CL we will save
the ringtone by subscription id here.
- Don't use default values on VoicemailRingtonePreference; default
values use the preference's key as the shared preference key, but we
will need to use subscription ids for our keys.

Bug: 18232725
Change-Id: Ifb52f47073418c76ad4bcf86c57c0ed75d05d0ca
diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java
index 0286e71..7207fa2 100644
--- a/src/com/android/phone/CallFeaturesSetting.java
+++ b/src/com/android/phone/CallFeaturesSetting.java
@@ -25,8 +25,6 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
@@ -41,7 +39,6 @@
 import android.preference.ListPreference;
 import android.preference.Preference;
 import android.preference.PreferenceActivity;
-import android.preference.PreferenceManager;
 import android.preference.PreferenceScreen;
 import android.provider.ContactsContract.CommonDataKinds;
 import android.provider.Settings;
@@ -64,6 +61,7 @@
 import com.android.phone.settings.VoicemailDialogUtil;
 import com.android.phone.settings.VoicemailProviderSettings;
 import com.android.phone.settings.VoicemailProviderSettingsUtil;
+import com.android.phone.settings.VoicemailNotificationSettingsUtil;
 import com.android.phone.settings.fdn.FdnSetting;
 import com.android.services.telephony.sip.SipUtil;
 
@@ -141,19 +139,14 @@
 
     // String keys for preference lookup
     // TODO: Naming these "BUTTON_*" is confusing since they're not actually buttons(!)
+    // TODO: Consider moving these strings to strings.xml, so that they are not duplicated here and
+    // in the layout files. These strings need to be treated carefully; if the setting is
+    // persistent, they are used as the key to store shared preferences and the name should not be
+    // changed unless the settings are also migrated.
     private static final String VOICEMAIL_SETTING_SCREEN_PREF_KEY = "button_voicemail_category_key";
     private static final String BUTTON_VOICEMAIL_KEY = "button_voicemail_key";
     private static final String BUTTON_VOICEMAIL_PROVIDER_KEY = "button_voicemail_provider_key";
     private static final String BUTTON_VOICEMAIL_SETTING_KEY = "button_voicemail_setting_key";
-    // New preference key for voicemail notification vibration
-    /* package */ static final String BUTTON_VOICEMAIL_NOTIFICATION_VIBRATE_KEY =
-            "button_voicemail_notification_vibrate_key";
-    // Old preference key for voicemail notification vibration. Used for migration to the new
-    // preference key only.
-    /* package */ static final String BUTTON_VOICEMAIL_NOTIFICATION_VIBRATE_WHEN_KEY =
-            "button_voicemail_notification_vibrate_when_key";
-    /* package */ static final String BUTTON_VOICEMAIL_NOTIFICATION_RINGTONE_KEY =
-            "button_voicemail_notification_ringtone_key";
     private static final String BUTTON_FDN_KEY   = "button_fdn_key";
 
     private static final String BUTTON_DTMF_KEY        = "button_dtmf_settings";
@@ -176,8 +169,6 @@
     private static final int EVENT_FORWARDING_CHANGED       = 501;
     private static final int EVENT_FORWARDING_GET_COMPLETED = 502;
 
-    private static final int MSG_UPDATE_VOICEMAIL_RINGTONE_SUMMARY = 1;
-
     public static final String HAC_KEY = "HACSetting";
     public static final String HAC_VAL_ON = "ON";
     public static final String HAC_VAL_OFF = "OFF";
@@ -190,10 +181,6 @@
     private AudioManager mAudioManager;
     private VoicemailProviderSettingsUtil mVmProviderSettingsUtil;
 
-    // voicemail notification vibration string constants
-    private static final String VOICEMAIL_VIBRATION_ALWAYS = "always";
-    private static final String VOICEMAIL_VIBRATION_NEVER = "never";
-
     private SubscriptionInfoHelper mSubscriptionInfoHelper;
 
     private EditPhoneNumberPreference mSubMenuVoicemailSettings;
@@ -432,6 +419,9 @@
                 mChangingVMorFwdDueToProviderChange = true;
                 saveVoiceMailAndForwardingNumber(newProviderKey, newProviderSettings);
             }
+        } else if (preference.getKey().equals(mVoicemailNotificationVibrate.getKey())) {
+            VoicemailNotificationSettingsUtil.setVibrationEnabled(
+                    mPhone.getContext(), Boolean.TRUE.equals(objValue));
         } else if (preference == mEnableVideoCalling) {
             if (ImsManager.isEnhanced4gLteModeSettingEnabledByUser(mPhone.getContext())) {
                 PhoneGlobals.getInstance().phoneMgr.enableVideoCalling((boolean) objValue);
@@ -1183,15 +1173,19 @@
         mButtonAutoRetry = (CheckBoxPreference) findPreference(BUTTON_RETRY_KEY);
         mButtonHAC = (CheckBoxPreference) findPreference(BUTTON_HAC_KEY);
         mButtonTTY = (ListPreference) findPreference(BUTTON_TTY_KEY);
-        mVoicemailProviders = (ListPreference) findPreference(BUTTON_VOICEMAIL_PROVIDER_KEY);
         mEnableVideoCalling = (CheckBoxPreference) findPreference(ENABLE_VIDEO_CALLING_KEY);
 
+        mVoicemailProviders = (ListPreference) findPreference(BUTTON_VOICEMAIL_PROVIDER_KEY);
         mVoicemailProviders.setOnPreferenceChangeListener(this);
+
         mVoicemailSettingsScreen =
                 (PreferenceScreen) findPreference(VOICEMAIL_SETTING_SCREEN_PREF_KEY);
         mVoicemailSettings = (PreferenceScreen)findPreference(BUTTON_VOICEMAIL_SETTING_KEY);
-        mVoicemailNotificationVibrate =
-                (CheckBoxPreference) findPreference(BUTTON_VOICEMAIL_NOTIFICATION_VIBRATE_KEY);
+
+        mVoicemailNotificationVibrate = (CheckBoxPreference) findPreference(
+                getResources().getString(R.string.voicemail_notification_vibrate_key));
+        mVoicemailNotificationVibrate.setOnPreferenceChangeListener(this);
+
         initVoiceMailProviders();
 
         if (getResources().getBoolean(R.bool.dtmf_type_enabled)) {
@@ -1303,12 +1297,8 @@
         updateVoiceNumberField();
         mVMProviderSettingsForced = false;
 
-        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(
-                mPhone.getContext());
-        if (migrateVoicemailVibrationSettingsIfNeeded(prefs)) {
-            mVoicemailNotificationVibrate.setChecked(prefs.getBoolean(
-                    BUTTON_VOICEMAIL_NOTIFICATION_VIBRATE_KEY, false));
-        }
+        mVoicemailNotificationVibrate.setChecked(
+                VoicemailNotificationSettingsUtil.isVibrationEnabled(mPhone.getContext()));
 
         if (ImsManager.isVtEnabledByPlatform(mPhone.getContext()) && ENABLE_VT_FLAG) {
             boolean currentValue =
@@ -1321,25 +1311,6 @@
         }
     }
 
-    // Migrate settings from BUTTON_VOICEMAIL_NOTIFICATION_VIBRATE_WHEN_KEY to
-    // BUTTON_VOICEMAIL_NOTIFICATION_VIBRATE_KEY, if the latter does not exist.
-    // Returns true if migration was performed.
-    public static boolean migrateVoicemailVibrationSettingsIfNeeded(SharedPreferences prefs) {
-        if (!prefs.contains(BUTTON_VOICEMAIL_NOTIFICATION_VIBRATE_KEY)) {
-            String vibrateWhen = prefs.getString(
-                    BUTTON_VOICEMAIL_NOTIFICATION_VIBRATE_WHEN_KEY, VOICEMAIL_VIBRATION_NEVER);
-            // If vibrateWhen is always, then voicemailVibrate should be True.
-            // otherwise if vibrateWhen is "only in silent mode", or "never", then
-            // voicemailVibrate = False.
-            boolean voicemailVibrate = vibrateWhen.equals(VOICEMAIL_VIBRATION_ALWAYS);
-            final SharedPreferences.Editor editor = prefs.edit();
-            editor.putBoolean(BUTTON_VOICEMAIL_NOTIFICATION_VIBRATE_KEY, voicemailVibrate);
-            editor.commit();
-            return true;
-        }
-        return false;
-    }
-
     private void handleTTYChange(Preference preference, Object objValue) {
         int buttonTtyMode;
         buttonTtyMode = Integer.valueOf((String) objValue).intValue();
@@ -1526,6 +1497,7 @@
         }
         return super.onOptionsItemSelected(item);
     }
+
     /**
      * Finish current Activity and go up to the top level Settings ({@link CallFeaturesSetting}).
      * This is useful for implementing "HomeAsUp" capability for second-level Settings.
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index e06684c..77daabb 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -42,6 +42,7 @@
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneBase;
 import com.android.internal.telephony.TelephonyCapabilities;
+import com.android.phone.settings.VoicemailNotificationSettingsUtil;
 
 import java.util.List;
 
@@ -313,16 +314,7 @@
             Intent intent = new Intent(Intent.ACTION_CALL,
                     Uri.fromParts(PhoneAccount.SCHEME_VOICEMAIL, "", null));
             PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
-
-            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
-            Uri ringtoneUri;
-            String uriString = prefs.getString(
-                    CallFeaturesSetting.BUTTON_VOICEMAIL_NOTIFICATION_RINGTONE_KEY, null);
-            if (!TextUtils.isEmpty(uriString)) {
-                ringtoneUri = Uri.parse(uriString);
-            } else {
-                ringtoneUri = Settings.System.DEFAULT_NOTIFICATION_URI;
-            }
+            Uri ringtoneUri = VoicemailNotificationSettingsUtil.getRingtoneUri(mContext);
 
             Notification.Builder builder = new Notification.Builder(mContext);
             builder.setSmallIcon(resId)
@@ -334,10 +326,7 @@
                     .setColor(mContext.getResources().getColor(R.color.dialer_theme_color))
                     .setOngoing(true);
 
-            CallFeaturesSetting.migrateVoicemailVibrationSettingsIfNeeded(prefs);
-            final boolean vibrate = prefs.getBoolean(
-                    CallFeaturesSetting.BUTTON_VOICEMAIL_NOTIFICATION_VIBRATE_KEY, false);
-            if (vibrate) {
+            if (VoicemailNotificationSettingsUtil.isVibrationEnabled(mContext)) {
                 builder.setDefaults(Notification.DEFAULT_VIBRATE);
             }
 
diff --git a/src/com/android/phone/settings/VoicemailNotificationSettingsUtil.java b/src/com/android/phone/settings/VoicemailNotificationSettingsUtil.java
new file mode 100644
index 0000000..3a93f11
--- /dev/null
+++ b/src/com/android/phone/settings/VoicemailNotificationSettingsUtil.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2014 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.phone.settings;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.net.Uri;
+import android.preference.PreferenceManager;
+import android.provider.Settings;
+import android.text.TextUtils;
+
+import com.android.phone.R;
+
+public class VoicemailNotificationSettingsUtil {
+    private static final String VOICEMAIL_NOTIFICATION_RINGTONE_SHARED_PREFS_KEY =
+            "button_voicemail_notification_ringtone_key";
+    private static final String VOICEMAIL_NOTIFICATION_VIBRATION_SHARED_PREFS_KEY =
+            "button_voicemail_notification_vibrate_key";
+
+    // Old voicemail notification vibration string constants used for migration.
+    private static final String OLD_VOICEMAIL_VIBRATE_WHEN_SHARED_PREFS_KEY =
+            "button_voicemail_notification_vibrate_when_key";
+    private static final String OLD_VOICEMAIL_RINGTONE_SHARED_PREFS_KEY =
+            "button_voicemail_notification_ringtone_key";
+    private static final String OLD_VOICEMAIL_VIBRATION_ALWAYS = "always";
+    private static final String OLD_VOICEMAIL_VIBRATION_NEVER = "never";
+
+    public static void setVibrationEnabled(Context context, boolean isEnabled) {
+        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+        SharedPreferences.Editor editor = prefs.edit();
+        editor.putBoolean(VOICEMAIL_NOTIFICATION_VIBRATION_SHARED_PREFS_KEY, isEnabled);
+        editor.commit();
+    }
+
+    public static boolean isVibrationEnabled(Context context) {
+        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+        migrateVoicemailVibrationSettingsIfNeeded(prefs);
+        return prefs.getBoolean(
+                VOICEMAIL_NOTIFICATION_VIBRATION_SHARED_PREFS_KEY, false /* defValue */);
+    }
+
+    /**
+     * Migrate settings from OLD_VIBRATE_WHEN_KEY to VOICEMAIL_NOTIFICATION_VIBRATE_KEY if the
+     * latter does not exist.
+     */
+    private static void migrateVoicemailVibrationSettingsIfNeeded(SharedPreferences prefs) {
+        if (!prefs.contains(VOICEMAIL_NOTIFICATION_VIBRATION_SHARED_PREFS_KEY)) {
+            // If vibrateWhen is always, then voicemailVibrate should be true.
+            // If it is "only in silent mode", or "never", then voicemailVibrate should be false.
+            String vibrateWhen = prefs.getString(
+                    OLD_VOICEMAIL_VIBRATE_WHEN_SHARED_PREFS_KEY, OLD_VOICEMAIL_VIBRATION_NEVER);
+            boolean voicemailVibrate = vibrateWhen.equals(OLD_VOICEMAIL_VIBRATION_ALWAYS);
+
+            SharedPreferences.Editor editor = prefs.edit();
+            editor.putBoolean(VOICEMAIL_NOTIFICATION_VIBRATION_SHARED_PREFS_KEY, voicemailVibrate)
+                    .remove(OLD_VOICEMAIL_VIBRATE_WHEN_SHARED_PREFS_KEY)
+                    .commit();
+        }
+    }
+
+    public static void setRingtoneUri(Context context, Uri ringtoneUri) {
+        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+        String ringtoneUriStr = ringtoneUri != null ? ringtoneUri.toString() : "";
+
+        SharedPreferences.Editor editor = prefs.edit();
+        editor.putString(VOICEMAIL_NOTIFICATION_RINGTONE_SHARED_PREFS_KEY, ringtoneUriStr);
+        editor.commit();
+    }
+
+    public static Uri getRingtoneUri(Context context) {
+        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+        if (!prefs.contains(VOICEMAIL_NOTIFICATION_RINGTONE_SHARED_PREFS_KEY)) {
+            return Settings.System.DEFAULT_NOTIFICATION_URI;
+        }
+        String uriString = prefs.getString(
+                VOICEMAIL_NOTIFICATION_RINGTONE_SHARED_PREFS_KEY, null /* defValue */);
+        return !TextUtils.isEmpty(uriString) ? Uri.parse(uriString) : null;
+    }
+
+    public static String getRingtoneSharedPreferencesKey() {
+        return VOICEMAIL_NOTIFICATION_RINGTONE_SHARED_PREFS_KEY;
+    }
+}
diff --git a/src/com/android/phone/settings/VoicemailRingtonePreference.java b/src/com/android/phone/settings/VoicemailRingtonePreference.java
index 3cc48af..48e5367 100644
--- a/src/com/android/phone/settings/VoicemailRingtonePreference.java
+++ b/src/com/android/phone/settings/VoicemailRingtonePreference.java
@@ -45,7 +45,7 @@
                         preference.getContext(),
                         mVoicemailRingtoneLookupComplete,
                         RingtoneManager.TYPE_NOTIFICATION,
-                        preference,
+                        VoicemailNotificationSettingsUtil.getRingtoneSharedPreferencesKey(),
                         MSG_UPDATE_VOICEMAIL_RINGTONE_SUMMARY);
             }
         };
@@ -54,8 +54,16 @@
     }
 
     @Override
+    protected Uri onRestoreRingtone() {
+        return VoicemailNotificationSettingsUtil.getRingtoneUri(getContext());
+    }
+
+    @Override
     protected void onSaveRingtone(Uri ringtoneUri) {
-        super.onSaveRingtone(ringtoneUri);
+        // Don't call superclass method because it uses the pref key as the SharedPreferences key.
+        // Delegate to the voicemail notification utility to save the ringtone instead.
+        VoicemailNotificationSettingsUtil.setRingtoneUri(getContext(), ringtoneUri);
+
         updateRingtoneName();
     }