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