1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.telephony;
18
19import android.os.Bundle;
20import android.os.Handler;
21import android.os.Message;
22import android.telephony.ServiceState;
23import android.telephony.SignalStrength;
24import android.telephony.CellLocation;
25import android.util.Log;
26
27import com.android.internal.telephony.IPhoneStateListener;
28import com.android.internal.telephony.Phone;
29
30/**
31 * A listener class for monitoring changes in specific telephony states
32 * on the device, including service state, signal strength, message
33 * waiting indicator (voicemail), and others.
34 * <p>
35 * Override the methods for the state that you wish to receive updates for, and
36 * pass your PhoneStateListener object, along with bitwise-or of the LISTEN_
37 * flags to {@link TelephonyManager#listen TelephonyManager.listen()}.
38 * <p>
39 * Note that access to some telephony information is
40 * permission-protected. Your application won't receive updates for protected
41 * information unless it has the appropriate permissions declared in
42 * its manifest file. Where permissions apply, they are noted in the
43 * appropriate LISTEN_ flags.
44 */
45public class PhoneStateListener {
46
47    /**
48     * Stop listening for updates.
49     */
50    public static final int LISTEN_NONE = 0;
51
52    /**
53     *  Listen for changes to the network service state (cellular).
54     *
55     *  @see #onServiceStateChanged
56     *  @see ServiceState
57     */
58    public static final int LISTEN_SERVICE_STATE                            = 0x00000001;
59
60    /**
61     * Listen for changes to the network signal strength (cellular).
62     * {@more}
63     * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
64     * READ_PHONE_STATE}
65     * <p>
66     *
67     * @see #onSignalStrengthChanged
68     *
69     * @deprecated by {@link #LISTEN_SIGNAL_STRENGTHS}
70     */
71    @Deprecated
72    public static final int LISTEN_SIGNAL_STRENGTH                          = 0x00000002;
73
74    /**
75     * Listen for changes to the message-waiting indicator.
76     * {@more}
77     * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
78     * READ_PHONE_STATE}
79     * <p>
80     * Example: The status bar uses this to determine when to display the
81     * voicemail icon.
82     *
83     * @see #onMessageWaitingIndicatorChanged
84     */
85    public static final int LISTEN_MESSAGE_WAITING_INDICATOR                = 0x00000004;
86
87    /**
88     * Listen for changes to the call-forwarding indicator.
89     * {@more}
90     * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
91     * READ_PHONE_STATE}
92     * @see #onCallForwardingIndicatorChanged
93     */
94    public static final int LISTEN_CALL_FORWARDING_INDICATOR                = 0x00000008;
95
96    /**
97     * Listen for changes to the device's cell location. Note that
98     * this will result in frequent callbacks to the listener.
99     * {@more}
100     * Requires Permission: {@link android.Manifest.permission#ACCESS_COARSE_LOCATION
101     * ACCESS_COARSE_LOCATION}
102     * <p>
103     * If you need regular location updates but want more control over
104     * the update interval or location precision, you can set up a listener
105     * through the {@link android.location.LocationManager location manager}
106     * instead.
107     *
108     * @see #onCellLocationChanged
109     */
110    public static final int LISTEN_CELL_LOCATION                            = 0x00000010;
111
112    /**
113     * Listen for changes to the device call state.
114     * {@more}
115     * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
116     * READ_PHONE_STATE}
117     * @see #onCallStateChanged
118     */
119    public static final int LISTEN_CALL_STATE                               = 0x00000020;
120
121    /**
122     * Listen for changes to the data connection state (cellular).
123     *
124     * @see #onDataConnectionStateChanged
125     */
126    public static final int LISTEN_DATA_CONNECTION_STATE                    = 0x00000040;
127
128    /**
129     * Listen for changes to the direction of data traffic on the data
130     * connection (cellular).
131     * {@more}
132     * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
133     * READ_PHONE_STATE}
134     * Example: The status bar uses this to display the appropriate
135     * data-traffic icon.
136     *
137     * @see #onDataActivity
138     */
139    public static final int LISTEN_DATA_ACTIVITY                            = 0x00000080;
140
141    /**
142     * Listen for changes to the network signal strengths (cellular).
143     * <p>
144     * Example: The status bar uses this to control the signal-strength
145     * icon.
146     *
147     * @see #onSignalStrengthsChanged
148     */
149    public static final int LISTEN_SIGNAL_STRENGTHS                         = 0x00000100;
150
151    /**
152     * Listen for changes to OTASP mode.
153     *
154     * @see #onOtaspChanged
155     * @hide
156     */
157    public static final int LISTEN_OTASP_CHANGED                            = 0x00000200;
158
159    public PhoneStateListener() {
160    }
161
162    /**
163     * Callback invoked when device service state changes.
164     *
165     * @see ServiceState#STATE_EMERGENCY_ONLY
166     * @see ServiceState#STATE_IN_SERVICE
167     * @see ServiceState#STATE_OUT_OF_SERVICE
168     * @see ServiceState#STATE_POWER_OFF
169     */
170    public void onServiceStateChanged(ServiceState serviceState) {
171        // default implementation empty
172    }
173
174    /**
175     * Callback invoked when network signal strength changes.
176     *
177     * @see ServiceState#STATE_EMERGENCY_ONLY
178     * @see ServiceState#STATE_IN_SERVICE
179     * @see ServiceState#STATE_OUT_OF_SERVICE
180     * @see ServiceState#STATE_POWER_OFF
181     * @deprecated Use {@link #onSignalStrengthsChanged(SignalStrength)}
182     */
183    @Deprecated
184    public void onSignalStrengthChanged(int asu) {
185        // default implementation empty
186    }
187
188    /**
189     * Callback invoked when the message-waiting indicator changes.
190     */
191    public void onMessageWaitingIndicatorChanged(boolean mwi) {
192        // default implementation empty
193    }
194
195    /**
196     * Callback invoked when the call-forwarding indicator changes.
197     */
198    public void onCallForwardingIndicatorChanged(boolean cfi) {
199        // default implementation empty
200    }
201
202    /**
203     * Callback invoked when device cell location changes.
204     */
205    public void onCellLocationChanged(CellLocation location) {
206        // default implementation empty
207    }
208
209    /**
210     * Callback invoked when device call state changes.
211     *
212     * @see TelephonyManager#CALL_STATE_IDLE
213     * @see TelephonyManager#CALL_STATE_RINGING
214     * @see TelephonyManager#CALL_STATE_OFFHOOK
215     */
216    public void onCallStateChanged(int state, String incomingNumber) {
217        // default implementation empty
218    }
219
220    /**
221     * Callback invoked when connection state changes.
222     *
223     * @see TelephonyManager#DATA_DISCONNECTED
224     * @see TelephonyManager#DATA_CONNECTING
225     * @see TelephonyManager#DATA_CONNECTED
226     * @see TelephonyManager#DATA_SUSPENDED
227     */
228    public void onDataConnectionStateChanged(int state) {
229        // default implementation empty
230    }
231
232    /**
233     * same as above, but with the network type.  Both called.
234     */
235    public void onDataConnectionStateChanged(int state, int networkType) {
236    }
237
238    /**
239     * Callback invoked when data activity state changes.
240     *
241     * @see TelephonyManager#DATA_ACTIVITY_NONE
242     * @see TelephonyManager#DATA_ACTIVITY_IN
243     * @see TelephonyManager#DATA_ACTIVITY_OUT
244     * @see TelephonyManager#DATA_ACTIVITY_INOUT
245     * @see TelephonyManager#DATA_ACTIVITY_DORMANT
246     */
247    public void onDataActivity(int direction) {
248        // default implementation empty
249    }
250
251    /**
252     * Callback invoked when network signal strengths changes.
253     *
254     * @see ServiceState#STATE_EMERGENCY_ONLY
255     * @see ServiceState#STATE_IN_SERVICE
256     * @see ServiceState#STATE_OUT_OF_SERVICE
257     * @see ServiceState#STATE_POWER_OFF
258     */
259    public void onSignalStrengthsChanged(SignalStrength signalStrength) {
260        // default implementation empty
261    }
262
263
264    /**
265     * The Over The Air Service Provisioning (OTASP) has changed. Requires
266     * the READ_PHONE_STATE permission.
267     * @param otaspMode is integer <code>OTASP_UNKNOWN=1<code>
268     *   means the value is currently unknown and the system should wait until
269     *   <code>OTASP_NEEDED=2<code> or <code>OTASP_NOT_NEEDED=3<code> is received before
270     *   making the decisision to perform OTASP or not.
271     *
272     * @hide
273     */
274    public void onOtaspChanged(int otaspMode) {
275        // default implementation empty
276    }
277
278    /**
279     * The callback methods need to be called on the handler thread where
280     * this object was created.  If the binder did that for us it'd be nice.
281     */
282    IPhoneStateListener callback = new IPhoneStateListener.Stub() {
283        public void onServiceStateChanged(ServiceState serviceState) {
284            Message.obtain(mHandler, LISTEN_SERVICE_STATE, 0, 0, serviceState).sendToTarget();
285        }
286
287        public void onSignalStrengthChanged(int asu) {
288            Message.obtain(mHandler, LISTEN_SIGNAL_STRENGTH, asu, 0, null).sendToTarget();
289        }
290
291        public void onMessageWaitingIndicatorChanged(boolean mwi) {
292            Message.obtain(mHandler, LISTEN_MESSAGE_WAITING_INDICATOR, mwi ? 1 : 0, 0, null)
293                    .sendToTarget();
294        }
295
296        public void onCallForwardingIndicatorChanged(boolean cfi) {
297            Message.obtain(mHandler, LISTEN_CALL_FORWARDING_INDICATOR, cfi ? 1 : 0, 0, null)
298                    .sendToTarget();
299        }
300
301        public void onCellLocationChanged(Bundle bundle) {
302            CellLocation location = CellLocation.newFromBundle(bundle);
303            Message.obtain(mHandler, LISTEN_CELL_LOCATION, 0, 0, location).sendToTarget();
304        }
305
306        public void onCallStateChanged(int state, String incomingNumber) {
307            Message.obtain(mHandler, LISTEN_CALL_STATE, state, 0, incomingNumber).sendToTarget();
308        }
309
310        public void onDataConnectionStateChanged(int state, int networkType) {
311            Message.obtain(mHandler, LISTEN_DATA_CONNECTION_STATE, state, networkType).
312                    sendToTarget();
313        }
314
315        public void onDataActivity(int direction) {
316            Message.obtain(mHandler, LISTEN_DATA_ACTIVITY, direction, 0, null).sendToTarget();
317        }
318
319        public void onSignalStrengthsChanged(SignalStrength signalStrength) {
320            Message.obtain(mHandler, LISTEN_SIGNAL_STRENGTHS, 0, 0, signalStrength).sendToTarget();
321        }
322
323        public void onOtaspChanged(int otaspMode) {
324            Message.obtain(mHandler, LISTEN_OTASP_CHANGED, otaspMode, 0).sendToTarget();
325        }
326    };
327
328    Handler mHandler = new Handler() {
329        public void handleMessage(Message msg) {
330            //Log.d("TelephonyRegistry", "what=0x" + Integer.toHexString(msg.what) + " msg=" + msg);
331            switch (msg.what) {
332                case LISTEN_SERVICE_STATE:
333                    PhoneStateListener.this.onServiceStateChanged((ServiceState)msg.obj);
334                    break;
335                case LISTEN_SIGNAL_STRENGTH:
336                    PhoneStateListener.this.onSignalStrengthChanged(msg.arg1);
337                    break;
338                case LISTEN_MESSAGE_WAITING_INDICATOR:
339                    PhoneStateListener.this.onMessageWaitingIndicatorChanged(msg.arg1 != 0);
340                    break;
341                case LISTEN_CALL_FORWARDING_INDICATOR:
342                    PhoneStateListener.this.onCallForwardingIndicatorChanged(msg.arg1 != 0);
343                    break;
344                case LISTEN_CELL_LOCATION:
345                    PhoneStateListener.this.onCellLocationChanged((CellLocation)msg.obj);
346                    break;
347                case LISTEN_CALL_STATE:
348                    PhoneStateListener.this.onCallStateChanged(msg.arg1, (String)msg.obj);
349                    break;
350                case LISTEN_DATA_CONNECTION_STATE:
351                    PhoneStateListener.this.onDataConnectionStateChanged(msg.arg1, msg.arg2);
352                    PhoneStateListener.this.onDataConnectionStateChanged(msg.arg1);
353                    break;
354                case LISTEN_DATA_ACTIVITY:
355                    PhoneStateListener.this.onDataActivity(msg.arg1);
356                    break;
357                case LISTEN_SIGNAL_STRENGTHS:
358                    PhoneStateListener.this.onSignalStrengthsChanged((SignalStrength)msg.obj);
359                    break;
360                case LISTEN_OTASP_CHANGED:
361                    PhoneStateListener.this.onOtaspChanged(msg.arg1);
362                    break;
363            }
364        }
365    };
366}
367