1 package com.android.phone; 2 3 import static com.android.phone.TimeConsumingPreferenceActivity.EXCEPTION_ERROR; 4 import static com.android.phone.TimeConsumingPreferenceActivity.RESPONSE_ERROR; 5 6 import android.app.AlertDialog; 7 import android.content.Context; 8 import android.content.DialogInterface; 9 import android.content.res.TypedArray; 10 import android.os.AsyncResult; 11 import android.os.Handler; 12 import android.os.Message; 13 import android.os.PersistableBundle; 14 import android.telephony.CarrierConfigManager; 15 import android.telephony.PhoneNumberUtils; 16 import android.telephony.TelephonyManager; 17 import android.text.BidiFormatter; 18 import android.text.SpannableString; 19 import android.text.TextDirectionHeuristics; 20 import android.text.TextUtils; 21 import android.util.AttributeSet; 22 import android.util.Log; 23 import android.view.View; 24 25 import com.android.internal.telephony.CallForwardInfo; 26 import com.android.internal.telephony.CommandException; 27 import com.android.internal.telephony.CommandsInterface; 28 import com.android.internal.telephony.Phone; 29 30 import java.util.HashMap; 31 32 public class CallForwardEditPreference extends EditPhoneNumberPreference { 33 private static final String LOG_TAG = "CallForwardEditPreference"; 34 35 private static final String SRC_TAGS[] = {"{0}"}; 36 private CharSequence mSummaryOnTemplate; 37 /** 38 * Remembers which button was clicked by a user. If no button is clicked yet, this should have 39 * {@link DialogInterface#BUTTON_NEGATIVE}, meaning "cancel". 40 * 41 * TODO: consider removing this variable and having getButtonClicked() in 42 * EditPhoneNumberPreference instead. 43 */ 44 private int mButtonClicked; 45 private int mServiceClass; 46 private MyHandler mHandler = new MyHandler(); 47 int reason; 48 private Phone mPhone; 49 CallForwardInfo callForwardInfo; 50 private TimeConsumingPreferenceListener mTcpListener; 51 // Should we replace CF queries containing an invalid number with "Voicemail" 52 private boolean mReplaceInvalidCFNumber = false; 53 private boolean mCallForwardByUssd = false; 54 private CarrierXmlParser mCarrierXmlParser; 55 private int mPreviousCommand = MyHandler.MESSAGE_GET_CF; 56 private Object mCommandException; 57 private CarrierXmlParser.SsEntry.SSAction mSsAction = 58 CarrierXmlParser.SsEntry.SSAction.UNKNOWN; 59 private int mAction; 60 private HashMap<String, String> mCfInfo; 61 CallForwardEditPreference(Context context, AttributeSet attrs)62 public CallForwardEditPreference(Context context, AttributeSet attrs) { 63 super(context, attrs); 64 65 mSummaryOnTemplate = this.getSummaryOn(); 66 67 TypedArray a = context.obtainStyledAttributes(attrs, 68 R.styleable.CallForwardEditPreference, 0, R.style.EditPhoneNumberPreference); 69 mServiceClass = a.getInt(R.styleable.CallForwardEditPreference_serviceClass, 70 CommandsInterface.SERVICE_CLASS_VOICE); 71 reason = a.getInt(R.styleable.CallForwardEditPreference_reason, 72 CommandsInterface.CF_REASON_UNCONDITIONAL); 73 a.recycle(); 74 75 Log.d(LOG_TAG, "mServiceClass=" + mServiceClass + ", reason=" + reason); 76 } 77 CallForwardEditPreference(Context context)78 public CallForwardEditPreference(Context context) { 79 this(context, null); 80 } 81 init(TimeConsumingPreferenceListener listener, Phone phone, boolean replaceInvalidCFNumber, boolean callForwardByUssd)82 void init(TimeConsumingPreferenceListener listener, Phone phone, 83 boolean replaceInvalidCFNumber, boolean callForwardByUssd) { 84 mPhone = phone; 85 mTcpListener = listener; 86 mReplaceInvalidCFNumber = replaceInvalidCFNumber; 87 mCallForwardByUssd = callForwardByUssd; 88 Log.d(LOG_TAG, 89 "init :mReplaceInvalidCFNumber " + mReplaceInvalidCFNumber + ", mCallForwardByUssd " 90 + mCallForwardByUssd); 91 if (mCallForwardByUssd) { 92 mCfInfo = new HashMap<String, String>(); 93 TelephonyManager telephonyManager = new TelephonyManager(getContext(), 94 phone.getSubId()); 95 mCarrierXmlParser = new CarrierXmlParser(getContext(), 96 telephonyManager.getSimCarrierId()); 97 } 98 } 99 restoreCallForwardInfo(CallForwardInfo cf)100 void restoreCallForwardInfo(CallForwardInfo cf) { 101 handleCallForwardResult(cf); 102 updateSummaryText(); 103 } 104 105 @Override onBindDialogView(View view)106 protected void onBindDialogView(View view) { 107 // default the button clicked to be the cancel button. 108 mButtonClicked = DialogInterface.BUTTON_NEGATIVE; 109 super.onBindDialogView(view); 110 } 111 112 @Override onClick(DialogInterface dialog, int which)113 public void onClick(DialogInterface dialog, int which) { 114 super.onClick(dialog, which); 115 mButtonClicked = which; 116 } 117 118 @Override onDialogClosed(boolean positiveResult)119 protected void onDialogClosed(boolean positiveResult) { 120 super.onDialogClosed(positiveResult); 121 122 Log.d(LOG_TAG, "mButtonClicked=" + mButtonClicked + ", positiveResult=" + positiveResult); 123 // Ignore this event if the user clicked the cancel button, or if the dialog is dismissed 124 // without any button being pressed (back button press or click event outside the dialog). 125 if (this.mButtonClicked != DialogInterface.BUTTON_NEGATIVE) { 126 int action = (isToggled() || (mButtonClicked == DialogInterface.BUTTON_POSITIVE)) ? 127 CommandsInterface.CF_ACTION_REGISTRATION : 128 CommandsInterface.CF_ACTION_DISABLE; 129 int time = 0; 130 if (reason == CommandsInterface.CF_REASON_NO_REPLY) { 131 PersistableBundle carrierConfig = PhoneGlobals.getInstance() 132 .getCarrierConfigForSubId(mPhone.getSubId()); 133 if (carrierConfig.getBoolean( 134 CarrierConfigManager.KEY_SUPPORT_NO_REPLY_TIMER_FOR_CFNRY_BOOL, true)) { 135 time = 20; 136 } 137 } 138 final String number = getPhoneNumber(); 139 140 Log.d(LOG_TAG, "callForwardInfo=" + callForwardInfo); 141 142 if (action == CommandsInterface.CF_ACTION_REGISTRATION 143 && callForwardInfo != null 144 && callForwardInfo.status == 1 145 && number.equals(callForwardInfo.number)) { 146 // no change, do nothing 147 Log.d(LOG_TAG, "no change, do nothing"); 148 } else { 149 // set to network 150 Log.d(LOG_TAG, "reason=" + reason + ", action=" + action 151 + ", number=" + number); 152 153 // Display no forwarding number while we're waiting for 154 // confirmation 155 setSummaryOn(""); 156 if (!mCallForwardByUssd) { 157 // the interface of Phone.setCallForwardingOption has error: 158 // should be action, reason... 159 mPhone.setCallForwardingOption(action, 160 reason, 161 number, 162 mServiceClass, 163 time, 164 mHandler.obtainMessage(MyHandler.MESSAGE_SET_CF, 165 action, 166 MyHandler.MESSAGE_SET_CF)); 167 } else { 168 if (action == CommandsInterface.CF_ACTION_REGISTRATION) { 169 mCfInfo.put(CarrierXmlParser.TAG_ENTRY_NUMBER, number); 170 mCfInfo.put(CarrierXmlParser.TAG_ENTRY_TIME, Integer.toString(time)); 171 } else { 172 mCfInfo.clear(); 173 } 174 mHandler.sendMessage(mHandler.obtainMessage(mHandler.MESSAGE_SET_CF_USSD, 175 action, MyHandler.MESSAGE_SET_CF)); 176 } 177 if (mTcpListener != null) { 178 mTcpListener.onStarted(this, false); 179 } 180 } 181 } 182 } 183 handleCallForwardResult(CallForwardInfo cf)184 private void handleCallForwardResult(CallForwardInfo cf) { 185 callForwardInfo = cf; 186 Log.d(LOG_TAG, "handleGetCFResponse done, callForwardInfo=" + callForwardInfo); 187 // In some cases, the network can send call forwarding URIs for voicemail that violate the 188 // 3gpp spec. This can cause us to receive "numbers" that are sequences of letters. In this 189 // case, we must detect these series of characters and replace them with "Voicemail". 190 // PhoneNumberUtils#formatNumber returns null if the number is not valid. 191 if (mReplaceInvalidCFNumber && (PhoneNumberUtils.formatNumber(callForwardInfo.number, 192 getCurrentCountryIso()) == null)) { 193 callForwardInfo.number = getContext().getString(R.string.voicemail); 194 Log.i(LOG_TAG, "handleGetCFResponse: Overridding CF number"); 195 } 196 197 setToggled(callForwardInfo.status == 1); 198 boolean displayVoicemailNumber = false; 199 if (TextUtils.isEmpty(callForwardInfo.number)) { 200 PersistableBundle carrierConfig = 201 PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId()); 202 if (carrierConfig != null) { 203 displayVoicemailNumber = carrierConfig.getBoolean(CarrierConfigManager 204 .KEY_DISPLAY_VOICEMAIL_NUMBER_AS_DEFAULT_CALL_FORWARDING_NUMBER_BOOL); 205 Log.d(LOG_TAG, "display voicemail number as default"); 206 } 207 } 208 String voicemailNumber = mPhone.getVoiceMailNumber(); 209 setPhoneNumber(displayVoicemailNumber ? voicemailNumber : callForwardInfo.number); 210 } 211 212 /** 213 * Starts the Call Forwarding Option query to the network and calls 214 * {@link TimeConsumingPreferenceListener#onStarted}. Will call 215 * {@link TimeConsumingPreferenceListener#onFinished} when finished, or 216 * {@link TimeConsumingPreferenceListener#onError} if an error has occurred. 217 */ startCallForwardOptionsQuery()218 void startCallForwardOptionsQuery() { 219 if (!mCallForwardByUssd) { 220 mPhone.getCallForwardingOption(reason, mServiceClass, 221 mHandler.obtainMessage(MyHandler.MESSAGE_GET_CF, 222 // unused in this case 223 CommandsInterface.CF_ACTION_DISABLE, 224 MyHandler.MESSAGE_GET_CF, null)); 225 } else { 226 mHandler.sendMessage(mHandler.obtainMessage(mHandler.MESSAGE_GET_CF_USSD, 227 // unused in this case 228 CommandsInterface.CF_ACTION_DISABLE, MyHandler.MESSAGE_GET_CF, null)); 229 } 230 if (mTcpListener != null) { 231 mTcpListener.onStarted(this, true); 232 } 233 } 234 updateSummaryText()235 private void updateSummaryText() { 236 if (isToggled()) { 237 final String number = getRawPhoneNumber(); 238 if (number != null && number.length() > 0) { 239 // Wrap the number to preserve presentation in RTL languages. 240 String wrappedNumber = BidiFormatter.getInstance().unicodeWrap( 241 number, TextDirectionHeuristics.LTR); 242 String values[] = { wrappedNumber }; 243 String summaryOn = String.valueOf( 244 TextUtils.replace(mSummaryOnTemplate, SRC_TAGS, values)); 245 int start = summaryOn.indexOf(wrappedNumber); 246 247 SpannableString spannableSummaryOn = new SpannableString(summaryOn); 248 PhoneNumberUtils.addTtsSpan(spannableSummaryOn, 249 start, start + wrappedNumber.length()); 250 setSummaryOn(spannableSummaryOn); 251 } else { 252 setSummaryOn(getContext().getString(R.string.sum_cfu_enabled_no_number)); 253 } 254 } 255 256 } 257 258 /** 259 * @return The ISO 3166-1 two letters country code of the country the user is in based on the 260 * network location. 261 */ getCurrentCountryIso()262 private String getCurrentCountryIso() { 263 final TelephonyManager telephonyManager = 264 (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE); 265 if (telephonyManager == null) { 266 return ""; 267 } 268 return telephonyManager.getNetworkCountryIso().toUpperCase(); 269 } 270 271 // Message protocol: 272 // what: get vs. set 273 // arg1: action -- register vs. disable 274 // arg2: get vs. set for the preceding request 275 private class MyHandler extends Handler { 276 static final int MESSAGE_GET_CF = 0; 277 static final int MESSAGE_SET_CF = 1; 278 static final int MESSAGE_GET_CF_USSD = 2; 279 static final int MESSAGE_SET_CF_USSD = 3; 280 281 TelephonyManager.UssdResponseCallback mUssdCallback = 282 new TelephonyManager.UssdResponseCallback() { 283 @Override 284 public void onReceiveUssdResponse(final TelephonyManager telephonyManager, 285 String request, CharSequence response) { 286 if (mSsAction == CarrierXmlParser.SsEntry.SSAction.UNKNOWN) { 287 return; 288 } 289 290 HashMap<String, String> analysisResult = mCarrierXmlParser.getFeature( 291 CarrierXmlParser.FEATURE_CALL_FORWARDING) 292 .getResponseSet(mSsAction, 293 response.toString()); 294 295 Throwable throwableException = null; 296 if (analysisResult.get(CarrierXmlParser.TAG_RESPONSE_STATUS_ERROR) 297 != null) { 298 throwableException = new CommandException( 299 CommandException.Error.GENERIC_FAILURE); 300 } 301 302 Object obj = null; 303 if (mSsAction == CarrierXmlParser.SsEntry.SSAction.QUERY) { 304 obj = makeCallForwardInfo(analysisResult); 305 } 306 307 sendCfMessage(obj, throwableException); 308 } 309 310 @Override 311 public void onReceiveUssdResponseFailed(final TelephonyManager telephonyManager, 312 String request, int failureCode) { 313 Log.d(LOG_TAG, "receive the ussd result failed"); 314 Throwable throwableException = new CommandException( 315 CommandException.Error.GENERIC_FAILURE); 316 sendCfMessage(null, throwableException); 317 } 318 }; 319 320 @Override handleMessage(Message msg)321 public void handleMessage(Message msg) { 322 switch (msg.what) { 323 case MESSAGE_GET_CF: 324 handleGetCFResponse(msg); 325 break; 326 case MESSAGE_SET_CF: 327 handleSetCFResponse(msg); 328 break; 329 case MESSAGE_GET_CF_USSD: 330 prepareUssdCommand(msg, CarrierXmlParser.SsEntry.SSAction.QUERY); 331 break; 332 case MESSAGE_SET_CF_USSD: 333 prepareUssdCommand(msg, CarrierXmlParser.SsEntry.SSAction.UNKNOWN); 334 break; 335 } 336 } 337 handleGetCFResponse(Message msg)338 private void handleGetCFResponse(Message msg) { 339 Log.d(LOG_TAG, "handleGetCFResponse: done"); 340 341 mTcpListener.onFinished(CallForwardEditPreference.this, msg.arg2 != MESSAGE_SET_CF); 342 343 AsyncResult ar = (AsyncResult) msg.obj; 344 345 callForwardInfo = null; 346 if (ar.exception != null) { 347 Log.d(LOG_TAG, "handleGetCFResponse: ar.exception=" + ar.exception); 348 if (ar.exception instanceof CommandException) { 349 mTcpListener.onException(CallForwardEditPreference.this, 350 (CommandException) ar.exception); 351 } else { 352 // Most likely an ImsException and we can't handle it the same way as 353 // a CommandException. The best we can do is to handle the exception 354 // the same way as mTcpListener.onException() does when it is not of type 355 // FDN_CHECK_FAILURE. 356 mTcpListener.onError(CallForwardEditPreference.this, EXCEPTION_ERROR); 357 } 358 } else { 359 if (ar.userObj instanceof Throwable) { 360 mTcpListener.onError(CallForwardEditPreference.this, RESPONSE_ERROR); 361 } 362 CallForwardInfo cfInfoArray[] = (CallForwardInfo[]) ar.result; 363 if (cfInfoArray == null || cfInfoArray.length == 0) { 364 Log.d(LOG_TAG, "handleGetCFResponse: cfInfoArray.length==0"); 365 mTcpListener.onError(CallForwardEditPreference.this, RESPONSE_ERROR); 366 } else { 367 for (int i = 0, length = cfInfoArray.length; i < length; i++) { 368 Log.d(LOG_TAG, "handleGetCFResponse, cfInfoArray[" + i + "]=" 369 + cfInfoArray[i]); 370 if ((mServiceClass & cfInfoArray[i].serviceClass) != 0) { 371 // corresponding class 372 CallForwardInfo info = cfInfoArray[i]; 373 handleCallForwardResult(info); 374 375 if (ar.userObj instanceof Throwable) { 376 Log.d(LOG_TAG, "Skipped duplicated error dialog"); 377 continue; 378 } 379 380 // Show an alert if we got a success response but 381 // with unexpected values. 382 // Currently only handle the fail-to-disable case 383 // since we haven't observed fail-to-enable. 384 if (msg.arg2 == MESSAGE_SET_CF && 385 msg.arg1 == CommandsInterface.CF_ACTION_DISABLE && 386 info.status == 1) { 387 // Skip showing error dialog since some operators return 388 // active status even if disable call forward succeeded. 389 // And they don't like the error dialog. 390 if (isSkipCFFailToDisableDialog()) { 391 Log.d(LOG_TAG, "Skipped Callforwarding fail-to-disable dialog"); 392 continue; 393 } 394 CharSequence s; 395 switch (reason) { 396 case CommandsInterface.CF_REASON_BUSY: 397 s = getContext().getText(R.string.disable_cfb_forbidden); 398 break; 399 case CommandsInterface.CF_REASON_NO_REPLY: 400 s = getContext().getText(R.string.disable_cfnry_forbidden); 401 break; 402 default: // not reachable 403 s = getContext().getText(R.string.disable_cfnrc_forbidden); 404 } 405 AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); 406 builder.setNeutralButton(R.string.close_dialog, null); 407 builder.setTitle(getContext().getText(R.string.error_updating_title)); 408 builder.setMessage(s); 409 builder.setCancelable(true); 410 builder.create().show(); 411 } 412 } 413 } 414 } 415 } 416 417 // Now whether or not we got a new number, reset our enabled 418 // summary text since it may have been replaced by an empty 419 // placeholder. 420 updateSummaryText(); 421 } 422 handleSetCFResponse(Message msg)423 private void handleSetCFResponse(Message msg) { 424 AsyncResult ar = (AsyncResult) msg.obj; 425 if (ar.exception != null) { 426 Log.d(LOG_TAG, "handleSetCFResponse: ar.exception=" + ar.exception); 427 // setEnabled(false); 428 } 429 Log.d(LOG_TAG, "handleSetCFResponse: re get"); 430 if (!mCallForwardByUssd) { 431 mPhone.getCallForwardingOption(reason, mServiceClass, 432 obtainMessage(MESSAGE_GET_CF, msg.arg1, MESSAGE_SET_CF, ar.exception)); 433 } else { 434 mHandler.sendMessage(mHandler.obtainMessage(mHandler.MESSAGE_GET_CF_USSD, 435 msg.arg1, MyHandler.MESSAGE_SET_CF, ar.exception)); 436 } 437 } 438 prepareUssdCommand(Message msg, CarrierXmlParser.SsEntry.SSAction inputSsAction)439 private void prepareUssdCommand(Message msg, 440 CarrierXmlParser.SsEntry.SSAction inputSsAction) { 441 mAction = msg.arg1; 442 mPreviousCommand = msg.arg2; 443 mCommandException = msg.obj; 444 mSsAction = inputSsAction; 445 446 if (mSsAction != CarrierXmlParser.SsEntry.SSAction.QUERY) { 447 if (mAction == CommandsInterface.CF_ACTION_REGISTRATION) { 448 mSsAction = CarrierXmlParser.SsEntry.SSAction.UPDATE_ACTIVATE; 449 } else { 450 mSsAction = CarrierXmlParser.SsEntry.SSAction.UPDATE_DEACTIVATE; 451 } 452 } 453 454 new Thread(new Runnable() { 455 @Override 456 public void run() { 457 sendUssdCommand(mUssdCallback, mSsAction, mCfInfo.isEmpty() ? null : mCfInfo); 458 } 459 }).start(); 460 } 461 sendUssdCommand(TelephonyManager.UssdResponseCallback inputCallback, CarrierXmlParser.SsEntry.SSAction inputAction, HashMap<String, String> inputCfInfo)462 private void sendUssdCommand(TelephonyManager.UssdResponseCallback inputCallback, 463 CarrierXmlParser.SsEntry.SSAction inputAction, 464 HashMap<String, String> inputCfInfo) { 465 String newUssdCommand = mCarrierXmlParser.getFeature( 466 CarrierXmlParser.FEATURE_CALL_FORWARDING) 467 .makeCommand(inputAction, inputCfInfo); 468 TelephonyManager telephonyManager = 469 (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE); 470 telephonyManager.sendUssdRequest(newUssdCommand, inputCallback, mHandler); 471 } 472 makeGetCfMessage(int inputMsgWhat, int inputMsgArg2, Object inputMsgObj)473 private Message makeGetCfMessage(int inputMsgWhat, int inputMsgArg2, Object inputMsgObj) { 474 return mHandler.obtainMessage(inputMsgWhat, 475 mAction, 476 inputMsgArg2, 477 inputMsgObj); 478 } 479 makeSetCfMessage(int inputMsgWhat, int inputMsgArg2)480 private Message makeSetCfMessage(int inputMsgWhat, int inputMsgArg2) { 481 return mHandler.obtainMessage(inputMsgWhat, 482 mAction, 483 inputMsgArg2); 484 } 485 sendCfMessage(Object inputArObj, Throwable inputThrowableException)486 private void sendCfMessage(Object inputArObj, Throwable inputThrowableException) { 487 Message message; 488 if (mSsAction == CarrierXmlParser.SsEntry.SSAction.UNKNOWN) { 489 return; 490 } 491 if (mSsAction == CarrierXmlParser.SsEntry.SSAction.QUERY) { 492 message = makeGetCfMessage(MyHandler.MESSAGE_GET_CF, mPreviousCommand, 493 mCommandException); 494 } else { 495 message = makeSetCfMessage(MyHandler.MESSAGE_SET_CF, MyHandler.MESSAGE_SET_CF); 496 } 497 AsyncResult.forMessage(message, inputArObj, inputThrowableException); 498 message.sendToTarget(); 499 } 500 makeCallForwardInfo(HashMap<String, String> inputInfo)501 private CallForwardInfo[] makeCallForwardInfo(HashMap<String, String> inputInfo) { 502 int tmpStatus = 0; 503 String tmpNumberStr = ""; 504 int tmpTime = 0; 505 if (inputInfo != null && inputInfo.size() != 0) { 506 String tmpStatusStr = inputInfo.get(CarrierXmlParser.TAG_RESPONSE_STATUS); 507 508 String tmpTimeStr = inputInfo.get(CarrierXmlParser.TAG_RESPONSE_TIME); 509 if (!TextUtils.isEmpty(tmpStatusStr)) { 510 if (tmpStatusStr.equals( 511 CarrierXmlParser.TAG_COMMAND_RESULT_DEFINITION_ACTIVATE)) { 512 tmpStatus = 1; 513 } else if (tmpStatusStr.equals( 514 CarrierXmlParser.TAG_COMMAND_RESULT_DEFINITION_DEACTIVATE) 515 || tmpStatusStr.equals( 516 CarrierXmlParser.TAG_COMMAND_RESULT_DEFINITION_UNREGISTER)) { 517 tmpStatus = 0; 518 } 519 } 520 521 tmpNumberStr = inputInfo.get(CarrierXmlParser.TAG_RESPONSE_NUMBER); 522 if (!TextUtils.isEmpty(tmpTimeStr)) { 523 tmpTime = Integer.valueOf(inputInfo.get(CarrierXmlParser.TAG_RESPONSE_TIME)); 524 } 525 } 526 527 CallForwardInfo[] newCallForwardInfo = new CallForwardInfo[1]; 528 newCallForwardInfo[0] = new CallForwardInfo(); 529 newCallForwardInfo[0].status = tmpStatus; 530 newCallForwardInfo[0].reason = reason; 531 newCallForwardInfo[0].serviceClass = mServiceClass; 532 newCallForwardInfo[0].number = tmpNumberStr; 533 newCallForwardInfo[0].timeSeconds = tmpTime; 534 return newCallForwardInfo; 535 } 536 } 537 538 /* 539 * Get the config of whether skip showing CF fail-to-disable dialog 540 * from carrier config manager. 541 * 542 * @return boolean value of the config 543 */ isSkipCFFailToDisableDialog()544 private boolean isSkipCFFailToDisableDialog() { 545 PersistableBundle carrierConfig = 546 PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId()); 547 if (carrierConfig != null) { 548 return carrierConfig.getBoolean( 549 CarrierConfigManager.KEY_SKIP_CF_FAIL_TO_DISABLE_DIALOG_BOOL); 550 } else { 551 // by default we should not skip 552 return false; 553 } 554 } 555 } 556