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 if (!(ar.userObj instanceof Throwable)) { 388 mTcpListener.onError(CallForwardEditPreference.this, RESPONSE_ERROR); 389 } 390 } else { 391 for (int i = 0, length = cfInfoArray.length; i < length; i++) { 392 Log.d(LOG_TAG, "handleGetCFResponse, cfInfoArray[" + i + "]=" 393 + cfInfoArray[i]); 394 if ((mServiceClass & cfInfoArray[i].serviceClass) != 0) { 395 // corresponding class 396 CallForwardInfo info = cfInfoArray[i]; 397 handleCallForwardResult(info); 398 399 summaryOff = (info.status == CommandsInterface.SS_STATUS_UNKNOWN); 400 401 if (ar.userObj instanceof Throwable) { 402 Log.d(LOG_TAG, "Skipped duplicated error dialog"); 403 continue; 404 } 405 406 // Show an alert if we got a success response but 407 // with unexpected values. 408 // Handle the fail-to-disable case. 409 if (msg.arg2 == MESSAGE_SET_CF && 410 msg.arg1 == CommandsInterface.CF_ACTION_DISABLE && 411 info.status == 1) { 412 // Skip showing error dialog since some operators return 413 // active status even if disable call forward succeeded. 414 // And they don't like the error dialog. 415 if (isSkipCFFailToDisableDialog()) { 416 Log.d(LOG_TAG, "Skipped Callforwarding fail-to-disable dialog"); 417 continue; 418 } 419 CharSequence s; 420 switch (reason) { 421 case CommandsInterface.CF_REASON_BUSY: 422 s = getContext().getText(R.string.disable_cfb_forbidden); 423 break; 424 case CommandsInterface.CF_REASON_NO_REPLY: 425 s = getContext().getText(R.string.disable_cfnry_forbidden); 426 break; 427 default: // not reachable 428 s = getContext().getText(R.string.disable_cfnrc_forbidden); 429 } 430 AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); 431 builder.setNeutralButton(R.string.close_dialog, null); 432 builder.setTitle(getContext() 433 .getText(R.string.error_updating_title)); 434 builder.setMessage(s); 435 builder.setCancelable(true); 436 builder.create().show(); 437 } else if (msg.arg2 == MESSAGE_SET_CF && 438 msg.arg1 == CommandsInterface.CF_ACTION_REGISTRATION && 439 info.status == 0) { 440 // Handle the fail-to-enable case. 441 CharSequence s = getContext() 442 .getText(R.string.registration_cf_forbidden); 443 AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); 444 builder.setNeutralButton(R.string.close_dialog, null); 445 builder.setTitle(getContext() 446 .getText(R.string.error_updating_title)); 447 builder.setMessage(s); 448 builder.setCancelable(true); 449 builder.create().show(); 450 } 451 } 452 } 453 } 454 } 455 456 // Now whether or not we got a new number, reset our enabled 457 // summary text since it may have been replaced by an empty 458 // placeholder. 459 // for CDMA, doesn't display summary. 460 if (summaryOff) { 461 setSummaryOff(""); 462 } else { 463 // Now whether or not we got a new number, reset our enabled 464 // summary text since it may have been replaced by an empty 465 // placeholder. 466 updateSummaryText(); 467 } 468 } 469 handleSetCFResponse(Message msg)470 private void handleSetCFResponse(Message msg) { 471 AsyncResult ar = (AsyncResult) msg.obj; 472 if (ar.exception != null) { 473 Log.d(LOG_TAG, "handleSetCFResponse: ar.exception=" + ar.exception); 474 // setEnabled(false); 475 } 476 477 if (ar.result != null) { 478 int arr = (int)ar.result; 479 if (arr == CommandsInterface.SS_STATUS_UNKNOWN) { 480 Log.d(LOG_TAG, "handleSetCFResponse: no need to re get in CDMA"); 481 mTcpListener.onFinished(CallForwardEditPreference.this, false); 482 return; 483 } 484 } 485 486 Log.d(LOG_TAG, "handleSetCFResponse: re get"); 487 if (!mCallForwardByUssd) { 488 mPhone.getCallForwardingOption(reason, mServiceClass, 489 obtainMessage(MESSAGE_GET_CF, msg.arg1, MESSAGE_SET_CF, ar.exception)); 490 } else { 491 mHandler.sendMessage(mHandler.obtainMessage(mHandler.MESSAGE_GET_CF_USSD, 492 msg.arg1, MyHandler.MESSAGE_SET_CF, ar.exception)); 493 } 494 } 495 prepareUssdCommand(Message msg, CarrierXmlParser.SsEntry.SSAction inputSsAction)496 private void prepareUssdCommand(Message msg, 497 CarrierXmlParser.SsEntry.SSAction inputSsAction) { 498 mAction = msg.arg1; 499 mPreviousCommand = msg.arg2; 500 mCommandException = msg.obj; 501 mSsAction = inputSsAction; 502 503 if (mSsAction != CarrierXmlParser.SsEntry.SSAction.QUERY) { 504 if (mAction == CommandsInterface.CF_ACTION_REGISTRATION) { 505 mSsAction = CarrierXmlParser.SsEntry.SSAction.UPDATE_ACTIVATE; 506 } else { 507 mSsAction = CarrierXmlParser.SsEntry.SSAction.UPDATE_DEACTIVATE; 508 } 509 } 510 511 new Thread(new Runnable() { 512 @Override 513 public void run() { 514 sendUssdCommand(mUssdCallback, mSsAction, mCfInfo.isEmpty() ? null : mCfInfo); 515 } 516 }).start(); 517 } 518 sendUssdCommand(TelephonyManager.UssdResponseCallback inputCallback, CarrierXmlParser.SsEntry.SSAction inputAction, HashMap<String, String> inputCfInfo)519 private void sendUssdCommand(TelephonyManager.UssdResponseCallback inputCallback, 520 CarrierXmlParser.SsEntry.SSAction inputAction, 521 HashMap<String, String> inputCfInfo) { 522 String newUssdCommand = mCarrierXmlParser.getFeature( 523 CarrierXmlParser.FEATURE_CALL_FORWARDING) 524 .makeCommand(inputAction, inputCfInfo); 525 TelephonyManager telephonyManager = 526 (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE); 527 telephonyManager.sendUssdRequest(newUssdCommand, inputCallback, mHandler); 528 } 529 makeGetCfMessage(int inputMsgWhat, int inputMsgArg2, Object inputMsgObj)530 private Message makeGetCfMessage(int inputMsgWhat, int inputMsgArg2, Object inputMsgObj) { 531 return mHandler.obtainMessage(inputMsgWhat, 532 mAction, 533 inputMsgArg2, 534 inputMsgObj); 535 } 536 makeSetCfMessage(int inputMsgWhat, int inputMsgArg2)537 private Message makeSetCfMessage(int inputMsgWhat, int inputMsgArg2) { 538 return mHandler.obtainMessage(inputMsgWhat, 539 mAction, 540 inputMsgArg2); 541 } 542 sendCfMessage(Object inputArObj, Throwable inputThrowableException)543 private void sendCfMessage(Object inputArObj, Throwable inputThrowableException) { 544 Message message; 545 if (mSsAction == CarrierXmlParser.SsEntry.SSAction.UNKNOWN) { 546 return; 547 } 548 if (mSsAction == CarrierXmlParser.SsEntry.SSAction.QUERY) { 549 message = makeGetCfMessage(MyHandler.MESSAGE_GET_CF, mPreviousCommand, 550 mCommandException); 551 } else { 552 message = makeSetCfMessage(MyHandler.MESSAGE_SET_CF, MyHandler.MESSAGE_SET_CF); 553 } 554 AsyncResult.forMessage(message, inputArObj, inputThrowableException); 555 message.sendToTarget(); 556 } 557 makeCallForwardInfo(HashMap<String, String> inputInfo)558 private CallForwardInfo[] makeCallForwardInfo(HashMap<String, String> inputInfo) { 559 int tmpStatus = 0; 560 String tmpNumberStr = ""; 561 int tmpTime = 0; 562 if (inputInfo != null && inputInfo.size() != 0) { 563 String tmpStatusStr = inputInfo.get(CarrierXmlParser.TAG_RESPONSE_STATUS); 564 565 String tmpTimeStr = inputInfo.get(CarrierXmlParser.TAG_RESPONSE_TIME); 566 if (!TextUtils.isEmpty(tmpStatusStr)) { 567 if (tmpStatusStr.equals( 568 CarrierXmlParser.TAG_COMMAND_RESULT_DEFINITION_ACTIVATE)) { 569 tmpStatus = 1; 570 } else if (tmpStatusStr.equals( 571 CarrierXmlParser.TAG_COMMAND_RESULT_DEFINITION_DEACTIVATE) 572 || tmpStatusStr.equals( 573 CarrierXmlParser.TAG_COMMAND_RESULT_DEFINITION_UNREGISTER)) { 574 tmpStatus = 0; 575 } 576 } 577 578 tmpNumberStr = inputInfo.get(CarrierXmlParser.TAG_RESPONSE_NUMBER); 579 if (!TextUtils.isEmpty(tmpTimeStr)) { 580 tmpTime = Integer.valueOf(inputInfo.get(CarrierXmlParser.TAG_RESPONSE_TIME)); 581 } 582 } 583 584 CallForwardInfo[] newCallForwardInfo = new CallForwardInfo[1]; 585 newCallForwardInfo[0] = new CallForwardInfo(); 586 newCallForwardInfo[0].status = tmpStatus; 587 newCallForwardInfo[0].reason = reason; 588 newCallForwardInfo[0].serviceClass = mServiceClass; 589 newCallForwardInfo[0].number = tmpNumberStr; 590 newCallForwardInfo[0].timeSeconds = tmpTime; 591 return newCallForwardInfo; 592 } 593 } 594 595 /* 596 * Get the config of whether skip showing CF fail-to-disable dialog 597 * from carrier config manager. 598 * 599 * @return boolean value of the config 600 */ isSkipCFFailToDisableDialog()601 private boolean isSkipCFFailToDisableDialog() { 602 PersistableBundle carrierConfig = 603 PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId()); 604 if (carrierConfig != null) { 605 return carrierConfig.getBoolean( 606 CarrierConfigManager.KEY_SKIP_CF_FAIL_TO_DISABLE_DIALOG_BOOL); 607 } else { 608 // by default we should not skip 609 return false; 610 } 611 } 612 } 613