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