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