diff options
Diffstat (limited to 'src/com/android/phone/CallForwardEditPreference.java')
-rw-r--r-- | src/com/android/phone/CallForwardEditPreference.java | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/src/com/android/phone/CallForwardEditPreference.java b/src/com/android/phone/CallForwardEditPreference.java new file mode 100644 index 00000000..f9250221 --- /dev/null +++ b/src/com/android/phone/CallForwardEditPreference.java @@ -0,0 +1,265 @@ +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)); + } + } +} |