Home | History | Annotate | Download | only in phone
      1 package com.android.phone;
      2 
      3 import com.android.internal.telephony.CallForwardInfo;
      4 import com.android.internal.telephony.CommandException;
      5 import com.android.internal.telephony.CommandsInterface;
      6 import com.android.internal.telephony.Phone;
      7 
      8 import android.app.AlertDialog;
      9 import android.content.Context;
     10 import android.content.DialogInterface;
     11 import android.content.res.TypedArray;
     12 import android.os.AsyncResult;
     13 import android.os.Handler;
     14 import android.os.Message;
     15 import android.text.TextUtils;
     16 import android.util.AttributeSet;
     17 import android.util.Log;
     18 
     19 import static com.android.phone.TimeConsumingPreferenceActivity.RESPONSE_ERROR;
     20 
     21 public class CallForwardEditPreference extends EditPhoneNumberPreference {
     22     private static final String LOG_TAG = "CallForwardEditPreference";
     23     private static final boolean DBG = (PhoneApp.DBG_LEVEL >= 2);
     24 
     25     private static final String SRC_TAGS[]       = {"{0}"};
     26     private CharSequence mSummaryOnTemplate;
     27     private int mButtonClicked;
     28     private int mServiceClass;
     29     private MyHandler mHandler = new MyHandler();
     30     int reason;
     31     Phone phone;
     32     CallForwardInfo callForwardInfo;
     33     TimeConsumingPreferenceListener tcpListener;
     34 
     35     public CallForwardEditPreference(Context context, AttributeSet attrs) {
     36         super(context, attrs);
     37 
     38         phone = PhoneApp.getPhone();
     39         mSummaryOnTemplate = this.getSummaryOn();
     40 
     41         TypedArray a = context.obtainStyledAttributes(attrs,
     42                 R.styleable.CallForwardEditPreference, 0, R.style.EditPhoneNumberPreference);
     43         mServiceClass = a.getInt(R.styleable.CallForwardEditPreference_serviceClass,
     44                 CommandsInterface.SERVICE_CLASS_VOICE);
     45         reason = a.getInt(R.styleable.CallForwardEditPreference_reason,
     46                 CommandsInterface.CF_REASON_UNCONDITIONAL);
     47         a.recycle();
     48 
     49         if (DBG) Log.d(LOG_TAG, "mServiceClass=" + mServiceClass + ", reason=" + reason);
     50     }
     51 
     52     public CallForwardEditPreference(Context context) {
     53         this(context, null);
     54     }
     55 
     56     void init(TimeConsumingPreferenceListener listener, boolean skipReading) {
     57         tcpListener = listener;
     58         if (!skipReading) {
     59             phone.getCallForwardingOption(reason,
     60                     mHandler.obtainMessage(MyHandler.MESSAGE_GET_CF,
     61                             // unused in this case
     62                             CommandsInterface.CF_ACTION_DISABLE,
     63                             MyHandler.MESSAGE_GET_CF, null));
     64             if (tcpListener != null) {
     65                 tcpListener.onStarted(this, true);
     66             }
     67         }
     68     }
     69 
     70     @Override
     71     public void onClick(DialogInterface dialog, int which) {
     72         super.onClick(dialog, which);
     73         mButtonClicked = which;
     74     }
     75 
     76     @Override
     77     protected void onDialogClosed(boolean positiveResult) {
     78         super.onDialogClosed(positiveResult);
     79 
     80         if (DBG) Log.d(LOG_TAG, "mButtonClicked=" + mButtonClicked
     81                 + ", positiveResult=" + positiveResult);
     82         if (this.mButtonClicked != DialogInterface.BUTTON_NEGATIVE) {
     83             int action = (isToggled() || (mButtonClicked == DialogInterface.BUTTON_POSITIVE)) ?
     84                     CommandsInterface.CF_ACTION_REGISTRATION :
     85                     CommandsInterface.CF_ACTION_DISABLE;
     86             int time = (reason != CommandsInterface.CF_REASON_NO_REPLY) ? 0 : 20;
     87             final String number = getPhoneNumber();
     88 
     89             if (DBG) Log.d(LOG_TAG, "callForwardInfo=" + callForwardInfo);
     90 
     91             if (action == CommandsInterface.CF_ACTION_REGISTRATION
     92                     && callForwardInfo != null
     93                     && callForwardInfo.status == 1
     94                     && number.equals(callForwardInfo.number)) {
     95                 // no change, do nothing
     96                 if (DBG) Log.d(LOG_TAG, "no change, do nothing");
     97             } else {
     98                 // set to network
     99                 if (DBG) Log.d(LOG_TAG, "reason=" + reason + ", action=" + action
    100                         + ", number=" + number);
    101 
    102                 // Display no forwarding number while we're waiting for
    103                 // confirmation
    104                 setSummaryOn("");
    105 
    106                 // the interface of Phone.setCallForwardingOption has error:
    107                 // should be action, reason...
    108                 phone.setCallForwardingOption(action,
    109                         reason,
    110                         number,
    111                         time,
    112                         mHandler.obtainMessage(MyHandler.MESSAGE_SET_CF,
    113                                 action,
    114                                 MyHandler.MESSAGE_SET_CF));
    115 
    116                 if (tcpListener != null) {
    117                     tcpListener.onStarted(this, false);
    118                 }
    119             }
    120         }
    121     }
    122 
    123     void handleCallForwardResult(CallForwardInfo cf) {
    124         callForwardInfo = cf;
    125         if (DBG) Log.d(LOG_TAG, "handleGetCFResponse done, callForwardInfo=" + callForwardInfo);
    126 
    127         setToggled(callForwardInfo.status == 1);
    128         setPhoneNumber(callForwardInfo.number);
    129     }
    130 
    131     private void updateSummaryText() {
    132         if (isToggled()) {
    133             CharSequence summaryOn;
    134             final String number = getRawPhoneNumber();
    135             if (number != null && number.length() > 0) {
    136                 String values[] = { number };
    137                 summaryOn = TextUtils.replace(mSummaryOnTemplate, SRC_TAGS, values);
    138             } else {
    139                 summaryOn = getContext().getString(R.string.sum_cfu_enabled_no_number);
    140             }
    141             setSummaryOn(summaryOn);
    142         }
    143 
    144     }
    145 
    146     // Message protocol:
    147     // what: get vs. set
    148     // arg1: action -- register vs. disable
    149     // arg2: get vs. set for the preceding request
    150     private class MyHandler extends Handler {
    151         private static final int MESSAGE_GET_CF = 0;
    152         private static final int MESSAGE_SET_CF = 1;
    153 
    154         @Override
    155         public void handleMessage(Message msg) {
    156             switch (msg.what) {
    157                 case MESSAGE_GET_CF:
    158                     handleGetCFResponse(msg);
    159                     break;
    160                 case MESSAGE_SET_CF:
    161                     handleSetCFResponse(msg);
    162                     break;
    163             }
    164         }
    165 
    166         private void handleGetCFResponse(Message msg) {
    167             if (DBG) Log.d(LOG_TAG, "handleGetCFResponse: done");
    168 
    169             if (msg.arg2 == MESSAGE_SET_CF) {
    170                 tcpListener.onFinished(CallForwardEditPreference.this, false);
    171             } else {
    172                 tcpListener.onFinished(CallForwardEditPreference.this, true);
    173             }
    174 
    175             AsyncResult ar = (AsyncResult) msg.obj;
    176 
    177             callForwardInfo = null;
    178             if (ar.exception != null) {
    179                 if (DBG) Log.d(LOG_TAG, "handleGetCFResponse: ar.exception=" + ar.exception);
    180                 tcpListener.onException(CallForwardEditPreference.this,
    181                         (CommandException) ar.exception);
    182             } else {
    183                 if (ar.userObj instanceof Throwable) {
    184                     tcpListener.onError(CallForwardEditPreference.this, RESPONSE_ERROR);
    185                 }
    186                 CallForwardInfo cfInfoArray[] = (CallForwardInfo[]) ar.result;
    187                 if (cfInfoArray.length == 0) {
    188                     if (DBG) Log.d(LOG_TAG, "handleGetCFResponse: cfInfoArray.length==0");
    189                     setEnabled(false);
    190                     tcpListener.onError(CallForwardEditPreference.this, RESPONSE_ERROR);
    191                 } else {
    192                     for (int i = 0, length = cfInfoArray.length; i < length; i++) {
    193                         if (DBG) Log.d(LOG_TAG, "handleGetCFResponse, cfInfoArray[" + i + "]="
    194                                 + cfInfoArray[i]);
    195                         if ((mServiceClass & cfInfoArray[i].serviceClass) != 0) {
    196                             // corresponding class
    197                             CallForwardInfo info = cfInfoArray[i];
    198                             handleCallForwardResult(info);
    199 
    200                             // Show an alert if we got a success response but
    201                             // with unexpected values.
    202                             // Currently only handle the fail-to-disable case
    203                             // since we haven't observed fail-to-enable.
    204                             if (msg.arg2 == MESSAGE_SET_CF &&
    205                                     msg.arg1 == CommandsInterface.CF_ACTION_DISABLE &&
    206                                     info.status == 1) {
    207                                 CharSequence s;
    208                                 switch (reason) {
    209                                     case CommandsInterface.CF_REASON_BUSY:
    210                                         s = getContext().getText(R.string.disable_cfb_forbidden);
    211                                         break;
    212                                     case CommandsInterface.CF_REASON_NO_REPLY:
    213                                         s = getContext().getText(R.string.disable_cfnry_forbidden);
    214                                         break;
    215                                     default: // not reachable
    216                                         s = getContext().getText(R.string.disable_cfnrc_forbidden);
    217                                 }
    218                                 AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
    219                                 builder.setNeutralButton(R.string.close_dialog, null);
    220                                 builder.setTitle(getContext().getText(R.string.error_updating_title));
    221                                 builder.setMessage(s);
    222                                 builder.setCancelable(true);
    223                                 builder.create().show();
    224                             }
    225                         }
    226                     }
    227                 }
    228             }
    229 
    230             // Now whether or not we got a new number, reset our enabled
    231             // summary text since it may have been replaced by an empty
    232             // placeholder.
    233             updateSummaryText();
    234         }
    235 
    236         private void handleSetCFResponse(Message msg) {
    237             AsyncResult ar = (AsyncResult) msg.obj;
    238 
    239             if (ar.exception != null) {
    240                 if (DBG) Log.d(LOG_TAG, "handleSetCFResponse: ar.exception=" + ar.exception);
    241                 // setEnabled(false);
    242             }
    243             if (DBG) Log.d(LOG_TAG, "handleSetCFResponse: re get");
    244             phone.getCallForwardingOption(reason,
    245                     obtainMessage(MESSAGE_GET_CF, msg.arg1, MESSAGE_SET_CF, ar.exception));
    246         }
    247     }
    248 }
    249