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