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