TelephonyManager.java revision fc94d45fc209dbcfdf7f57e0c04c581e1e51988b
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.annotation.SdkConstant;
20import android.annotation.SdkConstant.SdkConstantType;
21import android.content.Context;
22import android.os.Bundle;
23import android.os.RemoteException;
24import android.os.ServiceManager;
25import android.os.SystemProperties;
26import android.util.Log;
27
28import com.android.internal.telephony.IPhoneSubInfo;
29import com.android.internal.telephony.ITelephony;
30import com.android.internal.telephony.ITelephonyRegistry;
31import com.android.internal.telephony.Phone;
32import com.android.internal.telephony.PhoneFactory;
33import com.android.internal.telephony.TelephonyProperties;
34
35import java.util.List;
36
37/**
38 * Provides access to information about the telephony services on
39 * the device. Applications can use the methods in this class to
40 * determine telephony services and states, as well as to access some
41 * types of subscriber information. Applications can also register
42 * a listener to receive notification of telephony state changes.
43 * <p>
44 * You do not instantiate this class directly; instead, you retrieve
45 * a reference to an instance through
46 * {@link android.content.Context#getSystemService
47 * Context.getSystemService(Context.TELEPHONY_SERVICE)}.
48 * <p>
49 * Note that access to some telephony information is
50 * permission-protected. Your application cannot access the protected
51 * information unless it has the appropriate permissions declared in
52 * its manifest file. Where permissions apply, they are noted in the
53 * the methods through which you access the protected information.
54 */
55public class TelephonyManager {
56    private static final String TAG = "TelephonyManager";
57
58    private static Context sContext;
59    private static ITelephonyRegistry sRegistry;
60
61    /** @hide */
62    public TelephonyManager(Context context) {
63        if (sContext == null) {
64            sContext = context;
65
66            sRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
67                    "telephony.registry"));
68        } else {
69            Log.e(TAG, "Hidden constructor called more than once per process!");
70            Log.e(TAG, "Original: " + sContext.getPackageName() + ", new: " +
71                    context.getPackageName());
72        }
73    }
74
75    /** @hide */
76    private TelephonyManager() {
77    }
78
79    private static TelephonyManager sInstance = new TelephonyManager();
80
81    /** @hide
82    /* @deprecated - use getSystemService as described above */
83    public static TelephonyManager getDefault() {
84        return sInstance;
85    }
86
87
88    //
89    // Broadcast Intent actions
90    //
91
92    /**
93     * Broadcast intent action indicating that the call state (cellular)
94     * on the device has changed.
95     *
96     * <p>
97     * The {@link #EXTRA_STATE} extra indicates the new call state.
98     * If the new state is RINGING, a second extra
99     * {@link #EXTRA_INCOMING_NUMBER} provides the incoming phone number as
100     * a String.
101     *
102     * <p class="note">
103     * Requires the READ_PHONE_STATE permission.
104     *
105     * <p class="note">
106     * This was a {@link android.content.Context#sendStickyBroadcast sticky}
107     * broadcast in version 1.0, but it is no longer sticky.
108     * Instead, use {@link #getCallState} to synchronously query the current call state.
109     *
110     * @see #EXTRA_STATE
111     * @see #EXTRA_INCOMING_NUMBER
112     * @see #getCallState
113     */
114    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
115    public static final String ACTION_PHONE_STATE_CHANGED =
116            "android.intent.action.PHONE_STATE";
117
118    /**
119     * The lookup key used with the {@link #ACTION_PHONE_STATE_CHANGED} broadcast
120     * for a String containing the new call state.
121     *
122     * @see #EXTRA_STATE_IDLE
123     * @see #EXTRA_STATE_RINGING
124     * @see #EXTRA_STATE_OFFHOOK
125     *
126     * <p class="note">
127     * Retrieve with
128     * {@link android.content.Intent#getStringExtra(String)}.
129     */
130    public static final String EXTRA_STATE = Phone.STATE_KEY;
131
132    /**
133     * Value used with {@link #EXTRA_STATE} corresponding to
134     * {@link #CALL_STATE_IDLE}.
135     */
136    public static final String EXTRA_STATE_IDLE = Phone.State.IDLE.toString();
137
138    /**
139     * Value used with {@link #EXTRA_STATE} corresponding to
140     * {@link #CALL_STATE_RINGING}.
141     */
142    public static final String EXTRA_STATE_RINGING = Phone.State.RINGING.toString();
143
144    /**
145     * Value used with {@link #EXTRA_STATE} corresponding to
146     * {@link #CALL_STATE_OFFHOOK}.
147     */
148    public static final String EXTRA_STATE_OFFHOOK = Phone.State.OFFHOOK.toString();
149
150    /**
151     * The lookup key used with the {@link #ACTION_PHONE_STATE_CHANGED} broadcast
152     * for a String containing the incoming phone number.
153     * Only valid when the new call state is RINGING.
154     *
155     * <p class="note">
156     * Retrieve with
157     * {@link android.content.Intent#getStringExtra(String)}.
158     */
159    public static final String EXTRA_INCOMING_NUMBER = "incoming_number";
160
161
162    //
163    //
164    // Device Info
165    //
166    //
167
168    /**
169     * Returns the software version number for the device, for example,
170     * the IMEI/SV for GSM phones. Return null if the software version is
171     * not available.
172     *
173     * <p>Requires Permission:
174     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
175     */
176    public String getDeviceSoftwareVersion() {
177        try {
178            return getSubscriberInfo().getDeviceSvn();
179        } catch (RemoteException ex) {
180            return null;
181        } catch (NullPointerException ex) {
182            return null;
183        }
184    }
185
186    /**
187     * Returns the unique device ID, for example, the IMEI for GSM and the MEID
188     * or ESN for CDMA phones. Return null if device ID is not available.
189     *
190     * <p>Requires Permission:
191     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
192     */
193    public String getDeviceId() {
194        if (!isVoiceCapable()) {
195            return null;
196        }
197
198        try {
199            return getSubscriberInfo().getDeviceId();
200        } catch (RemoteException ex) {
201            return null;
202        } catch (NullPointerException ex) {
203            return null;
204        }
205    }
206
207    /**
208     * Returns the current location of the device.
209     * Return null if current location is not available.
210     *
211     * <p>Requires Permission:
212     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
213     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_FINE_LOCATION}.
214     */
215    public CellLocation getCellLocation() {
216        try {
217            Bundle bundle = getITelephony().getCellLocation();
218            CellLocation cl = CellLocation.newFromBundle(bundle);
219            if (cl.isEmpty())
220                return null;
221            return cl;
222        } catch (RemoteException ex) {
223            return null;
224        } catch (NullPointerException ex) {
225            return null;
226        }
227    }
228
229    /**
230     * Enables location update notifications.  {@link PhoneStateListener#onCellLocationChanged
231     * PhoneStateListener.onCellLocationChanged} will be called on location updates.
232     *
233     * <p>Requires Permission: {@link android.Manifest.permission#CONTROL_LOCATION_UPDATES
234     * CONTROL_LOCATION_UPDATES}
235     *
236     * @hide
237     */
238    public void enableLocationUpdates() {
239        try {
240            getITelephony().enableLocationUpdates();
241        } catch (RemoteException ex) {
242        } catch (NullPointerException ex) {
243        }
244    }
245
246    /**
247     * Disables location update notifications.  {@link PhoneStateListener#onCellLocationChanged
248     * PhoneStateListener.onCellLocationChanged} will be called on location updates.
249     *
250     * <p>Requires Permission: {@link android.Manifest.permission#CONTROL_LOCATION_UPDATES
251     * CONTROL_LOCATION_UPDATES}
252     *
253     * @hide
254     */
255    public void disableLocationUpdates() {
256        try {
257            getITelephony().disableLocationUpdates();
258        } catch (RemoteException ex) {
259        } catch (NullPointerException ex) {
260        }
261    }
262
263    /**
264     * Returns the neighboring cell information of the device.
265     *
266     * @return List of NeighboringCellInfo or null if info unavailable.
267     *
268     * <p>Requires Permission:
269     * (@link android.Manifest.permission#ACCESS_COARSE_UPDATES}
270     */
271    public List<NeighboringCellInfo> getNeighboringCellInfo() {
272        try {
273            return getITelephony().getNeighboringCellInfo();
274        } catch (RemoteException ex) {
275            return null;
276        } catch (NullPointerException ex) {
277            return null;
278        }
279    }
280
281    /** No phone radio. */
282    public static final int PHONE_TYPE_NONE = Phone.PHONE_TYPE_NONE;
283    /** Phone radio is GSM. */
284    public static final int PHONE_TYPE_GSM = Phone.PHONE_TYPE_GSM;
285    /** Phone radio is CDMA. */
286    public static final int PHONE_TYPE_CDMA = Phone.PHONE_TYPE_CDMA;
287    /** Phone is via SIP. */
288    public static final int PHONE_TYPE_SIP = Phone.PHONE_TYPE_SIP;
289
290    /**
291     * Returns the current phone type.
292     * TODO: This is a last minute change and hence hidden.
293     *
294     * @see #PHONE_TYPE_NONE
295     * @see #PHONE_TYPE_GSM
296     * @see #PHONE_TYPE_CDMA
297     * @see #PHONE_TYPE_SIP
298     *
299     * {@hide}
300     */
301    public int getCurrentPhoneType() {
302        try{
303            ITelephony telephony = getITelephony();
304            if (telephony != null) {
305                return telephony.getActivePhoneType();
306            } else {
307                // This can happen when the ITelephony interface is not up yet.
308                return getPhoneTypeFromProperty();
309            }
310        } catch (RemoteException ex) {
311            // This shouldn't happen in the normal case, as a backup we
312            // read from the system property.
313            return getPhoneTypeFromProperty();
314        } catch (NullPointerException ex) {
315            // This shouldn't happen in the normal case, as a backup we
316            // read from the system property.
317            return getPhoneTypeFromProperty();
318        }
319    }
320
321    /**
322     * Returns a constant indicating the device phone type.  This
323     * indicates the type of radio used to transmit voice calls.
324     *
325     * @see #PHONE_TYPE_NONE
326     * @see #PHONE_TYPE_GSM
327     * @see #PHONE_TYPE_CDMA
328     * @see #PHONE_TYPE_SIP
329     */
330    public int getPhoneType() {
331        if (!isVoiceCapable()) {
332            return PHONE_TYPE_NONE;
333        }
334        return getCurrentPhoneType();
335    }
336
337    private int getPhoneTypeFromProperty() {
338        int type =
339            SystemProperties.getInt(TelephonyProperties.CURRENT_ACTIVE_PHONE,
340                    getPhoneTypeFromNetworkType());
341        return type;
342    }
343
344    private int getPhoneTypeFromNetworkType() {
345        // When the system property CURRENT_ACTIVE_PHONE, has not been set,
346        // use the system property for default network type.
347        // This is a fail safe, and can only happen at first boot.
348        int mode = SystemProperties.getInt("ro.telephony.default_network", -1);
349        if (mode == -1)
350            return PHONE_TYPE_NONE;
351        return PhoneFactory.getPhoneType(mode);
352    }
353    //
354    //
355    // Current Network
356    //
357    //
358
359    /**
360     * Returns the alphabetic name of current registered operator.
361     * <p>
362     * Availability: Only when user is registered to a network. Result may be
363     * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
364     * on a CDMA network).
365     */
366    public String getNetworkOperatorName() {
367        return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ALPHA);
368    }
369
370    /**
371     * Returns the numeric name (MCC+MNC) of current registered operator.
372     * <p>
373     * Availability: Only when user is registered to a network. Result may be
374     * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
375     * on a CDMA network).
376     */
377    public String getNetworkOperator() {
378        return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC);
379    }
380
381    /**
382     * Returns true if the device is considered roaming on the current
383     * network, for GSM purposes.
384     * <p>
385     * Availability: Only when user registered to a network.
386     */
387    public boolean isNetworkRoaming() {
388        return "true".equals(SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING));
389    }
390
391    /**
392     * Returns the ISO country code equivalent of the current registered
393     * operator's MCC (Mobile Country Code).
394     * <p>
395     * Availability: Only when user is registered to a network. Result may be
396     * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
397     * on a CDMA network).
398     */
399    public String getNetworkCountryIso() {
400        return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY);
401    }
402
403    /** Network type is unknown */
404    public static final int NETWORK_TYPE_UNKNOWN = 0;
405    /** Current network is GPRS */
406    public static final int NETWORK_TYPE_GPRS = 1;
407    /** Current network is EDGE */
408    public static final int NETWORK_TYPE_EDGE = 2;
409    /** Current network is UMTS */
410    public static final int NETWORK_TYPE_UMTS = 3;
411    /** Current network is CDMA: Either IS95A or IS95B*/
412    public static final int NETWORK_TYPE_CDMA = 4;
413    /** Current network is EVDO revision 0*/
414    public static final int NETWORK_TYPE_EVDO_0 = 5;
415    /** Current network is EVDO revision A*/
416    public static final int NETWORK_TYPE_EVDO_A = 6;
417    /** Current network is 1xRTT*/
418    public static final int NETWORK_TYPE_1xRTT = 7;
419    /** Current network is HSDPA */
420    public static final int NETWORK_TYPE_HSDPA = 8;
421    /** Current network is HSUPA */
422    public static final int NETWORK_TYPE_HSUPA = 9;
423    /** Current network is HSPA */
424    public static final int NETWORK_TYPE_HSPA = 10;
425    /** Current network is iDen */
426    public static final int NETWORK_TYPE_IDEN = 11;
427    /** Current network is EVDO revision B*/
428    public static final int NETWORK_TYPE_EVDO_B = 12;
429    /** Current network is LTE */
430    public static final int NETWORK_TYPE_LTE = 13;
431    /** Current network is eHRPD */
432    public static final int NETWORK_TYPE_EHRPD = 14;
433    /** Current network is HSPA+ */
434    public static final int NETWORK_TYPE_HSPAP = 15;
435
436    /**
437     * Returns a constant indicating the radio technology (network type)
438     * currently in use on the device for data transmission.
439     * @return the network type
440     *
441     * @see #NETWORK_TYPE_UNKNOWN
442     * @see #NETWORK_TYPE_GPRS
443     * @see #NETWORK_TYPE_EDGE
444     * @see #NETWORK_TYPE_UMTS
445     * @see #NETWORK_TYPE_HSDPA
446     * @see #NETWORK_TYPE_HSUPA
447     * @see #NETWORK_TYPE_HSPA
448     * @see #NETWORK_TYPE_CDMA
449     * @see #NETWORK_TYPE_EVDO_0
450     * @see #NETWORK_TYPE_EVDO_A
451     * @see #NETWORK_TYPE_EVDO_B
452     * @see #NETWORK_TYPE_1xRTT
453     * @see #NETWORK_TYPE_IDEN
454     * @see #NETWORK_TYPE_LTE
455     * @see #NETWORK_TYPE_EHRPD
456     * @see #NETWORK_TYPE_HSPAP
457     */
458    public int getNetworkType() {
459        try{
460            ITelephony telephony = getITelephony();
461            if (telephony != null) {
462                return telephony.getNetworkType();
463            } else {
464                // This can happen when the ITelephony interface is not up yet.
465                return NETWORK_TYPE_UNKNOWN;
466            }
467        } catch(RemoteException ex) {
468            // This shouldn't happen in the normal case
469            return NETWORK_TYPE_UNKNOWN;
470        } catch (NullPointerException ex) {
471            // This could happen before phone restarts due to crashing
472            return NETWORK_TYPE_UNKNOWN;
473        }
474    }
475
476    /**
477     * Returns a string representation of the radio technology (network type)
478     * currently in use on the device.
479     * @return the name of the radio technology
480     *
481     * @hide pending API council review
482     */
483    public String getNetworkTypeName() {
484        switch (getNetworkType()) {
485            case NETWORK_TYPE_GPRS:
486                return "GPRS";
487            case NETWORK_TYPE_EDGE:
488                return "EDGE";
489            case NETWORK_TYPE_UMTS:
490                return "UMTS";
491            case NETWORK_TYPE_HSDPA:
492                return "HSDPA";
493            case NETWORK_TYPE_HSUPA:
494                return "HSUPA";
495            case NETWORK_TYPE_HSPA:
496                return "HSPA";
497            case NETWORK_TYPE_CDMA:
498                return "CDMA";
499            case NETWORK_TYPE_EVDO_0:
500                return "CDMA - EvDo rev. 0";
501            case NETWORK_TYPE_EVDO_A:
502                return "CDMA - EvDo rev. A";
503            case NETWORK_TYPE_EVDO_B:
504                return "CDMA - EvDo rev. B";
505            case NETWORK_TYPE_1xRTT:
506                return "CDMA - 1xRTT";
507            case NETWORK_TYPE_LTE:
508                return "LTE";
509            case NETWORK_TYPE_EHRPD:
510                return "CDMA - eHRPD";
511            case NETWORK_TYPE_IDEN:
512                return "iDEN";
513            case NETWORK_TYPE_HSPAP:
514                return "HSPA+";
515            default:
516                return "UNKNOWN";
517        }
518    }
519
520    //
521    //
522    // SIM Card
523    //
524    //
525
526    /** SIM card state: Unknown. Signifies that the SIM is in transition
527     *  between states. For example, when the user inputs the SIM pin
528     *  under PIN_REQUIRED state, a query for sim status returns
529     *  this state before turning to SIM_STATE_READY. */
530    public static final int SIM_STATE_UNKNOWN = 0;
531    /** SIM card state: no SIM card is available in the device */
532    public static final int SIM_STATE_ABSENT = 1;
533    /** SIM card state: Locked: requires the user's SIM PIN to unlock */
534    public static final int SIM_STATE_PIN_REQUIRED = 2;
535    /** SIM card state: Locked: requires the user's SIM PUK to unlock */
536    public static final int SIM_STATE_PUK_REQUIRED = 3;
537    /** SIM card state: Locked: requries a network PIN to unlock */
538    public static final int SIM_STATE_NETWORK_LOCKED = 4;
539    /** SIM card state: Ready */
540    public static final int SIM_STATE_READY = 5;
541
542    /**
543     * @return true if a ICC card is present
544     */
545    public boolean hasIccCard() {
546        try {
547            return getITelephony().hasIccCard();
548        } catch (RemoteException ex) {
549            // Assume no ICC card if remote exception which shouldn't happen
550            return false;
551        } catch (NullPointerException ex) {
552            // This could happen before phone restarts due to crashing
553            return false;
554        }
555    }
556
557    /**
558     * Returns a constant indicating the state of the
559     * device SIM card.
560     *
561     * @see #SIM_STATE_UNKNOWN
562     * @see #SIM_STATE_ABSENT
563     * @see #SIM_STATE_PIN_REQUIRED
564     * @see #SIM_STATE_PUK_REQUIRED
565     * @see #SIM_STATE_NETWORK_LOCKED
566     * @see #SIM_STATE_READY
567     */
568    public int getSimState() {
569        String prop = SystemProperties.get(TelephonyProperties.PROPERTY_SIM_STATE);
570        if ("ABSENT".equals(prop)) {
571            return SIM_STATE_ABSENT;
572        }
573        else if ("PIN_REQUIRED".equals(prop)) {
574            return SIM_STATE_PIN_REQUIRED;
575        }
576        else if ("PUK_REQUIRED".equals(prop)) {
577            return SIM_STATE_PUK_REQUIRED;
578        }
579        else if ("NETWORK_LOCKED".equals(prop)) {
580            return SIM_STATE_NETWORK_LOCKED;
581        }
582        else if ("READY".equals(prop)) {
583            return SIM_STATE_READY;
584        }
585        else {
586            return SIM_STATE_UNKNOWN;
587        }
588    }
589
590    /**
591     * Returns the MCC+MNC (mobile country code + mobile network code) of the
592     * provider of the SIM. 5 or 6 decimal digits.
593     * <p>
594     * Availability: SIM state must be {@link #SIM_STATE_READY}
595     *
596     * @see #getSimState
597     */
598    public String getSimOperator() {
599        return SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC);
600    }
601
602    /**
603     * Returns the Service Provider Name (SPN).
604     * <p>
605     * Availability: SIM state must be {@link #SIM_STATE_READY}
606     *
607     * @see #getSimState
608     */
609    public String getSimOperatorName() {
610        return SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA);
611    }
612
613    /**
614     * Returns the ISO country code equivalent for the SIM provider's country code.
615     */
616    public String getSimCountryIso() {
617        return SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY);
618    }
619
620    /**
621     * Returns the serial number of the SIM, if applicable. Return null if it is
622     * unavailable.
623     * <p>
624     * Requires Permission:
625     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
626     */
627    public String getSimSerialNumber() {
628        try {
629            return getSubscriberInfo().getIccSerialNumber();
630        } catch (RemoteException ex) {
631            return null;
632        } catch (NullPointerException ex) {
633            // This could happen before phone restarts due to crashing
634            return null;
635        }
636    }
637
638    /**
639     * Return if the current radio is LTE on CDMA. This
640     * is a tri-state return value as for a period of time
641     * the mode may be unknown.
642     *
643     * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
644     * or {@link Phone#LTE_ON_CDMA_TRUE}
645     *
646     * @hide
647     */
648    public int getLteOnCdmaMode() {
649        try {
650            return getITelephony().getLteOnCdmaMode();
651        } catch (RemoteException ex) {
652            // Assume no ICC card if remote exception which shouldn't happen
653            return Phone.LTE_ON_CDMA_UNKNOWN;
654        } catch (NullPointerException ex) {
655            // This could happen before phone restarts due to crashing
656            return Phone.LTE_ON_CDMA_UNKNOWN;
657        }
658    }
659
660    //
661    //
662    // Subscriber Info
663    //
664    //
665
666    /**
667     * Returns the unique subscriber ID, for example, the IMSI for a GSM phone.
668     * Return null if it is unavailable.
669     * <p>
670     * Requires Permission:
671     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
672     */
673    public String getSubscriberId() {
674        try {
675            return getSubscriberInfo().getSubscriberId();
676        } catch (RemoteException ex) {
677            return null;
678        } catch (NullPointerException ex) {
679            // This could happen before phone restarts due to crashing
680            return null;
681        }
682    }
683
684    /**
685     * Returns the phone number string for line 1, for example, the MSISDN
686     * for a GSM phone. Return null if it is unavailable.
687     * <p>
688     * Requires Permission:
689     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
690     */
691    public String getLine1Number() {
692        try {
693            return getSubscriberInfo().getLine1Number();
694        } catch (RemoteException ex) {
695            return null;
696        } catch (NullPointerException ex) {
697            // This could happen before phone restarts due to crashing
698            return null;
699        }
700    }
701
702    /**
703     * Returns the alphabetic identifier associated with the line 1 number.
704     * Return null if it is unavailable.
705     * <p>
706     * Requires Permission:
707     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
708     * @hide
709     * nobody seems to call this.
710     */
711    public String getLine1AlphaTag() {
712        try {
713            return getSubscriberInfo().getLine1AlphaTag();
714        } catch (RemoteException ex) {
715            return null;
716        } catch (NullPointerException ex) {
717            // This could happen before phone restarts due to crashing
718            return null;
719        }
720    }
721
722    /**
723     * Returns the voice mail number. Return null if it is unavailable.
724     * <p>
725     * Requires Permission:
726     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
727     */
728    public String getVoiceMailNumber() {
729        try {
730            return getSubscriberInfo().getVoiceMailNumber();
731        } catch (RemoteException ex) {
732            return null;
733        } catch (NullPointerException ex) {
734            // This could happen before phone restarts due to crashing
735            return null;
736        }
737    }
738
739    /**
740     * Returns the complete voice mail number. Return null if it is unavailable.
741     * <p>
742     * Requires Permission:
743     *   {@link android.Manifest.permission#CALL_PRIVILEGED CALL_PRIVILEGED}
744     *
745     * @hide
746     */
747    public String getCompleteVoiceMailNumber() {
748        try {
749            return getSubscriberInfo().getCompleteVoiceMailNumber();
750        } catch (RemoteException ex) {
751            return null;
752        } catch (NullPointerException ex) {
753            // This could happen before phone restarts due to crashing
754            return null;
755        }
756    }
757
758    /**
759     * Returns the voice mail count. Return 0 if unavailable.
760     * <p>
761     * Requires Permission:
762     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
763     * @hide
764     */
765    public int getVoiceMessageCount() {
766        try {
767            return getITelephony().getVoiceMessageCount();
768        } catch (RemoteException ex) {
769            return 0;
770        } catch (NullPointerException ex) {
771            // This could happen before phone restarts due to crashing
772            return 0;
773        }
774    }
775
776    /**
777     * Retrieves the alphabetic identifier associated with the voice
778     * mail number.
779     * <p>
780     * Requires Permission:
781     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
782     */
783    public String getVoiceMailAlphaTag() {
784        try {
785            return getSubscriberInfo().getVoiceMailAlphaTag();
786        } catch (RemoteException ex) {
787            return null;
788        } catch (NullPointerException ex) {
789            // This could happen before phone restarts due to crashing
790            return null;
791        }
792    }
793
794    private IPhoneSubInfo getSubscriberInfo() {
795        // get it each time because that process crashes a lot
796        return IPhoneSubInfo.Stub.asInterface(ServiceManager.getService("iphonesubinfo"));
797    }
798
799
800    /** Device call state: No activity. */
801    public static final int CALL_STATE_IDLE = 0;
802    /** Device call state: Ringing. A new call arrived and is
803     *  ringing or waiting. In the latter case, another call is
804     *  already active. */
805    public static final int CALL_STATE_RINGING = 1;
806    /** Device call state: Off-hook. At least one call exists
807      * that is dialing, active, or on hold, and no calls are ringing
808      * or waiting. */
809    public static final int CALL_STATE_OFFHOOK = 2;
810
811    /**
812     * Returns a constant indicating the call state (cellular) on the device.
813     */
814    public int getCallState() {
815        try {
816            return getITelephony().getCallState();
817        } catch (RemoteException ex) {
818            // the phone process is restarting.
819            return CALL_STATE_IDLE;
820        } catch (NullPointerException ex) {
821          // the phone process is restarting.
822          return CALL_STATE_IDLE;
823      }
824    }
825
826    /** Data connection activity: No traffic. */
827    public static final int DATA_ACTIVITY_NONE = 0x00000000;
828    /** Data connection activity: Currently receiving IP PPP traffic. */
829    public static final int DATA_ACTIVITY_IN = 0x00000001;
830    /** Data connection activity: Currently sending IP PPP traffic. */
831    public static final int DATA_ACTIVITY_OUT = 0x00000002;
832    /** Data connection activity: Currently both sending and receiving
833     *  IP PPP traffic. */
834    public static final int DATA_ACTIVITY_INOUT = DATA_ACTIVITY_IN | DATA_ACTIVITY_OUT;
835    /**
836     * Data connection is active, but physical link is down
837     */
838    public static final int DATA_ACTIVITY_DORMANT = 0x00000004;
839
840    /**
841     * Returns a constant indicating the type of activity on a data connection
842     * (cellular).
843     *
844     * @see #DATA_ACTIVITY_NONE
845     * @see #DATA_ACTIVITY_IN
846     * @see #DATA_ACTIVITY_OUT
847     * @see #DATA_ACTIVITY_INOUT
848     * @see #DATA_ACTIVITY_DORMANT
849     */
850    public int getDataActivity() {
851        try {
852            return getITelephony().getDataActivity();
853        } catch (RemoteException ex) {
854            // the phone process is restarting.
855            return DATA_ACTIVITY_NONE;
856        } catch (NullPointerException ex) {
857          // the phone process is restarting.
858          return DATA_ACTIVITY_NONE;
859      }
860    }
861
862    /** Data connection state: Unknown.  Used before we know the state.
863     * @hide
864     */
865    public static final int DATA_UNKNOWN        = -1;
866    /** Data connection state: Disconnected. IP traffic not available. */
867    public static final int DATA_DISCONNECTED   = 0;
868    /** Data connection state: Currently setting up a data connection. */
869    public static final int DATA_CONNECTING     = 1;
870    /** Data connection state: Connected. IP traffic should be available. */
871    public static final int DATA_CONNECTED      = 2;
872    /** Data connection state: Suspended. The connection is up, but IP
873     * traffic is temporarily unavailable. For example, in a 2G network,
874     * data activity may be suspended when a voice call arrives. */
875    public static final int DATA_SUSPENDED      = 3;
876
877    /**
878     * Returns a constant indicating the current data connection state
879     * (cellular).
880     *
881     * @see #DATA_DISCONNECTED
882     * @see #DATA_CONNECTING
883     * @see #DATA_CONNECTED
884     * @see #DATA_SUSPENDED
885     */
886    public int getDataState() {
887        try {
888            return getITelephony().getDataState();
889        } catch (RemoteException ex) {
890            // the phone process is restarting.
891            return DATA_DISCONNECTED;
892        } catch (NullPointerException ex) {
893            return DATA_DISCONNECTED;
894        }
895    }
896
897    private ITelephony getITelephony() {
898        return ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE));
899    }
900
901    //
902    //
903    // PhoneStateListener
904    //
905    //
906
907    /**
908     * Registers a listener object to receive notification of changes
909     * in specified telephony states.
910     * <p>
911     * To register a listener, pass a {@link PhoneStateListener}
912     * and specify at least one telephony state of interest in
913     * the events argument.
914     *
915     * At registration, and when a specified telephony state
916     * changes, the telephony manager invokes the appropriate
917     * callback method on the listener object and passes the
918     * current (udpated) values.
919     * <p>
920     * To unregister a listener, pass the listener object and set the
921     * events argument to
922     * {@link PhoneStateListener#LISTEN_NONE LISTEN_NONE} (0).
923     *
924     * @param listener The {@link PhoneStateListener} object to register
925     *                 (or unregister)
926     * @param events The telephony state(s) of interest to the listener,
927     *               as a bitwise-OR combination of {@link PhoneStateListener}
928     *               LISTEN_ flags.
929     */
930    public void listen(PhoneStateListener listener, int events) {
931        String pkgForDebug = sContext != null ? sContext.getPackageName() : "<unknown>";
932        try {
933            Boolean notifyNow = (getITelephony() != null);
934            sRegistry.listen(pkgForDebug, listener.callback, events, notifyNow);
935        } catch (RemoteException ex) {
936            // system process dead
937        } catch (NullPointerException ex) {
938            // system process dead
939        }
940    }
941
942    /**
943     * Returns the CDMA ERI icon index to display
944     *
945     * @hide
946     */
947    public int getCdmaEriIconIndex() {
948        try {
949            return getITelephony().getCdmaEriIconIndex();
950        } catch (RemoteException ex) {
951            // the phone process is restarting.
952            return -1;
953        } catch (NullPointerException ex) {
954            return -1;
955        }
956    }
957
958    /**
959     * Returns the CDMA ERI icon mode,
960     * 0 - ON
961     * 1 - FLASHING
962     *
963     * @hide
964     */
965    public int getCdmaEriIconMode() {
966        try {
967            return getITelephony().getCdmaEriIconMode();
968        } catch (RemoteException ex) {
969            // the phone process is restarting.
970            return -1;
971        } catch (NullPointerException ex) {
972            return -1;
973        }
974    }
975
976    /**
977     * Returns the CDMA ERI text,
978     *
979     * @hide
980     */
981    public String getCdmaEriText() {
982        try {
983            return getITelephony().getCdmaEriText();
984        } catch (RemoteException ex) {
985            // the phone process is restarting.
986            return null;
987        } catch (NullPointerException ex) {
988            return null;
989        }
990    }
991
992    /**
993     * @return true if the current device is "voice capable".
994     * <p>
995     * "Voice capable" means that this device supports circuit-switched
996     * (i.e. voice) phone calls over the telephony network, and is allowed
997     * to display the in-call UI while a cellular voice call is active.
998     * This will be false on "data only" devices which can't make voice
999     * calls and don't support any in-call UI.
1000     * <p>
1001     * Note: the meaning of this flag is subtly different from the
1002     * PackageManager.FEATURE_TELEPHONY system feature, which is available
1003     * on any device with a telephony radio, even if the device is
1004     * data-only.
1005     *
1006     * @hide pending API review
1007     */
1008    public boolean isVoiceCapable() {
1009        if (sContext == null) return true;
1010        return sContext.getResources().getBoolean(
1011                com.android.internal.R.bool.config_voice_capable);
1012    }
1013
1014    /**
1015     * @return true if the current device supports sms service.
1016     * <p>
1017     * If true, this means that the device supports both sending and
1018     * receiving sms via the telephony network.
1019     * <p>
1020     * Note: Voicemail waiting sms, cell broadcasting sms, and MMS are
1021     *       disabled when device doesn't support sms.
1022     *
1023     * @hide pending API review
1024     */
1025    public boolean isSmsCapable() {
1026        if (sContext == null) return true;
1027        return sContext.getResources().getBoolean(
1028                com.android.internal.R.bool.config_sms_capable);
1029    }
1030}
1031