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