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