• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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