1package com.android.phone;
2
3import com.android.internal.telephony.CommandException;
4import com.android.internal.telephony.Phone;
5
6import static com.android.phone.TimeConsumingPreferenceActivity.RESPONSE_ERROR;
7
8import android.content.Context;
9import android.os.AsyncResult;
10import android.os.Handler;
11import android.os.Message;
12import android.preference.SwitchPreference;
13import android.util.AttributeSet;
14import android.util.Log;
15
16public class CallWaitingSwitchPreference extends SwitchPreference {
17    private static final String LOG_TAG = "CallWaitingSwitchPreference";
18    private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
19
20    private final MyHandler mHandler = new MyHandler();
21    private Phone mPhone;
22    private TimeConsumingPreferenceListener mTcpListener;
23
24    public CallWaitingSwitchPreference(Context context, AttributeSet attrs, int defStyle) {
25        super(context, attrs, defStyle);
26    }
27
28    public CallWaitingSwitchPreference(Context context, AttributeSet attrs) {
29        this(context, attrs, com.android.internal.R.attr.switchPreferenceStyle);
30    }
31
32    public CallWaitingSwitchPreference(Context context) {
33        this(context, null);
34    }
35
36    /* package */ void init(
37            TimeConsumingPreferenceListener listener, boolean skipReading, Phone phone) {
38        mPhone = phone;
39        mTcpListener = listener;
40
41        if (!skipReading) {
42            mPhone.getCallWaiting(mHandler.obtainMessage(MyHandler.MESSAGE_GET_CALL_WAITING,
43                    MyHandler.MESSAGE_GET_CALL_WAITING, MyHandler.MESSAGE_GET_CALL_WAITING));
44            if (mTcpListener != null) {
45                mTcpListener.onStarted(this, true);
46            }
47        }
48    }
49
50    @Override
51    protected void onClick() {
52        super.onClick();
53
54        mPhone.setCallWaiting(isChecked(),
55                mHandler.obtainMessage(MyHandler.MESSAGE_SET_CALL_WAITING));
56        if (mTcpListener != null) {
57            mTcpListener.onStarted(this, false);
58        }
59    }
60
61    private class MyHandler extends Handler {
62        static final int MESSAGE_GET_CALL_WAITING = 0;
63        static final int MESSAGE_SET_CALL_WAITING = 1;
64
65        @Override
66        public void handleMessage(Message msg) {
67            switch (msg.what) {
68                case MESSAGE_GET_CALL_WAITING:
69                    handleGetCallWaitingResponse(msg);
70                    break;
71                case MESSAGE_SET_CALL_WAITING:
72                    handleSetCallWaitingResponse(msg);
73                    break;
74            }
75        }
76
77        private void handleGetCallWaitingResponse(Message msg) {
78            AsyncResult ar = (AsyncResult) msg.obj;
79
80            if (mTcpListener != null) {
81                if (msg.arg2 == MESSAGE_SET_CALL_WAITING) {
82                    mTcpListener.onFinished(CallWaitingSwitchPreference.this, false);
83                } else {
84                    mTcpListener.onFinished(CallWaitingSwitchPreference.this, true);
85                }
86            }
87
88            if (ar.exception instanceof CommandException) {
89                if (DBG) {
90                    Log.d(LOG_TAG, "handleGetCallWaitingResponse: CommandException=" +
91                            ar.exception);
92                }
93                if (mTcpListener != null) {
94                    mTcpListener.onException(CallWaitingSwitchPreference.this,
95                            (CommandException)ar.exception);
96                }
97            } else if (ar.userObj instanceof Throwable || ar.exception != null) {
98                // Still an error case but just not a CommandException.
99                if (DBG) {
100                    Log.d(LOG_TAG, "handleGetCallWaitingResponse: Exception" + ar.exception);
101                }
102                if (mTcpListener != null) {
103                    mTcpListener.onError(CallWaitingSwitchPreference.this, RESPONSE_ERROR);
104                }
105            } else {
106                if (DBG) {
107                    Log.d(LOG_TAG, "handleGetCallWaitingResponse: CW state successfully queried.");
108                }
109                int[] cwArray = (int[])ar.result;
110                // If cwArray[0] is = 1, then cwArray[1] must follow,
111                // with the TS 27.007 service class bit vector of services
112                // for which call waiting is enabled.
113                try {
114                    setChecked(((cwArray[0] == 1) && ((cwArray[1] & 0x01) == 0x01)));
115                } catch (ArrayIndexOutOfBoundsException e) {
116                    Log.e(LOG_TAG, "handleGetCallWaitingResponse: improper result: err ="
117                            + e.getMessage());
118                }
119            }
120        }
121
122        private void handleSetCallWaitingResponse(Message msg) {
123            AsyncResult ar = (AsyncResult) msg.obj;
124
125            if (ar.exception != null) {
126                if (DBG) {
127                    Log.d(LOG_TAG, "handleSetCallWaitingResponse: ar.exception=" + ar.exception);
128                }
129                //setEnabled(false);
130            }
131            if (DBG) Log.d(LOG_TAG, "handleSetCallWaitingResponse: re get");
132
133            mPhone.getCallWaiting(obtainMessage(MESSAGE_GET_CALL_WAITING,
134                    MESSAGE_SET_CALL_WAITING, MESSAGE_SET_CALL_WAITING, ar.exception));
135        }
136    }
137}
138