| package com.android.phone; |
| |
| import com.android.internal.telephony.CallForwardInfo; |
| import com.android.internal.telephony.CommandException; |
| import com.android.internal.telephony.CommandsInterface; |
| import com.android.internal.telephony.Phone; |
| |
| import android.app.AlertDialog; |
| import android.content.Context; |
| import android.content.DialogInterface; |
| import android.content.res.TypedArray; |
| import android.os.AsyncResult; |
| import android.os.Handler; |
| import android.os.Message; |
| import android.text.TextUtils; |
| import android.util.AttributeSet; |
| import android.util.Log; |
| import android.view.View; |
| |
| import static com.android.phone.TimeConsumingPreferenceActivity.RESPONSE_ERROR; |
| |
| public class CallForwardEditPreference extends EditPhoneNumberPreference { |
| private static final String LOG_TAG = "CallForwardEditPreference"; |
| private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2); |
| |
| private static final String SRC_TAGS[] = {"{0}"}; |
| private CharSequence mSummaryOnTemplate; |
| /** |
| * Remembers which button was clicked by a user. If no button is clicked yet, this should have |
| * {@link DialogInterface#BUTTON_NEGATIVE}, meaning "cancel". |
| * |
| * TODO: consider removing this variable and having getButtonClicked() in |
| * EditPhoneNumberPreference instead. |
| */ |
| private int mButtonClicked; |
| private int mServiceClass; |
| private MyHandler mHandler = new MyHandler(); |
| int reason; |
| Phone phone; |
| CallForwardInfo callForwardInfo; |
| TimeConsumingPreferenceListener tcpListener; |
| |
| public CallForwardEditPreference(Context context, AttributeSet attrs) { |
| super(context, attrs); |
| |
| phone = PhoneGlobals.getPhone(); |
| mSummaryOnTemplate = this.getSummaryOn(); |
| |
| TypedArray a = context.obtainStyledAttributes(attrs, |
| R.styleable.CallForwardEditPreference, 0, R.style.EditPhoneNumberPreference); |
| mServiceClass = a.getInt(R.styleable.CallForwardEditPreference_serviceClass, |
| CommandsInterface.SERVICE_CLASS_VOICE); |
| reason = a.getInt(R.styleable.CallForwardEditPreference_reason, |
| CommandsInterface.CF_REASON_UNCONDITIONAL); |
| a.recycle(); |
| |
| if (DBG) Log.d(LOG_TAG, "mServiceClass=" + mServiceClass + ", reason=" + reason); |
| } |
| |
| public CallForwardEditPreference(Context context) { |
| this(context, null); |
| } |
| |
| void init(TimeConsumingPreferenceListener listener, boolean skipReading) { |
| tcpListener = listener; |
| if (!skipReading) { |
| phone.getCallForwardingOption(reason, |
| mHandler.obtainMessage(MyHandler.MESSAGE_GET_CF, |
| // unused in this case |
| CommandsInterface.CF_ACTION_DISABLE, |
| MyHandler.MESSAGE_GET_CF, null)); |
| if (tcpListener != null) { |
| tcpListener.onStarted(this, true); |
| } |
| } |
| } |
| |
| @Override |
| protected void onBindDialogView(View view) { |
| // default the button clicked to be the cancel button. |
| mButtonClicked = DialogInterface.BUTTON_NEGATIVE; |
| super.onBindDialogView(view); |
| } |
| |
| @Override |
| public void onClick(DialogInterface dialog, int which) { |
| super.onClick(dialog, which); |
| mButtonClicked = which; |
| } |
| |
| @Override |
| protected void onDialogClosed(boolean positiveResult) { |
| super.onDialogClosed(positiveResult); |
| |
| if (DBG) Log.d(LOG_TAG, "mButtonClicked=" + mButtonClicked |
| + ", positiveResult=" + positiveResult); |
| // Ignore this event if the user clicked the cancel button, or if the dialog is dismissed |
| // without any button being pressed (back button press or click event outside the dialog). |
| if (this.mButtonClicked != DialogInterface.BUTTON_NEGATIVE) { |
| int action = (isToggled() || (mButtonClicked == DialogInterface.BUTTON_POSITIVE)) ? |
| CommandsInterface.CF_ACTION_REGISTRATION : |
| CommandsInterface.CF_ACTION_DISABLE; |
| int time = (reason != CommandsInterface.CF_REASON_NO_REPLY) ? 0 : 20; |
| final String number = getPhoneNumber(); |
| |
| if (DBG) Log.d(LOG_TAG, "callForwardInfo=" + callForwardInfo); |
| |
| if (action == CommandsInterface.CF_ACTION_REGISTRATION |
| && callForwardInfo != null |
| && callForwardInfo.status == 1 |
| && number.equals(callForwardInfo.number)) { |
| // no change, do nothing |
| if (DBG) Log.d(LOG_TAG, "no change, do nothing"); |
| } else { |
| // set to network |
| if (DBG) Log.d(LOG_TAG, "reason=" + reason + ", action=" + action |
| + ", number=" + number); |
| |
| // Display no forwarding number while we're waiting for |
| // confirmation |
| setSummaryOn(""); |
| |
| // the interface of Phone.setCallForwardingOption has error: |
| // should be action, reason... |
| phone.setCallForwardingOption(action, |
| reason, |
| number, |
| time, |
| mHandler.obtainMessage(MyHandler.MESSAGE_SET_CF, |
| action, |
| MyHandler.MESSAGE_SET_CF)); |
| |
| if (tcpListener != null) { |
| tcpListener.onStarted(this, false); |
| } |
| } |
| } |
| } |
| |
| void handleCallForwardResult(CallForwardInfo cf) { |
| callForwardInfo = cf; |
| if (DBG) Log.d(LOG_TAG, "handleGetCFResponse done, callForwardInfo=" + callForwardInfo); |
| |
| setToggled(callForwardInfo.status == 1); |
| setPhoneNumber(callForwardInfo.number); |
| } |
| |
| private void updateSummaryText() { |
| if (isToggled()) { |
| CharSequence summaryOn; |
| final String number = getRawPhoneNumber(); |
| if (number != null && number.length() > 0) { |
| String values[] = { number }; |
| summaryOn = TextUtils.replace(mSummaryOnTemplate, SRC_TAGS, values); |
| } else { |
| summaryOn = getContext().getString(R.string.sum_cfu_enabled_no_number); |
| } |
| setSummaryOn(summaryOn); |
| } |
| |
| } |
| |
| // Message protocol: |
| // what: get vs. set |
| // arg1: action -- register vs. disable |
| // arg2: get vs. set for the preceding request |
| private class MyHandler extends Handler { |
| static final int MESSAGE_GET_CF = 0; |
| static final int MESSAGE_SET_CF = 1; |
| |
| @Override |
| public void handleMessage(Message msg) { |
| switch (msg.what) { |
| case MESSAGE_GET_CF: |
| handleGetCFResponse(msg); |
| break; |
| case MESSAGE_SET_CF: |
| handleSetCFResponse(msg); |
| break; |
| } |
| } |
| |
| private void handleGetCFResponse(Message msg) { |
| if (DBG) Log.d(LOG_TAG, "handleGetCFResponse: done"); |
| |
| if (msg.arg2 == MESSAGE_SET_CF) { |
| tcpListener.onFinished(CallForwardEditPreference.this, false); |
| } else { |
| tcpListener.onFinished(CallForwardEditPreference.this, true); |
| } |
| |
| AsyncResult ar = (AsyncResult) msg.obj; |
| |
| callForwardInfo = null; |
| if (ar.exception != null) { |
| if (DBG) Log.d(LOG_TAG, "handleGetCFResponse: ar.exception=" + ar.exception); |
| tcpListener.onException(CallForwardEditPreference.this, |
| (CommandException) ar.exception); |
| } else { |
| if (ar.userObj instanceof Throwable) { |
| tcpListener.onError(CallForwardEditPreference.this, RESPONSE_ERROR); |
| } |
| CallForwardInfo cfInfoArray[] = (CallForwardInfo[]) ar.result; |
| if (cfInfoArray.length == 0) { |
| if (DBG) Log.d(LOG_TAG, "handleGetCFResponse: cfInfoArray.length==0"); |
| setEnabled(false); |
| tcpListener.onError(CallForwardEditPreference.this, RESPONSE_ERROR); |
| } else { |
| for (int i = 0, length = cfInfoArray.length; i < length; i++) { |
| if (DBG) Log.d(LOG_TAG, "handleGetCFResponse, cfInfoArray[" + i + "]=" |
| + cfInfoArray[i]); |
| if ((mServiceClass & cfInfoArray[i].serviceClass) != 0) { |
| // corresponding class |
| CallForwardInfo info = cfInfoArray[i]; |
| handleCallForwardResult(info); |
| |
| // Show an alert if we got a success response but |
| // with unexpected values. |
| // Currently only handle the fail-to-disable case |
| // since we haven't observed fail-to-enable. |
| if (msg.arg2 == MESSAGE_SET_CF && |
| msg.arg1 == CommandsInterface.CF_ACTION_DISABLE && |
| info.status == 1) { |
| CharSequence s; |
| switch (reason) { |
| case CommandsInterface.CF_REASON_BUSY: |
| s = getContext().getText(R.string.disable_cfb_forbidden); |
| break; |
| case CommandsInterface.CF_REASON_NO_REPLY: |
| s = getContext().getText(R.string.disable_cfnry_forbidden); |
| break; |
| default: // not reachable |
| s = getContext().getText(R.string.disable_cfnrc_forbidden); |
| } |
| AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); |
| builder.setNeutralButton(R.string.close_dialog, null); |
| builder.setTitle(getContext().getText(R.string.error_updating_title)); |
| builder.setMessage(s); |
| builder.setCancelable(true); |
| builder.create().show(); |
| } |
| } |
| } |
| } |
| } |
| |
| // Now whether or not we got a new number, reset our enabled |
| // summary text since it may have been replaced by an empty |
| // placeholder. |
| updateSummaryText(); |
| } |
| |
| private void handleSetCFResponse(Message msg) { |
| AsyncResult ar = (AsyncResult) msg.obj; |
| |
| if (ar.exception != null) { |
| if (DBG) Log.d(LOG_TAG, "handleSetCFResponse: ar.exception=" + ar.exception); |
| // setEnabled(false); |
| } |
| if (DBG) Log.d(LOG_TAG, "handleSetCFResponse: re get"); |
| phone.getCallForwardingOption(reason, |
| obtainMessage(MESSAGE_GET_CF, msg.arg1, MESSAGE_SET_CF, ar.exception)); |
| } |
| } |
| } |