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