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