summaryrefslogtreecommitdiff
path: root/src/com/android/phone/CallForwardEditPreference.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/phone/CallForwardEditPreference.java')
-rw-r--r--src/com/android/phone/CallForwardEditPreference.java265
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));
+ }
+ }
+}