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