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