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