1 /**
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * <p>Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5  * except in compliance with the License. You may obtain a copy of the License at
6  *
7  * <p>http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * <p>Unless required by applicable law or agreed to in writing, software distributed under the
10  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11  * express or implied. See the License for the specific language governing permissions and
12  * limitations under the License
13  */
14 package com.android.dialer.voicemail.settings;
15 
16 import android.annotation.TargetApi;
17 import android.app.AlertDialog;
18 import android.content.DialogInterface;
19 import android.content.Intent;
20 import android.os.Build.VERSION_CODES;
21 import android.os.Bundle;
22 import android.preference.Preference;
23 import android.preference.Preference.OnPreferenceClickListener;
24 import android.preference.PreferenceFragment;
25 import android.preference.PreferenceScreen;
26 import android.preference.SwitchPreference;
27 import android.provider.Settings;
28 import android.support.annotation.IntDef;
29 import android.support.annotation.Nullable;
30 import android.support.annotation.VisibleForTesting;
31 import android.telecom.PhoneAccount;
32 import android.telecom.PhoneAccountHandle;
33 import android.telecom.TelecomManager;
34 import android.telephony.SubscriptionInfo;
35 import android.telephony.TelephonyManager;
36 import com.android.dialer.common.Assert;
37 import com.android.dialer.common.LogUtil;
38 import com.android.dialer.common.preference.SwitchPreferenceWithClickableSummary;
39 import com.android.dialer.configprovider.ConfigProviderComponent;
40 import com.android.dialer.logging.DialerImpression;
41 import com.android.dialer.logging.Logger;
42 import com.android.dialer.notification.NotificationChannelManager;
43 import com.android.dialer.spannable.ContentWithLearnMoreSpanner;
44 import com.android.dialer.telecom.TelecomUtil;
45 import com.android.voicemail.VoicemailClient;
46 import com.android.voicemail.VoicemailClient.ActivationStateListener;
47 import com.android.voicemail.VoicemailComponent;
48 import com.google.common.base.Optional;
49 import java.lang.annotation.Retention;
50 import java.lang.annotation.RetentionPolicy;
51 
52 /**
53  * Fragment for voicemail settings. Requires {@link VoicemailClient#PARAM_PHONE_ACCOUNT_HANDLE} set
54  * in arguments.
55  */
56 @TargetApi(VERSION_CODES.O)
57 public class VoicemailSettingsFragment extends PreferenceFragment
58     implements Preference.OnPreferenceChangeListener, ActivationStateListener {
59 
60   // Extras copied from com.android.phone.settings.VoicemailSettingsActivity,
61   // it does not recognize EXTRA_PHONE_ACCOUNT_HANDLE in O.
62   @VisibleForTesting
63   static final String SUB_ID_EXTRA =
64       "com.android.phone.settings.SubscriptionInfoHelper.SubscriptionId";
65   // Extra on intent containing the label of a subscription.
66   @VisibleForTesting
67   static final String SUB_LABEL_EXTRA =
68       "com.android.phone.settings.SubscriptionInfoHelper.SubscriptionLabel";
69 
70   private static final String TAG = "VmSettingsActivity";
71   @Nullable private PhoneAccountHandle phoneAccountHandle;
72   private VoicemailClient voicemailClient;
73   // Settings that are independent of the carrier configurations
74   private Preference voicemailNotificationPreference;
75   private Preference changeGreetingPreference;
76   private PreferenceScreen advancedSettingsPreference;
77   // Settings that are supported by dialer only if the carrier configurations are valid.
78   private SwitchPreference visualVoicemailPreference;
79   private SwitchPreference voicemailAutoArchivePreference;
80   private SwitchPreferenceWithClickableSummary transcribeVoicemailPreference;
81   // Voicemail transcription analysis toggle
82   private SwitchPreferenceWithClickableSummary donateTranscribedVoicemailPreference;
83   private Preference voicemailChangePinPreference;
84 
85   @Override
onCreate(Bundle icicle)86   public void onCreate(Bundle icicle) {
87     super.onCreate(icicle);
88     phoneAccountHandle =
89         Assert.isNotNull(getArguments().getParcelable(VoicemailClient.PARAM_PHONE_ACCOUNT_HANDLE));
90     voicemailClient = VoicemailComponent.get(getContext()).getVoicemailClient();
91   }
92 
93   @Override
onResume()94   public void onResume() {
95     super.onResume();
96     Logger.get(getContext()).logImpression(DialerImpression.Type.VVM_SETTINGS_VIEWED);
97     voicemailClient.addActivationStateListener(this);
98     PreferenceScreen preferenceScreen = getPreferenceScreen();
99     if (preferenceScreen != null) {
100       preferenceScreen.removeAll();
101     }
102 
103     addPreferencesFromResource(R.xml.voicemail_settings);
104 
105     initializeXmlPreferences();
106 
107     setupVisualVoicemailPreferences();
108 
109     setupNotificationsPreference();
110     setupChangeGreetingPreference();
111     setupAdvancedSettingsPreference();
112   }
113 
setupVisualVoicemailPreferences()114   private void setupVisualVoicemailPreferences() {
115     if (!voicemailClient.hasCarrierSupport(getContext(), phoneAccountHandle)) {
116       removeAllVisualVoicemailPreferences();
117       return;
118     }
119 
120     setupVisualVoicemailPreference();
121 
122     setupVisualVoicemailFeaturePreferences();
123 
124     setupVoicemailChangePinPreference();
125   }
126 
setupVisualVoicemailFeaturePreferences()127   private void setupVisualVoicemailFeaturePreferences() {
128     if (!voicemailClient.isVoicemailEnabled(getContext(), phoneAccountHandle)
129         || !voicemailClient.isActivated(getContext(), phoneAccountHandle)) {
130       removeAllTranscriptionPreferences();
131       getPreferenceScreen().removePreference(voicemailAutoArchivePreference);
132       return;
133     }
134     setupAutoArchivePreference();
135     updateTranscriptionPreferences();
136   }
137 
updateTranscriptionPreferences()138   private void updateTranscriptionPreferences() {
139     if (!VoicemailComponent.get(getContext())
140         .getVoicemailClient()
141         .isVoicemailTranscriptionAvailable(getContext(), phoneAccountHandle)) {
142       removeAllTranscriptionPreferences();
143       return;
144     } else {
145       showTranscriptionEnabledPreference();
146       updateTranscriptionDonationPreference();
147     }
148   }
149 
showTranscriptionEnabledPreference()150   private void showTranscriptionEnabledPreference() {
151     transcribeVoicemailPreference.setOnPreferenceChangeListener(this);
152     transcribeVoicemailPreference.setChecked(
153         voicemailClient.isVoicemailTranscriptionEnabled(getContext(), phoneAccountHandle));
154     transcribeVoicemailPreference.setSummary(getVoicemailTranscriptionInformationalText());
155     transcribeVoicemailPreference.setEnabled(true);
156     getPreferenceScreen().addPreference(transcribeVoicemailPreference);
157   }
158 
159   /**
160    * Builds a spannable string containing the voicemail transcription informational text containing
161    * the appropriate "Learn More" urls.
162    *
163    * @return The voicemail transcription information text.
164    */
getVoicemailTranscriptionInformationalText()165   private CharSequence getVoicemailTranscriptionInformationalText() {
166     return new ContentWithLearnMoreSpanner(getContext())
167         .create(
168             getContext().getString(R.string.voicemail_transcription_preference_summary_info),
169             getContext().getString(R.string.transcription_learn_more_url));
170   }
171 
updateTranscriptionDonationPreference()172   private void updateTranscriptionDonationPreference() {
173     if (!VoicemailComponent.get(getContext())
174         .getVoicemailClient()
175         .isVoicemailDonationAvailable(getContext(), phoneAccountHandle)) {
176       getPreferenceScreen().removePreference(donateTranscribedVoicemailPreference);
177     } else {
178       showTranscriptionDonationEnabledPreferences();
179     }
180   }
181 
showTranscriptionDonationEnabledPreferences()182   private void showTranscriptionDonationEnabledPreferences() {
183     donateTranscribedVoicemailPreference.setEnabled(true);
184     donateTranscribedVoicemailPreference.setChecked(
185         voicemailClient.isVoicemailDonationEnabled(getContext(), phoneAccountHandle));
186     donateTranscribedVoicemailPreference.setOnPreferenceChangeListener(this);
187     donateTranscribedVoicemailPreference.setSummary(
188         getVoicemailTranscriptionDonationInformationalText());
189     getPreferenceScreen().addPreference(donateTranscribedVoicemailPreference);
190   }
191 
192   /**
193    * Builds a spannable string containing the voicemail donation informational text containing the
194    * appropriate "Learn More" urls.
195    *
196    * @return The voicemail donation information text.
197    */
getVoicemailTranscriptionDonationInformationalText()198   private CharSequence getVoicemailTranscriptionDonationInformationalText() {
199     return new ContentWithLearnMoreSpanner(getContext())
200         .create(
201             getContext().getString(R.string.voicemail_donate_preference_summary_info),
202             getContext().getString(R.string.donation_learn_more_url));
203   }
204 
removeAllTranscriptionPreferences()205   private void removeAllTranscriptionPreferences() {
206     getPreferenceScreen().removePreference(transcribeVoicemailPreference);
207     getPreferenceScreen().removePreference(donateTranscribedVoicemailPreference);
208   }
209 
setupAutoArchivePreference()210   private void setupAutoArchivePreference() {
211     if (!VoicemailComponent.get(getContext())
212         .getVoicemailClient()
213         .isVoicemailArchiveAvailable(getContext())) {
214       getPreferenceScreen().removePreference(voicemailAutoArchivePreference);
215     } else {
216       voicemailAutoArchivePreference.setOnPreferenceChangeListener(this);
217       voicemailAutoArchivePreference.setChecked(
218           voicemailClient.isVoicemailArchiveEnabled(getContext(), phoneAccountHandle));
219     }
220   }
221 
setupVisualVoicemailPreference()222   private void setupVisualVoicemailPreference() {
223     visualVoicemailPreference.setOnPreferenceChangeListener(this);
224     visualVoicemailPreference.setChecked(
225         voicemailClient.isVoicemailEnabled(getContext(), phoneAccountHandle));
226     updateVoicemailSummaryMessage();
227   }
228 
229   /** The preferences that are present in the voicemail_settings.xml file are initialized here. */
initializeXmlPreferences()230   private void initializeXmlPreferences() {
231     voicemailNotificationPreference =
232         findPreference(getString(R.string.voicemail_notifications_key));
233     voicemailNotificationPreference.setOrder(VMSettingOrdering.NOTIFICATIONS);
234 
235     changeGreetingPreference = findPreference(getString(R.string.voicemail_change_greeting_key));
236     changeGreetingPreference.setOrder(VMSettingOrdering.CHANGE_GREETING);
237 
238     advancedSettingsPreference =
239         (PreferenceScreen) findPreference(getString(R.string.voicemail_advanced_settings_key));
240     advancedSettingsPreference.setOrder(VMSettingOrdering.ADVANCED_SETTING);
241 
242     visualVoicemailPreference =
243         (SwitchPreference) findPreference(getString(R.string.voicemail_visual_voicemail_key));
244     visualVoicemailPreference.setOrder(VMSettingOrdering.VISUAL_VOICEMAIL);
245 
246     voicemailAutoArchivePreference =
247         (SwitchPreference)
248             findPreference(getString(R.string.voicemail_visual_voicemail_archive_key));
249     voicemailAutoArchivePreference.setOrder(VMSettingOrdering.VOICEMAIL_AUTO_ARCHIVE);
250 
251     transcribeVoicemailPreference =
252         (SwitchPreferenceWithClickableSummary)
253             findPreference(getString(R.string.voicemail_visual_voicemail_transcription_key));
254     transcribeVoicemailPreference.setOrder(VMSettingOrdering.VOICEMAIL_TRANSCRIPTION);
255 
256     donateTranscribedVoicemailPreference =
257         (SwitchPreferenceWithClickableSummary)
258             findPreference(getString(R.string.voicemail_visual_voicemail_donation_key));
259     donateTranscribedVoicemailPreference.setOrder(
260         VMSettingOrdering.VOICEMAIL_TRANSCRIPTION_DONATION);
261 
262     voicemailChangePinPreference = findPreference(getString(R.string.voicemail_change_pin_key));
263     voicemailChangePinPreference.setOrder(VMSettingOrdering.VOICEMAIL_CHANGE_PIN);
264   }
265 
266   /** Removes vvm settings since the carrier setup is not supported by Dialer */
removeAllVisualVoicemailPreferences()267   private void removeAllVisualVoicemailPreferences() {
268     PreferenceScreen prefSet = getPreferenceScreen();
269     prefSet.removePreference(visualVoicemailPreference);
270     prefSet.removePreference(voicemailAutoArchivePreference);
271     prefSet.removePreference(transcribeVoicemailPreference);
272     prefSet.removePreference(donateTranscribedVoicemailPreference);
273     prefSet.removePreference(voicemailChangePinPreference);
274   }
275 
setupVoicemailChangePinPreference()276   private void setupVoicemailChangePinPreference() {
277     Intent changePinIntent = new Intent(new Intent(getContext(), VoicemailChangePinActivity.class));
278     changePinIntent.putExtra(VoicemailClient.PARAM_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
279 
280     voicemailChangePinPreference.setIntent(changePinIntent);
281     voicemailChangePinPreference.setOnPreferenceClickListener(
282         new OnPreferenceClickListener() {
283           @Override
284           public boolean onPreferenceClick(Preference preference) {
285             Logger.get(getContext()).logImpression(DialerImpression.Type.VVM_CHANGE_PIN_CLICKED);
286             // Let the preference handle the click.
287             return false;
288           }
289         });
290     if (VoicemailChangePinActivity.isPinScrambled(getContext(), phoneAccountHandle)) {
291       voicemailChangePinPreference.setTitle(R.string.voicemail_set_pin_preference_title);
292     } else {
293       voicemailChangePinPreference.setTitle(R.string.voicemail_change_pin_preference_title);
294     }
295     updateChangePinPreference();
296   }
297 
setupNotificationsPreference()298   private void setupNotificationsPreference() {
299     voicemailNotificationPreference.setIntent(getNotificationSettingsIntent());
300 
301     voicemailNotificationPreference.setOnPreferenceClickListener(
302         new OnPreferenceClickListener() {
303           @Override
304           public boolean onPreferenceClick(Preference preference) {
305             Logger.get(getContext())
306                 .logImpression(DialerImpression.Type.VVM_NOTIFICATIONS_SETTING_CLICKED);
307             // Let the preference handle the click.
308             return false;
309           }
310         });
311   }
312 
setupChangeGreetingPreference()313   private void setupChangeGreetingPreference() {
314     if (!ConfigProviderComponent.get(getContext())
315         .getConfigProvider()
316         .getBoolean("voicemail_change_greeting_enabled", false)) {
317       getPreferenceScreen().removePreference(changeGreetingPreference);
318       return;
319     }
320 
321     Intent changeGreetingIntent = new Intent(getContext(), CurrentVoicemailGreetingActivity.class);
322     changeGreetingPreference.setIntent(changeGreetingIntent);
323   }
324 
setupAdvancedSettingsPreference()325   private void setupAdvancedSettingsPreference() {
326     Intent advancedSettingsIntent = new Intent(TelephonyManager.ACTION_CONFIGURE_VOICEMAIL);
327     advancedSettingsIntent.putExtra(TelephonyManager.EXTRA_HIDE_PUBLIC_SETTINGS, true);
328     advancedSettingsIntent.putExtra(
329         TelephonyManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
330 
331     // (a bug): EXTRA_PHONE_ACCOUNT_HANDLE not implemented in telephony in O.
332     Optional<SubscriptionInfo> subscriptionInfo =
333         TelecomUtil.getSubscriptionInfo(getContext(), phoneAccountHandle);
334     if (subscriptionInfo.isPresent()) {
335       advancedSettingsIntent.putExtra(SUB_ID_EXTRA, subscriptionInfo.get().getSubscriptionId());
336       PhoneAccount phoneAccount =
337           getContext().getSystemService(TelecomManager.class).getPhoneAccount(phoneAccountHandle);
338       if (phoneAccount != null) {
339         advancedSettingsIntent.putExtra(SUB_LABEL_EXTRA, phoneAccount.getLabel());
340       }
341     }
342 
343     advancedSettingsPreference.setIntent(advancedSettingsIntent);
344 
345     advancedSettingsPreference.setOnPreferenceClickListener(
346         new OnPreferenceClickListener() {
347           @Override
348           public boolean onPreferenceClick(Preference preference) {
349             Logger.get(getContext())
350                 .logImpression(DialerImpression.Type.VVM_ADVANCED_SETINGS_CLICKED);
351             // Let the preference handle the click.
352             return false;
353           }
354         });
355   }
356 
357   @Override
onPause()358   public void onPause() {
359     voicemailClient.removeActivationStateListener(this);
360     super.onPause();
361   }
362 
363   /**
364    * Implemented to support onPreferenceChangeListener to look for preference changes.
365    *
366    * @param preference is the preference to be changed
367    * @param objValue should be the value of the selection, NOT its localized display value.
368    */
369   @Override
onPreferenceChange(Preference preference, Object objValue)370   public boolean onPreferenceChange(Preference preference, Object objValue) {
371     LogUtil.d(TAG, "onPreferenceChange: \"" + preference + "\" changed to \"" + objValue + "\"");
372     if (preference.getKey().equals(visualVoicemailPreference.getKey())) {
373       boolean isEnabled = (boolean) objValue;
374       if (!isEnabled) {
375         showDisableConfirmationDialog();
376         // Don't let the preference setting proceed.
377         return false;
378       } else {
379         updateVoicemailEnabled(true);
380       }
381     } else if (preference.getKey().equals(voicemailAutoArchivePreference.getKey())) {
382       logArchiveToggle((boolean) objValue);
383       voicemailClient.setVoicemailArchiveEnabled(
384           getContext(), phoneAccountHandle, (boolean) objValue);
385     } else if (preference.getKey().equals(transcribeVoicemailPreference.getKey())) {
386       logTranscribeToggle((boolean) objValue);
387       voicemailClient.setVoicemailTranscriptionEnabled(
388           getContext(), phoneAccountHandle, (boolean) objValue);
389       updateTranscriptionDonationPreference();
390     } else if (preference.getKey().equals(donateTranscribedVoicemailPreference.getKey())) {
391       logDonationToggle((boolean) objValue);
392       voicemailClient.setVoicemailDonationEnabled(
393           getContext(), phoneAccountHandle, (boolean) objValue);
394     }
395 
396     // Let the preference setting proceed.
397     return true;
398   }
399 
updateVoicemailEnabled(boolean isEnabled)400   private void updateVoicemailEnabled(boolean isEnabled) {
401     voicemailClient.setVoicemailEnabled(getContext(), phoneAccountHandle, isEnabled);
402     visualVoicemailPreference.setChecked(isEnabled);
403 
404     if (isEnabled) {
405       Logger.get(getContext()).logImpression(DialerImpression.Type.VVM_USER_ENABLED_IN_SETTINGS);
406     } else {
407       Logger.get(getContext()).logImpression(DialerImpression.Type.VVM_USER_DISABLED_IN_SETTINGS);
408     }
409     updateVoicemailSummaryMessage();
410     updateTranscriptionPreferences();
411     updateChangePinPreference();
412   }
413 
updateChangePinPreference()414   private void updateChangePinPreference() {
415     if (!voicemailClient.isVoicemailEnabled(getContext(), phoneAccountHandle)) {
416       voicemailChangePinPreference.setSummary(
417           R.string.voicemail_change_pin_preference_summary_disable);
418       voicemailChangePinPreference.setEnabled(false);
419     } else if (!voicemailClient.isActivated(getContext(), phoneAccountHandle)) {
420       voicemailChangePinPreference.setSummary(
421           R.string.voicemail_change_pin_preference_summary_not_activated);
422       voicemailChangePinPreference.setEnabled(false);
423     } else {
424       voicemailChangePinPreference.setSummary(null);
425       voicemailChangePinPreference.setEnabled(true);
426     }
427   }
428 
logArchiveToggle(boolean userTurnedOn)429   private void logArchiveToggle(boolean userTurnedOn) {
430     if (userTurnedOn) {
431       Logger.get(getContext())
432           .logImpression(DialerImpression.Type.VVM_USER_TURNED_ARCHIVE_ON_FROM_SETTINGS);
433     } else {
434       Logger.get(getContext())
435           .logImpression(DialerImpression.Type.VVM_USER_TURNED_ARCHIVE_OFF_FROM_SETTINGS);
436     }
437   }
438 
logTranscribeToggle(boolean userTurnedOn)439   private void logTranscribeToggle(boolean userTurnedOn) {
440     if (userTurnedOn) {
441       Logger.get(getContext())
442           .logImpression(DialerImpression.Type.VVM_USER_TURNED_TRANSCRIBE_ON_FROM_SETTINGS);
443     } else {
444       Logger.get(getContext())
445           .logImpression(DialerImpression.Type.VVM_USER_TURNED_TRANSCRIBE_OFF_FROM_SETTINGS);
446     }
447   }
448 
logDonationToggle(boolean userTurnedOn)449   private void logDonationToggle(boolean userTurnedOn) {
450     if (userTurnedOn) {
451       Logger.get(getContext())
452           .logImpression(DialerImpression.Type.VVM_USER_TURNED_TRANSCRIBE_ON_FROM_SETTINGS);
453     } else {
454       Logger.get(getContext())
455           .logImpression(DialerImpression.Type.VVM_USER_TURNED_TRANSCRIBE_OFF_FROM_SETTINGS);
456     }
457   }
458 
459   @Override
onActivationStateChanged(PhoneAccountHandle phoneAccountHandle, boolean isActivated)460   public void onActivationStateChanged(PhoneAccountHandle phoneAccountHandle, boolean isActivated) {
461     if (this.phoneAccountHandle.equals(phoneAccountHandle)) {
462       updateVoicemailSummaryMessage();
463       updateTranscriptionPreferences();
464       updateChangePinPreference();
465     }
466   }
467 
468   /**
469    * Shows the activating message while visual voicemail is being activated. This is useful, since
470    * some toggles do not show up, until voicemail is activated e.g transcription and rating.
471    */
updateVoicemailSummaryMessage()472   private void updateVoicemailSummaryMessage() {
473     if (voicemailClient.isVoicemailEnabled(getContext(), phoneAccountHandle)
474         && !voicemailClient.isActivated(getContext(), phoneAccountHandle)) {
475       visualVoicemailPreference.setSummary(R.string.voicemail_activating_summary_info);
476     } else {
477       visualVoicemailPreference.setSummary("");
478     }
479   }
480 
getNotificationSettingsIntent()481   private Intent getNotificationSettingsIntent() {
482     String channelId =
483         NotificationChannelManager.getVoicemailChannelId(getContext(), phoneAccountHandle);
484     return new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
485         .putExtra(Settings.EXTRA_CHANNEL_ID, channelId)
486         .putExtra(Settings.EXTRA_APP_PACKAGE, getContext().getPackageName());
487   }
488 
showDisableConfirmationDialog()489   private void showDisableConfirmationDialog() {
490     LogUtil.i(TAG, "showDisableConfirmationDialog");
491     AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
492     builder.setTitle(R.string.confirm_disable_voicemail_dialog_title);
493     builder.setMessage(R.string.confirm_disable_voicemail_dialog_message);
494     builder.setPositiveButton(
495         R.string.confirm_disable_voicemail_accept_dialog_label,
496         new DialogInterface.OnClickListener() {
497           @Override
498           public void onClick(DialogInterface dialog, int which) {
499             LogUtil.i(TAG, "showDisableConfirmationDialog, confirmed");
500             updateVoicemailEnabled(false);
501             dialog.dismiss();
502           }
503         });
504 
505     builder.setNegativeButton(
506         android.R.string.cancel,
507         new DialogInterface.OnClickListener() {
508           @Override
509           public void onClick(DialogInterface dialog, int which) {
510             LogUtil.i(TAG, "showDisableConfirmationDialog, cancelled");
511             dialog.dismiss();
512           }
513         });
514 
515     builder.setCancelable(true);
516     builder.show();
517   }
518 
519   /** The ordering in which to show the voicemail settings */
520   @Retention(RetentionPolicy.SOURCE)
521   @IntDef({
522     VMSettingOrdering.NOTIFICATIONS,
523     VMSettingOrdering.VISUAL_VOICEMAIL,
524     VMSettingOrdering.VOICEMAIL_TRANSCRIPTION,
525     VMSettingOrdering.VOICEMAIL_TRANSCRIPTION_DONATION,
526     VMSettingOrdering.VOICEMAIL_CHANGE_PIN,
527     VMSettingOrdering.VOICEMAIL_AUTO_ARCHIVE,
528     VMSettingOrdering.ADVANCED_SETTING,
529     VMSettingOrdering.CHANGE_GREETING
530   })
531   private @interface VMSettingOrdering {
532     int NOTIFICATIONS = 1;
533     int VISUAL_VOICEMAIL = 2;
534     int VOICEMAIL_TRANSCRIPTION = 3;
535     int VOICEMAIL_TRANSCRIPTION_DONATION = 4;
536     int VOICEMAIL_CHANGE_PIN = 5;
537     int VOICEMAIL_AUTO_ARCHIVE = 6;
538     int ADVANCED_SETTING = 7;
539     int CHANGE_GREETING = 8;
540   }
541 }
542