Port VM settings to its own activity.
I gave up on PreferenceFragments because it's too hard to migrate
the Activity Dialog logic at this point. Moving voicemail settings
code to its own activity, with an eye towards avoiding any breakages
in the attends related to it.
I tried to rearrange some methods for better organization while I
was at it... all this logic is still in much need of clarity, but
I figure this is no worse of a state than before, and at least now
it's separated from the rest of the call settings.
No (deliberate) changes to logic besides that.
Bug: 17019623
Change-Id: I20aa177ca699ad2c823e49f0fed0dcd89f75596d
diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java
index 3bb3080..b88d8f1 100644
--- a/src/com/android/phone/CallFeaturesSetting.java
+++ b/src/com/android/phone/CallFeaturesSetting.java
@@ -25,18 +25,13 @@
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
-import android.database.Cursor;
-import android.os.AsyncResult;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
import android.os.UserHandle;
import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceScreen;
-import android.provider.ContactsContract.CommonDataKinds;
import android.provider.Settings;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
@@ -44,7 +39,6 @@
import android.text.TextUtils;
import android.util.Log;
import android.view.MenuItem;
-import android.widget.ListAdapter;
import android.widget.Toast;
import com.android.ims.ImsConfig;
@@ -54,26 +48,13 @@
import com.android.internal.telephony.PhoneConstants;
import com.android.phone.common.util.SettingsUtil;
import com.android.phone.settings.AccountSelectionPreference;
-import com.android.phone.settings.CallForwardInfoUtil;
-import com.android.phone.settings.SettingsConstants;
-import com.android.phone.settings.VoicemailDialogUtil;
-import com.android.phone.settings.VoicemailNotificationSettingsUtil;
-import com.android.phone.settings.VoicemailProviderListPreference;
-import com.android.phone.settings.VoicemailProviderListPreference.VoicemailProvider;
-import com.android.phone.settings.VoicemailProviderSettings;
-import com.android.phone.settings.VoicemailProviderSettingsUtil;
-import com.android.phone.settings.VoicemailRingtonePreference;
+import com.android.phone.settings.VoicemailSettingsActivity;
import com.android.phone.settings.fdn.FdnSetting;
import com.android.services.telephony.sip.SipUtil;
import java.lang.String;
import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
-import java.util.Map;
/**
* Top level "Call settings" UI; see res/xml/call_feature_setting.xml
@@ -90,57 +71,15 @@
* For the "Mobile network settings" screen under the main Settings app,
* See {@link MobileNetworkSettings}.
*
- * TODO: Settings should be split into PreferenceFragments where possible (ie. voicemail).
- *
* @see com.android.phone.MobileNetworkSettings
*/
public class CallFeaturesSetting extends PreferenceActivity
- implements DialogInterface.OnClickListener,
- Preference.OnPreferenceChangeListener,
- EditPhoneNumberPreference.OnDialogClosedListener,
- EditPhoneNumberPreference.GetDefaultNumberListener {
+ implements Preference.OnPreferenceChangeListener {
private static final String LOG_TAG = "CallFeaturesSetting";
private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
// STOPSHIP if true. Flag to override behavior default behavior to hide VT setting.
private static final boolean ENABLE_VT_FLAG = false;
- /**
- * Intent action to bring up Voicemail Provider settings.
- *
- * @see #IGNORE_PROVIDER_EXTRA
- */
- public static final String ACTION_ADD_VOICEMAIL =
- "com.android.phone.CallFeaturesSetting.ADD_VOICEMAIL";
- // intent action sent by this activity to a voice mail provider
- // to trigger its configuration UI
- public static final String ACTION_CONFIGURE_VOICEMAIL =
- "com.android.phone.CallFeaturesSetting.CONFIGURE_VOICEMAIL";
- // Extra put in the return from VM provider config containing voicemail number to set
- public static final String VM_NUMBER_EXTRA = "com.android.phone.VoicemailNumber";
- // Extra put in the return from VM provider config containing call forwarding number to set
- public static final String FWD_NUMBER_EXTRA = "com.android.phone.ForwardingNumber";
- // Extra put in the return from VM provider config containing call forwarding number to set
- public static final String FWD_NUMBER_TIME_EXTRA = "com.android.phone.ForwardingNumberTime";
- // If the VM provider returns non null value in this extra we will force the user to
- // choose another VM provider
- public static final String SIGNOUT_EXTRA = "com.android.phone.Signout";
-
- /**
- * String Extra put into ACTION_ADD_VOICEMAIL call to indicate which provider should be hidden
- * in the list of providers presented to the user. This allows a provider which is being
- * disabled (e.g. GV user logging out) to force the user to pick some other provider.
- */
- public static final String IGNORE_PROVIDER_EXTRA = "com.android.phone.ProviderToIgnore";
-
- /**
- * String Extra put into ACTION_ADD_VOICEMAIL to indicate that the voicemail setup screen should
- * be opened.
- */
- public static final String SETUP_VOICEMAIL_EXTRA = "com.android.phone.SetupVoicemail";
-
- // string constants
- private static final String NUM_PROJECTION[] = {CommonDataKinds.Phone.NUMBER};
-
// 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
@@ -148,13 +87,8 @@
// 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";
private static final String BUTTON_FDN_KEY = "button_fdn_key";
-
private static final String BUTTON_RETRY_KEY = "button_auto_retry_key";
-
private static final String BUTTON_GSM_UMTS_OPTIONS = "button_gsm_more_expand_key";
private static final String BUTTON_CDMA_OPTIONS = "button_cdma_more_expand_key";
private static final String CALL_FORWARDING_KEY = "call_forwarding_key";
@@ -165,119 +99,13 @@
private static final String ENABLE_VIDEO_CALLING_KEY = "button_enable_video_calling";
- /** Event for Async voicemail change call */
- private static final int EVENT_VOICEMAIL_CHANGED = 500;
- private static final int EVENT_FORWARDING_CHANGED = 501;
- private static final int EVENT_FORWARDING_GET_COMPLETED = 502;
-
- /** Handle to voicemail pref */
- private static final int VOICEMAIL_PREF_ID = 1;
- private static final int VOICEMAIL_PROVIDER_CFG_ID = 2;
-
private Phone mPhone;
-
private SubscriptionInfoHelper mSubscriptionInfoHelper;
- private EditPhoneNumberPreference mSubMenuVoicemailSettings;
-
private CheckBoxPreference mButtonAutoRetry;
- private VoicemailProviderListPreference mVoicemailProviders;
private PreferenceScreen mVoicemailSettingsScreen;
- private PreferenceScreen mVoicemailSettings;
- private VoicemailRingtonePreference mVoicemailNotificationRingtone;
- private CheckBoxPreference mVoicemailNotificationVibrate;
private CheckBoxPreference mEnableVideoCalling;
- /**
- * Results of reading forwarding settings
- */
- private CallForwardInfo[] mForwardingReadResults = null;
-
- /**
- * Result of forwarding number change.
- * Keys are reasons (eg. unconditional forwarding).
- */
- private Map<Integer, AsyncResult> mForwardingChangeResults = null;
-
- /**
- * Expected CF read result types.
- * This set keeps track of the CF types for which we've issued change
- * commands so we can tell when we've received all of the responses.
- */
- private Collection<Integer> mExpectedChangeResultReasons = null;
-
- /**
- * Result of vm number change
- */
- private AsyncResult mVoicemailChangeResult = null;
-
- /**
- * Previous VM provider setting so we can return to it in case of failure.
- */
- private String mPreviousVMProviderKey = null;
-
- /**
- * Id of the dialog being currently shown.
- */
- private int mCurrentDialogId = 0;
-
- /**
- * Flag indicating that we are invoking settings for the voicemail provider programmatically
- * due to vm provider change.
- */
- private boolean mVMProviderSettingsForced = false;
-
- /**
- * Flag indicating that we are making changes to vm or fwd numbers
- * due to vm provider change.
- */
- private boolean mChangingVMorFwdDueToProviderChange = false;
-
- /**
- * True if we are in the process of vm & fwd number change and vm has already been changed.
- * This is used to decide what to do in case of rollback.
- */
- private boolean mVMChangeCompletedSuccessfully = false;
-
- /**
- * True if we had full or partial failure setting forwarding numbers and so need to roll them
- * back.
- */
- private boolean mFwdChangesRequireRollback = false;
-
- /**
- * Id of error msg to display to user once we are done reverting the VM provider to the previous
- * one.
- */
- private int mVMOrFwdSetError = 0;
-
- /** string to hold old voicemail number as it is being updated. */
- private String mOldVmNumber;
-
- // New call forwarding settings and vm number we will be setting
- // Need to save these since before we get to saving we need to asynchronously
- // query the existing forwarding settings.
- private CallForwardInfo[] mNewFwdSettings;
- private String mNewVMNumber;
-
- private boolean mForeground;
-
- @Override
- public void onPause() {
- super.onPause();
- mForeground = false;
- }
-
- /**
- * Used to indicate that the voicemail preference should be shown.
- */
- private boolean mShowVoicemailPreference = false;
-
- /**
- * Used to indicate that the voicemail setup screen should be shown.
- */
- private boolean mSetupVoicemail = false;
-
/*
* Click Listeners, handle click based on objects attached to UI.
*/
@@ -285,44 +113,11 @@
// Click listener for all toggle events
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
- if (preference == mSubMenuVoicemailSettings) {
- return true;
- } else if (preference == mButtonAutoRetry) {
+ if (preference == mButtonAutoRetry) {
android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
android.provider.Settings.Global.CALL_AUTO_RETRY,
mButtonAutoRetry.isChecked() ? 1 : 0);
return true;
- } else if (preference.getKey().equals(mVoicemailSettings.getKey())) {
- // Check key instead of comparing reference because closing the voicemail notification
- // ringtone dialog invokes onResume(), but leaves the old preference screen up,
- // TODO: Revert to checking reference after migrating voicemail to its own activity.
- if (DBG) log("onPreferenceTreeClick: Voicemail Settings Preference is clicked.");
-
- final Dialog dialog = ((PreferenceScreen) preference).getDialog();
- if (dialog != null) {
- dialog.getActionBar().setDisplayHomeAsUpEnabled(false);
- }
-
- if (preference.getIntent() != null) {
- if (DBG) log("Invoking cfg intent " + preference.getIntent().getPackage());
-
- // onActivityResult() will be responsible for resetting some of variables.
- this.startActivityForResult(preference.getIntent(), VOICEMAIL_PROVIDER_CFG_ID);
- return true;
- } else {
- if (DBG) log("onPreferenceTreeClick(). No intent; use default behavior in xml.");
-
- // onActivityResult() will not be called, so reset variables here.
- mPreviousVMProviderKey = VoicemailProviderListPreference.DEFAULT_KEY;
- mVMProviderSettingsForced = false;
- return false;
- }
- } else if (preference == mVoicemailSettingsScreen) {
- final Dialog dialog = mVoicemailSettingsScreen.getDialog();
- if (dialog != null) {
- dialog.getActionBar().setDisplayHomeAsUpEnabled(false);
- }
- return false;
}
return false;
}
@@ -339,40 +134,7 @@
public boolean onPreferenceChange(Preference preference, Object objValue) {
if (DBG) log("onPreferenceChange: \"" + preference + "\" changed to \"" + objValue + "\"");
- if (preference == mVoicemailProviders) {
- final String newProviderKey = (String) objValue;
-
- // If previous provider key and the new one is same, we don't need to handle it.
- if (mPreviousVMProviderKey.equals(newProviderKey)) {
- if (DBG) log("No change is made to the VM provider setting.");
- return true;
- }
- updateVMPreferenceWidgets(newProviderKey);
-
- final VoicemailProviderSettings newProviderSettings =
- VoicemailProviderSettingsUtil.load(this, newProviderKey);
-
- // If the user switches to a voice mail provider and we have numbers stored for it we
- // will automatically change the phone's voice mail and forwarding number to the stored
- // ones. Otherwise we will bring up provider's configuration UI.
- if (newProviderSettings == null) {
- // Force the user into a configuration of the chosen provider
- Log.w(LOG_TAG, "Saved preferences not found - invoking config");
- mVMProviderSettingsForced = true;
- simulatePreferenceClick(mVoicemailSettings);
- } else {
- if (DBG) log("Saved preferences found - switching to them");
- // Set this flag so if we get a failure we revert to previous provider
- mChangingVMorFwdDueToProviderChange = true;
- saveVoiceMailAndForwardingNumber(newProviderKey, newProviderSettings);
- }
- } else if (preference.getKey().equals(mVoicemailNotificationVibrate.getKey())) {
- // Check key instead of comparing reference because closing the voicemail notification
- // ringtone dialog invokes onResume(), but leaves the old preference screen up,
- // TODO: Revert to checking reference after migrating voicemail to its own activity.
- VoicemailNotificationSettingsUtil.setVibrationEnabled(
- mPhone, Boolean.TRUE.equals(objValue));
- } else if (preference == mEnableVideoCalling) {
+ if (preference == mEnableVideoCalling) {
if (ImsManager.isEnhanced4gLteModeSettingEnabledByUser(mPhone.getContext())) {
PhoneGlobals.getInstance().phoneMgr.enableVideoCalling((boolean) objValue);
} else {
@@ -401,667 +163,6 @@
}
@Override
- public void onDialogClosed(EditPhoneNumberPreference preference, int buttonClicked) {
- if (DBG) log("onDialogClosed: Button clicked is " + buttonClicked);
-
- if (buttonClicked == DialogInterface.BUTTON_NEGATIVE) {
- return;
- }
-
- if (preference == mSubMenuVoicemailSettings) {
- VoicemailProviderSettings newSettings = new VoicemailProviderSettings(
- mSubMenuVoicemailSettings.getPhoneNumber(),
- VoicemailProviderSettings.NO_FORWARDING);
- saveVoiceMailAndForwardingNumber(mVoicemailProviders.getKey(), newSettings);
- }
- }
-
- /**
- * Implemented for EditPhoneNumberPreference.GetDefaultNumberListener.
- * This method set the default values for the various
- * EditPhoneNumberPreference dialogs.
- */
- @Override
- public String onGetDefaultNumber(EditPhoneNumberPreference preference) {
- if (preference == mSubMenuVoicemailSettings) {
- // update the voicemail number field, which takes care of the
- // mSubMenuVoicemailSettings itself, so we should return null.
- if (DBG) log("updating default for voicemail dialog");
- updateVoiceNumberField();
- return null;
- }
-
- String vmDisplay = mPhone.getVoiceMailNumber();
- if (TextUtils.isEmpty(vmDisplay)) {
- // if there is no voicemail number, we just return null to
- // indicate no contribution.
- return null;
- }
-
- // Return the voicemail number prepended with "VM: "
- if (DBG) log("updating default for call forwarding dialogs");
- return getString(R.string.voicemail_abbreviated) + " " + vmDisplay;
- }
-
- private void switchToPreviousVoicemailProvider() {
- if (DBG) log("switchToPreviousVoicemailProvider " + mPreviousVMProviderKey);
-
- if (mPreviousVMProviderKey == null) {
- return;
- }
-
- if (mVMChangeCompletedSuccessfully || mFwdChangesRequireRollback) {
- showDialogIfForeground(VoicemailDialogUtil.VM_REVERTING_DIALOG);
- final VoicemailProviderSettings prevSettings =
- VoicemailProviderSettingsUtil.load(this, mPreviousVMProviderKey);
- if (prevSettings == null) {
- Log.e(LOG_TAG, "VoicemailProviderSettings for the key \""
- + mPreviousVMProviderKey + "\" is null but should be loaded.");
- }
-
- if (mVMChangeCompletedSuccessfully) {
- mNewVMNumber = prevSettings.getVoicemailNumber();
- Log.i(LOG_TAG, "VM change is already completed successfully."
- + "Have to revert VM back to " + mNewVMNumber + " again.");
- mPhone.setVoiceMailNumber(
- mPhone.getVoiceMailAlphaTag().toString(),
- mNewVMNumber,
- Message.obtain(mRevertOptionComplete, EVENT_VOICEMAIL_CHANGED));
- }
-
- if (mFwdChangesRequireRollback) {
- Log.i(LOG_TAG, "Requested to rollback forwarding changes.");
-
- final CallForwardInfo[] prevFwdSettings = prevSettings.getForwardingSettings();
- if (prevFwdSettings != null) {
- Map<Integer, AsyncResult> results = mForwardingChangeResults;
- resetForwardingChangeState();
- for (int i = 0; i < prevFwdSettings.length; i++) {
- CallForwardInfo fi = prevFwdSettings[i];
- if (DBG) log("Reverting fwd #: " + i + ": " + fi.toString());
- // Only revert the settings for which the update succeeded.
- AsyncResult result = results.get(fi.reason);
- if (result != null && result.exception == null) {
- mExpectedChangeResultReasons.add(fi.reason);
- CallForwardInfoUtil.setCallForwardingOption(mPhone, fi,
- mRevertOptionComplete.obtainMessage(
- EVENT_FORWARDING_CHANGED, i, 0));
- }
- }
- }
- }
- } else {
- if (DBG) log("No need to revert");
- onRevertDone();
- }
- }
-
- private void onRevertDone() {
- if (DBG) log("onRevertDone: Changing provider key back to " + mPreviousVMProviderKey);
-
- updateVMPreferenceWidgets(mPreviousVMProviderKey);
- updateVoiceNumberField();
- if (mVMOrFwdSetError != 0) {
- showDialogIfForeground(mVMOrFwdSetError);
- mVMOrFwdSetError = 0;
- }
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (DBG) {
- log("onActivityResult: requestCode: " + requestCode
- + ", resultCode: " + resultCode
- + ", data: " + data);
- }
-
- // there are cases where the contact picker may end up sending us more than one
- // request. We want to ignore the request if we're not in the correct state.
- if (requestCode == VOICEMAIL_PROVIDER_CFG_ID) {
- boolean failure = false;
-
- // No matter how the processing of result goes lets clear the flag
- if (DBG) log("mVMProviderSettingsForced: " + mVMProviderSettingsForced);
- final boolean isVMProviderSettingsForced = mVMProviderSettingsForced;
- mVMProviderSettingsForced = false;
-
- String vmNum = null;
- if (resultCode != RESULT_OK) {
- if (DBG) log("onActivityResult: vm provider cfg result not OK.");
- failure = true;
- } else {
- if (data == null) {
- if (DBG) log("onActivityResult: vm provider cfg result has no data");
- failure = true;
- } else {
- if (data.getBooleanExtra(SIGNOUT_EXTRA, false)) {
- if (DBG) log("Provider requested signout");
- if (isVMProviderSettingsForced) {
- if (DBG) log("Going back to previous provider on signout");
- switchToPreviousVoicemailProvider();
- } else {
- final String victim = mVoicemailProviders.getKey();
- if (DBG) log("Relaunching activity and ignoring " + victim);
- Intent i = new Intent(ACTION_ADD_VOICEMAIL);
- i.putExtra(IGNORE_PROVIDER_EXTRA, victim);
- i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- this.startActivity(i);
- }
- return;
- }
- vmNum = data.getStringExtra(VM_NUMBER_EXTRA);
- if (vmNum == null || vmNum.length() == 0) {
- if (DBG) log("onActivityResult: vm provider cfg result has no vmnum");
- failure = true;
- }
- }
- }
- if (failure) {
- if (DBG) log("Failure in return from voicemail provider.");
- if (isVMProviderSettingsForced) {
- switchToPreviousVoicemailProvider();
- }
-
- return;
- }
- mChangingVMorFwdDueToProviderChange = isVMProviderSettingsForced;
- final String fwdNum = data.getStringExtra(FWD_NUMBER_EXTRA);
-
- // TODO: It would be nice to load the current network setting for this and
- // send it to the provider when it's config is invoked so it can use this as default
- final int fwdNumTime = data.getIntExtra(FWD_NUMBER_TIME_EXTRA, 20);
-
- if (DBG) log("onActivityResult: cfg result has forwarding number " + fwdNum);
- saveVoiceMailAndForwardingNumber(mVoicemailProviders.getKey(),
- new VoicemailProviderSettings(vmNum, fwdNum, fwdNumTime));
- return;
- }
-
- if (requestCode == VOICEMAIL_PREF_ID) {
- if (resultCode != RESULT_OK) {
- if (DBG) log("onActivityResult: contact picker result not OK.");
- return;
- }
-
- Cursor cursor = null;
- try {
- cursor = getContentResolver().query(data.getData(),
- NUM_PROJECTION, null, null, null);
- if ((cursor == null) || (!cursor.moveToFirst())) {
- if (DBG) log("onActivityResult: bad contact data, no results found.");
- return;
- }
- mSubMenuVoicemailSettings.onPickActivityResult(cursor.getString(0));
- return;
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- }
- }
-
- super.onActivityResult(requestCode, resultCode, data);
- }
-
- /**
- * Wrapper around showDialog() that will silently do nothing if we're
- * not in the foreground.
- *
- * This is useful here because most of the dialogs we display from
- * this class are triggered by asynchronous events (like
- * success/failure messages from the telephony layer) and it's
- * possible for those events to come in even after the user has gone
- * to a different screen.
- */
- // TODO: this is too brittle: it's still easy to accidentally add new
- // code here that calls showDialog() directly (which will result in a
- // WindowManager$BadTokenException if called after the activity has
- // been stopped.)
- //
- // It would be cleaner to do the "if (mForeground)" check in one
- // central place, maybe by using a single Handler for all asynchronous
- // events (and have *that* discard events if we're not in the
- // foreground.)
- //
- // Unfortunately it's not that simple, since we sometimes need to do
- // actual work to handle these events whether or not we're in the
- // foreground (see the Handler code in mSetOptionComplete for
- // example.)
- //
- // TODO: It's a bit worrisome that we don't do anything in error cases when we're not in the
- // foreground. Consider displaying a toast instead.
- private void showDialogIfForeground(int id) {
- if (mForeground) {
- showDialog(id);
- }
- }
-
- private void dismissDialogSafely(int id) {
- try {
- dismissDialog(id);
- } catch (IllegalArgumentException e) {
- // This is expected in the case where we were in the background
- // at the time we would normally have shown the dialog, so we didn't
- // show it.
- }
- }
-
- /**
- * TODO: Refactor to make it easier to understand what's done in the different stages.
- */
- private void saveVoiceMailAndForwardingNumber(
- String key, VoicemailProviderSettings newSettings) {
- if (DBG) log("saveVoiceMailAndForwardingNumber: " + newSettings.toString());
- mNewVMNumber = newSettings.getVoicemailNumber();
- mNewVMNumber = (mNewVMNumber == null) ? "" : mNewVMNumber;
- mNewFwdSettings = newSettings.getForwardingSettings();
-
- // Call forwarding is not suppported on CDMA.
- if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
- if (DBG) log("Ignoring forwarding setting since this is CDMA phone");
- mNewFwdSettings = VoicemailProviderSettings.NO_FORWARDING;
- }
-
- // Throw a warning if the voicemail is the same and we did not change forwarding.
- if (mNewVMNumber.equals(mOldVmNumber)
- && mNewFwdSettings == VoicemailProviderSettings.NO_FORWARDING) {
- showDialogIfForeground(VoicemailDialogUtil.VM_NOCHANGE_ERROR_DIALOG);
- return;
- }
-
- VoicemailProviderSettingsUtil.save(this, key, newSettings);
- mVMChangeCompletedSuccessfully = false;
- mFwdChangesRequireRollback = false;
- mVMOrFwdSetError = 0;
-
- if (mNewFwdSettings == VoicemailProviderSettings.NO_FORWARDING
- || key.equals(mPreviousVMProviderKey)) {
- if (DBG) log("Set voicemail number. No changes to forwarding number.");
- setVoicemailNumberWithCarrier();
- } else {
- if (DBG) log("Reading current forwarding settings.");
- int numSettingsReasons = VoicemailProviderSettings.FORWARDING_SETTINGS_REASONS.length;
- mForwardingReadResults = new CallForwardInfo[numSettingsReasons];
- for (int i = 0; i < mForwardingReadResults.length; i++) {
- mPhone.getCallForwardingOption(
- VoicemailProviderSettings.FORWARDING_SETTINGS_REASONS[i],
- mGetOptionComplete.obtainMessage(EVENT_FORWARDING_GET_COMPLETED, i, 0));
- }
- showDialogIfForeground(VoicemailDialogUtil.VM_FWD_READING_DIALOG);
- }
-
- PhoneGlobals.getInstance().refreshMwiIndicator(mSubscriptionInfoHelper.getSubId());
- }
-
- private final Handler mGetOptionComplete = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- AsyncResult result = (AsyncResult) msg.obj;
- switch (msg.what) {
- case EVENT_FORWARDING_GET_COMPLETED:
- handleForwardingSettingsReadResult(result, msg.arg1);
- break;
- }
- }
- };
-
- private void handleForwardingSettingsReadResult(AsyncResult ar, int idx) {
- if (DBG) Log.d(LOG_TAG, "handleForwardingSettingsReadResult: " + idx);
-
- Throwable error = null;
- if (ar.exception != null) {
- error = ar.exception;
- if (DBG) Log.d(LOG_TAG, "FwdRead: ar.exception=" + error.getMessage());
- }
- if (ar.userObj instanceof Throwable) {
- error = (Throwable) ar.userObj;
- if (DBG) Log.d(LOG_TAG, "FwdRead: userObj=" + error.getMessage());
- }
-
- // We may have already gotten an error and decided to ignore the other results.
- if (mForwardingReadResults == null) {
- if (DBG) Log.d(LOG_TAG, "Ignoring fwd reading result: " + idx);
- return;
- }
-
- // In case of error ignore other results, show an error dialog
- if (error != null) {
- if (DBG) Log.d(LOG_TAG, "Error discovered for fwd read : " + idx);
- mForwardingReadResults = null;
- dismissDialogSafely(VoicemailDialogUtil.VM_FWD_READING_DIALOG);
- showDialogIfForeground(VoicemailDialogUtil.FWD_GET_RESPONSE_ERROR_DIALOG);
- return;
- }
-
- // Get the forwarding info.
- mForwardingReadResults[idx] = CallForwardInfoUtil.getCallForwardInfo(
- (CallForwardInfo[]) ar.result,
- VoicemailProviderSettings.FORWARDING_SETTINGS_REASONS[idx]);
-
- // Check if we got all the results already
- boolean done = true;
- for (int i = 0; i < mForwardingReadResults.length; i++) {
- if (mForwardingReadResults[i] == null) {
- done = false;
- break;
- }
- }
-
- if (done) {
- if (DBG) Log.d(LOG_TAG, "Done receiving fwd info");
- dismissDialogSafely(VoicemailDialogUtil.VM_FWD_READING_DIALOG);
-
- if (mPreviousVMProviderKey.equals(VoicemailProviderListPreference.DEFAULT_KEY)) {
- VoicemailProviderSettingsUtil.save(mPhone.getContext(),
- VoicemailProviderListPreference.DEFAULT_KEY,
- new VoicemailProviderSettings(mOldVmNumber, mForwardingReadResults));
- }
- saveVoiceMailAndForwardingNumberStage2();
- }
- }
-
- private void resetForwardingChangeState() {
- mForwardingChangeResults = new HashMap<Integer, AsyncResult>();
- mExpectedChangeResultReasons = new HashSet<Integer>();
- }
-
- // Called after we are done saving the previous forwarding settings if we needed.
- private void saveVoiceMailAndForwardingNumberStage2() {
- mForwardingChangeResults = null;
- mVoicemailChangeResult = null;
-
- resetForwardingChangeState();
- for (int i = 0; i < mNewFwdSettings.length; i++) {
- CallForwardInfo fi = mNewFwdSettings[i];
- CallForwardInfo fiForReason =
- CallForwardInfoUtil.infoForReason(mForwardingReadResults, fi.reason);
- final boolean doUpdate = CallForwardInfoUtil.isUpdateRequired(fiForReason, fi);
-
- if (doUpdate) {
- if (DBG) log("Setting fwd #: " + i + ": " + fi.toString());
- mExpectedChangeResultReasons.add(i);
-
- CallForwardInfoUtil.setCallForwardingOption(mPhone, fi,
- mSetOptionComplete.obtainMessage(
- EVENT_FORWARDING_CHANGED, fi.reason, 0));
- }
- }
- showDialogIfForeground(VoicemailDialogUtil.VM_FWD_SAVING_DIALOG);
- }
-
- private void setVoicemailNumberWithCarrier() {
- if (DBG) log("save voicemail #: " + mNewVMNumber);
-
- mVoicemailChangeResult = null;
- mPhone.setVoiceMailNumber(
- mPhone.getVoiceMailAlphaTag().toString(),
- mNewVMNumber,
- Message.obtain(mSetOptionComplete, EVENT_VOICEMAIL_CHANGED));
- }
-
- /**
- * Callback to handle option update completions
- */
- private final Handler mSetOptionComplete = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- AsyncResult result = (AsyncResult) msg.obj;
- boolean done = false;
- switch (msg.what) {
- case EVENT_VOICEMAIL_CHANGED:
- mVoicemailChangeResult = result;
- mVMChangeCompletedSuccessfully = isVmChangeSuccess();
- done = true;
- break;
- case EVENT_FORWARDING_CHANGED:
- mForwardingChangeResults.put(msg.arg1, result);
- if (result.exception != null) {
- Log.w(LOG_TAG, "Error in setting fwd# " + msg.arg1 + ": " +
- result.exception.getMessage());
- }
- if (isForwardingCompleted()) {
- if (isFwdChangeSuccess()) {
- if (DBG) log("Overall fwd changes completed ok, starting vm change");
- setVoicemailNumberWithCarrier();
- } else {
- Log.w(LOG_TAG, "Overall fwd changes completed in failure. " +
- "Check if we need to try rollback for some settings.");
- mFwdChangesRequireRollback = false;
- Iterator<Map.Entry<Integer,AsyncResult>> it =
- mForwardingChangeResults.entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry<Integer,AsyncResult> entry = it.next();
- if (entry.getValue().exception == null) {
- // If at least one succeeded we have to revert
- Log.i(LOG_TAG, "Rollback will be required");
- mFwdChangesRequireRollback = true;
- break;
- }
- }
- if (!mFwdChangesRequireRollback) {
- Log.i(LOG_TAG, "No rollback needed.");
- }
- done = true;
- }
- }
- break;
- default:
- // TODO: should never reach this, may want to throw exception
- }
-
- if (done) {
- if (DBG) log("All VM provider related changes done");
- if (mForwardingChangeResults != null) {
- dismissDialogSafely(VoicemailDialogUtil.VM_FWD_SAVING_DIALOG);
- }
- handleSetVmOrFwdMessage();
- }
- }
- };
-
- /**
- * Callback to handle option revert completions
- */
- private final Handler mRevertOptionComplete = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- AsyncResult result = (AsyncResult) msg.obj;
- switch (msg.what) {
- case EVENT_VOICEMAIL_CHANGED:
- if (DBG) log("VM revert complete msg");
- mVoicemailChangeResult = result;
- break;
-
- case EVENT_FORWARDING_CHANGED:
- if (DBG) log("FWD revert complete msg ");
- mForwardingChangeResults.put(msg.arg1, result);
- if (result.exception != null) {
- if (DBG) log("Error in reverting fwd# " + msg.arg1 + ": " +
- result.exception.getMessage());
- }
- break;
-
- default:
- // TODO: should never reach this, may want to throw exception
- }
-
- final boolean done = (!mVMChangeCompletedSuccessfully || mVoicemailChangeResult != null)
- && (!mFwdChangesRequireRollback || isForwardingCompleted());
- if (done) {
- if (DBG) log("All VM reverts done");
- dismissDialogSafely(VoicemailDialogUtil.VM_REVERTING_DIALOG);
- onRevertDone();
- }
- }
- };
-
- /**
- * Return true if there is a change result for every reason for which we expect a result.
- */
- private boolean isForwardingCompleted() {
- if (mForwardingChangeResults == null) {
- return true;
- }
-
- for (Integer reason : mExpectedChangeResultReasons) {
- if (mForwardingChangeResults.get(reason) == null) {
- return false;
- }
- }
-
- return true;
- }
-
- private boolean isFwdChangeSuccess() {
- if (mForwardingChangeResults == null) {
- return true;
- }
-
- for (AsyncResult result : mForwardingChangeResults.values()) {
- Throwable exception = result.exception;
- if (exception != null) {
- String msg = exception.getMessage();
- msg = (msg != null) ? msg : "";
- Log.w(LOG_TAG, "Failed to change forwarding setting. Reason: " + msg);
- return false;
- }
- }
- return true;
- }
-
- private boolean isVmChangeSuccess() {
- if (mVoicemailChangeResult.exception != null) {
- String msg = mVoicemailChangeResult.exception.getMessage();
- msg = (msg != null) ? msg : "";
- Log.w(LOG_TAG, "Failed to change voicemail. Reason: " + msg);
- return false;
- }
- return true;
- }
-
- private void handleSetVmOrFwdMessage() {
- if (DBG) log("handleSetVMMessage: set VM request complete");
-
- if (!isFwdChangeSuccess()) {
- handleVmOrFwdSetError(VoicemailDialogUtil.FWD_SET_RESPONSE_ERROR_DIALOG);
- } else if (!isVmChangeSuccess()) {
- handleVmOrFwdSetError(VoicemailDialogUtil.VM_RESPONSE_ERROR_DIALOG);
- } else {
- handleVmAndFwdSetSuccess(VoicemailDialogUtil.VM_CONFIRM_DIALOG);
- }
- }
-
- /**
- * Called when Voicemail Provider or its forwarding settings failed. Rolls back partly made
- * changes to those settings and show "failure" dialog.
- *
- * @param dialogId ID of the dialog to show for the specific error case. Either
- * {@link #FWD_SET_RESPONSE_ERROR_DIALOG} or {@link #VM_RESPONSE_ERROR_DIALOG}
- */
- private void handleVmOrFwdSetError(int dialogId) {
- if (mChangingVMorFwdDueToProviderChange) {
- mVMOrFwdSetError = dialogId;
- mChangingVMorFwdDueToProviderChange = false;
- switchToPreviousVoicemailProvider();
- return;
- }
- mChangingVMorFwdDueToProviderChange = false;
- showDialogIfForeground(dialogId);
- updateVoiceNumberField();
- }
-
- /**
- * Called when Voicemail Provider and its forwarding settings were successfully finished.
- * This updates a bunch of variables and show "success" dialog.
- */
- private void handleVmAndFwdSetSuccess(int dialogId) {
- if (DBG) log("handleVmAndFwdSetSuccess: key is " + mVoicemailProviders.getKey());
-
- mPreviousVMProviderKey = mVoicemailProviders.getKey();
- mChangingVMorFwdDueToProviderChange = false;
- showDialogIfForeground(dialogId);
- updateVoiceNumberField();
- }
-
- /**
- * Update the voicemail number from what we've recorded on the sim.
- */
- private void updateVoiceNumberField() {
- if (DBG) log("updateVoiceNumberField()");
-
- mOldVmNumber = mPhone.getVoiceMailNumber();
- if (TextUtils.isEmpty(mOldVmNumber)) {
- mSubMenuVoicemailSettings.setPhoneNumber("");
- mSubMenuVoicemailSettings.setSummary(getString(R.string.voicemail_number_not_set));
- } else {
- mSubMenuVoicemailSettings.setPhoneNumber(mOldVmNumber);
- mSubMenuVoicemailSettings.setSummary(mOldVmNumber);
- }
- }
-
- /*
- * Helper Methods for Activity class.
- * The initial query commands are split into two pieces now
- * for individual expansion. This combined with the ability
- * to cancel queries allows for a much better user experience,
- * and also ensures that the user only waits to update the
- * data that is relevant.
- */
-
- @Override
- protected void onPrepareDialog(int id, Dialog dialog) {
- super.onPrepareDialog(id, dialog);
- mCurrentDialogId = id;
- }
-
- // dialog creation method, called by showDialog()
- @Override
- protected Dialog onCreateDialog(int dialogId) {
- return VoicemailDialogUtil.getDialog(this, dialogId);
- }
-
- // This is a method implemented for DialogInterface.OnClickListener.
- // Used with the error dialog to close the app, voicemail dialog to just dismiss.
- // Close button is mapped to BUTTON_POSITIVE for the errors that close the activity,
- // while those that are mapped to BUTTON_NEUTRAL only move the preference focus.
- public void onClick(DialogInterface dialog, int which) {
- if (DBG) log("onClick: button clicked is " + which);
-
- dialog.dismiss();
- switch (which){
- case DialogInterface.BUTTON_NEGATIVE:
- if (mCurrentDialogId == VoicemailDialogUtil.FWD_GET_RESPONSE_ERROR_DIALOG) {
- // We failed to get current forwarding settings and the user
- // does not wish to continue.
- switchToPreviousVoicemailProvider();
- }
- break;
- case DialogInterface.BUTTON_POSITIVE:
- if (mCurrentDialogId == VoicemailDialogUtil.FWD_GET_RESPONSE_ERROR_DIALOG) {
- // We failed to get current forwarding settings but the user
- // wishes to continue changing settings to the new vm provider
- setVoicemailNumberWithCarrier();
- } else {
- finish();
- }
- return;
- default:
- // just let the dialog close and go back to the input
- }
-
- // In all dialogs, all buttons except BUTTON_POSITIVE lead to the end of user interaction
- // with settings UI. If we were called to explicitly configure voice mail then
- // we finish the settings activity here to come back to whatever the user was doing.
- if (getIntent().getAction().equals(ACTION_ADD_VOICEMAIL)) {
- finish();
- }
- }
-
- /*
- * Activity class methods
- */
-
- @Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
if (DBG) log("onCreate: Intent is " + getIntent());
@@ -1074,13 +175,6 @@
return;
}
- // Show the voicemail preference in onResume if the calling intent specifies the
- // ACTION_ADD_VOICEMAIL action.
- mShowVoicemailPreference = (icicle == null) &&
- TextUtils.equals(getIntent().getAction(), ACTION_ADD_VOICEMAIL);
- mSetupVoicemail = mShowVoicemailPreference &&
- getIntent().getBooleanExtra(SETUP_VOICEMAIL_EXTRA, false);
-
mSubscriptionInfoHelper = new SubscriptionInfoHelper(this, getIntent());
mSubscriptionInfoHelper.setActionBarTitle(
getActionBar(), getResources(), R.string.call_settings_with_label);
@@ -1090,7 +184,6 @@
@Override
protected void onResume() {
super.onResume();
- mForeground = true;
PreferenceScreen preferenceScreen = getPreferenceScreen();
if (preferenceScreen != null) {
@@ -1110,32 +203,12 @@
}
PreferenceScreen prefSet = getPreferenceScreen();
- mSubMenuVoicemailSettings = (EditPhoneNumberPreference) findPreference(BUTTON_VOICEMAIL_KEY);
- mSubMenuVoicemailSettings.setParentActivity(this, VOICEMAIL_PREF_ID, this);
- mSubMenuVoicemailSettings.setDialogOnClosedListener(this);
- mSubMenuVoicemailSettings.setDialogTitle(R.string.voicemail_settings_number_label);
-
- mButtonAutoRetry = (CheckBoxPreference) findPreference(BUTTON_RETRY_KEY);
-
- mVoicemailProviders = (VoicemailProviderListPreference) findPreference(
- BUTTON_VOICEMAIL_PROVIDER_KEY);
- mVoicemailProviders.init(mPhone, getIntent());
- mVoicemailProviders.setOnPreferenceChangeListener(this);
- mPreviousVMProviderKey = mVoicemailProviders.getValue();
-
mVoicemailSettingsScreen =
(PreferenceScreen) findPreference(VOICEMAIL_SETTING_SCREEN_PREF_KEY);
- mVoicemailSettings = (PreferenceScreen) findPreference(BUTTON_VOICEMAIL_SETTING_KEY);
+ mVoicemailSettingsScreen.setIntent(mSubscriptionInfoHelper.getIntent(
+ VoicemailSettingsActivity.class));
- mVoicemailNotificationRingtone = (VoicemailRingtonePreference) findPreference(
- getResources().getString(R.string.voicemail_notification_ringtone_key));
- mVoicemailNotificationRingtone.init(mPhone);
-
- mVoicemailNotificationVibrate = (CheckBoxPreference) findPreference(
- getResources().getString(R.string.voicemail_notification_vibrate_key));
- mVoicemailNotificationVibrate.setOnPreferenceChangeListener(this);
-
- updateVMPreferenceWidgets(mVoicemailProviders.getValue());
+ mButtonAutoRetry = (CheckBoxPreference) findPreference(BUTTON_RETRY_KEY);
mEnableVideoCalling = (CheckBoxPreference) findPreference(ENABLE_VIDEO_CALLING_KEY);
@@ -1191,32 +264,6 @@
}
}
- // check the intent that started this activity and pop up the voicemail
- // dialog if we've been asked to.
- // If we have at least one non default VM provider registered then bring up
- // the selection for the VM provider, otherwise bring up a VM number dialog.
- // We only bring up the dialog the first time we are called (not after orientation change)
- if (mShowVoicemailPreference) {
- if (DBG) log("ACTION_ADD_VOICEMAIL Intent is thrown");
- if (mSetupVoicemail) {
- simulatePreferenceClick(mVoicemailSettingsScreen);
- mSetupVoicemail = false;
- } else if (mVoicemailProviders.hasMoreThanOneVoicemailProvider()) {
- if (DBG) log("Voicemail data has more than one provider.");
- simulatePreferenceClick(mVoicemailProviders);
- } else {
- onPreferenceChange(mVoicemailProviders, VoicemailProviderListPreference.DEFAULT_KEY);
- mVoicemailProviders.setValue(VoicemailProviderListPreference.DEFAULT_KEY);
- }
- mShowVoicemailPreference = false;
- }
-
- updateVoiceNumberField();
- mVMProviderSettingsForced = false;
-
- mVoicemailNotificationVibrate.setChecked(
- VoicemailNotificationSettingsUtil.isVibrationEnabled(mPhone));
-
if (ImsManager.isVtEnabledByPlatform(mPhone.getContext()) && ENABLE_VT_FLAG) {
boolean currentValue =
ImsManager.isEnhanced4gLteModeSettingEnabledByUser(mPhone.getContext())
@@ -1274,58 +321,6 @@
Log.d(LOG_TAG, msg);
}
- /**
- * Updates the look of the VM preference widgets based on current VM provider settings.
- * Note that the provider name is loaded fxrorm the found activity via loadLabel in
- * {@link VoicemailProviderListPreference#initVoiceMailProviders()} in order for it to be
- * localizable.
- */
- private void updateVMPreferenceWidgets(String currentProviderSetting) {
- final String key = currentProviderSetting;
- final VoicemailProvider provider = mVoicemailProviders.getVoicemailProvider(key);
-
- /* This is the case when we are coming up on a freshly wiped phone and there is no
- persisted value for the list preference mVoicemailProviders.
- In this case we want to show the UI asking the user to select a voicemail provider as
- opposed to silently falling back to default one. */
- if (provider == null) {
- if (DBG) log("updateVMPreferenceWidget: key: " + key + " -> null.");
-
- mVoicemailProviders.setSummary(getString(R.string.sum_voicemail_choose_provider));
- mVoicemailSettings.setEnabled(false);
- mVoicemailSettings.setIntent(null);
- mVoicemailNotificationVibrate.setEnabled(false);
- } else {
- if (DBG) log("updateVMPreferenceWidget: key: " + key + " -> " + provider.toString());
-
- final String providerName = provider.name;
- mVoicemailProviders.setSummary(providerName);
- mVoicemailSettings.setEnabled(true);
- mVoicemailSettings.setIntent(provider.intent);
- mVoicemailNotificationVibrate.setEnabled(true);
- }
- }
-
-
- /**
- * Simulates user clicking on a passed preference.
- * Usually needed when the preference is a dialog preference and we want to invoke
- * a dialog for this preference programmatically.
- * TODO: figure out if there is a cleaner way to cause preference dlg to come up
- */
- private void simulatePreferenceClick(Preference preference) {
- // Go through settings until we find our setting
- // and then simulate a click on it to bring up the dialog
- final ListAdapter adapter = getPreferenceScreen().getRootAdapter();
- for (int idx = 0; idx < adapter.getCount(); idx++) {
- if (adapter.getItem(idx) == preference) {
- getPreferenceScreen().onItemClick(this.getListView(),
- null, idx, adapter.getItemId(idx));
- break;
- }
- }
- }
-
@Override
public boolean onOptionsItemSelected(MenuItem item) {
final int itemId = item.getItemId();
diff --git a/src/com/android/phone/EditPhoneNumberPreference.java b/src/com/android/phone/EditPhoneNumberPreference.java
index 86671a8..8a672f1 100644
--- a/src/com/android/phone/EditPhoneNumberPreference.java
+++ b/src/com/android/phone/EditPhoneNumberPreference.java
@@ -94,7 +94,7 @@
* DialogPreference.onDialogClosed(), except we also pass in a buttonClicked
* value indicating which of the three possible buttons were pressed.
*/
- interface OnDialogClosedListener {
+ public interface OnDialogClosedListener {
void onDialogClosed(EditPhoneNumberPreference preference, int buttonClicked);
}
@@ -102,7 +102,7 @@
* Interface for the default number setting listener. Handles requests for
* the default display number for the dialog.
*/
- interface GetDefaultNumberListener {
+ public interface GetDefaultNumberListener {
/**
* Notify that we are looking for a default display value.
* @return null if there is no contribution from this interface,
diff --git a/src/com/android/phone/ErrorDialogActivity.java b/src/com/android/phone/ErrorDialogActivity.java
index 4635f86..bf09376 100644
--- a/src/com/android/phone/ErrorDialogActivity.java
+++ b/src/com/android/phone/ErrorDialogActivity.java
@@ -23,6 +23,8 @@
import android.os.Bundle;
import android.util.Log;
+import com.android.phone.settings.VoicemailSettingsActivity;
+
/**
* Used to display an error dialog from within the Telephony service when an outgoing call fails
*/
@@ -105,8 +107,8 @@
}
// navigate to the Voicemail setting in the Call Settings activity.
- Intent intent = new Intent(CallFeaturesSetting.ACTION_ADD_VOICEMAIL);
- intent.setClass(this, CallFeaturesSetting.class);
+ Intent intent = new Intent(VoicemailSettingsActivity.ACTION_ADD_VOICEMAIL);
+ intent.setClass(this, VoicemailSettingsActivity.class);
startActivity(intent);
finish();
}
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index d308a28..1460d63 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -49,6 +49,7 @@
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneBase;
import com.android.internal.telephony.TelephonyCapabilities;
+import com.android.phone.settings.VoicemailSettingsActivity;
import com.android.phone.settings.VoicemailNotificationSettingsUtil;
import com.android.phone.settings.VoicemailProviderSettingsUtil;
@@ -358,10 +359,9 @@
// to the voicemail settings.
notificationText = mContext.getString(
R.string.notification_voicemail_no_vm_number);
- intent = new Intent(CallFeaturesSetting.ACTION_ADD_VOICEMAIL);
- intent.putExtra(CallFeaturesSetting.SETUP_VOICEMAIL_EXTRA, true);
+ intent = new Intent(VoicemailSettingsActivity.ACTION_ADD_VOICEMAIL);
intent.putExtra(SubscriptionInfoHelper.SUB_ID_EXTRA, subId);
- intent.setClass(mContext, CallFeaturesSetting.class);
+ intent.setClass(mContext, VoicemailSettingsActivity.class);
} else {
if (mTelephonyManager.getPhoneCount() > 1) {
notificationText = subInfo.getDisplayName().toString();
diff --git a/src/com/android/phone/settings/VoicemailDialogUtil.java b/src/com/android/phone/settings/VoicemailDialogUtil.java
index 0a9e4bc..26bc227 100644
--- a/src/com/android/phone/settings/VoicemailDialogUtil.java
+++ b/src/com/android/phone/settings/VoicemailDialogUtil.java
@@ -21,7 +21,6 @@
import android.app.ProgressDialog;
import android.view.WindowManager;
-import com.android.phone.CallFeaturesSetting;
import com.android.phone.R;
public class VoicemailDialogUtil {
@@ -36,7 +35,7 @@
public static final int VM_FWD_READING_DIALOG = 602;
public static final int VM_REVERTING_DIALOG = 603;
- public static Dialog getDialog(CallFeaturesSetting parent, int id) {
+ public static Dialog getDialog(VoicemailSettingsActivity parent, int id) {
if ((id == VM_RESPONSE_ERROR_DIALOG) || (id == VM_NOCHANGE_ERROR_DIALOG) ||
(id == FWD_SET_RESPONSE_ERROR_DIALOG) || (id == FWD_GET_RESPONSE_ERROR_DIALOG) ||
(id == VM_CONFIRM_DIALOG)) {
diff --git a/src/com/android/phone/settings/VoicemailProviderListPreference.java b/src/com/android/phone/settings/VoicemailProviderListPreference.java
index 44a1c7c..d9f1a55 100644
--- a/src/com/android/phone/settings/VoicemailProviderListPreference.java
+++ b/src/com/android/phone/settings/VoicemailProviderListPreference.java
@@ -30,7 +30,6 @@
import android.util.Log;
import com.android.internal.telephony.Phone;
-import com.android.phone.CallFeaturesSetting;
import com.android.phone.PhoneGlobals;
import com.android.phone.R;
@@ -95,12 +94,14 @@
if (DBG) log("initVoicemailProviders()");
String providerToIgnore = null;
- if (activityIntent.getAction().equals(CallFeaturesSetting.ACTION_ADD_VOICEMAIL)
- && activityIntent.hasExtra(CallFeaturesSetting.IGNORE_PROVIDER_EXTRA)) {
+ String action = activityIntent.getAction();
+ if (!TextUtils.isEmpty(action)
+ && action.equals(VoicemailSettingsActivity.ACTION_ADD_VOICEMAIL)
+ && activityIntent.hasExtra(VoicemailSettingsActivity.IGNORE_PROVIDER_EXTRA)) {
// Remove this provider from the list.
if (DBG) log("Found ACTION_ADD_VOICEMAIL.");
providerToIgnore =
- activityIntent.getStringExtra(CallFeaturesSetting.IGNORE_PROVIDER_EXTRA);
+ activityIntent.getStringExtra(VoicemailSettingsActivity.IGNORE_PROVIDER_EXTRA);
VoicemailProviderSettingsUtil.delete(mPhone.getContext(), providerToIgnore);
}
@@ -119,7 +120,7 @@
// Add other voicemail providers.
PackageManager pm = mPhone.getContext().getPackageManager();
- Intent intent = new Intent(CallFeaturesSetting.ACTION_CONFIGURE_VOICEMAIL);
+ Intent intent = new Intent(VoicemailSettingsActivity.ACTION_CONFIGURE_VOICEMAIL);
List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
for (int i = 0; i < resolveInfos.size(); i++) {
final ResolveInfo ri= resolveInfos.get(i);
@@ -137,7 +138,7 @@
}
String nameForDisplay = (label != null) ? label.toString() : "";
Intent providerIntent = new Intent();
- providerIntent.setAction(CallFeaturesSetting.ACTION_CONFIGURE_VOICEMAIL);
+ providerIntent.setAction(VoicemailSettingsActivity.ACTION_CONFIGURE_VOICEMAIL);
providerIntent.setClassName(currentActivityInfo.packageName, currentActivityInfo.name);
VoicemailProvider vmProvider = new VoicemailProvider(nameForDisplay, providerIntent);
diff --git a/src/com/android/phone/settings/VoicemailSettingsActivity.java b/src/com/android/phone/settings/VoicemailSettingsActivity.java
index a94c27a..27349fe 100644
--- a/src/com/android/phone/settings/VoicemailSettingsActivity.java
+++ b/src/com/android/phone/settings/VoicemailSettingsActivity.java
@@ -16,21 +16,268 @@
package com.android.phone.settings;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.database.Cursor;
+import android.os.AsyncResult;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.preference.CheckBoxPreference;
+import android.preference.Preference;
import android.preference.PreferenceActivity;
+import android.preference.PreferenceScreen;
+import android.provider.ContactsContract.CommonDataKinds;
+import android.text.TextUtils;
+import android.util.Log;
import android.view.MenuItem;
+import android.widget.ListAdapter;
+import com.android.internal.telephony.CallForwardInfo;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
import com.android.phone.R;
+import com.android.phone.EditPhoneNumberPreference;
+import com.android.phone.PhoneGlobals;
+import com.android.phone.SubscriptionInfoHelper;
-public class VoicemailSettingsActivity extends PreferenceActivity {
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+
+public class VoicemailSettingsActivity extends PreferenceActivity
+ implements DialogInterface.OnClickListener,
+ Preference.OnPreferenceChangeListener,
+ EditPhoneNumberPreference.OnDialogClosedListener,
+ EditPhoneNumberPreference.GetDefaultNumberListener {
+ private static final String LOG_TAG = VoicemailSettingsActivity.class.getSimpleName();
+ private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
+
+ /**
+ * Intent action to bring up Voicemail Provider settings
+ * DO NOT RENAME. There are existing apps which use this intent value.
+ */
+ public static final String ACTION_ADD_VOICEMAIL =
+ "com.android.phone.CallFeaturesSetting.ADD_VOICEMAIL";
+
+ /**
+ * Intent action to bring up the {@code VoicemailSettingsActivity}.
+ * DO NOT RENAME. There are existing apps which use this intent value.
+ */
+ public static final String ACTION_CONFIGURE_VOICEMAIL =
+ "com.android.phone.CallFeaturesSetting.CONFIGURE_VOICEMAIL";
+
+ // Extra put in the return from VM provider config containing voicemail number to set
+ public static final String VM_NUMBER_EXTRA = "com.android.phone.VoicemailNumber";
+ // Extra put in the return from VM provider config containing call forwarding number to set
+ public static final String FWD_NUMBER_EXTRA = "com.android.phone.ForwardingNumber";
+ // Extra put in the return from VM provider config containing call forwarding number to set
+ public static final String FWD_NUMBER_TIME_EXTRA = "com.android.phone.ForwardingNumberTime";
+ // If the VM provider returns non null value in this extra we will force the user to
+ // choose another VM provider
+ public static final String SIGNOUT_EXTRA = "com.android.phone.Signout";
+
+ /**
+ * String Extra put into ACTION_ADD_VOICEMAIL call to indicate which provider should be hidden
+ * in the list of providers presented to the user. This allows a provider which is being
+ * disabled (e.g. GV user logging out) to force the user to pick some other provider.
+ */
+ public static final String IGNORE_PROVIDER_EXTRA = "com.android.phone.ProviderToIgnore";
+
+ /**
+ * String Extra put into ACTION_ADD_VOICEMAIL to indicate that the voicemail setup screen should
+ * be opened.
+ */
+ public static final String SETUP_VOICEMAIL_EXTRA = "com.android.phone.SetupVoicemail";
+
+ // TODO: Define these preference keys in XML.
+ 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";
+
+ /** Event for Async voicemail change call */
+ private static final int EVENT_VOICEMAIL_CHANGED = 500;
+ private static final int EVENT_FORWARDING_CHANGED = 501;
+ private static final int EVENT_FORWARDING_GET_COMPLETED = 502;
+
+ /** Handle to voicemail pref */
+ private static final int VOICEMAIL_PREF_ID = 1;
+ private static final int VOICEMAIL_PROVIDER_CFG_ID = 2;
+
+ /**
+ * Results of reading forwarding settings
+ */
+ private CallForwardInfo[] mForwardingReadResults = null;
+
+ /**
+ * Result of forwarding number change.
+ * Keys are reasons (eg. unconditional forwarding).
+ */
+ private Map<Integer, AsyncResult> mForwardingChangeResults = null;
+
+ /**
+ * Expected CF read result types.
+ * This set keeps track of the CF types for which we've issued change
+ * commands so we can tell when we've received all of the responses.
+ */
+ private Collection<Integer> mExpectedChangeResultReasons = null;
+
+ /**
+ * Result of vm number change
+ */
+ private AsyncResult mVoicemailChangeResult = null;
+
+ /**
+ * Previous VM provider setting so we can return to it in case of failure.
+ */
+ private String mPreviousVMProviderKey = null;
+
+ /**
+ * Id of the dialog being currently shown.
+ */
+ private int mCurrentDialogId = 0;
+
+ /**
+ * Flag indicating that we are invoking settings for the voicemail provider programmatically
+ * due to vm provider change.
+ */
+ private boolean mVMProviderSettingsForced = false;
+
+ /**
+ * Flag indicating that we are making changes to vm or fwd numbers
+ * due to vm provider change.
+ */
+ private boolean mChangingVMorFwdDueToProviderChange = false;
+
+ /**
+ * True if we are in the process of vm & fwd number change and vm has already been changed.
+ * This is used to decide what to do in case of rollback.
+ */
+ private boolean mVMChangeCompletedSuccessfully = false;
+
+ /**
+ * True if we had full or partial failure setting forwarding numbers and so need to roll them
+ * back.
+ */
+ private boolean mFwdChangesRequireRollback = false;
+
+ /**
+ * Id of error msg to display to user once we are done reverting the VM provider to the previous
+ * one.
+ */
+ private int mVMOrFwdSetError = 0;
+
+ /** string to hold old voicemail number as it is being updated. */
+ private String mOldVmNumber;
+
+ // New call forwarding settings and vm number we will be setting
+ // Need to save these since before we get to saving we need to asynchronously
+ // query the existing forwarding settings.
+ private CallForwardInfo[] mNewFwdSettings;
+ private String mNewVMNumber;
+
+ /**
+ * Used to indicate that the voicemail preference should be shown.
+ */
+ private boolean mShowVoicemailPreference = false;
+
+ private boolean mForeground;
+ private Phone mPhone;
+ private SubscriptionInfoHelper mSubscriptionInfoHelper;
+
+ private EditPhoneNumberPreference mSubMenuVoicemailSettings;
+ private VoicemailProviderListPreference mVoicemailProviders;
+ private PreferenceScreen mVoicemailSettings;
+ private VoicemailRingtonePreference mVoicemailNotificationRingtone;
+ private CheckBoxPreference mVoicemailNotificationVibrate;
+
+
+ //*********************************************************************************************
+ // Preference Activity Methods
+ //*********************************************************************************************
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
- getActionBar().setTitle(R.string.voicemail);
- getFragmentManager().beginTransaction().replace(
- android.R.id.content, new VoicemailSettingsFragment()).commit();
+ // Show the voicemail preference in onResume if the calling intent specifies the
+ // ACTION_ADD_VOICEMAIL action.
+ mShowVoicemailPreference = (icicle == null) &&
+ TextUtils.equals(getIntent().getAction(), ACTION_ADD_VOICEMAIL);
+
+ mSubscriptionInfoHelper = new SubscriptionInfoHelper(this, getIntent());
+ mSubscriptionInfoHelper.setActionBarTitle(
+ getActionBar(), getResources(), R.string.voicemail_settings_with_label);
+ mPhone = mSubscriptionInfoHelper.getPhone();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mForeground = true;
+
+ PreferenceScreen preferenceScreen = getPreferenceScreen();
+ if (preferenceScreen != null) {
+ preferenceScreen.removeAll();
+ }
+
+ addPreferencesFromResource(R.xml.voicemail_settings);
+
+ PreferenceScreen prefSet = getPreferenceScreen();
+ mSubMenuVoicemailSettings = (EditPhoneNumberPreference) findPreference(BUTTON_VOICEMAIL_KEY);
+ mSubMenuVoicemailSettings.setParentActivity(this, VOICEMAIL_PREF_ID, this);
+ mSubMenuVoicemailSettings.setDialogOnClosedListener(this);
+ mSubMenuVoicemailSettings.setDialogTitle(R.string.voicemail_settings_number_label);
+
+ mVoicemailProviders = (VoicemailProviderListPreference) findPreference(
+ BUTTON_VOICEMAIL_PROVIDER_KEY);
+ mVoicemailProviders.init(mPhone, getIntent());
+ mVoicemailProviders.setOnPreferenceChangeListener(this);
+ mPreviousVMProviderKey = mVoicemailProviders.getValue();
+
+ mVoicemailSettings = (PreferenceScreen) findPreference(BUTTON_VOICEMAIL_SETTING_KEY);
+
+ mVoicemailNotificationRingtone = (VoicemailRingtonePreference) findPreference(
+ getResources().getString(R.string.voicemail_notification_ringtone_key));
+ mVoicemailNotificationRingtone.init(mPhone);
+
+ mVoicemailNotificationVibrate = (CheckBoxPreference) findPreference(
+ getResources().getString(R.string.voicemail_notification_vibrate_key));
+ mVoicemailNotificationVibrate.setOnPreferenceChangeListener(this);
+
+ updateVMPreferenceWidgets(mVoicemailProviders.getValue());
+
+ // check the intent that started this activity and pop up the voicemail
+ // dialog if we've been asked to.
+ // If we have at least one non default VM provider registered then bring up
+ // the selection for the VM provider, otherwise bring up a VM number dialog.
+ // We only bring up the dialog the first time we are called (not after orientation change)
+ if (mShowVoicemailPreference) {
+ if (DBG) log("ACTION_ADD_VOICEMAIL Intent is thrown");
+ if (mVoicemailProviders.hasMoreThanOneVoicemailProvider()) {
+ if (DBG) log("Voicemail data has more than one provider.");
+ simulatePreferenceClick(mVoicemailProviders);
+ } else {
+ onPreferenceChange(mVoicemailProviders, VoicemailProviderListPreference.DEFAULT_KEY);
+ mVoicemailProviders.setValue(VoicemailProviderListPreference.DEFAULT_KEY);
+ }
+ mShowVoicemailPreference = false;
+ }
+
+ updateVoiceNumberField();
+ mVMProviderSettingsForced = false;
+
+ mVoicemailNotificationVibrate.setChecked(
+ VoicemailNotificationSettingsUtil.isVibrationEnabled(mPhone));
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mForeground = false;
}
@Override
@@ -41,4 +288,812 @@
}
return super.onOptionsItemSelected(item);
}
+
+ @Override
+ public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+ if (preference == mSubMenuVoicemailSettings) {
+ return true;
+ } else if (preference.getKey().equals(mVoicemailSettings.getKey())) {
+ // Check key instead of comparing reference because closing the voicemail notification
+ // ringtone dialog invokes onResume(), but leaves the old preference screen up,
+ // TODO: Revert to checking reference after migrating voicemail to its own activity.
+ if (DBG) log("onPreferenceTreeClick: Voicemail Settings Preference is clicked.");
+
+ final Dialog dialog = ((PreferenceScreen) preference).getDialog();
+ if (dialog != null) {
+ dialog.getActionBar().setDisplayHomeAsUpEnabled(false);
+ }
+
+ if (preference.getIntent() != null) {
+ if (DBG) log("Invoking cfg intent " + preference.getIntent().getPackage());
+
+ // onActivityResult() will be responsible for resetting some of variables.
+ this.startActivityForResult(preference.getIntent(), VOICEMAIL_PROVIDER_CFG_ID);
+ return true;
+ } else {
+ if (DBG) log("onPreferenceTreeClick(). No intent; use default behavior in xml.");
+
+ // onActivityResult() will not be called, so reset variables here.
+ mPreviousVMProviderKey = VoicemailProviderListPreference.DEFAULT_KEY;
+ mVMProviderSettingsForced = false;
+ return false;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Implemented to support onPreferenceChangeListener to look for preference changes.
+ *
+ * @param preference is the preference to be changed
+ * @param objValue should be the value of the selection, NOT its localized
+ * display value.
+ */
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object objValue) {
+ if (DBG) log("onPreferenceChange: \"" + preference + "\" changed to \"" + objValue + "\"");
+
+ if (preference == mVoicemailProviders) {
+ final String newProviderKey = (String) objValue;
+
+ // If previous provider key and the new one is same, we don't need to handle it.
+ if (mPreviousVMProviderKey.equals(newProviderKey)) {
+ if (DBG) log("No change is made to the VM provider setting.");
+ return true;
+ }
+ updateVMPreferenceWidgets(newProviderKey);
+
+ final VoicemailProviderSettings newProviderSettings =
+ VoicemailProviderSettingsUtil.load(this, newProviderKey);
+
+ // If the user switches to a voice mail provider and we have numbers stored for it we
+ // will automatically change the phone's voice mail and forwarding number to the stored
+ // ones. Otherwise we will bring up provider's configuration UI.
+ if (newProviderSettings == null) {
+ // Force the user into a configuration of the chosen provider
+ Log.w(LOG_TAG, "Saved preferences not found - invoking config");
+ mVMProviderSettingsForced = true;
+ simulatePreferenceClick(mVoicemailSettings);
+ } else {
+ if (DBG) log("Saved preferences found - switching to them");
+ // Set this flag so if we get a failure we revert to previous provider
+ mChangingVMorFwdDueToProviderChange = true;
+ saveVoiceMailAndForwardingNumber(newProviderKey, newProviderSettings);
+ }
+ } else if (preference.getKey().equals(mVoicemailNotificationVibrate.getKey())) {
+ // Check key instead of comparing reference because closing the voicemail notification
+ // ringtone dialog invokes onResume(), but leaves the old preference screen up,
+ // TODO: Revert to checking reference after migrating voicemail to its own activity.
+ VoicemailNotificationSettingsUtil.setVibrationEnabled(
+ mPhone, Boolean.TRUE.equals(objValue));
+ }
+
+ // Always let the preference setting proceed.
+ return true;
+ }
+
+ /**
+ * Implemented for EditPhoneNumberPreference.GetDefaultNumberListener.
+ * This method set the default values for the various
+ * EditPhoneNumberPreference dialogs.
+ */
+ @Override
+ public String onGetDefaultNumber(EditPhoneNumberPreference preference) {
+ if (preference == mSubMenuVoicemailSettings) {
+ // update the voicemail number field, which takes care of the
+ // mSubMenuVoicemailSettings itself, so we should return null.
+ if (DBG) log("updating default for voicemail dialog");
+ updateVoiceNumberField();
+ return null;
+ }
+
+ String vmDisplay = mPhone.getVoiceMailNumber();
+ if (TextUtils.isEmpty(vmDisplay)) {
+ // if there is no voicemail number, we just return null to
+ // indicate no contribution.
+ return null;
+ }
+
+ // Return the voicemail number prepended with "VM: "
+ if (DBG) log("updating default for call forwarding dialogs");
+ return getString(R.string.voicemail_abbreviated) + " " + vmDisplay;
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (DBG) {
+ log("onActivityResult: requestCode: " + requestCode
+ + ", resultCode: " + resultCode
+ + ", data: " + data);
+ }
+
+ // there are cases where the contact picker may end up sending us more than one
+ // request. We want to ignore the request if we're not in the correct state.
+ if (requestCode == VOICEMAIL_PROVIDER_CFG_ID) {
+ boolean failure = false;
+
+ // No matter how the processing of result goes lets clear the flag
+ if (DBG) log("mVMProviderSettingsForced: " + mVMProviderSettingsForced);
+ final boolean isVMProviderSettingsForced = mVMProviderSettingsForced;
+ mVMProviderSettingsForced = false;
+
+ String vmNum = null;
+ if (resultCode != RESULT_OK) {
+ if (DBG) log("onActivityResult: vm provider cfg result not OK.");
+ failure = true;
+ } else {
+ if (data == null) {
+ if (DBG) log("onActivityResult: vm provider cfg result has no data");
+ failure = true;
+ } else {
+ if (data.getBooleanExtra(SIGNOUT_EXTRA, false)) {
+ if (DBG) log("Provider requested signout");
+ if (isVMProviderSettingsForced) {
+ if (DBG) log("Going back to previous provider on signout");
+ switchToPreviousVoicemailProvider();
+ } else {
+ final String victim = mVoicemailProviders.getKey();
+ if (DBG) log("Relaunching activity and ignoring " + victim);
+ Intent i = new Intent(ACTION_ADD_VOICEMAIL);
+ i.putExtra(IGNORE_PROVIDER_EXTRA, victim);
+ i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ this.startActivity(i);
+ }
+ return;
+ }
+ vmNum = data.getStringExtra(VM_NUMBER_EXTRA);
+ if (vmNum == null || vmNum.length() == 0) {
+ if (DBG) log("onActivityResult: vm provider cfg result has no vmnum");
+ failure = true;
+ }
+ }
+ }
+ if (failure) {
+ if (DBG) log("Failure in return from voicemail provider.");
+ if (isVMProviderSettingsForced) {
+ switchToPreviousVoicemailProvider();
+ }
+
+ return;
+ }
+ mChangingVMorFwdDueToProviderChange = isVMProviderSettingsForced;
+ final String fwdNum = data.getStringExtra(FWD_NUMBER_EXTRA);
+
+ // TODO: It would be nice to load the current network setting for this and
+ // send it to the provider when it's config is invoked so it can use this as default
+ final int fwdNumTime = data.getIntExtra(FWD_NUMBER_TIME_EXTRA, 20);
+
+ if (DBG) log("onActivityResult: cfg result has forwarding number " + fwdNum);
+ saveVoiceMailAndForwardingNumber(mVoicemailProviders.getKey(),
+ new VoicemailProviderSettings(vmNum, fwdNum, fwdNumTime));
+ return;
+ }
+
+ if (requestCode == VOICEMAIL_PREF_ID) {
+ if (resultCode != RESULT_OK) {
+ if (DBG) log("onActivityResult: contact picker result not OK.");
+ return;
+ }
+
+ Cursor cursor = null;
+ try {
+ cursor = getContentResolver().query(data.getData(),
+ new String[] { CommonDataKinds.Phone.NUMBER }, null, null, null);
+ if ((cursor == null) || (!cursor.moveToFirst())) {
+ if (DBG) log("onActivityResult: bad contact data, no results found.");
+ return;
+ }
+ mSubMenuVoicemailSettings.onPickActivityResult(cursor.getString(0));
+ return;
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+ }
+
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+
+ /**
+ * Simulates user clicking on a passed preference.
+ * Usually needed when the preference is a dialog preference and we want to invoke
+ * a dialog for this preference programmatically.
+ * TODO: figure out if there is a cleaner way to cause preference dlg to come up
+ */
+ private void simulatePreferenceClick(Preference preference) {
+ // Go through settings until we find our setting
+ // and then simulate a click on it to bring up the dialog
+ final ListAdapter adapter = getPreferenceScreen().getRootAdapter();
+ for (int idx = 0; idx < adapter.getCount(); idx++) {
+ if (adapter.getItem(idx) == preference) {
+ getPreferenceScreen().onItemClick(this.getListView(),
+ null, idx, adapter.getItemId(idx));
+ break;
+ }
+ }
+ }
+
+
+ //*********************************************************************************************
+ // Activity Dialog Methods
+ //*********************************************************************************************
+
+ @Override
+ protected void onPrepareDialog(int id, Dialog dialog) {
+ super.onPrepareDialog(id, dialog);
+ mCurrentDialogId = id;
+ }
+
+ // dialog creation method, called by showDialog()
+ @Override
+ protected Dialog onCreateDialog(int dialogId) {
+ return VoicemailDialogUtil.getDialog(this, dialogId);
+ }
+
+ @Override
+ public void onDialogClosed(EditPhoneNumberPreference preference, int buttonClicked) {
+ if (DBG) log("onDialogClosed: Button clicked is " + buttonClicked);
+
+ if (buttonClicked == DialogInterface.BUTTON_NEGATIVE) {
+ return;
+ }
+
+ if (preference == mSubMenuVoicemailSettings) {
+ VoicemailProviderSettings newSettings = new VoicemailProviderSettings(
+ mSubMenuVoicemailSettings.getPhoneNumber(),
+ VoicemailProviderSettings.NO_FORWARDING);
+ saveVoiceMailAndForwardingNumber(mVoicemailProviders.getKey(), newSettings);
+ }
+ }
+
+ /**
+ * Wrapper around showDialog() that will silently do nothing if we're
+ * not in the foreground.
+ *
+ * This is useful here because most of the dialogs we display from
+ * this class are triggered by asynchronous events (like
+ * success/failure messages from the telephony layer) and it's
+ * possible for those events to come in even after the user has gone
+ * to a different screen.
+ */
+ // TODO: this is too brittle: it's still easy to accidentally add new
+ // code here that calls showDialog() directly (which will result in a
+ // WindowManager$BadTokenException if called after the activity has
+ // been stopped.)
+ //
+ // It would be cleaner to do the "if (mForeground)" check in one
+ // central place, maybe by using a single Handler for all asynchronous
+ // events (and have *that* discard events if we're not in the
+ // foreground.)
+ //
+ // Unfortunately it's not that simple, since we sometimes need to do
+ // actual work to handle these events whether or not we're in the
+ // foreground (see the Handler code in mSetOptionComplete for
+ // example.)
+ //
+ // TODO: It's a bit worrisome that we don't do anything in error cases when we're not in the
+ // foreground. Consider displaying a toast instead.
+ private void showDialogIfForeground(int id) {
+ if (mForeground) {
+ showDialog(id);
+ }
+ }
+
+ private void dismissDialogSafely(int id) {
+ try {
+ dismissDialog(id);
+ } catch (IllegalArgumentException e) {
+ // This is expected in the case where we were in the background
+ // at the time we would normally have shown the dialog, so we didn't
+ // show it.
+ }
+ }
+
+ // This is a method implemented for DialogInterface.OnClickListener.
+ // Used with the error dialog to close the app, voicemail dialog to just dismiss.
+ // Close button is mapped to BUTTON_POSITIVE for the errors that close the activity,
+ // while those that are mapped to BUTTON_NEUTRAL only move the preference focus.
+ public void onClick(DialogInterface dialog, int which) {
+ if (DBG) log("onClick: button clicked is " + which);
+
+ dialog.dismiss();
+ switch (which){
+ case DialogInterface.BUTTON_NEGATIVE:
+ if (mCurrentDialogId == VoicemailDialogUtil.FWD_GET_RESPONSE_ERROR_DIALOG) {
+ // We failed to get current forwarding settings and the user
+ // does not wish to continue.
+ switchToPreviousVoicemailProvider();
+ }
+ break;
+ case DialogInterface.BUTTON_POSITIVE:
+ if (mCurrentDialogId == VoicemailDialogUtil.FWD_GET_RESPONSE_ERROR_DIALOG) {
+ // We failed to get current forwarding settings but the user
+ // wishes to continue changing settings to the new vm provider
+ setVoicemailNumberWithCarrier();
+ } else {
+ finish();
+ }
+ return;
+ default:
+ // just let the dialog close and go back to the input
+ }
+
+ // In all dialogs, all buttons except BUTTON_POSITIVE lead to the end of user interaction
+ // with settings UI. If we were called to explicitly configure voice mail then
+ // we finish the settings activity here to come back to whatever the user was doing.
+ if (getIntent().getAction().equals(ACTION_ADD_VOICEMAIL)) {
+ finish();
+ }
+ }
+
+
+ //*********************************************************************************************
+ // Voicemail Methods
+ //*********************************************************************************************
+
+ /**
+ * TODO: Refactor to make it easier to understand what's done in the different stages.
+ */
+ private void saveVoiceMailAndForwardingNumber(
+ String key, VoicemailProviderSettings newSettings) {
+ if (DBG) log("saveVoiceMailAndForwardingNumber: " + newSettings.toString());
+ mNewVMNumber = newSettings.getVoicemailNumber();
+ mNewVMNumber = (mNewVMNumber == null) ? "" : mNewVMNumber;
+ mNewFwdSettings = newSettings.getForwardingSettings();
+
+ // Call forwarding is not suppported on CDMA.
+ if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
+ if (DBG) log("Ignoring forwarding setting since this is CDMA phone");
+ mNewFwdSettings = VoicemailProviderSettings.NO_FORWARDING;
+ }
+
+ // Throw a warning if the voicemail is the same and we did not change forwarding.
+ if (mNewVMNumber.equals(mOldVmNumber)
+ && mNewFwdSettings == VoicemailProviderSettings.NO_FORWARDING) {
+ showDialogIfForeground(VoicemailDialogUtil.VM_NOCHANGE_ERROR_DIALOG);
+ return;
+ }
+
+ VoicemailProviderSettingsUtil.save(this, key, newSettings);
+ mVMChangeCompletedSuccessfully = false;
+ mFwdChangesRequireRollback = false;
+ mVMOrFwdSetError = 0;
+
+ if (mNewFwdSettings == VoicemailProviderSettings.NO_FORWARDING
+ || key.equals(mPreviousVMProviderKey)) {
+ if (DBG) log("Set voicemail number. No changes to forwarding number.");
+ setVoicemailNumberWithCarrier();
+ } else {
+ if (DBG) log("Reading current forwarding settings.");
+ int numSettingsReasons = VoicemailProviderSettings.FORWARDING_SETTINGS_REASONS.length;
+ mForwardingReadResults = new CallForwardInfo[numSettingsReasons];
+ for (int i = 0; i < mForwardingReadResults.length; i++) {
+ mPhone.getCallForwardingOption(
+ VoicemailProviderSettings.FORWARDING_SETTINGS_REASONS[i],
+ mGetOptionComplete.obtainMessage(EVENT_FORWARDING_GET_COMPLETED, i, 0));
+ }
+ showDialogIfForeground(VoicemailDialogUtil.VM_FWD_READING_DIALOG);
+ }
+
+ PhoneGlobals.getInstance().refreshMwiIndicator(mSubscriptionInfoHelper.getSubId());
+ }
+
+ private final Handler mGetOptionComplete = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ AsyncResult result = (AsyncResult) msg.obj;
+ switch (msg.what) {
+ case EVENT_FORWARDING_GET_COMPLETED:
+ handleForwardingSettingsReadResult(result, msg.arg1);
+ break;
+ }
+ }
+ };
+
+ private void handleForwardingSettingsReadResult(AsyncResult ar, int idx) {
+ if (DBG) Log.d(LOG_TAG, "handleForwardingSettingsReadResult: " + idx);
+
+ Throwable error = null;
+ if (ar.exception != null) {
+ error = ar.exception;
+ if (DBG) Log.d(LOG_TAG, "FwdRead: ar.exception=" + error.getMessage());
+ }
+ if (ar.userObj instanceof Throwable) {
+ error = (Throwable) ar.userObj;
+ if (DBG) Log.d(LOG_TAG, "FwdRead: userObj=" + error.getMessage());
+ }
+
+ // We may have already gotten an error and decided to ignore the other results.
+ if (mForwardingReadResults == null) {
+ if (DBG) Log.d(LOG_TAG, "Ignoring fwd reading result: " + idx);
+ return;
+ }
+
+ // In case of error ignore other results, show an error dialog
+ if (error != null) {
+ if (DBG) Log.d(LOG_TAG, "Error discovered for fwd read : " + idx);
+ mForwardingReadResults = null;
+ dismissDialogSafely(VoicemailDialogUtil.VM_FWD_READING_DIALOG);
+ showDialogIfForeground(VoicemailDialogUtil.FWD_GET_RESPONSE_ERROR_DIALOG);
+ return;
+ }
+
+ // Get the forwarding info.
+ mForwardingReadResults[idx] = CallForwardInfoUtil.getCallForwardInfo(
+ (CallForwardInfo[]) ar.result,
+ VoicemailProviderSettings.FORWARDING_SETTINGS_REASONS[idx]);
+
+ // Check if we got all the results already
+ boolean done = true;
+ for (int i = 0; i < mForwardingReadResults.length; i++) {
+ if (mForwardingReadResults[i] == null) {
+ done = false;
+ break;
+ }
+ }
+
+ if (done) {
+ if (DBG) Log.d(LOG_TAG, "Done receiving fwd info");
+ dismissDialogSafely(VoicemailDialogUtil.VM_FWD_READING_DIALOG);
+
+ if (mPreviousVMProviderKey.equals(VoicemailProviderListPreference.DEFAULT_KEY)) {
+ VoicemailProviderSettingsUtil.save(mPhone.getContext(),
+ VoicemailProviderListPreference.DEFAULT_KEY,
+ new VoicemailProviderSettings(mOldVmNumber, mForwardingReadResults));
+ }
+ saveVoiceMailAndForwardingNumberStage2();
+ }
+ }
+
+ private void resetForwardingChangeState() {
+ mForwardingChangeResults = new HashMap<Integer, AsyncResult>();
+ mExpectedChangeResultReasons = new HashSet<Integer>();
+ }
+
+ // Called after we are done saving the previous forwarding settings if we needed.
+ private void saveVoiceMailAndForwardingNumberStage2() {
+ mForwardingChangeResults = null;
+ mVoicemailChangeResult = null;
+
+ resetForwardingChangeState();
+ for (int i = 0; i < mNewFwdSettings.length; i++) {
+ CallForwardInfo fi = mNewFwdSettings[i];
+ CallForwardInfo fiForReason =
+ CallForwardInfoUtil.infoForReason(mForwardingReadResults, fi.reason);
+ final boolean doUpdate = CallForwardInfoUtil.isUpdateRequired(fiForReason, fi);
+
+ if (doUpdate) {
+ if (DBG) log("Setting fwd #: " + i + ": " + fi.toString());
+ mExpectedChangeResultReasons.add(i);
+
+ CallForwardInfoUtil.setCallForwardingOption(mPhone, fi,
+ mSetOptionComplete.obtainMessage(
+ EVENT_FORWARDING_CHANGED, fi.reason, 0));
+ }
+ }
+ showDialogIfForeground(VoicemailDialogUtil.VM_FWD_SAVING_DIALOG);
+ }
+
+
+ /**
+ * Callback to handle option update completions
+ */
+ private final Handler mSetOptionComplete = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ AsyncResult result = (AsyncResult) msg.obj;
+ boolean done = false;
+ switch (msg.what) {
+ case EVENT_VOICEMAIL_CHANGED:
+ mVoicemailChangeResult = result;
+ mVMChangeCompletedSuccessfully = isVmChangeSuccess();
+ done = true;
+ break;
+ case EVENT_FORWARDING_CHANGED:
+ mForwardingChangeResults.put(msg.arg1, result);
+ if (result.exception != null) {
+ Log.w(LOG_TAG, "Error in setting fwd# " + msg.arg1 + ": " +
+ result.exception.getMessage());
+ }
+ if (isForwardingCompleted()) {
+ if (isFwdChangeSuccess()) {
+ if (DBG) log("Overall fwd changes completed ok, starting vm change");
+ setVoicemailNumberWithCarrier();
+ } else {
+ Log.w(LOG_TAG, "Overall fwd changes completed in failure. " +
+ "Check if we need to try rollback for some settings.");
+ mFwdChangesRequireRollback = false;
+ Iterator<Map.Entry<Integer,AsyncResult>> it =
+ mForwardingChangeResults.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry<Integer,AsyncResult> entry = it.next();
+ if (entry.getValue().exception == null) {
+ // If at least one succeeded we have to revert
+ Log.i(LOG_TAG, "Rollback will be required");
+ mFwdChangesRequireRollback = true;
+ break;
+ }
+ }
+ if (!mFwdChangesRequireRollback) {
+ Log.i(LOG_TAG, "No rollback needed.");
+ }
+ done = true;
+ }
+ }
+ break;
+ default:
+ // TODO: should never reach this, may want to throw exception
+ }
+
+ if (done) {
+ if (DBG) log("All VM provider related changes done");
+ if (mForwardingChangeResults != null) {
+ dismissDialogSafely(VoicemailDialogUtil.VM_FWD_SAVING_DIALOG);
+ }
+ handleSetVmOrFwdMessage();
+ }
+ }
+ };
+
+ /**
+ * Callback to handle option revert completions
+ */
+ private final Handler mRevertOptionComplete = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ AsyncResult result = (AsyncResult) msg.obj;
+ switch (msg.what) {
+ case EVENT_VOICEMAIL_CHANGED:
+ if (DBG) log("VM revert complete msg");
+ mVoicemailChangeResult = result;
+ break;
+
+ case EVENT_FORWARDING_CHANGED:
+ if (DBG) log("FWD revert complete msg ");
+ mForwardingChangeResults.put(msg.arg1, result);
+ if (result.exception != null) {
+ if (DBG) log("Error in reverting fwd# " + msg.arg1 + ": " +
+ result.exception.getMessage());
+ }
+ break;
+
+ default:
+ // TODO: should never reach this, may want to throw exception
+ }
+
+ final boolean done = (!mVMChangeCompletedSuccessfully || mVoicemailChangeResult != null)
+ && (!mFwdChangesRequireRollback || isForwardingCompleted());
+ if (done) {
+ if (DBG) log("All VM reverts done");
+ dismissDialogSafely(VoicemailDialogUtil.VM_REVERTING_DIALOG);
+ onRevertDone();
+ }
+ }
+ };
+
+ private void setVoicemailNumberWithCarrier() {
+ if (DBG) log("save voicemail #: " + mNewVMNumber);
+
+ mVoicemailChangeResult = null;
+ mPhone.setVoiceMailNumber(
+ mPhone.getVoiceMailAlphaTag().toString(),
+ mNewVMNumber,
+ Message.obtain(mSetOptionComplete, EVENT_VOICEMAIL_CHANGED));
+ }
+
+ private void switchToPreviousVoicemailProvider() {
+ if (DBG) log("switchToPreviousVoicemailProvider " + mPreviousVMProviderKey);
+
+ if (mPreviousVMProviderKey == null) {
+ return;
+ }
+
+ if (mVMChangeCompletedSuccessfully || mFwdChangesRequireRollback) {
+ showDialogIfForeground(VoicemailDialogUtil.VM_REVERTING_DIALOG);
+ final VoicemailProviderSettings prevSettings =
+ VoicemailProviderSettingsUtil.load(this, mPreviousVMProviderKey);
+ if (prevSettings == null) {
+ Log.e(LOG_TAG, "VoicemailProviderSettings for the key \""
+ + mPreviousVMProviderKey + "\" is null but should be loaded.");
+ }
+
+ if (mVMChangeCompletedSuccessfully) {
+ mNewVMNumber = prevSettings.getVoicemailNumber();
+ Log.i(LOG_TAG, "VM change is already completed successfully."
+ + "Have to revert VM back to " + mNewVMNumber + " again.");
+ mPhone.setVoiceMailNumber(
+ mPhone.getVoiceMailAlphaTag().toString(),
+ mNewVMNumber,
+ Message.obtain(mRevertOptionComplete, EVENT_VOICEMAIL_CHANGED));
+ }
+
+ if (mFwdChangesRequireRollback) {
+ Log.i(LOG_TAG, "Requested to rollback forwarding changes.");
+
+ final CallForwardInfo[] prevFwdSettings = prevSettings.getForwardingSettings();
+ if (prevFwdSettings != null) {
+ Map<Integer, AsyncResult> results = mForwardingChangeResults;
+ resetForwardingChangeState();
+ for (int i = 0; i < prevFwdSettings.length; i++) {
+ CallForwardInfo fi = prevFwdSettings[i];
+ if (DBG) log("Reverting fwd #: " + i + ": " + fi.toString());
+ // Only revert the settings for which the update succeeded.
+ AsyncResult result = results.get(fi.reason);
+ if (result != null && result.exception == null) {
+ mExpectedChangeResultReasons.add(fi.reason);
+ CallForwardInfoUtil.setCallForwardingOption(mPhone, fi,
+ mRevertOptionComplete.obtainMessage(
+ EVENT_FORWARDING_CHANGED, i, 0));
+ }
+ }
+ }
+ }
+ } else {
+ if (DBG) log("No need to revert");
+ onRevertDone();
+ }
+ }
+
+
+ //*********************************************************************************************
+ // Voicemail Handler Helpers
+ //*********************************************************************************************
+
+ /**
+ * Updates the look of the VM preference widgets based on current VM provider settings.
+ * Note that the provider name is loaded fxrorm the found activity via loadLabel in
+ * {@link VoicemailProviderListPreference#initVoiceMailProviders()} in order for it to be
+ * localizable.
+ */
+ private void updateVMPreferenceWidgets(String currentProviderSetting) {
+ final String key = currentProviderSetting;
+ final VoicemailProviderListPreference.VoicemailProvider provider =
+ mVoicemailProviders.getVoicemailProvider(key);
+
+ /* This is the case when we are coming up on a freshly wiped phone and there is no
+ persisted value for the list preference mVoicemailProviders.
+ In this case we want to show the UI asking the user to select a voicemail provider as
+ opposed to silently falling back to default one. */
+ if (provider == null) {
+ if (DBG) log("updateVMPreferenceWidget: key: " + key + " -> null.");
+
+ mVoicemailProviders.setSummary(getString(R.string.sum_voicemail_choose_provider));
+ mVoicemailSettings.setEnabled(false);
+ mVoicemailSettings.setIntent(null);
+ mVoicemailNotificationVibrate.setEnabled(false);
+ } else {
+ if (DBG) log("updateVMPreferenceWidget: key: " + key + " -> " + provider.toString());
+
+ final String providerName = provider.name;
+ mVoicemailProviders.setSummary(providerName);
+ mVoicemailSettings.setEnabled(true);
+ mVoicemailSettings.setIntent(provider.intent);
+ mVoicemailNotificationVibrate.setEnabled(true);
+ }
+ }
+
+ /**
+ * Update the voicemail number from what we've recorded on the sim.
+ */
+ private void updateVoiceNumberField() {
+ if (DBG) log("updateVoiceNumberField()");
+
+ mOldVmNumber = mPhone.getVoiceMailNumber();
+ if (TextUtils.isEmpty(mOldVmNumber)) {
+ mSubMenuVoicemailSettings.setPhoneNumber("");
+ mSubMenuVoicemailSettings.setSummary(getString(R.string.voicemail_number_not_set));
+ } else {
+ mSubMenuVoicemailSettings.setPhoneNumber(mOldVmNumber);
+ mSubMenuVoicemailSettings.setSummary(mOldVmNumber);
+ }
+ }
+
+ private void handleSetVmOrFwdMessage() {
+ if (DBG) log("handleSetVMMessage: set VM request complete");
+
+ if (!isFwdChangeSuccess()) {
+ handleVmOrFwdSetError(VoicemailDialogUtil.FWD_SET_RESPONSE_ERROR_DIALOG);
+ } else if (!isVmChangeSuccess()) {
+ handleVmOrFwdSetError(VoicemailDialogUtil.VM_RESPONSE_ERROR_DIALOG);
+ } else {
+ handleVmAndFwdSetSuccess(VoicemailDialogUtil.VM_CONFIRM_DIALOG);
+ }
+ }
+
+ /**
+ * Called when Voicemail Provider or its forwarding settings failed. Rolls back partly made
+ * changes to those settings and show "failure" dialog.
+ *
+ * @param dialogId ID of the dialog to show for the specific error case. Either
+ * {@link #FWD_SET_RESPONSE_ERROR_DIALOG} or {@link #VM_RESPONSE_ERROR_DIALOG}
+ */
+ private void handleVmOrFwdSetError(int dialogId) {
+ if (mChangingVMorFwdDueToProviderChange) {
+ mVMOrFwdSetError = dialogId;
+ mChangingVMorFwdDueToProviderChange = false;
+ switchToPreviousVoicemailProvider();
+ return;
+ }
+ mChangingVMorFwdDueToProviderChange = false;
+ showDialogIfForeground(dialogId);
+ updateVoiceNumberField();
+ }
+
+ /**
+ * Called when Voicemail Provider and its forwarding settings were successfully finished.
+ * This updates a bunch of variables and show "success" dialog.
+ */
+ private void handleVmAndFwdSetSuccess(int dialogId) {
+ if (DBG) log("handleVmAndFwdSetSuccess: key is " + mVoicemailProviders.getKey());
+
+ mPreviousVMProviderKey = mVoicemailProviders.getKey();
+ mChangingVMorFwdDueToProviderChange = false;
+ showDialogIfForeground(dialogId);
+ updateVoiceNumberField();
+ }
+
+ private void onRevertDone() {
+ if (DBG) log("onRevertDone: Changing provider key back to " + mPreviousVMProviderKey);
+
+ updateVMPreferenceWidgets(mPreviousVMProviderKey);
+ updateVoiceNumberField();
+ if (mVMOrFwdSetError != 0) {
+ showDialogIfForeground(mVMOrFwdSetError);
+ mVMOrFwdSetError = 0;
+ }
+ }
+
+
+ //*********************************************************************************************
+ // Voicemail State Helpers
+ //*********************************************************************************************
+
+ /**
+ * Return true if there is a change result for every reason for which we expect a result.
+ */
+ private boolean isForwardingCompleted() {
+ if (mForwardingChangeResults == null) {
+ return true;
+ }
+
+ for (Integer reason : mExpectedChangeResultReasons) {
+ if (mForwardingChangeResults.get(reason) == null) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private boolean isFwdChangeSuccess() {
+ if (mForwardingChangeResults == null) {
+ return true;
+ }
+
+ for (AsyncResult result : mForwardingChangeResults.values()) {
+ Throwable exception = result.exception;
+ if (exception != null) {
+ String msg = exception.getMessage();
+ msg = (msg != null) ? msg : "";
+ Log.w(LOG_TAG, "Failed to change forwarding setting. Reason: " + msg);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean isVmChangeSuccess() {
+ if (mVoicemailChangeResult.exception != null) {
+ String msg = mVoicemailChangeResult.exception.getMessage();
+ msg = (msg != null) ? msg : "";
+ Log.w(LOG_TAG, "Failed to change voicemail. Reason: " + msg);
+ return false;
+ }
+ return true;
+ }
+
+ private static void log(String msg) {
+ Log.d(LOG_TAG, msg);
+ }
}
diff --git a/src/com/android/phone/settings/VoicemailSettingsFragment.java b/src/com/android/phone/settings/VoicemailSettingsFragment.java
deleted file mode 100644
index fef3e8c..0000000
--- a/src/com/android/phone/settings/VoicemailSettingsFragment.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * 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.os.Bundle;
-import android.preference.PreferenceFragment;
-
-import com.android.phone.R;
-
-public class VoicemailSettingsFragment extends PreferenceFragment {
-
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- addPreferencesFromResource(R.xml.voicemail_settings);
- }
-}