TelephonyManager.java revision 094beeccf5bf6e68d73f94a1aeaeda6690f4bf06
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 android.content.Intent#getData} is a URI describing the recipient of the message.
140     * <p>
141     * The {@link android.content.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 Group Identifier Level1 for a GSM phone.
911     * 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 getGroupIdLevel1() {
917        try {
918            return getSubscriberInfo().getGroupIdLevel1();
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 phone number string for line 1, for example, the MSISDN
929     * for a GSM phone. Return null if it is unavailable.
930     * <p>
931     * Requires Permission:
932     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
933     */
934    public String getLine1Number() {
935        try {
936            return getSubscriberInfo().getLine1Number();
937        } catch (RemoteException ex) {
938            return null;
939        } catch (NullPointerException ex) {
940            // This could happen before phone restarts due to crashing
941            return null;
942        }
943    }
944
945    /**
946     * Returns the alphabetic identifier associated with the line 1 number.
947     * Return null if it is unavailable.
948     * <p>
949     * Requires Permission:
950     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
951     * @hide
952     * nobody seems to call this.
953     */
954    public String getLine1AlphaTag() {
955        try {
956            return getSubscriberInfo().getLine1AlphaTag();
957        } catch (RemoteException ex) {
958            return null;
959        } catch (NullPointerException ex) {
960            // This could happen before phone restarts due to crashing
961            return null;
962        }
963    }
964
965    /**
966     * Returns the MSISDN string.
967     * for a GSM phone. Return null if it is unavailable.
968     * <p>
969     * Requires Permission:
970     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
971     *
972     * @hide
973     */
974    public String getMsisdn() {
975        try {
976            return getSubscriberInfo().getMsisdn();
977        } catch (RemoteException ex) {
978            return null;
979        } catch (NullPointerException ex) {
980            // This could happen before phone restarts due to crashing
981            return null;
982        }
983    }
984
985    /**
986     * Returns the voice mail number. Return null if it is unavailable.
987     * <p>
988     * Requires Permission:
989     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
990     */
991    public String getVoiceMailNumber() {
992        try {
993            return getSubscriberInfo().getVoiceMailNumber();
994        } catch (RemoteException ex) {
995            return null;
996        } catch (NullPointerException ex) {
997            // This could happen before phone restarts due to crashing
998            return null;
999        }
1000    }
1001
1002    /**
1003     * Returns the complete voice mail number. Return null if it is unavailable.
1004     * <p>
1005     * Requires Permission:
1006     *   {@link android.Manifest.permission#CALL_PRIVILEGED CALL_PRIVILEGED}
1007     *
1008     * @hide
1009     */
1010    public String getCompleteVoiceMailNumber() {
1011        try {
1012            return getSubscriberInfo().getCompleteVoiceMailNumber();
1013        } catch (RemoteException ex) {
1014            return null;
1015        } catch (NullPointerException ex) {
1016            // This could happen before phone restarts due to crashing
1017            return null;
1018        }
1019    }
1020
1021    /**
1022     * Returns the voice mail count. Return 0 if unavailable.
1023     * <p>
1024     * Requires Permission:
1025     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1026     * @hide
1027     */
1028    public int getVoiceMessageCount() {
1029        try {
1030            return getITelephony().getVoiceMessageCount();
1031        } catch (RemoteException ex) {
1032            return 0;
1033        } catch (NullPointerException ex) {
1034            // This could happen before phone restarts due to crashing
1035            return 0;
1036        }
1037    }
1038
1039    /**
1040     * Retrieves the alphabetic identifier associated with the voice
1041     * mail number.
1042     * <p>
1043     * Requires Permission:
1044     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1045     */
1046    public String getVoiceMailAlphaTag() {
1047        try {
1048            return getSubscriberInfo().getVoiceMailAlphaTag();
1049        } catch (RemoteException ex) {
1050            return null;
1051        } catch (NullPointerException ex) {
1052            // This could happen before phone restarts due to crashing
1053            return null;
1054        }
1055    }
1056
1057    /**
1058     * Returns the IMS private user identity (IMPI) that was loaded from the ISIM.
1059     * @return the IMPI, or null if not present or not loaded
1060     * @hide
1061     */
1062    public String getIsimImpi() {
1063        try {
1064            return getSubscriberInfo().getIsimImpi();
1065        } catch (RemoteException ex) {
1066            return null;
1067        } catch (NullPointerException ex) {
1068            // This could happen before phone restarts due to crashing
1069            return null;
1070        }
1071    }
1072
1073    /**
1074     * Returns the IMS home network domain name that was loaded from the ISIM.
1075     * @return the IMS domain name, or null if not present or not loaded
1076     * @hide
1077     */
1078    public String getIsimDomain() {
1079        try {
1080            return getSubscriberInfo().getIsimDomain();
1081        } catch (RemoteException ex) {
1082            return null;
1083        } catch (NullPointerException ex) {
1084            // This could happen before phone restarts due to crashing
1085            return null;
1086        }
1087    }
1088
1089    /**
1090     * Returns the IMS public user identities (IMPU) that were loaded from the ISIM.
1091     * @return an array of IMPU strings, with one IMPU per string, or null if
1092     *      not present or not loaded
1093     * @hide
1094     */
1095    public String[] getIsimImpu() {
1096        try {
1097            return getSubscriberInfo().getIsimImpu();
1098        } catch (RemoteException ex) {
1099            return null;
1100        } catch (NullPointerException ex) {
1101            // This could happen before phone restarts due to crashing
1102            return null;
1103        }
1104    }
1105
1106    private IPhoneSubInfo getSubscriberInfo() {
1107        // get it each time because that process crashes a lot
1108        return IPhoneSubInfo.Stub.asInterface(ServiceManager.getService("iphonesubinfo"));
1109    }
1110
1111
1112    /** Device call state: No activity. */
1113    public static final int CALL_STATE_IDLE = 0;
1114    /** Device call state: Ringing. A new call arrived and is
1115     *  ringing or waiting. In the latter case, another call is
1116     *  already active. */
1117    public static final int CALL_STATE_RINGING = 1;
1118    /** Device call state: Off-hook. At least one call exists
1119      * that is dialing, active, or on hold, and no calls are ringing
1120      * or waiting. */
1121    public static final int CALL_STATE_OFFHOOK = 2;
1122
1123    /**
1124     * Returns a constant indicating the call state (cellular) on the device.
1125     */
1126    public int getCallState() {
1127        try {
1128            return getITelephony().getCallState();
1129        } catch (RemoteException ex) {
1130            // the phone process is restarting.
1131            return CALL_STATE_IDLE;
1132        } catch (NullPointerException ex) {
1133          // the phone process is restarting.
1134          return CALL_STATE_IDLE;
1135      }
1136    }
1137
1138    /** Data connection activity: No traffic. */
1139    public static final int DATA_ACTIVITY_NONE = 0x00000000;
1140    /** Data connection activity: Currently receiving IP PPP traffic. */
1141    public static final int DATA_ACTIVITY_IN = 0x00000001;
1142    /** Data connection activity: Currently sending IP PPP traffic. */
1143    public static final int DATA_ACTIVITY_OUT = 0x00000002;
1144    /** Data connection activity: Currently both sending and receiving
1145     *  IP PPP traffic. */
1146    public static final int DATA_ACTIVITY_INOUT = DATA_ACTIVITY_IN | DATA_ACTIVITY_OUT;
1147    /**
1148     * Data connection is active, but physical link is down
1149     */
1150    public static final int DATA_ACTIVITY_DORMANT = 0x00000004;
1151
1152    /**
1153     * Returns a constant indicating the type of activity on a data connection
1154     * (cellular).
1155     *
1156     * @see #DATA_ACTIVITY_NONE
1157     * @see #DATA_ACTIVITY_IN
1158     * @see #DATA_ACTIVITY_OUT
1159     * @see #DATA_ACTIVITY_INOUT
1160     * @see #DATA_ACTIVITY_DORMANT
1161     */
1162    public int getDataActivity() {
1163        try {
1164            return getITelephony().getDataActivity();
1165        } catch (RemoteException ex) {
1166            // the phone process is restarting.
1167            return DATA_ACTIVITY_NONE;
1168        } catch (NullPointerException ex) {
1169          // the phone process is restarting.
1170          return DATA_ACTIVITY_NONE;
1171      }
1172    }
1173
1174    /** Data connection state: Unknown.  Used before we know the state.
1175     * @hide
1176     */
1177    public static final int DATA_UNKNOWN        = -1;
1178    /** Data connection state: Disconnected. IP traffic not available. */
1179    public static final int DATA_DISCONNECTED   = 0;
1180    /** Data connection state: Currently setting up a data connection. */
1181    public static final int DATA_CONNECTING     = 1;
1182    /** Data connection state: Connected. IP traffic should be available. */
1183    public static final int DATA_CONNECTED      = 2;
1184    /** Data connection state: Suspended. The connection is up, but IP
1185     * traffic is temporarily unavailable. For example, in a 2G network,
1186     * data activity may be suspended when a voice call arrives. */
1187    public static final int DATA_SUSPENDED      = 3;
1188
1189    /**
1190     * Returns a constant indicating the current data connection state
1191     * (cellular).
1192     *
1193     * @see #DATA_DISCONNECTED
1194     * @see #DATA_CONNECTING
1195     * @see #DATA_CONNECTED
1196     * @see #DATA_SUSPENDED
1197     */
1198    public int getDataState() {
1199        try {
1200            return getITelephony().getDataState();
1201        } catch (RemoteException ex) {
1202            // the phone process is restarting.
1203            return DATA_DISCONNECTED;
1204        } catch (NullPointerException ex) {
1205            return DATA_DISCONNECTED;
1206        }
1207    }
1208
1209    private ITelephony getITelephony() {
1210        return ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE));
1211    }
1212
1213    //
1214    //
1215    // PhoneStateListener
1216    //
1217    //
1218
1219    /**
1220     * Registers a listener object to receive notification of changes
1221     * in specified telephony states.
1222     * <p>
1223     * To register a listener, pass a {@link PhoneStateListener}
1224     * and specify at least one telephony state of interest in
1225     * the events argument.
1226     *
1227     * At registration, and when a specified telephony state
1228     * changes, the telephony manager invokes the appropriate
1229     * callback method on the listener object and passes the
1230     * current (udpated) values.
1231     * <p>
1232     * To unregister a listener, pass the listener object and set the
1233     * events argument to
1234     * {@link PhoneStateListener#LISTEN_NONE LISTEN_NONE} (0).
1235     *
1236     * @param listener The {@link PhoneStateListener} object to register
1237     *                 (or unregister)
1238     * @param events The telephony state(s) of interest to the listener,
1239     *               as a bitwise-OR combination of {@link PhoneStateListener}
1240     *               LISTEN_ flags.
1241     */
1242    public void listen(PhoneStateListener listener, int events) {
1243        String pkgForDebug = mContext != null ? mContext.getPackageName() : "<unknown>";
1244        try {
1245            Boolean notifyNow = (getITelephony() != null);
1246            sRegistry.listen(pkgForDebug, listener.callback, events, notifyNow);
1247        } catch (RemoteException ex) {
1248            // system process dead
1249        } catch (NullPointerException ex) {
1250            // system process dead
1251        }
1252    }
1253
1254    /**
1255     * Returns the CDMA ERI icon index to display
1256     *
1257     * @hide
1258     */
1259    public int getCdmaEriIconIndex() {
1260        try {
1261            return getITelephony().getCdmaEriIconIndex();
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 icon mode,
1272     * 0 - ON
1273     * 1 - FLASHING
1274     *
1275     * @hide
1276     */
1277    public int getCdmaEriIconMode() {
1278        try {
1279            return getITelephony().getCdmaEriIconMode();
1280        } catch (RemoteException ex) {
1281            // the phone process is restarting.
1282            return -1;
1283        } catch (NullPointerException ex) {
1284            return -1;
1285        }
1286    }
1287
1288    /**
1289     * Returns the CDMA ERI text,
1290     *
1291     * @hide
1292     */
1293    public String getCdmaEriText() {
1294        try {
1295            return getITelephony().getCdmaEriText();
1296        } catch (RemoteException ex) {
1297            // the phone process is restarting.
1298            return null;
1299        } catch (NullPointerException ex) {
1300            return null;
1301        }
1302    }
1303
1304    /**
1305     * @return true if the current device is "voice capable".
1306     * <p>
1307     * "Voice capable" means that this device supports circuit-switched
1308     * (i.e. voice) phone calls over the telephony network, and is allowed
1309     * to display the in-call UI while a cellular voice call is active.
1310     * This will be false on "data only" devices which can't make voice
1311     * calls and don't support any in-call UI.
1312     * <p>
1313     * Note: the meaning of this flag is subtly different from the
1314     * PackageManager.FEATURE_TELEPHONY system feature, which is available
1315     * on any device with a telephony radio, even if the device is
1316     * data-only.
1317     *
1318     * @hide pending API review
1319     */
1320    public boolean isVoiceCapable() {
1321        if (mContext == null) return true;
1322        return mContext.getResources().getBoolean(
1323                com.android.internal.R.bool.config_voice_capable);
1324    }
1325
1326    /**
1327     * @return true if the current device supports sms service.
1328     * <p>
1329     * If true, this means that the device supports both sending and
1330     * receiving sms via the telephony network.
1331     * <p>
1332     * Note: Voicemail waiting sms, cell broadcasting sms, and MMS are
1333     *       disabled when device doesn't support sms.
1334     *
1335     * @hide pending API review
1336     */
1337    public boolean isSmsCapable() {
1338        if (mContext == null) return true;
1339        return mContext.getResources().getBoolean(
1340                com.android.internal.R.bool.config_sms_capable);
1341    }
1342
1343    /**
1344     * Returns all observed cell information of the device.
1345     *
1346     * @return List of CellInfo or null if info unavailable.
1347     *
1348     * <p>Requires Permission:
1349     * (@link android.Manifest.permission#ACCESS_COARSE_UPDATES}
1350     */
1351    public List<CellInfo> getAllCellInfo() {
1352        try {
1353            return getITelephony().getAllCellInfo();
1354        } catch (RemoteException ex) {
1355            return null;
1356        } catch (NullPointerException ex) {
1357            return null;
1358        }
1359    }
1360
1361    /**
1362     * Sets the minimum time in milli-seconds between {@link PhoneStateListener#onCellInfoChanged
1363     * PhoneStateListener.onCellInfoChanged} will be invoked.
1364     *
1365     * The default, 0, means invoke onCellInfoChanged when any of the reported
1366     * information changes. Setting the value to INT_MAX(0x7fffffff) means never issue
1367     * A onCellInfoChanged.
1368     *
1369     * @param rateInMillis the rate
1370     *
1371     * @hide
1372     */
1373    public void setCellInfoListRate(int rateInMillis) {
1374        try {
1375            getITelephony().setCellInfoListRate(rateInMillis);
1376        } catch (RemoteException ex) {
1377        } catch (NullPointerException ex) {
1378        }
1379    }
1380}
1381