blob: 7207fa295dad5a85589e10698ccf87ba1eb396d8 [file] [log] [blame]
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.phone;
18
19import android.app.ActionBar;
20import android.app.Activity;
Evan Charlton1c696832014-04-15 14:24:23 -070021import android.app.ActivityOptions;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070022import android.app.AlertDialog;
23import android.app.Dialog;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070024import android.content.ContentResolver;
25import android.content.Context;
26import android.content.DialogInterface;
27import android.content.Intent;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070028import android.content.pm.ActivityInfo;
29import android.content.pm.PackageManager;
30import android.content.pm.ResolveInfo;
31import android.database.Cursor;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070032import android.media.AudioManager;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070033import android.os.AsyncResult;
34import android.os.Bundle;
35import android.os.Handler;
36import android.os.Message;
37import android.os.UserHandle;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070038import android.preference.CheckBoxPreference;
39import android.preference.ListPreference;
40import android.preference.Preference;
41import android.preference.PreferenceActivity;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070042import android.preference.PreferenceScreen;
43import android.provider.ContactsContract.CommonDataKinds;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070044import android.provider.Settings;
Tyler Gunn4d45d1c2014-09-12 22:17:53 -070045import android.telecom.PhoneAccountHandle;
46import android.telecom.TelecomManager;
Andrew Lee93c345f2014-10-27 15:25:07 -070047import android.telephony.TelephonyManager;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070048import android.text.TextUtils;
49import android.util.Log;
50import android.view.MenuItem;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070051import android.widget.ListAdapter;
Jay Shraunerc2684732014-11-12 12:10:37 -080052import android.widget.Toast;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070053
Andrew Lee312e8172014-10-23 17:01:36 -070054import com.android.ims.ImsManager;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070055import com.android.internal.telephony.CallForwardInfo;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070056import com.android.internal.telephony.Phone;
57import com.android.internal.telephony.PhoneConstants;
Andrew Lee2170a972014-08-13 18:13:01 -070058import com.android.phone.common.util.SettingsUtil;
Andrew Leedb2fe562014-09-03 15:40:43 -070059import com.android.phone.settings.AccountSelectionPreference;
Andrew Lee1af6cf72014-11-04 17:35:26 -080060import com.android.phone.settings.CallForwardInfoUtil;
Andrew Lee84024342014-11-06 23:37:09 -080061import com.android.phone.settings.VoicemailDialogUtil;
Andrew Leeb490d732014-10-27 15:00:41 -070062import com.android.phone.settings.VoicemailProviderSettings;
Andrew Lee88b51e22014-10-29 15:48:51 -070063import com.android.phone.settings.VoicemailProviderSettingsUtil;
Andrew Lee8d66d812014-11-24 14:54:02 -080064import com.android.phone.settings.VoicemailNotificationSettingsUtil;
Andrew Lee5ed870c2014-10-29 11:47:49 -070065import com.android.phone.settings.fdn.FdnSetting;
Sailesh Nepal788959e2014-07-08 23:36:40 -070066import com.android.services.telephony.sip.SipUtil;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070067
Andrew Lee2170a972014-08-13 18:13:01 -070068import java.lang.String;
Andrew Leef1776d82014-11-04 14:45:02 -080069import java.util.ArrayList;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070070import java.util.Collection;
71import java.util.HashMap;
72import java.util.HashSet;
73import java.util.Iterator;
74import java.util.List;
75import java.util.Map;
76
77/**
78 * Top level "Call settings" UI; see res/xml/call_feature_setting.xml
79 *
Andrew Leece8ae2a2014-09-10 10:41:48 -070080 * This preference screen is the root of the "Call settings" hierarchy available from the Phone
81 * app; the settings here let you control various features related to phone calls (including
82 * voicemail settings, the "Respond via SMS" feature, and others.) It's used only on
83 * voice-capable phone devices.
Santos Cordon7d4ddf62013-07-10 11:58:08 -070084 *
85 * Note that this activity is part of the package com.android.phone, even
86 * though you reach it from the "Phone" app (i.e. DialtactsActivity) which
87 * is from the package com.android.contacts.
88 *
89 * For the "Mobile network settings" screen under the main Settings app,
90 * See {@link MobileNetworkSettings}.
91 *
Andrew Leece8ae2a2014-09-10 10:41:48 -070092 * TODO: Settings should be split into PreferenceFragments where possible (ie. voicemail).
Andrew Lee2170a972014-08-13 18:13:01 -070093 *
Santos Cordon7d4ddf62013-07-10 11:58:08 -070094 * @see com.android.phone.MobileNetworkSettings
95 */
96public class CallFeaturesSetting extends PreferenceActivity
97 implements DialogInterface.OnClickListener,
Andrew Lee2170a972014-08-13 18:13:01 -070098 Preference.OnPreferenceChangeListener,
Andrew Lee2170a972014-08-13 18:13:01 -070099 EditPhoneNumberPreference.OnDialogClosedListener,
Andrew Leece8ae2a2014-09-10 10:41:48 -0700100 EditPhoneNumberPreference.GetDefaultNumberListener {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700101 private static final String LOG_TAG = "CallFeaturesSetting";
102 private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
Andrew Lee77527ac2014-10-21 16:57:39 -0700103 // STOPSHIP if true. Flag to override behavior default behavior to hide VT setting.
104 private static final boolean ENABLE_VT_FLAG = false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700105
106 /**
107 * Intent action to bring up Voicemail Provider settings.
108 *
109 * @see #IGNORE_PROVIDER_EXTRA
110 */
111 public static final String ACTION_ADD_VOICEMAIL =
112 "com.android.phone.CallFeaturesSetting.ADD_VOICEMAIL";
113 // intent action sent by this activity to a voice mail provider
114 // to trigger its configuration UI
115 public static final String ACTION_CONFIGURE_VOICEMAIL =
116 "com.android.phone.CallFeaturesSetting.CONFIGURE_VOICEMAIL";
117 // Extra put in the return from VM provider config containing voicemail number to set
118 public static final String VM_NUMBER_EXTRA = "com.android.phone.VoicemailNumber";
119 // Extra put in the return from VM provider config containing call forwarding number to set
120 public static final String FWD_NUMBER_EXTRA = "com.android.phone.ForwardingNumber";
121 // Extra put in the return from VM provider config containing call forwarding number to set
122 public static final String FWD_NUMBER_TIME_EXTRA = "com.android.phone.ForwardingNumberTime";
123 // If the VM provider returns non null value in this extra we will force the user to
124 // choose another VM provider
125 public static final String SIGNOUT_EXTRA = "com.android.phone.Signout";
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700126
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700127 // Key identifying the default vocie mail provider
128 public static final String DEFAULT_VM_PROVIDER_KEY = "";
129
130 /**
131 * String Extra put into ACTION_ADD_VOICEMAIL call to indicate which provider should be hidden
132 * in the list of providers presented to the user. This allows a provider which is being
133 * disabled (e.g. GV user logging out) to force the user to pick some other provider.
134 */
135 public static final String IGNORE_PROVIDER_EXTRA = "com.android.phone.ProviderToIgnore";
136
137 // string constants
138 private static final String NUM_PROJECTION[] = {CommonDataKinds.Phone.NUMBER};
139
140 // String keys for preference lookup
141 // TODO: Naming these "BUTTON_*" is confusing since they're not actually buttons(!)
Andrew Lee8d66d812014-11-24 14:54:02 -0800142 // TODO: Consider moving these strings to strings.xml, so that they are not duplicated here and
143 // in the layout files. These strings need to be treated carefully; if the setting is
144 // persistent, they are used as the key to store shared preferences and the name should not be
145 // changed unless the settings are also migrated.
Andrew Lee97708a42014-09-25 12:39:07 -0700146 private static final String VOICEMAIL_SETTING_SCREEN_PREF_KEY = "button_voicemail_category_key";
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700147 private static final String BUTTON_VOICEMAIL_KEY = "button_voicemail_key";
148 private static final String BUTTON_VOICEMAIL_PROVIDER_KEY = "button_voicemail_provider_key";
149 private static final String BUTTON_VOICEMAIL_SETTING_KEY = "button_voicemail_setting_key";
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700150 private static final String BUTTON_FDN_KEY = "button_fdn_key";
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700151
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700152 private static final String BUTTON_DTMF_KEY = "button_dtmf_settings";
153 private static final String BUTTON_RETRY_KEY = "button_auto_retry_key";
154 private static final String BUTTON_TTY_KEY = "button_tty_mode_key";
155 private static final String BUTTON_HAC_KEY = "button_hac_key";
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700156
157 private static final String BUTTON_GSM_UMTS_OPTIONS = "button_gsm_more_expand_key";
158 private static final String BUTTON_CDMA_OPTIONS = "button_cdma_more_expand_key";
Andrew Lee2b36ba22014-11-05 17:08:49 -0800159 private static final String CALL_FORWARDING_KEY = "call_forwarding_key";
160 private static final String ADDITIONAL_GSM_SETTINGS_KEY = "additional_gsm_call_settings_key";
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700161
Andrew Leece8ae2a2014-09-10 10:41:48 -0700162 private static final String PHONE_ACCOUNT_SETTINGS_KEY =
163 "phone_account_settings_preference_screen";
Andrew Leedb2fe562014-09-03 15:40:43 -0700164
Andrew Leedf14ead2014-10-17 14:22:52 -0700165 private static final String ENABLE_VIDEO_CALLING_KEY = "button_enable_video_calling";
166
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700167 /** Event for Async voicemail change call */
168 private static final int EVENT_VOICEMAIL_CHANGED = 500;
169 private static final int EVENT_FORWARDING_CHANGED = 501;
170 private static final int EVENT_FORWARDING_GET_COMPLETED = 502;
171
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700172 public static final String HAC_KEY = "HACSetting";
173 public static final String HAC_VAL_ON = "ON";
174 public static final String HAC_VAL_OFF = "OFF";
175
176 /** Handle to voicemail pref */
177 private static final int VOICEMAIL_PREF_ID = 1;
178 private static final int VOICEMAIL_PROVIDER_CFG_ID = 2;
179
180 private Phone mPhone;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700181 private AudioManager mAudioManager;
Andrew Lee88b51e22014-10-29 15:48:51 -0700182 private VoicemailProviderSettingsUtil mVmProviderSettingsUtil;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700183
Andrew Lee5ed870c2014-10-29 11:47:49 -0700184 private SubscriptionInfoHelper mSubscriptionInfoHelper;
185
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700186 private EditPhoneNumberPreference mSubMenuVoicemailSettings;
187
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700188 /** Whether dialpad plays DTMF tone or not. */
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700189 private CheckBoxPreference mButtonAutoRetry;
190 private CheckBoxPreference mButtonHAC;
191 private ListPreference mButtonDTMF;
192 private ListPreference mButtonTTY;
Andrew Leece8ae2a2014-09-10 10:41:48 -0700193 private Preference mPhoneAccountSettingsPreference;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700194 private ListPreference mVoicemailProviders;
Andrew Lee97708a42014-09-25 12:39:07 -0700195 private PreferenceScreen mVoicemailSettingsScreen;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700196 private PreferenceScreen mVoicemailSettings;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700197 private CheckBoxPreference mVoicemailNotificationVibrate;
Andrew Leedf14ead2014-10-17 14:22:52 -0700198 private CheckBoxPreference mEnableVideoCalling;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700199
200 private class VoiceMailProvider {
Andrew Leef1776d82014-11-04 14:45:02 -0800201 public String name;
202 public Intent intent;
203
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700204 public VoiceMailProvider(String name, Intent intent) {
205 this.name = name;
206 this.intent = intent;
207 }
Andrew Leef1776d82014-11-04 14:45:02 -0800208
209 public String toString() {
210 return "[ Name: " + name + ", Intent: " + intent + " ]";
211 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700212 }
213
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700214 /**
215 * Results of reading forwarding settings
216 */
217 private CallForwardInfo[] mForwardingReadResults = null;
218
219 /**
220 * Result of forwarding number change.
221 * Keys are reasons (eg. unconditional forwarding).
222 */
223 private Map<Integer, AsyncResult> mForwardingChangeResults = null;
224
225 /**
226 * Expected CF read result types.
227 * This set keeps track of the CF types for which we've issued change
228 * commands so we can tell when we've received all of the responses.
229 */
230 private Collection<Integer> mExpectedChangeResultReasons = null;
231
232 /**
233 * Result of vm number change
234 */
235 private AsyncResult mVoicemailChangeResult = null;
236
237 /**
238 * Previous VM provider setting so we can return to it in case of failure.
239 */
240 private String mPreviousVMProviderKey = null;
241
242 /**
243 * Id of the dialog being currently shown.
244 */
245 private int mCurrentDialogId = 0;
246
247 /**
248 * Flag indicating that we are invoking settings for the voicemail provider programmatically
249 * due to vm provider change.
250 */
251 private boolean mVMProviderSettingsForced = false;
252
253 /**
254 * Flag indicating that we are making changes to vm or fwd numbers
255 * due to vm provider change.
256 */
257 private boolean mChangingVMorFwdDueToProviderChange = false;
258
259 /**
260 * True if we are in the process of vm & fwd number change and vm has already been changed.
261 * This is used to decide what to do in case of rollback.
262 */
263 private boolean mVMChangeCompletedSuccessfully = false;
264
265 /**
266 * True if we had full or partial failure setting forwarding numbers and so need to roll them
267 * back.
268 */
269 private boolean mFwdChangesRequireRollback = false;
270
271 /**
272 * Id of error msg to display to user once we are done reverting the VM provider to the previous
273 * one.
274 */
275 private int mVMOrFwdSetError = 0;
276
277 /**
278 * Data about discovered voice mail settings providers.
279 * Is populated by querying which activities can handle ACTION_CONFIGURE_VOICEMAIL.
280 * They key in this map is package name + activity name.
281 * We always add an entry for the default provider with a key of empty
282 * string and intent value of null.
283 * @see #initVoiceMailProviders()
284 */
285 private final Map<String, VoiceMailProvider> mVMProvidersData =
286 new HashMap<String, VoiceMailProvider>();
287
288 /** string to hold old voicemail number as it is being updated. */
289 private String mOldVmNumber;
290
291 // New call forwarding settings and vm number we will be setting
292 // Need to save these since before we get to saving we need to asynchronously
293 // query the existing forwarding settings.
294 private CallForwardInfo[] mNewFwdSettings;
295 private String mNewVMNumber;
296
297 private boolean mForeground;
298
299 @Override
300 public void onPause() {
301 super.onPause();
302 mForeground = false;
303 }
304
305 /**
306 * We have to pull current settings from the network for all kinds of
307 * voicemail providers so we can tell whether we have to update them,
308 * so use this bit to keep track of whether we're reading settings for the
309 * default provider and should therefore save them out when done.
310 */
311 private boolean mReadingSettingsForDefaultProvider = false;
312
Tyler Gunnbaee2952014-09-10 16:01:02 -0700313 /**
314 * Used to indicate that the voicemail preference should be shown.
315 */
316 private boolean mShowVoicemailPreference = false;
317
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700318 /*
319 * Click Listeners, handle click based on objects attached to UI.
320 */
321
322 // Click listener for all toggle events
323 @Override
324 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
325 if (preference == mSubMenuVoicemailSettings) {
326 return true;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700327 } else if (preference == mButtonDTMF) {
328 return true;
329 } else if (preference == mButtonTTY) {
330 return true;
331 } else if (preference == mButtonAutoRetry) {
332 android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
333 android.provider.Settings.Global.CALL_AUTO_RETRY,
334 mButtonAutoRetry.isChecked() ? 1 : 0);
335 return true;
336 } else if (preference == mButtonHAC) {
337 int hac = mButtonHAC.isChecked() ? 1 : 0;
338 // Update HAC value in Settings database
339 Settings.System.putInt(mPhone.getContext().getContentResolver(),
340 Settings.System.HEARING_AID, hac);
341
342 // Update HAC Value in AudioManager
343 mAudioManager.setParameter(HAC_KEY, hac != 0 ? HAC_VAL_ON : HAC_VAL_OFF);
344 return true;
345 } else if (preference == mVoicemailSettings) {
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800346 if (DBG) log("onPreferenceTreeClick: Voicemail Settings Preference is clicked.");
347
Yorke Leea0f63bf2014-10-09 18:27:20 -0700348 final Dialog dialog = mVoicemailSettings.getDialog();
349 if (dialog != null) {
350 dialog.getActionBar().setDisplayHomeAsUpEnabled(false);
351 }
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800352
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700353 if (preference.getIntent() != null) {
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800354 if (DBG) log("Invoking cfg intent " + preference.getIntent().getPackage());
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700355
356 // onActivityResult() will be responsible for resetting some of variables.
357 this.startActivityForResult(preference.getIntent(), VOICEMAIL_PROVIDER_CFG_ID);
358 return true;
359 } else {
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800360 if (DBG) log("onPreferenceTreeClick(). No intent; use default behavior in xml.");
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700361
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800362 // onActivityResult() will not be called, so reset variables here.
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700363 mPreviousVMProviderKey = DEFAULT_VM_PROVIDER_KEY;
364 mVMProviderSettingsForced = false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700365 return false;
366 }
Andrew Lee97708a42014-09-25 12:39:07 -0700367 } else if (preference == mVoicemailSettingsScreen) {
Yorke Leea0f63bf2014-10-09 18:27:20 -0700368 final Dialog dialog = mVoicemailSettingsScreen.getDialog();
369 if (dialog != null) {
370 dialog.getActionBar().setDisplayHomeAsUpEnabled(false);
371 }
Andrew Lee97708a42014-09-25 12:39:07 -0700372 return false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700373 }
374 return false;
375 }
376
377 /**
378 * Implemented to support onPreferenceChangeListener to look for preference
379 * changes.
380 *
381 * @param preference is the preference to be changed
382 * @param objValue should be the value of the selection, NOT its localized
383 * display value.
384 */
385 @Override
386 public boolean onPreferenceChange(Preference preference, Object objValue) {
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800387 if (DBG) log("onPreferenceChange: \"" + preference + "\" changed to \"" + objValue + "\"");
Andrew Lee2170a972014-08-13 18:13:01 -0700388
389 if (preference == mButtonDTMF) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700390 int index = mButtonDTMF.findIndexOfValue((String) objValue);
391 Settings.System.putInt(mPhone.getContext().getContentResolver(),
392 Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, index);
393 } else if (preference == mButtonTTY) {
394 handleTTYChange(preference, objValue);
395 } else if (preference == mVoicemailProviders) {
396 final String newProviderKey = (String) objValue;
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800397
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700398 // If previous provider key and the new one is same, we don't need to handle it.
399 if (mPreviousVMProviderKey.equals(newProviderKey)) {
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800400 if (DBG) log("No change is made to the VM provider setting.");
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700401 return true;
402 }
403 updateVMPreferenceWidgets(newProviderKey);
404
Andrew Leeb490d732014-10-27 15:00:41 -0700405 final VoicemailProviderSettings newProviderSettings =
Andrew Lee88b51e22014-10-29 15:48:51 -0700406 mVmProviderSettingsUtil.load(newProviderKey);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700407
Andrew Lee88b51e22014-10-29 15:48:51 -0700408 // If the user switches to a voice mail provider and we have numbers stored for it we
409 // will automatically change the phone's voice mail and forwarding number to the stored
410 // ones. Otherwise we will bring up provider's configuration UI.
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700411 if (newProviderSettings == null) {
412 // Force the user into a configuration of the chosen provider
413 Log.w(LOG_TAG, "Saved preferences not found - invoking config");
414 mVMProviderSettingsForced = true;
415 simulatePreferenceClick(mVoicemailSettings);
416 } else {
417 if (DBG) log("Saved preferences found - switching to them");
418 // Set this flag so if we get a failure we revert to previous provider
419 mChangingVMorFwdDueToProviderChange = true;
420 saveVoiceMailAndForwardingNumber(newProviderKey, newProviderSettings);
421 }
Andrew Lee8d66d812014-11-24 14:54:02 -0800422 } else if (preference.getKey().equals(mVoicemailNotificationVibrate.getKey())) {
423 VoicemailNotificationSettingsUtil.setVibrationEnabled(
424 mPhone.getContext(), Boolean.TRUE.equals(objValue));
Andrew Leedf14ead2014-10-17 14:22:52 -0700425 } else if (preference == mEnableVideoCalling) {
Andrew Lee312e8172014-10-23 17:01:36 -0700426 if (ImsManager.isEnhanced4gLteModeSettingEnabledByUser(mPhone.getContext())) {
427 PhoneGlobals.getInstance().phoneMgr.enableVideoCalling((boolean) objValue);
428 } else {
429 AlertDialog.Builder builder = new AlertDialog.Builder(this);
430 DialogInterface.OnClickListener networkSettingsClickListener =
431 new Dialog.OnClickListener() {
432 @Override
433 public void onClick(DialogInterface dialog, int which) {
434 startActivity(new Intent(mPhone.getContext(),
435 com.android.phone.MobileNetworkSettings.class));
436 }
437 };
438 builder.setMessage(getResources().getString(
439 R.string.enable_video_calling_dialog_msg))
440 .setNeutralButton(getResources().getString(
441 R.string.enable_video_calling_dialog_settings),
442 networkSettingsClickListener)
443 .setPositiveButton(android.R.string.ok, null)
444 .show();
445 return false;
446 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700447 }
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800448
449 // Always let the preference setting proceed.
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700450 return true;
451 }
452
453 @Override
454 public void onDialogClosed(EditPhoneNumberPreference preference, int buttonClicked) {
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800455 if (DBG) log("onDialogClosed: Button clicked is " + buttonClicked);
456
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700457 if (buttonClicked == DialogInterface.BUTTON_NEGATIVE) {
458 return;
459 }
460
461 if (preference == mSubMenuVoicemailSettings) {
Andrew Leee438b312014-10-29 16:59:15 -0700462 VoicemailProviderSettings newSettings = new VoicemailProviderSettings(
463 mSubMenuVoicemailSettings.getPhoneNumber(),
464 VoicemailProviderSettings.NO_FORWARDING);
465 saveVoiceMailAndForwardingNumber(getCurrentVoicemailProviderKey(), newSettings);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700466 }
467 }
468
469 /**
470 * Implemented for EditPhoneNumberPreference.GetDefaultNumberListener.
471 * This method set the default values for the various
472 * EditPhoneNumberPreference dialogs.
473 */
474 @Override
475 public String onGetDefaultNumber(EditPhoneNumberPreference preference) {
476 if (preference == mSubMenuVoicemailSettings) {
477 // update the voicemail number field, which takes care of the
478 // mSubMenuVoicemailSettings itself, so we should return null.
479 if (DBG) log("updating default for voicemail dialog");
480 updateVoiceNumberField();
481 return null;
482 }
483
484 String vmDisplay = mPhone.getVoiceMailNumber();
485 if (TextUtils.isEmpty(vmDisplay)) {
486 // if there is no voicemail number, we just return null to
487 // indicate no contribution.
488 return null;
489 }
490
491 // Return the voicemail number prepended with "VM: "
492 if (DBG) log("updating default for call forwarding dialogs");
493 return getString(R.string.voicemail_abbreviated) + " " + vmDisplay;
494 }
495
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700496 private void switchToPreviousVoicemailProvider() {
497 if (DBG) log("switchToPreviousVoicemailProvider " + mPreviousVMProviderKey);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700498
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800499 if (mPreviousVMProviderKey == null) {
500 return;
501 }
502
503 if (mVMChangeCompletedSuccessfully || mFwdChangesRequireRollback) {
Andrew Lee84024342014-11-06 23:37:09 -0800504 showDialogIfForeground(VoicemailDialogUtil.VM_REVERTING_DIALOG);
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800505 final VoicemailProviderSettings prevSettings =
506 mVmProviderSettingsUtil.load(mPreviousVMProviderKey);
507 if (prevSettings == null) {
508 Log.e(LOG_TAG, "VoicemailProviderSettings for the key \""
509 + mPreviousVMProviderKey + "\" is null but should be loaded.");
510 }
511
512 if (mVMChangeCompletedSuccessfully) {
513 mNewVMNumber = prevSettings.getVoicemailNumber();
514 Log.i(LOG_TAG, "VM change is already completed successfully."
515 + "Have to revert VM back to " + mNewVMNumber + " again.");
516 mPhone.setVoiceMailNumber(
517 mPhone.getVoiceMailAlphaTag().toString(),
518 mNewVMNumber,
519 Message.obtain(mRevertOptionComplete, EVENT_VOICEMAIL_CHANGED));
520 }
521
522 if (mFwdChangesRequireRollback) {
523 Log.i(LOG_TAG, "Requested to rollback forwarding changes.");
524
525 final CallForwardInfo[] prevFwdSettings = prevSettings.getForwardingSettings();
526 if (prevFwdSettings != null) {
527 Map<Integer, AsyncResult> results = mForwardingChangeResults;
528 resetForwardingChangeState();
529 for (int i = 0; i < prevFwdSettings.length; i++) {
530 CallForwardInfo fi = prevFwdSettings[i];
531 if (DBG) log("Reverting fwd #: " + i + ": " + fi.toString());
532 // Only revert the settings for which the update succeeded.
533 AsyncResult result = results.get(fi.reason);
534 if (result != null && result.exception == null) {
535 mExpectedChangeResultReasons.add(fi.reason);
536 CallForwardInfoUtil.setCallForwardingOption(mPhone, fi,
537 mRevertOptionComplete.obtainMessage(
538 EVENT_FORWARDING_CHANGED, i, 0));
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700539 }
540 }
541 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700542 }
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800543 } else {
544 if (DBG) log("No need to revert");
545 onRevertDone();
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700546 }
547 }
548
549 private void onRevertDone() {
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800550 if (DBG) log("onRevertDone: Changing provider key back to " + mPreviousVMProviderKey);
551
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700552 updateVMPreferenceWidgets(mPreviousVMProviderKey);
553 updateVoiceNumberField();
554 if (mVMOrFwdSetError != 0) {
Andrew Leeab082272014-11-04 15:50:42 -0800555 showDialogIfForeground(mVMOrFwdSetError);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700556 mVMOrFwdSetError = 0;
557 }
558 }
559
560 @Override
561 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
562 if (DBG) {
563 log("onActivityResult: requestCode: " + requestCode
564 + ", resultCode: " + resultCode
565 + ", data: " + data);
566 }
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800567
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700568 // there are cases where the contact picker may end up sending us more than one
569 // request. We want to ignore the request if we're not in the correct state.
570 if (requestCode == VOICEMAIL_PROVIDER_CFG_ID) {
571 boolean failure = false;
572
573 // No matter how the processing of result goes lets clear the flag
574 if (DBG) log("mVMProviderSettingsForced: " + mVMProviderSettingsForced);
575 final boolean isVMProviderSettingsForced = mVMProviderSettingsForced;
576 mVMProviderSettingsForced = false;
577
578 String vmNum = null;
579 if (resultCode != RESULT_OK) {
580 if (DBG) log("onActivityResult: vm provider cfg result not OK.");
581 failure = true;
582 } else {
583 if (data == null) {
584 if (DBG) log("onActivityResult: vm provider cfg result has no data");
585 failure = true;
586 } else {
587 if (data.getBooleanExtra(SIGNOUT_EXTRA, false)) {
588 if (DBG) log("Provider requested signout");
589 if (isVMProviderSettingsForced) {
590 if (DBG) log("Going back to previous provider on signout");
591 switchToPreviousVoicemailProvider();
592 } else {
593 final String victim = getCurrentVoicemailProviderKey();
594 if (DBG) log("Relaunching activity and ignoring " + victim);
595 Intent i = new Intent(ACTION_ADD_VOICEMAIL);
596 i.putExtra(IGNORE_PROVIDER_EXTRA, victim);
597 i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
598 this.startActivity(i);
599 }
600 return;
601 }
602 vmNum = data.getStringExtra(VM_NUMBER_EXTRA);
603 if (vmNum == null || vmNum.length() == 0) {
604 if (DBG) log("onActivityResult: vm provider cfg result has no vmnum");
605 failure = true;
606 }
607 }
608 }
609 if (failure) {
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800610 if (DBG) log("Failure in return from voicemail provider.");
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700611 if (isVMProviderSettingsForced) {
612 switchToPreviousVoicemailProvider();
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700613 }
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800614
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700615 return;
616 }
617 mChangingVMorFwdDueToProviderChange = isVMProviderSettingsForced;
618 final String fwdNum = data.getStringExtra(FWD_NUMBER_EXTRA);
619
Santos Cordonda120f42014-08-06 04:44:34 -0700620 // TODO: It would be nice to load the current network setting for this and
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700621 // send it to the provider when it's config is invoked so it can use this as default
622 final int fwdNumTime = data.getIntExtra(FWD_NUMBER_TIME_EXTRA, 20);
623
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800624 if (DBG) log("onActivityResult: cfg result has forwarding number " + fwdNum);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700625 saveVoiceMailAndForwardingNumber(getCurrentVoicemailProviderKey(),
Andrew Leeb490d732014-10-27 15:00:41 -0700626 new VoicemailProviderSettings(vmNum, fwdNum, fwdNumTime));
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700627 return;
628 }
629
630 if (requestCode == VOICEMAIL_PREF_ID) {
631 if (resultCode != RESULT_OK) {
632 if (DBG) log("onActivityResult: contact picker result not OK.");
633 return;
634 }
635
636 Cursor cursor = null;
637 try {
638 cursor = getContentResolver().query(data.getData(),
639 NUM_PROJECTION, null, null, null);
640 if ((cursor == null) || (!cursor.moveToFirst())) {
641 if (DBG) log("onActivityResult: bad contact data, no results found.");
642 return;
643 }
644 mSubMenuVoicemailSettings.onPickActivityResult(cursor.getString(0));
645 return;
646 } finally {
647 if (cursor != null) {
648 cursor.close();
649 }
650 }
651 }
652
653 super.onActivityResult(requestCode, resultCode, data);
654 }
655
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700656 /**
657 * Wrapper around showDialog() that will silently do nothing if we're
658 * not in the foreground.
659 *
660 * This is useful here because most of the dialogs we display from
661 * this class are triggered by asynchronous events (like
662 * success/failure messages from the telephony layer) and it's
663 * possible for those events to come in even after the user has gone
664 * to a different screen.
665 */
666 // TODO: this is too brittle: it's still easy to accidentally add new
667 // code here that calls showDialog() directly (which will result in a
668 // WindowManager$BadTokenException if called after the activity has
669 // been stopped.)
670 //
671 // It would be cleaner to do the "if (mForeground)" check in one
672 // central place, maybe by using a single Handler for all asynchronous
673 // events (and have *that* discard events if we're not in the
674 // foreground.)
675 //
676 // Unfortunately it's not that simple, since we sometimes need to do
677 // actual work to handle these events whether or not we're in the
678 // foreground (see the Handler code in mSetOptionComplete for
679 // example.)
Andrew Leeab082272014-11-04 15:50:42 -0800680 //
681 // TODO: It's a bit worrisome that we don't do anything in error cases when we're not in the
682 // foreground. Consider displaying a toast instead.
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700683 private void showDialogIfForeground(int id) {
684 if (mForeground) {
685 showDialog(id);
686 }
687 }
688
689 private void dismissDialogSafely(int id) {
690 try {
691 dismissDialog(id);
692 } catch (IllegalArgumentException e) {
693 // This is expected in the case where we were in the background
694 // at the time we would normally have shown the dialog, so we didn't
695 // show it.
696 }
697 }
698
Andrew Leeb490d732014-10-27 15:00:41 -0700699 private void saveVoiceMailAndForwardingNumber(
700 String key, VoicemailProviderSettings newSettings) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700701 if (DBG) log("saveVoiceMailAndForwardingNumber: " + newSettings.toString());
Andrew Leeb490d732014-10-27 15:00:41 -0700702 mNewVMNumber = newSettings.getVoicemailNumber();
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800703 mNewVMNumber = (mNewVMNumber == null) ? "" : mNewVMNumber;
Andrew Leeb490d732014-10-27 15:00:41 -0700704 mNewFwdSettings = newSettings.getForwardingSettings();
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700705
706 // No fwd settings on CDMA
707 if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
708 if (DBG) log("ignoring forwarding setting since this is CDMA phone");
Andrew Leeb490d732014-10-27 15:00:41 -0700709 mNewFwdSettings = VoicemailProviderSettings.NO_FORWARDING;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700710 }
711
Andrew Leee3c15212014-10-28 13:12:55 -0700712 // Throw a warning if the voicemail is the same and we did not change forwarding.
Andrew Leeb490d732014-10-27 15:00:41 -0700713 if (mNewVMNumber.equals(mOldVmNumber)
714 && mNewFwdSettings == VoicemailProviderSettings.NO_FORWARDING) {
Andrew Lee84024342014-11-06 23:37:09 -0800715 showDialogIfForeground(VoicemailDialogUtil.VM_NOCHANGE_ERROR_DIALOG);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700716 return;
717 }
718
Andrew Lee88b51e22014-10-29 15:48:51 -0700719 mVmProviderSettingsUtil.save(key, newSettings);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700720 mVMChangeCompletedSuccessfully = false;
721 mFwdChangesRequireRollback = false;
722 mVMOrFwdSetError = 0;
723 if (!key.equals(mPreviousVMProviderKey)) {
724 mReadingSettingsForDefaultProvider =
725 mPreviousVMProviderKey.equals(DEFAULT_VM_PROVIDER_KEY);
726 if (DBG) log("Reading current forwarding settings");
Andrew Leeb490d732014-10-27 15:00:41 -0700727 int numSettingsReasons = VoicemailProviderSettings.FORWARDING_SETTINGS_REASONS.length;
728 mForwardingReadResults = new CallForwardInfo[numSettingsReasons];
729 for (int i = 0; i < mForwardingReadResults.length; i++) {
730 mPhone.getCallForwardingOption(
731 VoicemailProviderSettings.FORWARDING_SETTINGS_REASONS[i],
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700732 mGetOptionComplete.obtainMessage(EVENT_FORWARDING_GET_COMPLETED, i, 0));
733 }
Andrew Lee84024342014-11-06 23:37:09 -0800734 showDialogIfForeground(VoicemailDialogUtil.VM_FWD_READING_DIALOG);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700735 } else {
736 saveVoiceMailAndForwardingNumberStage2();
737 }
738 }
739
740 private final Handler mGetOptionComplete = new Handler() {
741 @Override
742 public void handleMessage(Message msg) {
743 AsyncResult result = (AsyncResult) msg.obj;
744 switch (msg.what) {
745 case EVENT_FORWARDING_GET_COMPLETED:
746 handleForwardingSettingsReadResult(result, msg.arg1);
747 break;
748 }
749 }
750 };
751
752 private void handleForwardingSettingsReadResult(AsyncResult ar, int idx) {
753 if (DBG) Log.d(LOG_TAG, "handleForwardingSettingsReadResult: " + idx);
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800754
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700755 Throwable error = null;
756 if (ar.exception != null) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700757 error = ar.exception;
Andrew Lee1af6cf72014-11-04 17:35:26 -0800758 if (DBG) Log.d(LOG_TAG, "FwdRead: ar.exception=" + error.getMessage());
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700759 }
760 if (ar.userObj instanceof Throwable) {
Andrew Lee1af6cf72014-11-04 17:35:26 -0800761 error = (Throwable) ar.userObj;
762 if (DBG) Log.d(LOG_TAG, "FwdRead: userObj=" + error.getMessage());
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700763 }
764
765 // We may have already gotten an error and decided to ignore the other results.
766 if (mForwardingReadResults == null) {
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800767 if (DBG) Log.d(LOG_TAG, "Ignoring fwd reading result: " + idx);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700768 return;
769 }
770
771 // In case of error ignore other results, show an error dialog
772 if (error != null) {
773 if (DBG) Log.d(LOG_TAG, "Error discovered for fwd read : " + idx);
774 mForwardingReadResults = null;
Andrew Lee84024342014-11-06 23:37:09 -0800775 dismissDialogSafely(VoicemailDialogUtil.VM_FWD_READING_DIALOG);
776 showDialogIfForeground(VoicemailDialogUtil.FWD_GET_RESPONSE_ERROR_DIALOG);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700777 return;
778 }
779
Andrew Lee1af6cf72014-11-04 17:35:26 -0800780 // Get the forwarding info.
781 mForwardingReadResults[idx] = CallForwardInfoUtil.getCallForwardInfo(
782 (CallForwardInfo[]) ar.result,
783 VoicemailProviderSettings.FORWARDING_SETTINGS_REASONS[idx]);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700784
785 // Check if we got all the results already
786 boolean done = true;
787 for (int i = 0; i < mForwardingReadResults.length; i++) {
788 if (mForwardingReadResults[i] == null) {
789 done = false;
790 break;
791 }
792 }
Andrew Lee1af6cf72014-11-04 17:35:26 -0800793
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700794 if (done) {
795 if (DBG) Log.d(LOG_TAG, "Done receiving fwd info");
Andrew Lee84024342014-11-06 23:37:09 -0800796 dismissDialogSafely(VoicemailDialogUtil.VM_FWD_READING_DIALOG);
Andrew Lee1af6cf72014-11-04 17:35:26 -0800797
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700798 if (mReadingSettingsForDefaultProvider) {
Andrew Lee88b51e22014-10-29 15:48:51 -0700799 mVmProviderSettingsUtil.save(DEFAULT_VM_PROVIDER_KEY,
800 new VoicemailProviderSettings(this.mOldVmNumber, mForwardingReadResults));
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700801 mReadingSettingsForDefaultProvider = false;
802 }
803 saveVoiceMailAndForwardingNumberStage2();
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700804 }
805 }
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800806
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700807 private void resetForwardingChangeState() {
808 mForwardingChangeResults = new HashMap<Integer, AsyncResult>();
809 mExpectedChangeResultReasons = new HashSet<Integer>();
810 }
811
812 // Called after we are done saving the previous forwarding settings if
813 // we needed.
814 private void saveVoiceMailAndForwardingNumberStage2() {
815 mForwardingChangeResults = null;
816 mVoicemailChangeResult = null;
Andrew Leeb490d732014-10-27 15:00:41 -0700817 if (mNewFwdSettings != VoicemailProviderSettings.NO_FORWARDING) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700818 resetForwardingChangeState();
819 for (int i = 0; i < mNewFwdSettings.length; i++) {
820 CallForwardInfo fi = mNewFwdSettings[i];
Andrew Lee1af6cf72014-11-04 17:35:26 -0800821 CallForwardInfo fiForReason =
822 CallForwardInfoUtil.infoForReason(mForwardingReadResults, fi.reason);
823 final boolean doUpdate = CallForwardInfoUtil.isUpdateRequired(fiForReason, fi);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700824
825 if (doUpdate) {
826 if (DBG) log("Setting fwd #: " + i + ": " + fi.toString());
827 mExpectedChangeResultReasons.add(i);
828
Andrew Lee1af6cf72014-11-04 17:35:26 -0800829 CallForwardInfoUtil.setCallForwardingOption(mPhone, fi,
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700830 mSetOptionComplete.obtainMessage(
831 EVENT_FORWARDING_CHANGED, fi.reason, 0));
832 }
833 }
Andrew Lee84024342014-11-06 23:37:09 -0800834 showDialogIfForeground(VoicemailDialogUtil.VM_FWD_SAVING_DIALOG);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700835 } else {
836 if (DBG) log("Not touching fwd #");
837 setVMNumberWithCarrier();
838 }
839 }
840
841 private void setVMNumberWithCarrier() {
842 if (DBG) log("save voicemail #: " + mNewVMNumber);
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800843
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700844 mPhone.setVoiceMailNumber(
845 mPhone.getVoiceMailAlphaTag().toString(),
846 mNewVMNumber,
847 Message.obtain(mSetOptionComplete, EVENT_VOICEMAIL_CHANGED));
848 }
849
850 /**
851 * Callback to handle option update completions
852 */
853 private final Handler mSetOptionComplete = new Handler() {
854 @Override
855 public void handleMessage(Message msg) {
856 AsyncResult result = (AsyncResult) msg.obj;
857 boolean done = false;
858 switch (msg.what) {
859 case EVENT_VOICEMAIL_CHANGED:
860 mVoicemailChangeResult = result;
Andrew Leee438b312014-10-29 16:59:15 -0700861 mVMChangeCompletedSuccessfully = isVmChangeSuccess();
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700862 done = true;
863 break;
864 case EVENT_FORWARDING_CHANGED:
865 mForwardingChangeResults.put(msg.arg1, result);
866 if (result.exception != null) {
867 Log.w(LOG_TAG, "Error in setting fwd# " + msg.arg1 + ": " +
868 result.exception.getMessage());
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700869 }
Andrew Leee438b312014-10-29 16:59:15 -0700870 if (isForwardingCompleted()) {
871 if (isFwdChangeSuccess()) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700872 if (DBG) log("Overall fwd changes completed ok, starting vm change");
873 setVMNumberWithCarrier();
874 } else {
875 Log.w(LOG_TAG, "Overall fwd changes completed in failure. " +
876 "Check if we need to try rollback for some settings.");
877 mFwdChangesRequireRollback = false;
878 Iterator<Map.Entry<Integer,AsyncResult>> it =
879 mForwardingChangeResults.entrySet().iterator();
880 while (it.hasNext()) {
881 Map.Entry<Integer,AsyncResult> entry = it.next();
882 if (entry.getValue().exception == null) {
883 // If at least one succeeded we have to revert
884 Log.i(LOG_TAG, "Rollback will be required");
885 mFwdChangesRequireRollback = true;
886 break;
887 }
888 }
889 if (!mFwdChangesRequireRollback) {
890 Log.i(LOG_TAG, "No rollback needed.");
891 }
892 done = true;
893 }
894 }
895 break;
896 default:
897 // TODO: should never reach this, may want to throw exception
898 }
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800899
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700900 if (done) {
901 if (DBG) log("All VM provider related changes done");
902 if (mForwardingChangeResults != null) {
Andrew Lee84024342014-11-06 23:37:09 -0800903 dismissDialogSafely(VoicemailDialogUtil.VM_FWD_SAVING_DIALOG);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700904 }
Andrew Leee438b312014-10-29 16:59:15 -0700905 handleSetVmOrFwdMessage();
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700906 }
907 }
908 };
909
910 /**
911 * Callback to handle option revert completions
912 */
913 private final Handler mRevertOptionComplete = new Handler() {
914 @Override
915 public void handleMessage(Message msg) {
916 AsyncResult result = (AsyncResult) msg.obj;
917 switch (msg.what) {
918 case EVENT_VOICEMAIL_CHANGED:
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700919 if (DBG) log("VM revert complete msg");
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800920 mVoicemailChangeResult = result;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700921 break;
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800922
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700923 case EVENT_FORWARDING_CHANGED:
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800924 if (DBG) log("FWD revert complete msg ");
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700925 mForwardingChangeResults.put(msg.arg1, result);
926 if (result.exception != null) {
927 if (DBG) log("Error in reverting fwd# " + msg.arg1 + ": " +
928 result.exception.getMessage());
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700929 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700930 break;
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800931
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700932 default:
933 // TODO: should never reach this, may want to throw exception
934 }
Andrew Lee4ddb9bb2014-11-05 15:03:20 -0800935
936 final boolean done = (!mVMChangeCompletedSuccessfully || mVoicemailChangeResult != null)
937 && (!mFwdChangesRequireRollback || isForwardingCompleted());
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700938 if (done) {
939 if (DBG) log("All VM reverts done");
Andrew Lee84024342014-11-06 23:37:09 -0800940 dismissDialogSafely(VoicemailDialogUtil.VM_REVERTING_DIALOG);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700941 onRevertDone();
942 }
943 }
944 };
945
946 /**
Andrew Leee438b312014-10-29 16:59:15 -0700947 * Return true if there is a change result for every reason for which we expect a result.
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700948 */
Andrew Leee438b312014-10-29 16:59:15 -0700949 private boolean isForwardingCompleted() {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700950 if (mForwardingChangeResults == null) {
Andrew Leee438b312014-10-29 16:59:15 -0700951 return true;
952 }
953
954 for (Integer reason : mExpectedChangeResultReasons) {
955 if (mForwardingChangeResults.get(reason) == null) {
956 return false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700957 }
958 }
Andrew Leee438b312014-10-29 16:59:15 -0700959
960 return true;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700961 }
Andrew Leee438b312014-10-29 16:59:15 -0700962
963 private boolean isFwdChangeSuccess() {
964 if (mForwardingChangeResults == null) {
965 return true;
966 }
967
968 for (AsyncResult result : mForwardingChangeResults.values()) {
969 Throwable exception = result.exception;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700970 if (exception != null) {
Andrew Leee438b312014-10-29 16:59:15 -0700971 String msg = exception.getMessage();
972 msg = (msg != null) ? msg : "";
973 Log.w(LOG_TAG, "Failed to change forwarding setting. Reason: " + msg);
974 return false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700975 }
976 }
Andrew Leee438b312014-10-29 16:59:15 -0700977 return true;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700978 }
979
Andrew Leee438b312014-10-29 16:59:15 -0700980 private boolean isVmChangeSuccess() {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700981 if (mVoicemailChangeResult.exception != null) {
Andrew Leee438b312014-10-29 16:59:15 -0700982 String msg = mVoicemailChangeResult.exception.getMessage();
983 msg = (msg != null) ? msg : "";
984 Log.w(LOG_TAG, "Failed to change voicemail. Reason: " + msg);
985 return false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700986 }
Andrew Leee438b312014-10-29 16:59:15 -0700987 return true;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700988 }
989
Andrew Leee438b312014-10-29 16:59:15 -0700990 private void handleSetVmOrFwdMessage() {
991 if (DBG) log("handleSetVMMessage: set VM request complete");
992
993 if (!isFwdChangeSuccess()) {
Andrew Lee84024342014-11-06 23:37:09 -0800994 handleVmOrFwdSetError(VoicemailDialogUtil.FWD_SET_RESPONSE_ERROR_DIALOG);
Andrew Leee438b312014-10-29 16:59:15 -0700995 } else if (!isVmChangeSuccess()) {
Andrew Lee84024342014-11-06 23:37:09 -0800996 handleVmOrFwdSetError(VoicemailDialogUtil.VM_RESPONSE_ERROR_DIALOG);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700997 } else {
Andrew Lee84024342014-11-06 23:37:09 -0800998 handleVmAndFwdSetSuccess(VoicemailDialogUtil.VM_CONFIRM_DIALOG);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700999 }
1000 }
1001
1002 /**
1003 * Called when Voicemail Provider or its forwarding settings failed. Rolls back partly made
1004 * changes to those settings and show "failure" dialog.
1005 *
Andrew Leeab082272014-11-04 15:50:42 -08001006 * @param dialogId ID of the dialog to show for the specific error case. Either
Andrew Lee84024342014-11-06 23:37:09 -08001007 * {@link #FWD_SET_RESPONSE_ERROR_DIALOG} or {@link #VM_RESPONSE_ERROR_DIALOG}
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001008 */
Andrew Leeab082272014-11-04 15:50:42 -08001009 private void handleVmOrFwdSetError(int dialogId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001010 if (mChangingVMorFwdDueToProviderChange) {
Andrew Leeab082272014-11-04 15:50:42 -08001011 mVMOrFwdSetError = dialogId;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001012 mChangingVMorFwdDueToProviderChange = false;
1013 switchToPreviousVoicemailProvider();
1014 return;
1015 }
1016 mChangingVMorFwdDueToProviderChange = false;
Andrew Leeab082272014-11-04 15:50:42 -08001017 showDialogIfForeground(dialogId);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001018 updateVoiceNumberField();
1019 }
1020
1021 /**
1022 * Called when Voicemail Provider and its forwarding settings were successfully finished.
1023 * This updates a bunch of variables and show "success" dialog.
1024 */
Andrew Leeab082272014-11-04 15:50:42 -08001025 private void handleVmAndFwdSetSuccess(int dialogId) {
Andrew Lee4ddb9bb2014-11-05 15:03:20 -08001026 if (DBG) log("handleVmAndFwdSetSuccess: key is " + getCurrentVoicemailProviderKey());
1027
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001028 mPreviousVMProviderKey = getCurrentVoicemailProviderKey();
1029 mChangingVMorFwdDueToProviderChange = false;
Andrew Leeab082272014-11-04 15:50:42 -08001030 showDialogIfForeground(dialogId);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001031 updateVoiceNumberField();
1032 }
1033
1034 /**
1035 * Update the voicemail number from what we've recorded on the sim.
1036 */
1037 private void updateVoiceNumberField() {
Andrew Lee2d5d1a42014-11-05 12:34:14 -08001038 if (DBG) log("updateVoiceNumberField()");
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001039
1040 mOldVmNumber = mPhone.getVoiceMailNumber();
Andrew Lee2d5d1a42014-11-05 12:34:14 -08001041 if (TextUtils.isEmpty(mOldVmNumber)) {
1042 mSubMenuVoicemailSettings.setPhoneNumber("");
1043 mSubMenuVoicemailSettings.setSummary(getString(R.string.voicemail_number_not_set));
1044 } else {
1045 mSubMenuVoicemailSettings.setPhoneNumber(mOldVmNumber);
1046 mSubMenuVoicemailSettings.setSummary(mOldVmNumber);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001047 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001048 }
1049
1050 /*
1051 * Helper Methods for Activity class.
1052 * The initial query commands are split into two pieces now
1053 * for individual expansion. This combined with the ability
1054 * to cancel queries allows for a much better user experience,
1055 * and also ensures that the user only waits to update the
1056 * data that is relevant.
1057 */
1058
1059 @Override
1060 protected void onPrepareDialog(int id, Dialog dialog) {
1061 super.onPrepareDialog(id, dialog);
1062 mCurrentDialogId = id;
1063 }
1064
1065 // dialog creation method, called by showDialog()
1066 @Override
Andrew Lee84024342014-11-06 23:37:09 -08001067 protected Dialog onCreateDialog(int dialogId) {
1068 return VoicemailDialogUtil.getDialog(this, dialogId);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001069 }
1070
1071 // This is a method implemented for DialogInterface.OnClickListener.
1072 // Used with the error dialog to close the app, voicemail dialog to just dismiss.
1073 // Close button is mapped to BUTTON_POSITIVE for the errors that close the activity,
1074 // while those that are mapped to BUTTON_NEUTRAL only move the preference focus.
1075 public void onClick(DialogInterface dialog, int which) {
Andrew Lee4ddb9bb2014-11-05 15:03:20 -08001076 if (DBG) log("onClick: button clicked is " + which);
1077
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001078 dialog.dismiss();
1079 switch (which){
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001080 case DialogInterface.BUTTON_NEGATIVE:
Andrew Lee84024342014-11-06 23:37:09 -08001081 if (mCurrentDialogId == VoicemailDialogUtil.FWD_GET_RESPONSE_ERROR_DIALOG) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001082 // We failed to get current forwarding settings and the user
1083 // does not wish to continue.
1084 switchToPreviousVoicemailProvider();
1085 }
1086 break;
1087 case DialogInterface.BUTTON_POSITIVE:
Andrew Lee84024342014-11-06 23:37:09 -08001088 if (mCurrentDialogId == VoicemailDialogUtil.FWD_GET_RESPONSE_ERROR_DIALOG) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001089 // We failed to get current forwarding settings but the user
1090 // wishes to continue changing settings to the new vm provider
1091 saveVoiceMailAndForwardingNumberStage2();
1092 } else {
1093 finish();
1094 }
1095 return;
1096 default:
1097 // just let the dialog close and go back to the input
1098 }
Andrew Lee4ddb9bb2014-11-05 15:03:20 -08001099
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001100 // In all dialogs, all buttons except BUTTON_POSITIVE lead to the end of user interaction
1101 // with settings UI. If we were called to explicitly configure voice mail then
1102 // we finish the settings activity here to come back to whatever the user was doing.
1103 if (getIntent().getAction().equals(ACTION_ADD_VOICEMAIL)) {
1104 finish();
1105 }
1106 }
1107
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001108 /*
1109 * Activity class methods
1110 */
1111
1112 @Override
1113 protected void onCreate(Bundle icicle) {
1114 super.onCreate(icicle);
Andrew Lee4ddb9bb2014-11-05 15:03:20 -08001115 if (DBG) log("onCreate: Intent is " + getIntent());
1116
Jay Shraunerc2684732014-11-12 12:10:37 -08001117 // Make sure we are running as the primary user.
1118 if (UserHandle.myUserId() != UserHandle.USER_OWNER) {
1119 Toast.makeText(this, R.string.call_settings_primary_user_only,
1120 Toast.LENGTH_SHORT).show();
1121 finish();
1122 return;
1123 }
1124
Tyler Gunnbaee2952014-09-10 16:01:02 -07001125 mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
Andrew Lee88b51e22014-10-29 15:48:51 -07001126 mVmProviderSettingsUtil = new VoicemailProviderSettingsUtil(getApplicationContext());
Tyler Gunnbaee2952014-09-10 16:01:02 -07001127
Tyler Gunnbaee2952014-09-10 16:01:02 -07001128 // Show the voicemail preference in onResume if the calling intent specifies the
1129 // ACTION_ADD_VOICEMAIL action.
1130 mShowVoicemailPreference = (icicle == null) &&
Jay Shraunerbe2fb262014-11-11 15:19:58 -08001131 TextUtils.equals(getIntent().getAction(), ACTION_ADD_VOICEMAIL);
Andrew Lee5ed870c2014-10-29 11:47:49 -07001132
1133 mSubscriptionInfoHelper = new SubscriptionInfoHelper(getIntent());
1134 mSubscriptionInfoHelper.setActionBarTitle(
1135 getActionBar(), getResources(), R.string.call_settings_with_label);
Andrew Lee1479dd12014-11-06 23:06:32 -08001136 mPhone = mSubscriptionInfoHelper.getPhone();
Andrew Lee5ed870c2014-10-29 11:47:49 -07001137 }
Tyler Gunnbaee2952014-09-10 16:01:02 -07001138
1139 private void initPhoneAccountPreferences() {
Andrew Leece8ae2a2014-09-10 10:41:48 -07001140 mPhoneAccountSettingsPreference = findPreference(PHONE_ACCOUNT_SETTINGS_KEY);
Tyler Gunnbaee2952014-09-10 16:01:02 -07001141
Tyler Gunn4d45d1c2014-09-12 22:17:53 -07001142 TelecomManager telecomManager = TelecomManager.from(this);
Andrew Lee93c345f2014-10-27 15:25:07 -07001143 TelephonyManager telephonyManager =
1144 (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
Tyler Gunnbaee2952014-09-10 16:01:02 -07001145
Andrew Lee93c345f2014-10-27 15:25:07 -07001146 if ((telecomManager.getSimCallManagers().isEmpty() && !SipUtil.isVoipSupported(this))
1147 || telephonyManager.getPhoneCount() > 1) {
Andrew Leece8ae2a2014-09-10 10:41:48 -07001148 getPreferenceScreen().removePreference(mPhoneAccountSettingsPreference);
Tyler Gunnbaee2952014-09-10 16:01:02 -07001149 }
1150 }
1151
Tyler Gunnbaee2952014-09-10 16:01:02 -07001152 @Override
1153 protected void onResume() {
1154 super.onResume();
1155 mForeground = true;
1156
1157 PreferenceScreen preferenceScreen = getPreferenceScreen();
1158 if (preferenceScreen != null) {
1159 preferenceScreen.removeAll();
1160 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001161
1162 addPreferencesFromResource(R.xml.call_feature_setting);
Andrew Lee5ed870c2014-10-29 11:47:49 -07001163
Andrew Leedb2fe562014-09-03 15:40:43 -07001164 initPhoneAccountPreferences();
1165
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001166 PreferenceScreen prefSet = getPreferenceScreen();
Andrew Lee64a7d792014-10-15 17:38:38 -07001167 mSubMenuVoicemailSettings = (EditPhoneNumberPreference) findPreference(BUTTON_VOICEMAIL_KEY);
1168 mSubMenuVoicemailSettings.setParentActivity(this, VOICEMAIL_PREF_ID, this);
1169 mSubMenuVoicemailSettings.setDialogOnClosedListener(this);
1170 mSubMenuVoicemailSettings.setDialogTitle(R.string.voicemail_settings_number_label);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001171
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001172 mButtonDTMF = (ListPreference) findPreference(BUTTON_DTMF_KEY);
1173 mButtonAutoRetry = (CheckBoxPreference) findPreference(BUTTON_RETRY_KEY);
1174 mButtonHAC = (CheckBoxPreference) findPreference(BUTTON_HAC_KEY);
1175 mButtonTTY = (ListPreference) findPreference(BUTTON_TTY_KEY);
Andrew Lee312e8172014-10-23 17:01:36 -07001176 mEnableVideoCalling = (CheckBoxPreference) findPreference(ENABLE_VIDEO_CALLING_KEY);
Andrew Lee2170a972014-08-13 18:13:01 -07001177
Andrew Lee8d66d812014-11-24 14:54:02 -08001178 mVoicemailProviders = (ListPreference) findPreference(BUTTON_VOICEMAIL_PROVIDER_KEY);
Andrew Lee2c027892014-10-29 11:29:54 -07001179 mVoicemailProviders.setOnPreferenceChangeListener(this);
Andrew Lee8d66d812014-11-24 14:54:02 -08001180
Andrew Lee2c027892014-10-29 11:29:54 -07001181 mVoicemailSettingsScreen =
1182 (PreferenceScreen) findPreference(VOICEMAIL_SETTING_SCREEN_PREF_KEY);
1183 mVoicemailSettings = (PreferenceScreen)findPreference(BUTTON_VOICEMAIL_SETTING_KEY);
Andrew Lee8d66d812014-11-24 14:54:02 -08001184
1185 mVoicemailNotificationVibrate = (CheckBoxPreference) findPreference(
1186 getResources().getString(R.string.voicemail_notification_vibrate_key));
1187 mVoicemailNotificationVibrate.setOnPreferenceChangeListener(this);
1188
Andrew Lee2c027892014-10-29 11:29:54 -07001189 initVoiceMailProviders();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001190
Andrew Lee64a7d792014-10-15 17:38:38 -07001191 if (getResources().getBoolean(R.bool.dtmf_type_enabled)) {
1192 mButtonDTMF.setOnPreferenceChangeListener(this);
1193 int dtmf = Settings.System.getInt(getContentResolver(),
1194 Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, Constants.DTMF_TONE_TYPE_NORMAL);
1195 mButtonDTMF.setValueIndex(dtmf);
1196 } else {
1197 prefSet.removePreference(mButtonDTMF);
1198 mButtonDTMF = null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001199 }
1200
Andrew Lee64a7d792014-10-15 17:38:38 -07001201 if (getResources().getBoolean(R.bool.auto_retry_enabled)) {
1202 mButtonAutoRetry.setOnPreferenceChangeListener(this);
1203 int autoretry = Settings.Global.getInt(
1204 getContentResolver(), Settings.Global.CALL_AUTO_RETRY, 0);
1205 mButtonAutoRetry.setChecked(autoretry != 0);
1206 } else {
1207 prefSet.removePreference(mButtonAutoRetry);
1208 mButtonAutoRetry = null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001209 }
1210
Andrew Lee64a7d792014-10-15 17:38:38 -07001211 if (getResources().getBoolean(R.bool.hac_enabled)) {
1212 mButtonHAC.setOnPreferenceChangeListener(this);
1213 int hac = Settings.System.getInt(getContentResolver(), Settings.System.HEARING_AID, 0);
1214 mButtonHAC.setChecked(hac != 0);
1215 } else {
1216 prefSet.removePreference(mButtonHAC);
1217 mButtonHAC = null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001218 }
1219
Andrew Lee64a7d792014-10-15 17:38:38 -07001220 TelecomManager telecomManager = TelecomManager.from(this);
1221 if (telecomManager != null && telecomManager.isTtySupported()) {
1222 mButtonTTY.setOnPreferenceChangeListener(this);
1223 int settingsTtyMode = Settings.Secure.getInt(getContentResolver(),
1224 Settings.Secure.PREFERRED_TTY_MODE,
1225 TelecomManager.TTY_MODE_OFF);
1226 mButtonTTY.setValue(Integer.toString(settingsTtyMode));
1227 updatePreferredTtyModeSummary(settingsTtyMode);
1228 } else {
1229 prefSet.removePreference(mButtonTTY);
1230 mButtonTTY = null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001231 }
1232
1233 if (!getResources().getBoolean(R.bool.world_phone)) {
Andrew Lee2b36ba22014-11-05 17:08:49 -08001234 Preference cdmaOptions = prefSet.findPreference(BUTTON_CDMA_OPTIONS);
1235 prefSet.removePreference(cdmaOptions);
1236
1237 // TODO: Support MSIM for this preference option.
1238 Preference gsmOptions = prefSet.findPreference(BUTTON_GSM_UMTS_OPTIONS);
1239 prefSet.removePreference(gsmOptions);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001240
1241 int phoneType = mPhone.getPhoneType();
Andrew Lee5ed870c2014-10-29 11:47:49 -07001242 Preference fdnButton = prefSet.findPreference(BUTTON_FDN_KEY);
Junda Liua09d6962014-11-12 13:39:02 -08001243 boolean shouldHideCarrierSettings = Settings.Global.getInt(
1244 getContentResolver(), Settings.Global.HIDE_CARRIER_NETWORK_SETTINGS, 0) == 1;
1245 if (shouldHideCarrierSettings) {
Andrew Lee5ed870c2014-10-29 11:47:49 -07001246 prefSet.removePreference(fdnButton);
Junda Liua09d6962014-11-12 13:39:02 -08001247 if (mButtonDTMF != null) {
1248 prefSet.removePreference(mButtonDTMF);
Etan Cohen0ca1c802014-07-07 15:35:48 -07001249 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001250 } else {
Junda Liua09d6962014-11-12 13:39:02 -08001251 if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
1252 prefSet.removePreference(fdnButton);
1253
1254 if (!getResources().getBoolean(R.bool.config_voice_privacy_disable)) {
1255 addPreferencesFromResource(R.xml.cdma_call_privacy);
1256 }
1257 } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
1258 fdnButton.setIntent(mSubscriptionInfoHelper.getIntent(this, FdnSetting.class));
1259
1260 if (getResources().getBoolean(R.bool.config_additional_call_setting)) {
1261 addPreferencesFromResource(R.xml.gsm_umts_call_options);
1262
1263 Preference callForwardingPref = prefSet.findPreference(CALL_FORWARDING_KEY);
1264 callForwardingPref.setIntent(mSubscriptionInfoHelper.getIntent(
1265 this, GsmUmtsCallForwardOptions.class));
1266
1267 Preference additionalGsmSettingsPref =
1268 prefSet.findPreference(ADDITIONAL_GSM_SETTINGS_KEY);
1269 additionalGsmSettingsPref.setIntent(mSubscriptionInfoHelper.getIntent(
1270 this, GsmUmtsAdditionalCallOptions.class));
1271 }
1272 } else {
1273 throw new IllegalStateException("Unexpected phone type: " + phoneType);
1274 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001275 }
1276 }
1277
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001278 // check the intent that started this activity and pop up the voicemail
1279 // dialog if we've been asked to.
1280 // If we have at least one non default VM provider registered then bring up
1281 // the selection for the VM provider, otherwise bring up a VM number dialog.
1282 // We only bring up the dialog the first time we are called (not after orientation change)
Andrew Lee2c027892014-10-29 11:29:54 -07001283 if (mShowVoicemailPreference) {
Tyler Gunnbaee2952014-09-10 16:01:02 -07001284 if (DBG) {
1285 log("ACTION_ADD_VOICEMAIL Intent is thrown. current VM data size: "
1286 + mVMProvidersData.size());
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001287 }
Tyler Gunnbaee2952014-09-10 16:01:02 -07001288 if (mVMProvidersData.size() > 1) {
1289 simulatePreferenceClick(mVoicemailProviders);
1290 } else {
1291 onPreferenceChange(mVoicemailProviders, DEFAULT_VM_PROVIDER_KEY);
1292 mVoicemailProviders.setValue(DEFAULT_VM_PROVIDER_KEY);
1293 }
1294 mShowVoicemailPreference = false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001295 }
Tyler Gunnbaee2952014-09-10 16:01:02 -07001296
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001297 updateVoiceNumberField();
1298 mVMProviderSettingsForced = false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001299
Andrew Lee8d66d812014-11-24 14:54:02 -08001300 mVoicemailNotificationVibrate.setChecked(
1301 VoicemailNotificationSettingsUtil.isVibrationEnabled(mPhone.getContext()));
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001302
Andrew Lee312e8172014-10-23 17:01:36 -07001303 if (ImsManager.isVtEnabledByPlatform(mPhone.getContext()) && ENABLE_VT_FLAG) {
1304 boolean currentValue =
1305 ImsManager.isEnhanced4gLteModeSettingEnabledByUser(mPhone.getContext())
1306 ? PhoneGlobals.getInstance().phoneMgr.isVideoCallingEnabled() : false;
1307 mEnableVideoCalling.setChecked(currentValue);
Andrew Lee77527ac2014-10-21 16:57:39 -07001308 mEnableVideoCalling.setOnPreferenceChangeListener(this);
1309 } else {
1310 prefSet.removePreference(mEnableVideoCalling);
1311 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001312 }
1313
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001314 private void handleTTYChange(Preference preference, Object objValue) {
1315 int buttonTtyMode;
1316 buttonTtyMode = Integer.valueOf((String) objValue).intValue();
1317 int settingsTtyMode = android.provider.Settings.Secure.getInt(
1318 getContentResolver(),
Sailesh Nepalbf900542014-07-15 16:18:32 -07001319 android.provider.Settings.Secure.PREFERRED_TTY_MODE,
Tyler Gunn4d45d1c2014-09-12 22:17:53 -07001320 TelecomManager.TTY_MODE_OFF);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001321 if (DBG) log("handleTTYChange: requesting set TTY mode enable (TTY) to" +
1322 Integer.toString(buttonTtyMode));
1323
1324 if (buttonTtyMode != settingsTtyMode) {
1325 switch(buttonTtyMode) {
Tyler Gunn4d45d1c2014-09-12 22:17:53 -07001326 case TelecomManager.TTY_MODE_OFF:
1327 case TelecomManager.TTY_MODE_FULL:
1328 case TelecomManager.TTY_MODE_HCO:
1329 case TelecomManager.TTY_MODE_VCO:
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001330 android.provider.Settings.Secure.putInt(getContentResolver(),
1331 android.provider.Settings.Secure.PREFERRED_TTY_MODE, buttonTtyMode);
1332 break;
1333 default:
Tyler Gunn4d45d1c2014-09-12 22:17:53 -07001334 buttonTtyMode = TelecomManager.TTY_MODE_OFF;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001335 }
1336
1337 mButtonTTY.setValue(Integer.toString(buttonTtyMode));
1338 updatePreferredTtyModeSummary(buttonTtyMode);
Tyler Gunn4d45d1c2014-09-12 22:17:53 -07001339 Intent ttyModeChanged = new Intent(TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED);
1340 ttyModeChanged.putExtra(TelecomManager.EXTRA_TTY_PREFERRED_MODE, buttonTtyMode);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001341 sendBroadcastAsUser(ttyModeChanged, UserHandle.ALL);
1342 }
1343 }
1344
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001345 private void updatePreferredTtyModeSummary(int TtyMode) {
1346 String [] txts = getResources().getStringArray(R.array.tty_mode_entries);
1347 switch(TtyMode) {
Tyler Gunn4d45d1c2014-09-12 22:17:53 -07001348 case TelecomManager.TTY_MODE_OFF:
1349 case TelecomManager.TTY_MODE_HCO:
1350 case TelecomManager.TTY_MODE_VCO:
1351 case TelecomManager.TTY_MODE_FULL:
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001352 mButtonTTY.setSummary(txts[TtyMode]);
1353 break;
1354 default:
1355 mButtonTTY.setEnabled(false);
Tyler Gunn4d45d1c2014-09-12 22:17:53 -07001356 mButtonTTY.setSummary(txts[TelecomManager.TTY_MODE_OFF]);
Sailesh Nepalbf900542014-07-15 16:18:32 -07001357 break;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001358 }
1359 }
1360
1361 private static void log(String msg) {
1362 Log.d(LOG_TAG, msg);
1363 }
1364
1365 /**
1366 * Updates the look of the VM preference widgets based on current VM provider settings.
1367 * Note that the provider name is loaded form the found activity via loadLabel in
1368 * {@link #initVoiceMailProviders()} in order for it to be localizable.
1369 */
1370 private void updateVMPreferenceWidgets(String currentProviderSetting) {
1371 final String key = currentProviderSetting;
1372 final VoiceMailProvider provider = mVMProvidersData.get(key);
1373
1374 /* This is the case when we are coming up on a freshly wiped phone and there is no
1375 persisted value for the list preference mVoicemailProviders.
1376 In this case we want to show the UI asking the user to select a voicemail provider as
1377 opposed to silently falling back to default one. */
1378 if (provider == null) {
Andrew Lee4ddb9bb2014-11-05 15:03:20 -08001379 if (DBG) log("updateVMPreferenceWidget: key: " + key + " -> null.");
1380
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001381 mVoicemailProviders.setSummary(getString(R.string.sum_voicemail_choose_provider));
1382 mVoicemailSettings.setEnabled(false);
1383 mVoicemailSettings.setIntent(null);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001384 mVoicemailNotificationVibrate.setEnabled(false);
1385 } else {
Andrew Lee4ddb9bb2014-11-05 15:03:20 -08001386 if (DBG) log("updateVMPreferenceWidget: key: " + key + " -> " + provider.toString());
1387
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001388 final String providerName = provider.name;
1389 mVoicemailProviders.setSummary(providerName);
1390 mVoicemailSettings.setEnabled(true);
1391 mVoicemailSettings.setIntent(provider.intent);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001392 mVoicemailNotificationVibrate.setEnabled(true);
1393 }
1394 }
1395
1396 /**
1397 * Enumerates existing VM providers and puts their data into the list and populates
1398 * the preference list objects with their names.
1399 * In case we are called with ACTION_ADD_VOICEMAIL intent the intent may have
1400 * an extra string called IGNORE_PROVIDER_EXTRA with "package.activityName" of the provider
1401 * which should be hidden when we bring up the list of possible VM providers to choose.
1402 */
1403 private void initVoiceMailProviders() {
1404 if (DBG) log("initVoiceMailProviders()");
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001405
1406 String providerToIgnore = null;
Andrew Leef1776d82014-11-04 14:45:02 -08001407 if (getIntent().getAction().equals(ACTION_ADD_VOICEMAIL)
1408 && getIntent().hasExtra(IGNORE_PROVIDER_EXTRA)) {
1409 providerToIgnore = getIntent().getStringExtra(IGNORE_PROVIDER_EXTRA);
1410 // Remove this provider from the list.
1411 if (!TextUtils.isEmpty(providerToIgnore)) {
1412 if (DBG) log("Found ACTION_ADD_VOICEMAIL. providerToIgnore= " + providerToIgnore);
Andrew Lee88b51e22014-10-29 15:48:51 -07001413 mVmProviderSettingsUtil.delete(providerToIgnore);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001414 }
1415 }
1416
1417 mVMProvidersData.clear();
1418
Andrew Leef1776d82014-11-04 14:45:02 -08001419 List<String> entries = new ArrayList<String>();
1420 List<String> values = new ArrayList<String>();
1421
1422 // Add default voicemail provider.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001423 final String myCarrier = getString(R.string.voicemail_default);
1424 mVMProvidersData.put(DEFAULT_VM_PROVIDER_KEY, new VoiceMailProvider(myCarrier, null));
Andrew Leef1776d82014-11-04 14:45:02 -08001425 entries.add(myCarrier);
1426 values.add(DEFAULT_VM_PROVIDER_KEY);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001427
Andrew Leef1776d82014-11-04 14:45:02 -08001428 // Add other voicemail providers.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001429 PackageManager pm = getPackageManager();
Andrew Leef1776d82014-11-04 14:45:02 -08001430 Intent intent = new Intent(ACTION_CONFIGURE_VOICEMAIL);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001431 List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001432 for (int i = 0; i < resolveInfos.size(); i++) {
1433 final ResolveInfo ri= resolveInfos.get(i);
1434 final ActivityInfo currentActivityInfo = ri.activityInfo;
Andrew Lee6214e2b2014-11-04 13:57:38 -08001435 final String key = currentActivityInfo.name;
Andrew Leef1776d82014-11-04 14:45:02 -08001436
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001437 if (key.equals(providerToIgnore)) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001438 continue;
1439 }
Andrew Leef1776d82014-11-04 14:45:02 -08001440
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001441 if (DBG) log("Loading key: " + key);
1442 final String nameForDisplay = ri.loadLabel(pm).toString();
1443 Intent providerIntent = new Intent();
1444 providerIntent.setAction(ACTION_CONFIGURE_VOICEMAIL);
Andrew Leef1776d82014-11-04 14:45:02 -08001445 providerIntent.setClassName(currentActivityInfo.packageName, currentActivityInfo.name);
1446 VoiceMailProvider vmProvider = new VoiceMailProvider(nameForDisplay, providerIntent);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001447
Andrew Leef1776d82014-11-04 14:45:02 -08001448 if (DBG) log("Store VoiceMailProvider. Key: " + key + " -> " + vmProvider.toString());
1449 mVMProvidersData.put(key, vmProvider);
1450 entries.add(vmProvider.name);
1451 values.add(key);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001452 }
1453
Andrew Leef1776d82014-11-04 14:45:02 -08001454 mVoicemailProviders.setEntries(entries.toArray(new String[0]));
1455 mVoicemailProviders.setEntryValues(values.toArray(new String[0]));
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001456
Andrew Leef1776d82014-11-04 14:45:02 -08001457 // Remember the current Voicemail Provider key as a "previous" key. This will be used when
1458 // we fail to update Voicemail Provider, which requires rollback. We will update this when
1459 // the VM Provider setting is successfully updated.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001460 mPreviousVMProviderKey = getCurrentVoicemailProviderKey();
1461 if (DBG) log("Set up the first mPreviousVMProviderKey: " + mPreviousVMProviderKey);
1462
1463 // Finally update the preference texts.
1464 updateVMPreferenceWidgets(mPreviousVMProviderKey);
1465 }
1466
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001467 /**
1468 * Simulates user clicking on a passed preference.
1469 * Usually needed when the preference is a dialog preference and we want to invoke
1470 * a dialog for this preference programmatically.
Santos Cordonda120f42014-08-06 04:44:34 -07001471 * TODO: figure out if there is a cleaner way to cause preference dlg to come up
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001472 */
1473 private void simulatePreferenceClick(Preference preference) {
1474 // Go through settings until we find our setting
1475 // and then simulate a click on it to bring up the dialog
1476 final ListAdapter adapter = getPreferenceScreen().getRootAdapter();
1477 for (int idx = 0; idx < adapter.getCount(); idx++) {
1478 if (adapter.getItem(idx) == preference) {
1479 getPreferenceScreen().onItemClick(this.getListView(),
1480 null, idx, adapter.getItemId(idx));
1481 break;
1482 }
1483 }
1484 }
1485
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001486 private String getCurrentVoicemailProviderKey() {
1487 final String key = mVoicemailProviders.getValue();
1488 return (key != null) ? key : DEFAULT_VM_PROVIDER_KEY;
1489 }
1490
1491 @Override
1492 public boolean onOptionsItemSelected(MenuItem item) {
1493 final int itemId = item.getItemId();
1494 if (itemId == android.R.id.home) { // See ActionBar#setDisplayHomeAsUpEnabled()
Yorke Leef2d0cac2013-09-09 19:42:56 -07001495 onBackPressed();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001496 return true;
1497 }
1498 return super.onOptionsItemSelected(item);
1499 }
Andrew Lee8d66d812014-11-24 14:54:02 -08001500
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001501 /**
1502 * Finish current Activity and go up to the top level Settings ({@link CallFeaturesSetting}).
1503 * This is useful for implementing "HomeAsUp" capability for second-level Settings.
1504 */
1505 public static void goUpToTopLevelSetting(Activity activity) {
1506 Intent intent = new Intent(activity, CallFeaturesSetting.class);
1507 intent.setAction(Intent.ACTION_MAIN);
1508 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
1509 activity.startActivity(intent);
1510 activity.finish();
1511 }
1512}