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