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