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.Looper;
22import android.os.Message;
23import android.telephony.SubscriptionManager;
24import android.telephony.CellLocation;
25import android.telephony.CellInfo;
26import android.telephony.VoLteServiceState;
27import android.telephony.Rlog;
28import android.telephony.ServiceState;
29import android.telephony.SignalStrength;
30import android.telephony.PreciseCallState;
31import android.telephony.PreciseDataConnectionState;
32
33import com.android.internal.telephony.IPhoneStateListener;
34import java.util.List;
35import java.lang.ref.WeakReference;
36
37/**
38 * A listener class for monitoring changes in specific telephony states
39 * on the device, including service state, signal strength, message
40 * waiting indicator (voicemail), and others.
41 * <p>
42 * Override the methods for the state that you wish to receive updates for, and
43 * pass your PhoneStateListener object, along with bitwise-or of the LISTEN_
44 * flags to {@link TelephonyManager#listen TelephonyManager.listen()}.
45 * <p>
46 * Note that access to some telephony information is
47 * permission-protected. Your application won't receive updates for protected
48 * information unless it has the appropriate permissions declared in
49 * its manifest file. Where permissions apply, they are noted in the
50 * appropriate LISTEN_ flags.
51 */
52public class PhoneStateListener {
53    private static final String LOG_TAG = "PhoneStateListener";
54    private static final boolean DBG = false; // STOPSHIP if true
55
56    /**
57     * Stop listening for updates.
58     */
59    public static final int LISTEN_NONE = 0;
60
61    /**
62     *  Listen for changes to the network service state (cellular).
63     *
64     *  @see #onServiceStateChanged
65     *  @see ServiceState
66     */
67    public static final int LISTEN_SERVICE_STATE                            = 0x00000001;
68
69    /**
70     * Listen for changes to the network signal strength (cellular).
71     * {@more}
72     * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
73     * READ_PHONE_STATE}
74     * <p>
75     *
76     * @see #onSignalStrengthChanged
77     *
78     * @deprecated by {@link #LISTEN_SIGNAL_STRENGTHS}
79     */
80    @Deprecated
81    public static final int LISTEN_SIGNAL_STRENGTH                          = 0x00000002;
82
83    /**
84     * Listen for changes to the message-waiting indicator.
85     * {@more}
86     * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
87     * READ_PHONE_STATE}
88     * <p>
89     * Example: The status bar uses this to determine when to display the
90     * voicemail icon.
91     *
92     * @see #onMessageWaitingIndicatorChanged
93     */
94    public static final int LISTEN_MESSAGE_WAITING_INDICATOR                = 0x00000004;
95
96    /**
97     * Listen for changes to the call-forwarding indicator.
98     * {@more}
99     * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
100     * READ_PHONE_STATE}
101     * @see #onCallForwardingIndicatorChanged
102     */
103    public static final int LISTEN_CALL_FORWARDING_INDICATOR                = 0x00000008;
104
105    /**
106     * Listen for changes to the device's cell location. Note that
107     * this will result in frequent callbacks to the listener.
108     * {@more}
109     * Requires Permission: {@link android.Manifest.permission#ACCESS_COARSE_LOCATION
110     * ACCESS_COARSE_LOCATION}
111     * <p>
112     * If you need regular location updates but want more control over
113     * the update interval or location precision, you can set up a listener
114     * through the {@link android.location.LocationManager location manager}
115     * instead.
116     *
117     * @see #onCellLocationChanged
118     */
119    public static final int LISTEN_CELL_LOCATION                            = 0x00000010;
120
121    /**
122     * Listen for changes to the device call state.
123     * {@more}
124     *
125     * @see #onCallStateChanged
126     */
127    public static final int LISTEN_CALL_STATE                               = 0x00000020;
128
129    /**
130     * Listen for changes to the data connection state (cellular).
131     *
132     * @see #onDataConnectionStateChanged
133     */
134    public static final int LISTEN_DATA_CONNECTION_STATE                    = 0x00000040;
135
136    /**
137     * Listen for changes to the direction of data traffic on the data
138     * connection (cellular).
139     * {@more}
140     * Example: The status bar uses this to display the appropriate
141     * data-traffic icon.
142     *
143     * @see #onDataActivity
144     */
145    public static final int LISTEN_DATA_ACTIVITY                            = 0x00000080;
146
147    /**
148     * Listen for changes to the network signal strengths (cellular).
149     * <p>
150     * Example: The status bar uses this to control the signal-strength
151     * icon.
152     *
153     * @see #onSignalStrengthsChanged
154     */
155    public static final int LISTEN_SIGNAL_STRENGTHS                         = 0x00000100;
156
157    /**
158     * Listen for changes to OTASP mode.
159     *
160     * @see #onOtaspChanged
161     * @hide
162     */
163    public static final int LISTEN_OTASP_CHANGED                            = 0x00000200;
164
165    /**
166     * Listen for changes to observed cell info.
167     *
168     * @see #onCellInfoChanged
169     */
170    public static final int LISTEN_CELL_INFO = 0x00000400;
171
172    /**
173     * Listen for precise changes and fails to the device calls (cellular).
174     * {@more}
175     * Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE
176     * READ_PRECISE_PHONE_STATE}
177     *
178     * @hide
179     */
180    public static final int LISTEN_PRECISE_CALL_STATE                       = 0x00000800;
181
182    /**
183     * Listen for precise changes and fails on the data connection (cellular).
184     * {@more}
185     * Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE
186     * READ_PRECISE_PHONE_STATE}
187     *
188     * @see #onPreciseDataConnectionStateChanged
189     * @hide
190     */
191    public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE            = 0x00001000;
192
193    /**
194     * Listen for real time info for all data connections (cellular)).
195     * {@more}
196     * Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE
197     * READ_PRECISE_PHONE_STATE}
198     * @see #onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo)
199     *
200     * @deprecated Use {@link TelephonyManager#getModemActivityInfo()}
201     * @hide
202     */
203    @Deprecated
204    public static final int LISTEN_DATA_CONNECTION_REAL_TIME_INFO           = 0x00002000;
205
206    /**
207     * Listen for changes to LTE network state
208     *
209     * @see #onLteNetworkStateChanged
210     * @hide
211     */
212    public static final int LISTEN_VOLTE_STATE                              = 0x00004000;
213
214    /**
215     * Listen for OEM hook raw event
216     *
217     * @see #onOemHookRawEvent
218     * @hide
219     */
220    public static final int LISTEN_OEM_HOOK_RAW_EVENT                       = 0x00008000;
221
222    /**
223     * Listen for carrier network changes indicated by a carrier app.
224     *
225     * @see #onCarrierNetworkRequest
226     * @see TelephonyManager#notifyCarrierNetworkChange(boolean)
227     * @hide
228     */
229    public static final int LISTEN_CARRIER_NETWORK_CHANGE                   = 0x00010000;
230
231     /*
232     * Subscription used to listen to the phone state changes
233     * @hide
234     */
235    /** @hide */
236    protected int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
237
238    private final Handler mHandler;
239
240    /**
241     * Create a PhoneStateListener for the Phone with the default subscription.
242     * This class requires Looper.myLooper() not return null.
243     */
244    public PhoneStateListener() {
245        this(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, Looper.myLooper());
246    }
247
248    /**
249     * Create a PhoneStateListener for the Phone with the default subscription
250     * using a particular non-null Looper.
251     * @hide
252     */
253    public PhoneStateListener(Looper looper) {
254        this(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, looper);
255    }
256
257    /**
258     * Create a PhoneStateListener for the Phone using the specified subscription.
259     * This class requires Looper.myLooper() not return null. To supply your
260     * own non-null Looper use PhoneStateListener(int subId, Looper looper) below.
261     * @hide
262     */
263    public PhoneStateListener(int subId) {
264        this(subId, Looper.myLooper());
265    }
266
267    /**
268     * Create a PhoneStateListener for the Phone using the specified subscription
269     * and non-null Looper.
270     * @hide
271     */
272    public PhoneStateListener(int subId, Looper looper) {
273        if (DBG) log("ctor: subId=" + subId + " looper=" + looper);
274        mSubId = subId;
275        mHandler = new Handler(looper) {
276            public void handleMessage(Message msg) {
277                if (DBG) {
278                    log("mSubId=" + mSubId + " what=0x" + Integer.toHexString(msg.what)
279                            + " msg=" + msg);
280                }
281                switch (msg.what) {
282                    case LISTEN_SERVICE_STATE:
283                        PhoneStateListener.this.onServiceStateChanged((ServiceState)msg.obj);
284                        break;
285                    case LISTEN_SIGNAL_STRENGTH:
286                        PhoneStateListener.this.onSignalStrengthChanged(msg.arg1);
287                        break;
288                    case LISTEN_MESSAGE_WAITING_INDICATOR:
289                        PhoneStateListener.this.onMessageWaitingIndicatorChanged(msg.arg1 != 0);
290                        break;
291                    case LISTEN_CALL_FORWARDING_INDICATOR:
292                        PhoneStateListener.this.onCallForwardingIndicatorChanged(msg.arg1 != 0);
293                        break;
294                    case LISTEN_CELL_LOCATION:
295                        PhoneStateListener.this.onCellLocationChanged((CellLocation)msg.obj);
296                        break;
297                    case LISTEN_CALL_STATE:
298                        PhoneStateListener.this.onCallStateChanged(msg.arg1, (String)msg.obj);
299                        break;
300                    case LISTEN_DATA_CONNECTION_STATE:
301                        PhoneStateListener.this.onDataConnectionStateChanged(msg.arg1, msg.arg2);
302                        PhoneStateListener.this.onDataConnectionStateChanged(msg.arg1);
303                        break;
304                    case LISTEN_DATA_ACTIVITY:
305                        PhoneStateListener.this.onDataActivity(msg.arg1);
306                        break;
307                    case LISTEN_SIGNAL_STRENGTHS:
308                        PhoneStateListener.this.onSignalStrengthsChanged((SignalStrength)msg.obj);
309                        break;
310                    case LISTEN_OTASP_CHANGED:
311                        PhoneStateListener.this.onOtaspChanged(msg.arg1);
312                        break;
313                    case LISTEN_CELL_INFO:
314                        PhoneStateListener.this.onCellInfoChanged((List<CellInfo>)msg.obj);
315                        break;
316                    case LISTEN_PRECISE_CALL_STATE:
317                        PhoneStateListener.this.onPreciseCallStateChanged((PreciseCallState)msg.obj);
318                        break;
319                    case LISTEN_PRECISE_DATA_CONNECTION_STATE:
320                        PhoneStateListener.this.onPreciseDataConnectionStateChanged(
321                                (PreciseDataConnectionState)msg.obj);
322                        break;
323                    case LISTEN_DATA_CONNECTION_REAL_TIME_INFO:
324                        PhoneStateListener.this.onDataConnectionRealTimeInfoChanged(
325                                (DataConnectionRealTimeInfo)msg.obj);
326                        break;
327                    case LISTEN_VOLTE_STATE:
328                        PhoneStateListener.this.onVoLteServiceStateChanged((VoLteServiceState)msg.obj);
329                        break;
330                    case LISTEN_OEM_HOOK_RAW_EVENT:
331                        PhoneStateListener.this.onOemHookRawEvent((byte[])msg.obj);
332                        break;
333                    case LISTEN_CARRIER_NETWORK_CHANGE:
334                        PhoneStateListener.this.onCarrierNetworkChange((boolean)msg.obj);
335                        break;
336
337                }
338            }
339        };
340    }
341
342    /**
343     * Callback invoked when device service state changes.
344     *
345     * @see ServiceState#STATE_EMERGENCY_ONLY
346     * @see ServiceState#STATE_IN_SERVICE
347     * @see ServiceState#STATE_OUT_OF_SERVICE
348     * @see ServiceState#STATE_POWER_OFF
349     */
350    public void onServiceStateChanged(ServiceState serviceState) {
351        // default implementation empty
352    }
353
354    /**
355     * Callback invoked when network signal strength changes.
356     *
357     * @see ServiceState#STATE_EMERGENCY_ONLY
358     * @see ServiceState#STATE_IN_SERVICE
359     * @see ServiceState#STATE_OUT_OF_SERVICE
360     * @see ServiceState#STATE_POWER_OFF
361     * @deprecated Use {@link #onSignalStrengthsChanged(SignalStrength)}
362     */
363    @Deprecated
364    public void onSignalStrengthChanged(int asu) {
365        // default implementation empty
366    }
367
368    /**
369     * Callback invoked when the message-waiting indicator changes.
370     */
371    public void onMessageWaitingIndicatorChanged(boolean mwi) {
372        // default implementation empty
373    }
374
375    /**
376     * Callback invoked when the call-forwarding indicator changes.
377     */
378    public void onCallForwardingIndicatorChanged(boolean cfi) {
379        // default implementation empty
380    }
381
382    /**
383     * Callback invoked when device cell location changes.
384     */
385    public void onCellLocationChanged(CellLocation location) {
386        // default implementation empty
387    }
388
389    /**
390     * Callback invoked when device call state changes.
391     * @param state call state
392     * @param incomingNumber incoming call phone number. If application does not have
393     * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} permission, an empty
394     * string will be passed as an argument.
395     *
396     * @see TelephonyManager#CALL_STATE_IDLE
397     * @see TelephonyManager#CALL_STATE_RINGING
398     * @see TelephonyManager#CALL_STATE_OFFHOOK
399     */
400    public void onCallStateChanged(int state, String incomingNumber) {
401        // default implementation empty
402    }
403
404    /**
405     * Callback invoked when connection state changes.
406     *
407     * @see TelephonyManager#DATA_DISCONNECTED
408     * @see TelephonyManager#DATA_CONNECTING
409     * @see TelephonyManager#DATA_CONNECTED
410     * @see TelephonyManager#DATA_SUSPENDED
411     */
412    public void onDataConnectionStateChanged(int state) {
413        // default implementation empty
414    }
415
416    /**
417     * same as above, but with the network type.  Both called.
418     */
419    public void onDataConnectionStateChanged(int state, int networkType) {
420    }
421
422    /**
423     * Callback invoked when data activity state changes.
424     *
425     * @see TelephonyManager#DATA_ACTIVITY_NONE
426     * @see TelephonyManager#DATA_ACTIVITY_IN
427     * @see TelephonyManager#DATA_ACTIVITY_OUT
428     * @see TelephonyManager#DATA_ACTIVITY_INOUT
429     * @see TelephonyManager#DATA_ACTIVITY_DORMANT
430     */
431    public void onDataActivity(int direction) {
432        // default implementation empty
433    }
434
435    /**
436     * Callback invoked when network signal strengths changes.
437     *
438     * @see ServiceState#STATE_EMERGENCY_ONLY
439     * @see ServiceState#STATE_IN_SERVICE
440     * @see ServiceState#STATE_OUT_OF_SERVICE
441     * @see ServiceState#STATE_POWER_OFF
442     */
443    public void onSignalStrengthsChanged(SignalStrength signalStrength) {
444        // default implementation empty
445    }
446
447
448    /**
449     * The Over The Air Service Provisioning (OTASP) has changed. Requires
450     * the READ_PHONE_STATE permission.
451     * @param otaspMode is integer <code>OTASP_UNKNOWN=1<code>
452     *   means the value is currently unknown and the system should wait until
453     *   <code>OTASP_NEEDED=2<code> or <code>OTASP_NOT_NEEDED=3<code> is received before
454     *   making the decision to perform OTASP or not.
455     *
456     * @hide
457     */
458    public void onOtaspChanged(int otaspMode) {
459        // default implementation empty
460    }
461
462    /**
463     * Callback invoked when a observed cell info has changed,
464     * or new cells have been added or removed.
465     * @param cellInfo is the list of currently visible cells.
466     */
467    public void onCellInfoChanged(List<CellInfo> cellInfo) {
468    }
469
470    /**
471     * Callback invoked when precise device call state changes.
472     *
473     * @hide
474     */
475    public void onPreciseCallStateChanged(PreciseCallState callState) {
476        // default implementation empty
477    }
478
479    /**
480     * Callback invoked when data connection state changes with precise information.
481     *
482     * @hide
483     */
484    public void onPreciseDataConnectionStateChanged(
485            PreciseDataConnectionState dataConnectionState) {
486        // default implementation empty
487    }
488
489    /**
490     * Callback invoked when data connection state changes with precise information.
491     *
492     * @hide
493     */
494    public void onDataConnectionRealTimeInfoChanged(
495            DataConnectionRealTimeInfo dcRtInfo) {
496        // default implementation empty
497    }
498
499    /**
500     * Callback invoked when the service state of LTE network
501     * related to the VoLTE service has changed.
502     * @param stateInfo is the current LTE network information
503     * @hide
504     */
505    public void onVoLteServiceStateChanged(VoLteServiceState stateInfo) {
506    }
507
508    /**
509     * Callback invoked when OEM hook raw event is received. Requires
510     * the READ_PRIVILEGED_PHONE_STATE permission.
511     * @param rawData is the byte array of the OEM hook raw data.
512     * @hide
513     */
514    public void onOemHookRawEvent(byte[] rawData) {
515        // default implementation empty
516    }
517
518    /**
519     * Callback invoked when telephony has received notice from a carrier
520     * app that a network action that could result in connectivity loss
521     * has been requested by an app using
522     * {@link android.telephony.TelephonyManager#notifyCarrierNetworkChange(boolean)}
523     *
524     * @param active Whether the carrier network change is or shortly
525     *               will be active. This value is true to indicate
526     *               showing alternative UI and false to stop.
527     *
528     * @hide
529     */
530    public void onCarrierNetworkChange(boolean active) {
531        // default implementation empty
532    }
533
534    /**
535     * The callback methods need to be called on the handler thread where
536     * this object was created.  If the binder did that for us it'd be nice.
537     *
538     * Using a static class and weak reference here to avoid memory leak caused by the
539     * IPhoneStateListener.Stub callback retaining references to the outside PhoneStateListeners:
540     * even caller has been destroyed and "un-registered" the PhoneStateListener, it is still not
541     * eligible for GC given the references coming from:
542     * Native Stack --> PhoneStateListener --> Context (Activity).
543     * memory of caller's context will be collected after GC from service side get triggered
544     */
545    private static class IPhoneStateListenerStub extends IPhoneStateListener.Stub {
546        private WeakReference<PhoneStateListener> mPhoneStateListenerWeakRef;
547
548        public IPhoneStateListenerStub(PhoneStateListener phoneStateListener) {
549            mPhoneStateListenerWeakRef = new WeakReference<PhoneStateListener>(phoneStateListener);
550        }
551
552        private void send(int what, int arg1, int arg2, Object obj) {
553            PhoneStateListener listener = mPhoneStateListenerWeakRef.get();
554            if (listener != null) {
555                Message.obtain(listener.mHandler, what, arg1, arg2, obj).sendToTarget();
556            }
557        }
558
559        public void onServiceStateChanged(ServiceState serviceState) {
560            send(LISTEN_SERVICE_STATE, 0, 0, serviceState);
561        }
562
563        public void onSignalStrengthChanged(int asu) {
564            send(LISTEN_SIGNAL_STRENGTH, asu, 0, null);
565        }
566
567        public void onMessageWaitingIndicatorChanged(boolean mwi) {
568            send(LISTEN_MESSAGE_WAITING_INDICATOR, mwi ? 1 : 0, 0, null);
569        }
570
571        public void onCallForwardingIndicatorChanged(boolean cfi) {
572            send(LISTEN_CALL_FORWARDING_INDICATOR, cfi ? 1 : 0, 0, null);
573        }
574
575        public void onCellLocationChanged(Bundle bundle) {
576            CellLocation location = CellLocation.newFromBundle(bundle);
577            send(LISTEN_CELL_LOCATION, 0, 0, location);
578        }
579
580        public void onCallStateChanged(int state, String incomingNumber) {
581            send(LISTEN_CALL_STATE, state, 0, incomingNumber);
582        }
583
584        public void onDataConnectionStateChanged(int state, int networkType) {
585            send(LISTEN_DATA_CONNECTION_STATE, state, networkType, null);
586        }
587
588        public void onDataActivity(int direction) {
589            send(LISTEN_DATA_ACTIVITY, direction, 0, null);
590        }
591
592        public void onSignalStrengthsChanged(SignalStrength signalStrength) {
593            send(LISTEN_SIGNAL_STRENGTHS, 0, 0, signalStrength);
594        }
595
596        public void onOtaspChanged(int otaspMode) {
597            send(LISTEN_OTASP_CHANGED, otaspMode, 0, null);
598        }
599
600        public void onCellInfoChanged(List<CellInfo> cellInfo) {
601            send(LISTEN_CELL_INFO, 0, 0, cellInfo);
602        }
603
604        public void onPreciseCallStateChanged(PreciseCallState callState) {
605            send(LISTEN_PRECISE_CALL_STATE, 0, 0, callState);
606        }
607
608        public void onPreciseDataConnectionStateChanged(
609                PreciseDataConnectionState dataConnectionState) {
610            send(LISTEN_PRECISE_DATA_CONNECTION_STATE, 0, 0, dataConnectionState);
611        }
612
613        public void onDataConnectionRealTimeInfoChanged(
614                DataConnectionRealTimeInfo dcRtInfo) {
615            send(LISTEN_DATA_CONNECTION_REAL_TIME_INFO, 0, 0, dcRtInfo);
616        }
617
618        public void onVoLteServiceStateChanged(VoLteServiceState lteState) {
619            send(LISTEN_VOLTE_STATE, 0, 0, lteState);
620        }
621
622        public void onOemHookRawEvent(byte[] rawData) {
623            send(LISTEN_OEM_HOOK_RAW_EVENT, 0, 0, rawData);
624        }
625
626        public void onCarrierNetworkChange(boolean active) {
627            send(LISTEN_CARRIER_NETWORK_CHANGE, 0, 0, active);
628        }
629    }
630
631    IPhoneStateListener callback = new IPhoneStateListenerStub(this);
632
633    private void log(String s) {
634        Rlog.d(LOG_TAG, s);
635    }
636}
637