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 (isUnknownStatus() && this.mButtonClicked != DialogInterface.BUTTON_NEGATIVE) { 126 int action = (mButtonClicked == DialogInterface.BUTTON_POSITIVE) ? 127 CommandsInterface.CF_ACTION_REGISTRATION : 128 CommandsInterface.CF_ACTION_DISABLE; 129 final String number = (action == CommandsInterface.CF_ACTION_DISABLE) ? 130 "" : getPhoneNumber(); 131 132 Log.d(LOG_TAG, "reason=" + reason + ", action=" + action + ", number=" + number); 133 134 // Display no forwarding number while we're waiting for confirmation. 135 setSummaryOff(""); 136 137 mPhone.setCallForwardingOption(action, 138 reason, 139 number, 140 mServiceClass, 141 0, 142 mHandler.obtainMessage(MyHandler.MESSAGE_SET_CF, 143 action, 144 MyHandler.MESSAGE_SET_CF)); 145 } else if (this.mButtonClicked != DialogInterface.BUTTON_NEGATIVE) { 146 int action = (isToggled() || (mButtonClicked == DialogInterface.BUTTON_POSITIVE)) ? 147 CommandsInterface.CF_ACTION_REGISTRATION : 148 CommandsInterface.CF_ACTION_DISABLE; 149 int time = 0; 150 if (reason == CommandsInterface.CF_REASON_NO_REPLY) { 151 PersistableBundle carrierConfig = PhoneGlobals.getInstance() 152 .getCarrierConfigForSubId(mPhone.getSubId()); 153 if (carrierConfig.getBoolean( 154 CarrierConfigManager.KEY_SUPPORT_NO_REPLY_TIMER_FOR_CFNRY_BOOL, true)) { 155 time = 20; 156 } 157 } 158 final String number = getPhoneNumber(); 159 160 Log.d(LOG_TAG, "callForwardInfo=" + callForwardInfo); 161 162 if (action == CommandsInterface.CF_ACTION_REGISTRATION 163 && callForwardInfo != null 164 && callForwardInfo.status == 1 165 && number.equals(callForwardInfo.number)) { 166 // no change, do nothing 167 Log.d(LOG_TAG, "no change, do nothing"); 168 } else { 169 // set to network 170 Log.d(LOG_TAG, "reason=" + reason + ", action=" + action 171 + ", number=" + number); 172 173 // Display no forwarding number while we're waiting for 174 // confirmation 175 setSummaryOn(""); 176 if (!mCallForwardByUssd) { 177 // the interface of Phone.setCallForwardingOption has error: 178 // should be action, reason... 179 mPhone.setCallForwardingOption(action, 180 reason, 181 number, 182 mServiceClass, 183 time, 184 mHandler.obtainMessage(MyHandler.MESSAGE_SET_CF, 185 action, 186 MyHandler.MESSAGE_SET_CF)); 187 } else { 188 if (action == CommandsInterface.CF_ACTION_REGISTRATION) { 189 mCfInfo.put(CarrierXmlParser.TAG_ENTRY_NUMBER, number); 190 mCfInfo.put(CarrierXmlParser.TAG_ENTRY_TIME, Integer.toString(time)); 191 } else { 192 mCfInfo.clear(); 193 } 194 mHandler.sendMessage(mHandler.obtainMessage(mHandler.MESSAGE_SET_CF_USSD, 195 action, MyHandler.MESSAGE_SET_CF)); 196 } 197 if (mTcpListener != null) { 198 mTcpListener.onStarted(this, false); 199 } 200 } 201 } 202 } 203 handleCallForwardResult(CallForwardInfo cf)204 private void handleCallForwardResult(CallForwardInfo cf) { 205 callForwardInfo = cf; 206 Log.d(LOG_TAG, "handleGetCFResponse done, callForwardInfo=" + callForwardInfo); 207 // In some cases, the network can send call forwarding URIs for voicemail that violate the 208 // 3gpp spec. This can cause us to receive "numbers" that are sequences of letters. In this 209 // case, we must detect these series of characters and replace them with "Voicemail". 210 // PhoneNumberUtils#formatNumber returns null if the number is not valid. 211 if (mReplaceInvalidCFNumber && (PhoneNumberUtils.formatNumber(callForwardInfo.number, 212 getCurrentCountryIso()) == null)) { 213 callForwardInfo.number = getContext().getString(R.string.voicemail); 214 Log.i(LOG_TAG, "handleGetCFResponse: Overridding CF number"); 215 } 216 217 setUnknownStatus(callForwardInfo.status == CommandsInterface.SS_STATUS_UNKNOWN); 218 setToggled(callForwardInfo.status == 1); 219 boolean displayVoicemailNumber = false; 220 if (TextUtils.isEmpty(callForwardInfo.number)) { 221 PersistableBundle carrierConfig = 222 PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId()); 223 if (carrierConfig != null) { 224 displayVoicemailNumber = carrierConfig.getBoolean(CarrierConfigManager 225 .KEY_DISPLAY_VOICEMAIL_NUMBER_AS_DEFAULT_CALL_FORWARDING_NUMBER_BOOL); 226 Log.d(LOG_TAG, "display voicemail number as default"); 227 } 228 } 229 String voicemailNumber = mPhone.getVoiceMailNumber(); 230 setPhoneNumber(displayVoicemailNumber ? voicemailNumber : callForwardInfo.number); 231 } 232 233 /** 234 * Starts the Call Forwarding Option query to the network and calls 235 * {@link TimeConsumingPreferenceListener#onStarted}. Will call 236 * {@link TimeConsumingPreferenceListener#onFinished} when finished, or 237 * {@link TimeConsumingPreferenceListener#onError} if an error has occurred. 238 */ startCallForwardOptionsQuery()239 void startCallForwardOptionsQuery() { 240 if (!mCallForwardByUssd) { 241 mPhone.getCallForwardingOption(reason, mServiceClass, 242 mHandler.obtainMessage(MyHandler.MESSAGE_GET_CF, 243 // unused in this case 244 CommandsInterface.CF_ACTION_DISABLE, 245 MyHandler.MESSAGE_GET_CF, null)); 246 } else { 247 mHandler.sendMessage(mHandler.obtainMessage(mHandler.MESSAGE_GET_CF_USSD, 248 // unused in this case 249 CommandsInterface.CF_ACTION_DISABLE, MyHandler.MESSAGE_GET_CF, null)); 250 } 251 if (mTcpListener != null) { 252 mTcpListener.onStarted(this, true); 253 } 254 } 255 updateSummaryText()256 private void updateSummaryText() { 257 if (isToggled()) { 258 final String number = getRawPhoneNumber(); 259 if (number != null && number.length() > 0) { 260 // Wrap the number to preserve presentation in RTL languages. 261 String wrappedNumber = BidiFormatter.getInstance().unicodeWrap( 262 number, TextDirectionHeuristics.LTR); 263 String values[] = { wrappedNumber }; 264 String summaryOn = String.valueOf( 265 TextUtils.replace(mSummaryOnTemplate, SRC_TAGS, values)); 266 int start = summaryOn.indexOf(wrappedNumber); 267 268 SpannableString spannableSummaryOn = new SpannableString(summaryOn); 269 PhoneNumberUtils.addTtsSpan(spannableSummaryOn, 270 start, start + wrappedNumber.length()); 271 setSummaryOn(spannableSummaryOn); 272 } else { 273 setSummaryOn(getContext().getString(R.string.sum_cfu_enabled_no_number)); 274 } 275 } 276 277 } 278 279 /** 280 * @return The ISO 3166-1 two letters country code of the country the user is in based on the 281 * network location. 282 */ getCurrentCountryIso()283 private String getCurrentCountryIso() { 284 final TelephonyManager telephonyManager = 285 (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE); 286 if (telephonyManager == null) { 287 return ""; 288 } 289 return telephonyManager.getNetworkCountryIso().toUpperCase(); 290 } 291 292 // Message protocol: 293 // what: get vs. set 294 // arg1: action -- register vs. disable 295 // arg2: get vs. set for the preceding request 296 private class MyHandler extends Handler { 297 static final int MESSAGE_GET_CF = 0; 298 static final int MESSAGE_SET_CF = 1; 299 static final int MESSAGE_GET_CF_USSD = 2; 300 static final int MESSAGE_SET_CF_USSD = 3; 301 302 TelephonyManager.UssdResponseCallback mUssdCallback = 303 new TelephonyManager.UssdResponseCallback() { 304 @Override 305 public void onReceiveUssdResponse(final TelephonyManager telephonyManager, 306 String request, CharSequence response) { 307 if (mSsAction == CarrierXmlParser.SsEntry.SSAction.UNKNOWN) { 308 return; 309 } 310 311 HashMap<String, String> analysisResult = mCarrierXmlParser.getFeature( 312 CarrierXmlParser.FEATURE_CALL_FORWARDING) 313 .getResponseSet(mSsAction, 314 response.toString()); 315 316 Throwable throwableException = null; 317 if (analysisResult.get(CarrierXmlParser.TAG_RESPONSE_STATUS_ERROR) 318 != null) { 319 throwableException = new CommandException( 320 CommandException.Error.GENERIC_FAILURE); 321 } 322 323 Object obj = null; 324 if (mSsAction == CarrierXmlParser.SsEntry.SSAction.QUERY) { 325 obj = makeCallForwardInfo(analysisResult); 326 } 327 328 sendCfMessage(obj, throwableException); 329 } 330 331 @Override 332 public void onReceiveUssdResponseFailed(final TelephonyManager telephonyManager, 333 String request, int failureCode) { 334 Log.d(LOG_TAG, "receive the ussd result failed"); 335 Throwable throwableException = new CommandException( 336 CommandException.Error.GENERIC_FAILURE); 337 sendCfMessage(null, throwableException); 338 } 339 }; 340 341 @Override handleMessage(Message msg)342 public void handleMessage(Message msg) { 343 switch (msg.what) { 344 case MESSAGE_GET_CF: 345 handleGetCFResponse(msg); 346 break; 347 case MESSAGE_SET_CF: 348 handleSetCFResponse(msg); 349 break; 350 case MESSAGE_GET_CF_USSD: 351 prepareUssdCommand(msg, CarrierXmlParser.SsEntry.SSAction.QUERY); 352 break; 353 case MESSAGE_SET_CF_USSD: 354 prepareUssdCommand(msg, CarrierXmlParser.SsEntry.SSAction.UNKNOWN); 355 break; 356 } 357 } 358 handleGetCFResponse(Message msg)359 private void handleGetCFResponse(Message msg) { 360 Log.d(LOG_TAG, "handleGetCFResponse: done"); 361 362 mTcpListener.onFinished(CallForwardEditPreference.this, msg.arg2 != MESSAGE_SET_CF); 363 364 AsyncResult ar = (AsyncResult) msg.obj; 365 366 callForwardInfo = null; 367 boolean summaryOff = false; 368 if (ar.exception != null) { 369 Log.d(LOG_TAG, "handleGetCFResponse: ar.exception=" + ar.exception); 370 if (ar.exception instanceof CommandException) { 371 mTcpListener.onException(CallForwardEditPreference.this, 372 (CommandException) ar.exception); 373 } else { 374 // Most likely an ImsException and we can't handle it the same way as 375 // a CommandException. The best we can do is to handle the exception 376 // the same way as mTcpListener.onException() does when it is not of type 377 // FDN_CHECK_FAILURE. 378 mTcpListener.onError(CallForwardEditPreference.this, EXCEPTION_ERROR); 379 } 380 } else { 381 if (ar.userObj instanceof Throwable) { 382 mTcpListener.onError(CallForwardEditPreference.this, RESPONSE_ERROR); 383 } 384 CallForwardInfo cfInfoArray[] = (CallForwardInfo[]) ar.result; 385 if (cfInfoArray == null || cfInfoArray.length == 0) { 386 Log.d(LOG_TAG, "handleGetCFResponse: cfInfoArray.length==0"); 387 mTcpListener.onError(CallForwardEditPreference.this, RESPONSE_ERROR); 388 } else { 389 for (int i = 0, length = cfInfoArray.length; i < length; i++) { 390 Log.d(LOG_TAG, "handleGetCFResponse, cfInfoArray[" + i + "]=" 391 + cfInfoArray[i]); 392 if ((mServiceClass & cfInfoArray[i].serviceClass) != 0) { 393 // corresponding class 394 CallForwardInfo info = cfInfoArray[i]; 395 handleCallForwardResult(info); 396 397 summaryOff = (info.status == CommandsInterface.SS_STATUS_UNKNOWN); 398 399 if (ar.userObj instanceof Throwable) { 400 Log.d(LOG_TAG, "Skipped duplicated error dialog"); 401 continue; 402 } 403 404 // Show an alert if we got a success response but 405 // with unexpected values. 406 // Handle the fail-to-disable case. 407 if (msg.arg2 == MESSAGE_SET_CF && 408 msg.arg1 == CommandsInterface.CF_ACTION_DISABLE && 409 info.status == 1) { 410 // Skip showing error dialog since some operators return 411 // active status even if disable call forward succeeded. 412 // And they don't like the error dialog. 413 if (isSkipCFFailToDisableDialog()) { 414 Log.d(LOG_TAG, "Skipped Callforwarding fail-to-disable dialog"); 415 continue; 416 } 417 CharSequence s; 418 switch (reason) { 419 case CommandsInterface.CF_REASON_BUSY: 420 s = getContext().getText(R.string.disable_cfb_forbidden); 421 break; 422 case CommandsInterface.CF_REASON_NO_REPLY: 423 s = getContext().getText(R.string.disable_cfnry_forbidden); 424 break; 425 default: // not reachable 426 s = getContext().getText(R.string.disable_cfnrc_forbidden); 427 } 428 AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); 429 builder.setNeutralButton(R.string.close_dialog, null); 430 builder.setTitle(getContext() 431 .getText(R.string.error_updating_title)); 432 builder.setMessage(s); 433 builder.setCancelable(true); 434 builder.create().show(); 435 } else if (msg.arg2 == MESSAGE_SET_CF && 436 msg.arg1 == CommandsInterface.CF_ACTION_REGISTRATION && 437 info.status == 0) { 438 // Handle the fail-to-enable case. 439 CharSequence s = getContext() 440 .getText(R.string.registration_cf_forbidden); 441 AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); 442 builder.setNeutralButton(R.string.close_dialog, null); 443 builder.setTitle(getContext() 444 .getText(R.string.error_updating_title)); 445 builder.setMessage(s); 446 builder.setCancelable(true); 447 builder.create().show(); 448 } 449 } 450 } 451 } 452 } 453 454 // Now whether or not we got a new number, reset our enabled 455 // summary text since it may have been replaced by an empty 456 // placeholder. 457 // for CDMA, doesn't display summary. 458 if (summaryOff) { 459 setSummaryOff(""); 460 } else { 461 // Now whether or not we got a new number, reset our enabled 462 // summary text since it may have been replaced by an empty 463 // placeholder. 464 updateSummaryText(); 465 } 466 } 467 handleSetCFResponse(Message msg)468 private void handleSetCFResponse(Message msg) { 469 AsyncResult ar = (AsyncResult) msg.obj; 470 if (ar.exception != null) { 471 Log.d(LOG_TAG, "handleSetCFResponse: ar.exception=" + ar.exception); 472 // setEnabled(false); 473 } 474 475 if (ar.result != null) { 476 int arr = (int)ar.result; 477 if (arr == CommandsInterface.SS_STATUS_UNKNOWN) { 478 Log.d(LOG_TAG, "handleSetCFResponse: no need to re get in CDMA"); 479 mTcpListener.onFinished(CallForwardEditPreference.this, false); 480 return; 481 } 482 } 483 484 Log.d(LOG_TAG, "handleSetCFResponse: re get"); 485 if (!mCallForwardByUssd) { 486 mPhone.getCallForwardingOption(reason, mServiceClass, 487 obtainMessage(MESSAGE_GET_CF, msg.arg1, MESSAGE_SET_CF, ar.exception)); 488 } else { 489 mHandler.sendMessage(mHandler.obtainMessage(mHandler.MESSAGE_GET_CF_USSD, 490 msg.arg1, MyHandler.MESSAGE_SET_CF, ar.exception)); 491 } 492 } 493 prepareUssdCommand(Message msg, CarrierXmlParser.SsEntry.SSAction inputSsAction)494 private void prepareUssdCommand(Message msg, 495 CarrierXmlParser.SsEntry.SSAction inputSsAction) { 496 mAction = msg.arg1; 497 mPreviousCommand = msg.arg2; 498 mCommandException = msg.obj; 499 mSsAction = inputSsAction; 500 501 if (mSsAction != CarrierXmlParser.SsEntry.SSAction.QUERY) { 502 if (mAction == CommandsInterface.CF_ACTION_REGISTRATION) { 503 mSsAction = CarrierXmlParser.SsEntry.SSAction.UPDATE_ACTIVATE; 504 } else { 505 mSsAction = CarrierXmlParser.SsEntry.SSAction.UPDATE_DEACTIVATE; 506 } 507 } 508 509 new Thread(new Runnable() { 510 @Override 511 public void run() { 512 sendUssdCommand(mUssdCallback, mSsAction, mCfInfo.isEmpty() ? null : mCfInfo); 513 } 514 }).start(); 515 } 516 sendUssdCommand(TelephonyManager.UssdResponseCallback inputCallback, CarrierXmlParser.SsEntry.SSAction inputAction, HashMap<String, String> inputCfInfo)517 private void sendUssdCommand(TelephonyManager.UssdResponseCallback inputCallback, 518 CarrierXmlParser.SsEntry.SSAction inputAction, 519 HashMap<String, String> inputCfInfo) { 520 String newUssdCommand = mCarrierXmlParser.getFeature( 521 CarrierXmlParser.FEATURE_CALL_FORWARDING) 522 .makeCommand(inputAction, inputCfInfo); 523 TelephonyManager telephonyManager = 524 (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE); 525 telephonyManager.sendUssdRequest(newUssdCommand, inputCallback, mHandler); 526 } 527 makeGetCfMessage(int inputMsgWhat, int inputMsgArg2, Object inputMsgObj)528 private Message makeGetCfMessage(int inputMsgWhat, int inputMsgArg2, Object inputMsgObj) { 529 return mHandler.obtainMessage(inputMsgWhat, 530 mAction, 531 inputMsgArg2, 532 inputMsgObj); 533 } 534 makeSetCfMessage(int inputMsgWhat, int inputMsgArg2)535 private Message makeSetCfMessage(int inputMsgWhat, int inputMsgArg2) { 536 return mHandler.obtainMessage(inputMsgWhat, 537 mAction, 538 inputMsgArg2); 539 } 540 sendCfMessage(Object inputArObj, Throwable inputThrowableException)541 private void sendCfMessage(Object inputArObj, Throwable inputThrowableException) { 542 Message message; 543 if (mSsAction == CarrierXmlParser.SsEntry.SSAction.UNKNOWN) { 544 return; 545 } 546 if (mSsAction == CarrierXmlParser.SsEntry.SSAction.QUERY) { 547 message = makeGetCfMessage(MyHandler.MESSAGE_GET_CF, mPreviousCommand, 548 mCommandException); 549 } else { 550 message = makeSetCfMessage(MyHandler.MESSAGE_SET_CF, MyHandler.MESSAGE_SET_CF); 551 } 552 AsyncResult.forMessage(message, inputArObj, inputThrowableException); 553 message.sendToTarget(); 554 } 555 makeCallForwardInfo(HashMap<String, String> inputInfo)556 private CallForwardInfo[] makeCallForwardInfo(HashMap<String, String> inputInfo) { 557 int tmpStatus = 0; 558 String tmpNumberStr = ""; 559 int tmpTime = 0; 560 if (inputInfo != null && inputInfo.size() != 0) { 561 String tmpStatusStr = inputInfo.get(CarrierXmlParser.TAG_RESPONSE_STATUS); 562 563 String tmpTimeStr = inputInfo.get(CarrierXmlParser.TAG_RESPONSE_TIME); 564 if (!TextUtils.isEmpty(tmpStatusStr)) { 565 if (tmpStatusStr.equals( 566 CarrierXmlParser.TAG_COMMAND_RESULT_DEFINITION_ACTIVATE)) { 567 tmpStatus = 1; 568 } else if (tmpStatusStr.equals( 569 CarrierXmlParser.TAG_COMMAND_RESULT_DEFINITION_DEACTIVATE) 570 || tmpStatusStr.equals( 571 CarrierXmlParser.TAG_COMMAND_RESULT_DEFINITION_UNREGISTER)) { 572 tmpStatus = 0; 573 } 574 } 575 576 tmpNumberStr = inputInfo.get(CarrierXmlParser.TAG_RESPONSE_NUMBER); 577 if (!TextUtils.isEmpty(tmpTimeStr)) { 578 tmpTime = Integer.valueOf(inputInfo.get(CarrierXmlParser.TAG_RESPONSE_TIME)); 579 } 580 } 581 582 CallForwardInfo[] newCallForwardInfo = new CallForwardInfo[1]; 583 newCallForwardInfo[0] = new CallForwardInfo(); 584 newCallForwardInfo[0].status = tmpStatus; 585 newCallForwardInfo[0].reason = reason; 586 newCallForwardInfo[0].serviceClass = mServiceClass; 587 newCallForwardInfo[0].number = tmpNumberStr; 588 newCallForwardInfo[0].timeSeconds = tmpTime; 589 return newCallForwardInfo; 590 } 591 } 592 593 /* 594 * Get the config of whether skip showing CF fail-to-disable dialog 595 * from carrier config manager. 596 * 597 * @return boolean value of the config 598 */ isSkipCFFailToDisableDialog()599 private boolean isSkipCFFailToDisableDialog() { 600 PersistableBundle carrierConfig = 601 PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId()); 602 if (carrierConfig != null) { 603 return carrierConfig.getBoolean( 604 CarrierConfigManager.KEY_SKIP_CF_FAIL_TO_DISABLE_DIALOG_BOOL); 605 } else { 606 // by default we should not skip 607 return false; 608 } 609 } 610 } 611