TelephonyManager.java revision 83da75d938d519bbcffb9c3b52802fd2daad4aee
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.PrivateApi;
20import android.annotation.SdkConstant;
21import android.annotation.SdkConstant.SdkConstantType;
22import android.content.Context;
23import android.os.Bundle;
24import android.os.Handler;
25import android.os.Message;
26import android.os.RemoteException;
27import android.os.ServiceManager;
28import android.os.SystemProperties;
29import android.telephony.Rlog;
30import android.util.Log;
31
32import com.android.internal.telephony.IPhoneSubInfo;
33import com.android.internal.telephony.ITelephony;
34import com.android.internal.telephony.ITelephonyListener;
35import com.android.internal.telephony.ITelephonyRegistry;
36import com.android.internal.telephony.PhoneConstants;
37import com.android.internal.telephony.RILConstants;
38import com.android.internal.telephony.TelephonyProperties;
39
40import java.io.FileInputStream;
41import java.io.IOException;
42import java.util.HashMap;
43import java.util.List;
44import java.util.regex.Matcher;
45import java.util.regex.Pattern;
46
47/**
48 * Provides access to information about the telephony services on
49 * the device. Applications can use the methods in this class to
50 * determine telephony services and states, as well as to access some
51 * types of subscriber information. Applications can also register
52 * a listener to receive notification of telephony state changes.
53 * <p>
54 * You do not instantiate this class directly; instead, you retrieve
55 * a reference to an instance through
56 * {@link android.content.Context#getSystemService
57 * Context.getSystemService(Context.TELEPHONY_SERVICE)}.
58 * <p>
59 * Note that access to some telephony information is
60 * permission-protected. Your application cannot access the protected
61 * information unless it has the appropriate permissions declared in
62 * its manifest file. Where permissions apply, they are noted in the
63 * the methods through which you access the protected information.
64 */
65public class TelephonyManager {
66    private static final String TAG = "TelephonyManager";
67
68    private static ITelephonyRegistry sRegistry;
69
70    private final HashMap<CallStateListener,Listener> mListeners
71            = new HashMap<CallStateListener,Listener>();
72    private final Context mContext;
73
74    private static class Listener extends ITelephonyListener.Stub {
75        final CallStateListener mListener;
76        private static final int WHAT = 1;
77
78        private Handler mHandler = new Handler() {
79            @Override
80            public void handleMessage(Message msg) {
81                mListener.onCallStateChanged(msg.arg1, msg.arg2, (String)msg.obj);
82            }
83        };
84
85        Listener(CallStateListener listener) {
86            mListener = listener;
87        }
88
89        @Override
90        public void onUpdate(final int callId, final int state, final String number) {
91            if (mHandler != null) {
92                mHandler.sendMessage(mHandler.obtainMessage(WHAT, callId, state, number));
93            }
94        }
95
96        void clearQueue() {
97            mHandler.removeMessages(WHAT);
98
99            // Don't accept more incoming binder calls either.
100            mHandler = null;
101        }
102    }
103
104    /** @hide */
105    public TelephonyManager(Context context) {
106        Context appContext = context.getApplicationContext();
107        if (appContext != null) {
108            mContext = appContext;
109        } else {
110            mContext = context;
111        }
112
113        if (sRegistry == null) {
114            sRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
115                    "telephony.registry"));
116        }
117    }
118
119    /** @hide */
120    private TelephonyManager() {
121        mContext = null;
122    }
123
124    private static TelephonyManager sInstance = new TelephonyManager();
125
126    /** @hide
127    /* @deprecated - use getSystemService as described above */
128    public static TelephonyManager getDefault() {
129        return sInstance;
130    }
131
132    /** {@hide} */
133    public static TelephonyManager from(Context context) {
134        return (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
135    }
136
137    //
138    // Broadcast Intent actions
139    //
140
141    /**
142     * Broadcast intent action indicating that the call state (cellular)
143     * on the device has changed.
144     *
145     * <p>
146     * The {@link #EXTRA_STATE} extra indicates the new call state.
147     * If the new state is RINGING, a second extra
148     * {@link #EXTRA_INCOMING_NUMBER} provides the incoming phone number as
149     * a String.
150     *
151     * <p class="note">
152     * Requires the READ_PHONE_STATE permission.
153     *
154     * <p class="note">
155     * This was a {@link android.content.Context#sendStickyBroadcast sticky}
156     * broadcast in version 1.0, but it is no longer sticky.
157     * Instead, use {@link #getCallState} to synchronously query the current call state.
158     *
159     * @see #EXTRA_STATE
160     * @see #EXTRA_INCOMING_NUMBER
161     * @see #getCallState
162     */
163    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
164    public static final String ACTION_PHONE_STATE_CHANGED =
165            "android.intent.action.PHONE_STATE";
166
167    /**
168     * The Phone app sends this intent when a user opts to respond-via-message during an incoming
169     * call. By default, the device's default SMS app consumes this message and sends a text message
170     * to the caller. A third party app can also provide this functionality by consuming this Intent
171     * with a {@link android.app.Service} and sending the message using its own messaging system.
172     * <p>The intent contains a URI (available from {@link android.content.Intent#getData})
173     * describing the recipient, using either the {@code sms:}, {@code smsto:}, {@code mms:},
174     * or {@code mmsto:} URI schema. Each of these URI schema carry the recipient information the
175     * same way: the path part of the URI contains the recipient's phone number or a comma-separated
176     * set of phone numbers if there are multiple recipients. For example, {@code
177     * smsto:2065551234}.</p>
178     *
179     * <p>The intent may also contain extras for the message text (in {@link
180     * android.content.Intent#EXTRA_TEXT}) and a message subject
181     * (in {@link android.content.Intent#EXTRA_SUBJECT}).</p>
182     *
183     * <p class="note"><strong>Note:</strong>
184     * The intent-filter that consumes this Intent needs to be in a {@link android.app.Service}
185     * that requires the
186     * permission {@link android.Manifest.permission#SEND_RESPOND_VIA_MESSAGE}.</p>
187     * <p>For example, the service that receives this intent can be declared in the manifest file
188     * with an intent filter like this:</p>
189     * <pre>
190     * &lt;!-- Service that delivers SMS messages received from the phone "quick response" -->
191     * &lt;service android:name=".HeadlessSmsSendService"
192     *          android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE"
193     *          android:exported="true" >
194     *   &lt;intent-filter>
195     *     &lt;action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />
196     *     &lt;category android:name="android.intent.category.DEFAULT" />
197     *     &lt;data android:scheme="sms" />
198     *     &lt;data android:scheme="smsto" />
199     *     &lt;data android:scheme="mms" />
200     *     &lt;data android:scheme="mmsto" />
201     *   &lt;/intent-filter>
202     * &lt;/service></pre>
203     * <p>
204     * Output: nothing.
205     */
206    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
207    public static final String ACTION_RESPOND_VIA_MESSAGE =
208            "android.intent.action.RESPOND_VIA_MESSAGE";
209
210    /**
211     * The lookup key used with the {@link #ACTION_PHONE_STATE_CHANGED} broadcast
212     * for a String containing the new call state.
213     *
214     * @see #EXTRA_STATE_IDLE
215     * @see #EXTRA_STATE_RINGING
216     * @see #EXTRA_STATE_OFFHOOK
217     *
218     * <p class="note">
219     * Retrieve with
220     * {@link android.content.Intent#getStringExtra(String)}.
221     */
222    public static final String EXTRA_STATE = PhoneConstants.STATE_KEY;
223
224    /**
225     * Value used with {@link #EXTRA_STATE} corresponding to
226     * {@link #CALL_STATE_IDLE}.
227     */
228    public static final String EXTRA_STATE_IDLE = PhoneConstants.State.IDLE.toString();
229
230    /**
231     * Value used with {@link #EXTRA_STATE} corresponding to
232     * {@link #CALL_STATE_RINGING}.
233     */
234    public static final String EXTRA_STATE_RINGING = PhoneConstants.State.RINGING.toString();
235
236    /**
237     * Value used with {@link #EXTRA_STATE} corresponding to
238     * {@link #CALL_STATE_OFFHOOK}.
239     */
240    public static final String EXTRA_STATE_OFFHOOK = PhoneConstants.State.OFFHOOK.toString();
241
242    /**
243     * The lookup key used with the {@link #ACTION_PHONE_STATE_CHANGED} broadcast
244     * for a String containing the incoming phone number.
245     * Only valid when the new call state is RINGING.
246     *
247     * <p class="note">
248     * Retrieve with
249     * {@link android.content.Intent#getStringExtra(String)}.
250     */
251    public static final String EXTRA_INCOMING_NUMBER = "incoming_number";
252
253
254    //
255    //
256    // Device Info
257    //
258    //
259
260    /**
261     * Returns the software version number for the device, for example,
262     * the IMEI/SV for GSM phones. Return null if the software version is
263     * not available.
264     *
265     * <p>Requires Permission:
266     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
267     */
268    public String getDeviceSoftwareVersion() {
269        try {
270            return getSubscriberInfo().getDeviceSvn();
271        } catch (RemoteException ex) {
272            return null;
273        } catch (NullPointerException ex) {
274            return null;
275        }
276    }
277
278    /**
279     * Returns the unique device ID, for example, the IMEI for GSM and the MEID
280     * or ESN for CDMA phones. Return null if device ID is not available.
281     *
282     * <p>Requires Permission:
283     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
284     */
285    public String getDeviceId() {
286        try {
287            return getSubscriberInfo().getDeviceId();
288        } catch (RemoteException ex) {
289            return null;
290        } catch (NullPointerException ex) {
291            return null;
292        }
293    }
294
295    /**
296     * Returns the current location of the device.
297     *<p>
298     * If there is only one radio in the device and that radio has an LTE connection,
299     * this method will return null. The implementation must not to try add LTE
300     * identifiers into the existing cdma/gsm classes.
301     *<p>
302     * In the future this call will be deprecated.
303     *<p>
304     * @return Current location of the device or null if not available.
305     *
306     * <p>Requires Permission:
307     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
308     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_FINE_LOCATION}.
309     */
310    public CellLocation getCellLocation() {
311        try {
312            Bundle bundle = getITelephony().getCellLocation();
313            if (bundle.isEmpty()) return null;
314            CellLocation cl = CellLocation.newFromBundle(bundle);
315            if (cl.isEmpty())
316                return null;
317            return cl;
318        } catch (RemoteException ex) {
319            return null;
320        } catch (NullPointerException ex) {
321            return null;
322        }
323    }
324
325    /**
326     * Enables location update notifications.  {@link PhoneStateListener#onCellLocationChanged
327     * PhoneStateListener.onCellLocationChanged} will be called on location updates.
328     *
329     * <p>Requires Permission: {@link android.Manifest.permission#CONTROL_LOCATION_UPDATES
330     * CONTROL_LOCATION_UPDATES}
331     *
332     * @hide
333     */
334    public void enableLocationUpdates() {
335        try {
336            getITelephony().enableLocationUpdates();
337        } catch (RemoteException ex) {
338        } catch (NullPointerException ex) {
339        }
340    }
341
342    /**
343     * Disables location update notifications.  {@link PhoneStateListener#onCellLocationChanged
344     * PhoneStateListener.onCellLocationChanged} will be called on location updates.
345     *
346     * <p>Requires Permission: {@link android.Manifest.permission#CONTROL_LOCATION_UPDATES
347     * CONTROL_LOCATION_UPDATES}
348     *
349     * @hide
350     */
351    public void disableLocationUpdates() {
352        try {
353            getITelephony().disableLocationUpdates();
354        } catch (RemoteException ex) {
355        } catch (NullPointerException ex) {
356        }
357    }
358
359    /**
360     * Returns the neighboring cell information of the device. The getAllCellInfo is preferred
361     * and use this only if getAllCellInfo return nulls or an empty list.
362     *<p>
363     * In the future this call will be deprecated.
364     *<p>
365     * @return List of NeighboringCellInfo or null if info unavailable.
366     *
367     * <p>Requires Permission:
368     * (@link android.Manifest.permission#ACCESS_COARSE_UPDATES}
369     */
370    public List<NeighboringCellInfo> getNeighboringCellInfo() {
371        try {
372            return getITelephony().getNeighboringCellInfo(mContext.getOpPackageName());
373        } catch (RemoteException ex) {
374            return null;
375        } catch (NullPointerException ex) {
376            return null;
377        }
378    }
379
380    /** No phone radio. */
381    public static final int PHONE_TYPE_NONE = PhoneConstants.PHONE_TYPE_NONE;
382    /** Phone radio is GSM. */
383    public static final int PHONE_TYPE_GSM = PhoneConstants.PHONE_TYPE_GSM;
384    /** Phone radio is CDMA. */
385    public static final int PHONE_TYPE_CDMA = PhoneConstants.PHONE_TYPE_CDMA;
386    /** Phone is via SIP. */
387    public static final int PHONE_TYPE_SIP = PhoneConstants.PHONE_TYPE_SIP;
388
389    /**
390     * Returns the current phone type.
391     * TODO: This is a last minute change and hence hidden.
392     *
393     * @see #PHONE_TYPE_NONE
394     * @see #PHONE_TYPE_GSM
395     * @see #PHONE_TYPE_CDMA
396     * @see #PHONE_TYPE_SIP
397     *
398     * {@hide}
399     */
400    public int getCurrentPhoneType() {
401        try{
402            ITelephony telephony = getITelephony();
403            if (telephony != null) {
404                return telephony.getActivePhoneType();
405            } else {
406                // This can happen when the ITelephony interface is not up yet.
407                return getPhoneTypeFromProperty();
408            }
409        } catch (RemoteException ex) {
410            // This shouldn't happen in the normal case, as a backup we
411            // read from the system property.
412            return getPhoneTypeFromProperty();
413        } catch (NullPointerException ex) {
414            // This shouldn't happen in the normal case, as a backup we
415            // read from the system property.
416            return getPhoneTypeFromProperty();
417        }
418    }
419
420    /**
421     * Returns a constant indicating the device phone type.  This
422     * indicates the type of radio used to transmit voice calls.
423     *
424     * @see #PHONE_TYPE_NONE
425     * @see #PHONE_TYPE_GSM
426     * @see #PHONE_TYPE_CDMA
427     * @see #PHONE_TYPE_SIP
428     */
429    public int getPhoneType() {
430        if (!isVoiceCapable()) {
431            return PHONE_TYPE_NONE;
432        }
433        return getCurrentPhoneType();
434    }
435
436    private int getPhoneTypeFromProperty() {
437        int type =
438            SystemProperties.getInt(TelephonyProperties.CURRENT_ACTIVE_PHONE,
439                    getPhoneTypeFromNetworkType());
440        return type;
441    }
442
443    private int getPhoneTypeFromNetworkType() {
444        // When the system property CURRENT_ACTIVE_PHONE, has not been set,
445        // use the system property for default network type.
446        // This is a fail safe, and can only happen at first boot.
447        int mode = SystemProperties.getInt("ro.telephony.default_network", -1);
448        if (mode == -1)
449            return PHONE_TYPE_NONE;
450        return getPhoneType(mode);
451    }
452
453    /**
454     * This function returns the type of the phone, depending
455     * on the network mode.
456     *
457     * @param networkMode
458     * @return Phone Type
459     *
460     * @hide
461     */
462    public static int getPhoneType(int networkMode) {
463        switch(networkMode) {
464        case RILConstants.NETWORK_MODE_CDMA:
465        case RILConstants.NETWORK_MODE_CDMA_NO_EVDO:
466        case RILConstants.NETWORK_MODE_EVDO_NO_CDMA:
467            return PhoneConstants.PHONE_TYPE_CDMA;
468
469        case RILConstants.NETWORK_MODE_WCDMA_PREF:
470        case RILConstants.NETWORK_MODE_GSM_ONLY:
471        case RILConstants.NETWORK_MODE_WCDMA_ONLY:
472        case RILConstants.NETWORK_MODE_GSM_UMTS:
473        case RILConstants.NETWORK_MODE_LTE_GSM_WCDMA:
474        case RILConstants.NETWORK_MODE_LTE_WCDMA:
475        case RILConstants.NETWORK_MODE_LTE_CMDA_EVDO_GSM_WCDMA:
476            return PhoneConstants.PHONE_TYPE_GSM;
477
478        // Use CDMA Phone for the global mode including CDMA
479        case RILConstants.NETWORK_MODE_GLOBAL:
480        case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO:
481            return PhoneConstants.PHONE_TYPE_CDMA;
482
483        case RILConstants.NETWORK_MODE_LTE_ONLY:
484            if (getLteOnCdmaModeStatic() == PhoneConstants.LTE_ON_CDMA_TRUE) {
485                return PhoneConstants.PHONE_TYPE_CDMA;
486            } else {
487                return PhoneConstants.PHONE_TYPE_GSM;
488            }
489        default:
490            return PhoneConstants.PHONE_TYPE_GSM;
491        }
492    }
493
494    /**
495     * The contents of the /proc/cmdline file
496     */
497    private static String getProcCmdLine()
498    {
499        String cmdline = "";
500        FileInputStream is = null;
501        try {
502            is = new FileInputStream("/proc/cmdline");
503            byte [] buffer = new byte[2048];
504            int count = is.read(buffer);
505            if (count > 0) {
506                cmdline = new String(buffer, 0, count);
507            }
508        } catch (IOException e) {
509            Rlog.d(TAG, "No /proc/cmdline exception=" + e);
510        } finally {
511            if (is != null) {
512                try {
513                    is.close();
514                } catch (IOException e) {
515                }
516            }
517        }
518        Rlog.d(TAG, "/proc/cmdline=" + cmdline);
519        return cmdline;
520    }
521
522    /** Kernel command line */
523    private static final String sKernelCmdLine = getProcCmdLine();
524
525    /** Pattern for selecting the product type from the kernel command line */
526    private static final Pattern sProductTypePattern =
527        Pattern.compile("\\sproduct_type\\s*=\\s*(\\w+)");
528
529    /** The ProductType used for LTE on CDMA devices */
530    private static final String sLteOnCdmaProductType =
531        SystemProperties.get(TelephonyProperties.PROPERTY_LTE_ON_CDMA_PRODUCT_TYPE, "");
532
533    /**
534     * Return if the current radio is LTE on CDMA. This
535     * is a tri-state return value as for a period of time
536     * the mode may be unknown.
537     *
538     * @return {@link PhoneConstants#LTE_ON_CDMA_UNKNOWN}, {@link PhoneConstants#LTE_ON_CDMA_FALSE}
539     * or {@link PhoneConstants#LTE_ON_CDMA_TRUE}
540     *
541     * @hide
542     */
543    public static int getLteOnCdmaModeStatic() {
544        int retVal;
545        int curVal;
546        String productType = "";
547
548        curVal = SystemProperties.getInt(TelephonyProperties.PROPERTY_LTE_ON_CDMA_DEVICE,
549                    PhoneConstants.LTE_ON_CDMA_UNKNOWN);
550        retVal = curVal;
551        if (retVal == PhoneConstants.LTE_ON_CDMA_UNKNOWN) {
552            Matcher matcher = sProductTypePattern.matcher(sKernelCmdLine);
553            if (matcher.find()) {
554                productType = matcher.group(1);
555                if (sLteOnCdmaProductType.equals(productType)) {
556                    retVal = PhoneConstants.LTE_ON_CDMA_TRUE;
557                } else {
558                    retVal = PhoneConstants.LTE_ON_CDMA_FALSE;
559                }
560            } else {
561                retVal = PhoneConstants.LTE_ON_CDMA_FALSE;
562            }
563        }
564
565        Rlog.d(TAG, "getLteOnCdmaMode=" + retVal + " curVal=" + curVal +
566                " product_type='" + productType +
567                "' lteOnCdmaProductType='" + sLteOnCdmaProductType + "'");
568        return retVal;
569    }
570
571    //
572    //
573    // Current Network
574    //
575    //
576
577    /**
578     * Returns the alphabetic name of current registered operator.
579     * <p>
580     * Availability: Only when user is registered to a network. Result may be
581     * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
582     * on a CDMA network).
583     */
584    public String getNetworkOperatorName() {
585        return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ALPHA);
586    }
587
588    /**
589     * Returns the numeric name (MCC+MNC) of current registered operator.
590     * <p>
591     * Availability: Only when user is registered to a network. Result may be
592     * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
593     * on a CDMA network).
594     */
595    public String getNetworkOperator() {
596        return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC);
597    }
598
599    /**
600     * Returns true if the device is considered roaming on the current
601     * network, for GSM purposes.
602     * <p>
603     * Availability: Only when user registered to a network.
604     */
605    public boolean isNetworkRoaming() {
606        return "true".equals(SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING));
607    }
608
609    /**
610     * Returns the ISO country code equivalent of the current registered
611     * operator's MCC (Mobile Country Code).
612     * <p>
613     * Availability: Only when user is registered to a network. Result may be
614     * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
615     * on a CDMA network).
616     */
617    public String getNetworkCountryIso() {
618        return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY);
619    }
620
621    /** Network type is unknown */
622    public static final int NETWORK_TYPE_UNKNOWN = 0;
623    /** Current network is GPRS */
624    public static final int NETWORK_TYPE_GPRS = 1;
625    /** Current network is EDGE */
626    public static final int NETWORK_TYPE_EDGE = 2;
627    /** Current network is UMTS */
628    public static final int NETWORK_TYPE_UMTS = 3;
629    /** Current network is CDMA: Either IS95A or IS95B*/
630    public static final int NETWORK_TYPE_CDMA = 4;
631    /** Current network is EVDO revision 0*/
632    public static final int NETWORK_TYPE_EVDO_0 = 5;
633    /** Current network is EVDO revision A*/
634    public static final int NETWORK_TYPE_EVDO_A = 6;
635    /** Current network is 1xRTT*/
636    public static final int NETWORK_TYPE_1xRTT = 7;
637    /** Current network is HSDPA */
638    public static final int NETWORK_TYPE_HSDPA = 8;
639    /** Current network is HSUPA */
640    public static final int NETWORK_TYPE_HSUPA = 9;
641    /** Current network is HSPA */
642    public static final int NETWORK_TYPE_HSPA = 10;
643    /** Current network is iDen */
644    public static final int NETWORK_TYPE_IDEN = 11;
645    /** Current network is EVDO revision B*/
646    public static final int NETWORK_TYPE_EVDO_B = 12;
647    /** Current network is LTE */
648    public static final int NETWORK_TYPE_LTE = 13;
649    /** Current network is eHRPD */
650    public static final int NETWORK_TYPE_EHRPD = 14;
651    /** Current network is HSPA+ */
652    public static final int NETWORK_TYPE_HSPAP = 15;
653
654    /**
655     * @return the NETWORK_TYPE_xxxx for current data connection.
656     */
657    public int getNetworkType() {
658        return getDataNetworkType();
659    }
660
661    /**
662     * Returns a constant indicating the radio technology (network type)
663     * currently in use on the device for data transmission.
664     * @return the network type
665     *
666     * @see #NETWORK_TYPE_UNKNOWN
667     * @see #NETWORK_TYPE_GPRS
668     * @see #NETWORK_TYPE_EDGE
669     * @see #NETWORK_TYPE_UMTS
670     * @see #NETWORK_TYPE_HSDPA
671     * @see #NETWORK_TYPE_HSUPA
672     * @see #NETWORK_TYPE_HSPA
673     * @see #NETWORK_TYPE_CDMA
674     * @see #NETWORK_TYPE_EVDO_0
675     * @see #NETWORK_TYPE_EVDO_A
676     * @see #NETWORK_TYPE_EVDO_B
677     * @see #NETWORK_TYPE_1xRTT
678     * @see #NETWORK_TYPE_IDEN
679     * @see #NETWORK_TYPE_LTE
680     * @see #NETWORK_TYPE_EHRPD
681     * @see #NETWORK_TYPE_HSPAP
682     *
683     * @hide
684     */
685    public int getDataNetworkType() {
686        try{
687            ITelephony telephony = getITelephony();
688            if (telephony != null) {
689                return telephony.getDataNetworkType();
690            } else {
691                // This can happen when the ITelephony interface is not up yet.
692                return NETWORK_TYPE_UNKNOWN;
693            }
694        } catch(RemoteException ex) {
695            // This shouldn't happen in the normal case
696            return NETWORK_TYPE_UNKNOWN;
697        } catch (NullPointerException ex) {
698            // This could happen before phone restarts due to crashing
699            return NETWORK_TYPE_UNKNOWN;
700        }
701    }
702
703    /**
704     * Returns the NETWORK_TYPE_xxxx for voice
705     *
706     * @hide
707     */
708    public int getVoiceNetworkType() {
709        try{
710            ITelephony telephony = getITelephony();
711            if (telephony != null) {
712                return telephony.getVoiceNetworkType();
713            } else {
714                // This can happen when the ITelephony interface is not up yet.
715                return NETWORK_TYPE_UNKNOWN;
716            }
717        } catch(RemoteException ex) {
718            // This shouldn't happen in the normal case
719            return NETWORK_TYPE_UNKNOWN;
720        } catch (NullPointerException ex) {
721            // This could happen before phone restarts due to crashing
722            return NETWORK_TYPE_UNKNOWN;
723        }
724    }
725
726    /** Unknown network class. {@hide} */
727    public static final int NETWORK_CLASS_UNKNOWN = 0;
728    /** Class of broadly defined "2G" networks. {@hide} */
729    public static final int NETWORK_CLASS_2_G = 1;
730    /** Class of broadly defined "3G" networks. {@hide} */
731    public static final int NETWORK_CLASS_3_G = 2;
732    /** Class of broadly defined "4G" networks. {@hide} */
733    public static final int NETWORK_CLASS_4_G = 3;
734
735    /**
736     * Return general class of network type, such as "3G" or "4G". In cases
737     * where classification is contentious, this method is conservative.
738     *
739     * @hide
740     */
741    public static int getNetworkClass(int networkType) {
742        switch (networkType) {
743            case NETWORK_TYPE_GPRS:
744            case NETWORK_TYPE_EDGE:
745            case NETWORK_TYPE_CDMA:
746            case NETWORK_TYPE_1xRTT:
747            case NETWORK_TYPE_IDEN:
748                return NETWORK_CLASS_2_G;
749            case NETWORK_TYPE_UMTS:
750            case NETWORK_TYPE_EVDO_0:
751            case NETWORK_TYPE_EVDO_A:
752            case NETWORK_TYPE_HSDPA:
753            case NETWORK_TYPE_HSUPA:
754            case NETWORK_TYPE_HSPA:
755            case NETWORK_TYPE_EVDO_B:
756            case NETWORK_TYPE_EHRPD:
757            case NETWORK_TYPE_HSPAP:
758                return NETWORK_CLASS_3_G;
759            case NETWORK_TYPE_LTE:
760                return NETWORK_CLASS_4_G;
761            default:
762                return NETWORK_CLASS_UNKNOWN;
763        }
764    }
765
766    /**
767     * Returns a string representation of the radio technology (network type)
768     * currently in use on the device.
769     * @return the name of the radio technology
770     *
771     * @hide pending API council review
772     */
773    public String getNetworkTypeName() {
774        return getNetworkTypeName(getNetworkType());
775    }
776
777    /** {@hide} */
778    public static String getNetworkTypeName(int type) {
779        switch (type) {
780            case NETWORK_TYPE_GPRS:
781                return "GPRS";
782            case NETWORK_TYPE_EDGE:
783                return "EDGE";
784            case NETWORK_TYPE_UMTS:
785                return "UMTS";
786            case NETWORK_TYPE_HSDPA:
787                return "HSDPA";
788            case NETWORK_TYPE_HSUPA:
789                return "HSUPA";
790            case NETWORK_TYPE_HSPA:
791                return "HSPA";
792            case NETWORK_TYPE_CDMA:
793                return "CDMA";
794            case NETWORK_TYPE_EVDO_0:
795                return "CDMA - EvDo rev. 0";
796            case NETWORK_TYPE_EVDO_A:
797                return "CDMA - EvDo rev. A";
798            case NETWORK_TYPE_EVDO_B:
799                return "CDMA - EvDo rev. B";
800            case NETWORK_TYPE_1xRTT:
801                return "CDMA - 1xRTT";
802            case NETWORK_TYPE_LTE:
803                return "LTE";
804            case NETWORK_TYPE_EHRPD:
805                return "CDMA - eHRPD";
806            case NETWORK_TYPE_IDEN:
807                return "iDEN";
808            case NETWORK_TYPE_HSPAP:
809                return "HSPA+";
810            default:
811                return "UNKNOWN";
812        }
813    }
814
815    //
816    //
817    // SIM Card
818    //
819    //
820
821    /** SIM card state: Unknown. Signifies that the SIM is in transition
822     *  between states. For example, when the user inputs the SIM pin
823     *  under PIN_REQUIRED state, a query for sim status returns
824     *  this state before turning to SIM_STATE_READY. */
825    public static final int SIM_STATE_UNKNOWN = 0;
826    /** SIM card state: no SIM card is available in the device */
827    public static final int SIM_STATE_ABSENT = 1;
828    /** SIM card state: Locked: requires the user's SIM PIN to unlock */
829    public static final int SIM_STATE_PIN_REQUIRED = 2;
830    /** SIM card state: Locked: requires the user's SIM PUK to unlock */
831    public static final int SIM_STATE_PUK_REQUIRED = 3;
832    /** SIM card state: Locked: requries a network PIN to unlock */
833    public static final int SIM_STATE_NETWORK_LOCKED = 4;
834    /** SIM card state: Ready */
835    public static final int SIM_STATE_READY = 5;
836
837    /**
838     * @return true if a ICC card is present
839     */
840    public boolean hasIccCard() {
841        try {
842            return getITelephony().hasIccCard();
843        } catch (RemoteException ex) {
844            // Assume no ICC card if remote exception which shouldn't happen
845            return false;
846        } catch (NullPointerException ex) {
847            // This could happen before phone restarts due to crashing
848            return false;
849        }
850    }
851
852    /**
853     * Returns a constant indicating the state of the
854     * device SIM card.
855     *
856     * @see #SIM_STATE_UNKNOWN
857     * @see #SIM_STATE_ABSENT
858     * @see #SIM_STATE_PIN_REQUIRED
859     * @see #SIM_STATE_PUK_REQUIRED
860     * @see #SIM_STATE_NETWORK_LOCKED
861     * @see #SIM_STATE_READY
862     */
863    public int getSimState() {
864        String prop = SystemProperties.get(TelephonyProperties.PROPERTY_SIM_STATE);
865        if ("ABSENT".equals(prop)) {
866            return SIM_STATE_ABSENT;
867        }
868        else if ("PIN_REQUIRED".equals(prop)) {
869            return SIM_STATE_PIN_REQUIRED;
870        }
871        else if ("PUK_REQUIRED".equals(prop)) {
872            return SIM_STATE_PUK_REQUIRED;
873        }
874        else if ("NETWORK_LOCKED".equals(prop)) {
875            return SIM_STATE_NETWORK_LOCKED;
876        }
877        else if ("READY".equals(prop)) {
878            return SIM_STATE_READY;
879        }
880        else {
881            return SIM_STATE_UNKNOWN;
882        }
883    }
884
885    /**
886     * Returns the MCC+MNC (mobile country code + mobile network code) of the
887     * provider of the SIM. 5 or 6 decimal digits.
888     * <p>
889     * Availability: SIM state must be {@link #SIM_STATE_READY}
890     *
891     * @see #getSimState
892     */
893    public String getSimOperator() {
894        return SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC);
895    }
896
897    /**
898     * Returns the Service Provider Name (SPN).
899     * <p>
900     * Availability: SIM state must be {@link #SIM_STATE_READY}
901     *
902     * @see #getSimState
903     */
904    public String getSimOperatorName() {
905        return SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA);
906    }
907
908    /**
909     * Returns the ISO country code equivalent for the SIM provider's country code.
910     */
911    public String getSimCountryIso() {
912        return SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY);
913    }
914
915    /**
916     * Returns the serial number of the SIM, if applicable. Return null if it is
917     * unavailable.
918     * <p>
919     * Requires Permission:
920     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
921     */
922    public String getSimSerialNumber() {
923        try {
924            return getSubscriberInfo().getIccSerialNumber();
925        } catch (RemoteException ex) {
926            return null;
927        } catch (NullPointerException ex) {
928            // This could happen before phone restarts due to crashing
929            return null;
930        }
931    }
932
933    /**
934     * Return if the current radio is LTE on CDMA. This
935     * is a tri-state return value as for a period of time
936     * the mode may be unknown.
937     *
938     * @return {@link PhoneConstants#LTE_ON_CDMA_UNKNOWN}, {@link PhoneConstants#LTE_ON_CDMA_FALSE}
939     * or {@link PhoneConstants#LTE_ON_CDMA_TRUE}
940     *
941     * @hide
942     */
943    public int getLteOnCdmaMode() {
944        try {
945            return getITelephony().getLteOnCdmaMode();
946        } catch (RemoteException ex) {
947            // Assume no ICC card if remote exception which shouldn't happen
948            return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
949        } catch (NullPointerException ex) {
950            // This could happen before phone restarts due to crashing
951            return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
952        }
953    }
954
955    //
956    //
957    // Subscriber Info
958    //
959    //
960
961    /**
962     * Returns the unique subscriber ID, for example, the IMSI for a GSM phone.
963     * Return null if it is unavailable.
964     * <p>
965     * Requires Permission:
966     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
967     */
968    public String getSubscriberId() {
969        try {
970            return getSubscriberInfo().getSubscriberId();
971        } catch (RemoteException ex) {
972            return null;
973        } catch (NullPointerException ex) {
974            // This could happen before phone restarts due to crashing
975            return null;
976        }
977    }
978
979    /**
980     * Returns the Group Identifier Level1 for a GSM phone.
981     * Return null if it is unavailable.
982     * <p>
983     * Requires Permission:
984     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
985     */
986    public String getGroupIdLevel1() {
987        try {
988            return getSubscriberInfo().getGroupIdLevel1();
989        } catch (RemoteException ex) {
990            return null;
991        } catch (NullPointerException ex) {
992            // This could happen before phone restarts due to crashing
993            return null;
994        }
995    }
996
997    /**
998     * Returns the phone number string for line 1, for example, the MSISDN
999     * for a GSM phone. Return null if it is unavailable.
1000     * <p>
1001     * Requires Permission:
1002     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1003     */
1004    public String getLine1Number() {
1005        try {
1006            return getSubscriberInfo().getLine1Number();
1007        } catch (RemoteException ex) {
1008            return null;
1009        } catch (NullPointerException ex) {
1010            // This could happen before phone restarts due to crashing
1011            return null;
1012        }
1013    }
1014
1015    /**
1016     * Returns the alphabetic identifier associated with the line 1 number.
1017     * Return null if it is unavailable.
1018     * <p>
1019     * Requires Permission:
1020     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1021     * @hide
1022     * nobody seems to call this.
1023     */
1024    public String getLine1AlphaTag() {
1025        try {
1026            return getSubscriberInfo().getLine1AlphaTag();
1027        } catch (RemoteException ex) {
1028            return null;
1029        } catch (NullPointerException ex) {
1030            // This could happen before phone restarts due to crashing
1031            return null;
1032        }
1033    }
1034
1035    /**
1036     * Returns the MSISDN string.
1037     * for a GSM phone. Return null if it is unavailable.
1038     * <p>
1039     * Requires Permission:
1040     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1041     *
1042     * @hide
1043     */
1044    public String getMsisdn() {
1045        try {
1046            return getSubscriberInfo().getMsisdn();
1047        } catch (RemoteException ex) {
1048            return null;
1049        } catch (NullPointerException ex) {
1050            // This could happen before phone restarts due to crashing
1051            return null;
1052        }
1053    }
1054
1055    /**
1056     * Returns the voice mail number. Return null if it is unavailable.
1057     * <p>
1058     * Requires Permission:
1059     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1060     */
1061    public String getVoiceMailNumber() {
1062        try {
1063            return getSubscriberInfo().getVoiceMailNumber();
1064        } catch (RemoteException ex) {
1065            return null;
1066        } catch (NullPointerException ex) {
1067            // This could happen before phone restarts due to crashing
1068            return null;
1069        }
1070    }
1071
1072    /**
1073     * Returns the complete voice mail number. Return null if it is unavailable.
1074     * <p>
1075     * Requires Permission:
1076     *   {@link android.Manifest.permission#CALL_PRIVILEGED CALL_PRIVILEGED}
1077     *
1078     * @hide
1079     */
1080    public String getCompleteVoiceMailNumber() {
1081        try {
1082            return getSubscriberInfo().getCompleteVoiceMailNumber();
1083        } catch (RemoteException ex) {
1084            return null;
1085        } catch (NullPointerException ex) {
1086            // This could happen before phone restarts due to crashing
1087            return null;
1088        }
1089    }
1090
1091    /**
1092     * Returns the voice mail count. Return 0 if unavailable.
1093     * <p>
1094     * Requires Permission:
1095     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1096     * @hide
1097     */
1098    public int getVoiceMessageCount() {
1099        try {
1100            return getITelephony().getVoiceMessageCount();
1101        } catch (RemoteException ex) {
1102            return 0;
1103        } catch (NullPointerException ex) {
1104            // This could happen before phone restarts due to crashing
1105            return 0;
1106        }
1107    }
1108
1109    /**
1110     * Retrieves the alphabetic identifier associated with the voice
1111     * mail number.
1112     * <p>
1113     * Requires Permission:
1114     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1115     */
1116    public String getVoiceMailAlphaTag() {
1117        try {
1118            return getSubscriberInfo().getVoiceMailAlphaTag();
1119        } catch (RemoteException ex) {
1120            return null;
1121        } catch (NullPointerException ex) {
1122            // This could happen before phone restarts due to crashing
1123            return null;
1124        }
1125    }
1126
1127    /**
1128     * Returns the IMS private user identity (IMPI) that was loaded from the ISIM.
1129     * @return the IMPI, or null if not present or not loaded
1130     * @hide
1131     */
1132    public String getIsimImpi() {
1133        try {
1134            return getSubscriberInfo().getIsimImpi();
1135        } catch (RemoteException ex) {
1136            return null;
1137        } catch (NullPointerException ex) {
1138            // This could happen before phone restarts due to crashing
1139            return null;
1140        }
1141    }
1142
1143    /**
1144     * Returns the IMS home network domain name that was loaded from the ISIM.
1145     * @return the IMS domain name, or null if not present or not loaded
1146     * @hide
1147     */
1148    public String getIsimDomain() {
1149        try {
1150            return getSubscriberInfo().getIsimDomain();
1151        } catch (RemoteException ex) {
1152            return null;
1153        } catch (NullPointerException ex) {
1154            // This could happen before phone restarts due to crashing
1155            return null;
1156        }
1157    }
1158
1159    /**
1160     * Returns the IMS public user identities (IMPU) that were loaded from the ISIM.
1161     * @return an array of IMPU strings, with one IMPU per string, or null if
1162     *      not present or not loaded
1163     * @hide
1164     */
1165    public String[] getIsimImpu() {
1166        try {
1167            return getSubscriberInfo().getIsimImpu();
1168        } catch (RemoteException ex) {
1169            return null;
1170        } catch (NullPointerException ex) {
1171            // This could happen before phone restarts due to crashing
1172            return null;
1173        }
1174    }
1175
1176    private IPhoneSubInfo getSubscriberInfo() {
1177        // get it each time because that process crashes a lot
1178        return IPhoneSubInfo.Stub.asInterface(ServiceManager.getService("iphonesubinfo"));
1179    }
1180
1181
1182    /** Device call state: No activity. */
1183    public static final int CALL_STATE_IDLE = 0;
1184    /** Device call state: Ringing. A new call arrived and is
1185     *  ringing or waiting. In the latter case, another call is
1186     *  already active. */
1187    public static final int CALL_STATE_RINGING = 1;
1188    /** Device call state: Off-hook. At least one call exists
1189      * that is dialing, active, or on hold, and no calls are ringing
1190      * or waiting. */
1191    public static final int CALL_STATE_OFFHOOK = 2;
1192
1193    /**
1194     * Returns a constant indicating the call state (cellular) on the device.
1195     */
1196    public int getCallState() {
1197        try {
1198            return getITelephony().getCallState();
1199        } catch (RemoteException ex) {
1200            // the phone process is restarting.
1201            return CALL_STATE_IDLE;
1202        } catch (NullPointerException ex) {
1203          // the phone process is restarting.
1204          return CALL_STATE_IDLE;
1205      }
1206    }
1207
1208    /** Data connection activity: No traffic. */
1209    public static final int DATA_ACTIVITY_NONE = 0x00000000;
1210    /** Data connection activity: Currently receiving IP PPP traffic. */
1211    public static final int DATA_ACTIVITY_IN = 0x00000001;
1212    /** Data connection activity: Currently sending IP PPP traffic. */
1213    public static final int DATA_ACTIVITY_OUT = 0x00000002;
1214    /** Data connection activity: Currently both sending and receiving
1215     *  IP PPP traffic. */
1216    public static final int DATA_ACTIVITY_INOUT = DATA_ACTIVITY_IN | DATA_ACTIVITY_OUT;
1217    /**
1218     * Data connection is active, but physical link is down
1219     */
1220    public static final int DATA_ACTIVITY_DORMANT = 0x00000004;
1221
1222    /**
1223     * Returns a constant indicating the type of activity on a data connection
1224     * (cellular).
1225     *
1226     * @see #DATA_ACTIVITY_NONE
1227     * @see #DATA_ACTIVITY_IN
1228     * @see #DATA_ACTIVITY_OUT
1229     * @see #DATA_ACTIVITY_INOUT
1230     * @see #DATA_ACTIVITY_DORMANT
1231     */
1232    public int getDataActivity() {
1233        try {
1234            return getITelephony().getDataActivity();
1235        } catch (RemoteException ex) {
1236            // the phone process is restarting.
1237            return DATA_ACTIVITY_NONE;
1238        } catch (NullPointerException ex) {
1239          // the phone process is restarting.
1240          return DATA_ACTIVITY_NONE;
1241      }
1242    }
1243
1244    /** Data connection state: Unknown.  Used before we know the state.
1245     * @hide
1246     */
1247    public static final int DATA_UNKNOWN        = -1;
1248    /** Data connection state: Disconnected. IP traffic not available. */
1249    public static final int DATA_DISCONNECTED   = 0;
1250    /** Data connection state: Currently setting up a data connection. */
1251    public static final int DATA_CONNECTING     = 1;
1252    /** Data connection state: Connected. IP traffic should be available. */
1253    public static final int DATA_CONNECTED      = 2;
1254    /** Data connection state: Suspended. The connection is up, but IP
1255     * traffic is temporarily unavailable. For example, in a 2G network,
1256     * data activity may be suspended when a voice call arrives. */
1257    public static final int DATA_SUSPENDED      = 3;
1258
1259    /**
1260     * Returns a constant indicating the current data connection state
1261     * (cellular).
1262     *
1263     * @see #DATA_DISCONNECTED
1264     * @see #DATA_CONNECTING
1265     * @see #DATA_CONNECTED
1266     * @see #DATA_SUSPENDED
1267     */
1268    public int getDataState() {
1269        try {
1270            return getITelephony().getDataState();
1271        } catch (RemoteException ex) {
1272            // the phone process is restarting.
1273            return DATA_DISCONNECTED;
1274        } catch (NullPointerException ex) {
1275            return DATA_DISCONNECTED;
1276        }
1277    }
1278
1279    private ITelephony getITelephony() {
1280        return ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE));
1281    }
1282
1283    //
1284    //
1285    // PhoneStateListener
1286    //
1287    //
1288
1289    /**
1290     * Registers a listener object to receive notification of changes
1291     * in specified telephony states.
1292     * <p>
1293     * To register a listener, pass a {@link PhoneStateListener}
1294     * and specify at least one telephony state of interest in
1295     * the events argument.
1296     *
1297     * At registration, and when a specified telephony state
1298     * changes, the telephony manager invokes the appropriate
1299     * callback method on the listener object and passes the
1300     * current (udpated) values.
1301     * <p>
1302     * To unregister a listener, pass the listener object and set the
1303     * events argument to
1304     * {@link PhoneStateListener#LISTEN_NONE LISTEN_NONE} (0).
1305     *
1306     * @param listener The {@link PhoneStateListener} object to register
1307     *                 (or unregister)
1308     * @param events The telephony state(s) of interest to the listener,
1309     *               as a bitwise-OR combination of {@link PhoneStateListener}
1310     *               LISTEN_ flags.
1311     */
1312    public void listen(PhoneStateListener listener, int events) {
1313        String pkgForDebug = mContext != null ? mContext.getPackageName() : "<unknown>";
1314        try {
1315            Boolean notifyNow = true;
1316            sRegistry.listen(pkgForDebug, listener.callback, events, notifyNow);
1317        } catch (RemoteException ex) {
1318            // system process dead
1319        } catch (NullPointerException ex) {
1320            // system process dead
1321        }
1322    }
1323
1324    /**
1325     * Returns the CDMA ERI icon index to display
1326     *
1327     * @hide
1328     */
1329    public int getCdmaEriIconIndex() {
1330        try {
1331            return getITelephony().getCdmaEriIconIndex();
1332        } catch (RemoteException ex) {
1333            // the phone process is restarting.
1334            return -1;
1335        } catch (NullPointerException ex) {
1336            return -1;
1337        }
1338    }
1339
1340    /**
1341     * Returns the CDMA ERI icon mode,
1342     * 0 - ON
1343     * 1 - FLASHING
1344     *
1345     * @hide
1346     */
1347    public int getCdmaEriIconMode() {
1348        try {
1349            return getITelephony().getCdmaEriIconMode();
1350        } catch (RemoteException ex) {
1351            // the phone process is restarting.
1352            return -1;
1353        } catch (NullPointerException ex) {
1354            return -1;
1355        }
1356    }
1357
1358    /**
1359     * Returns the CDMA ERI text,
1360     *
1361     * @hide
1362     */
1363    public String getCdmaEriText() {
1364        try {
1365            return getITelephony().getCdmaEriText();
1366        } catch (RemoteException ex) {
1367            // the phone process is restarting.
1368            return null;
1369        } catch (NullPointerException ex) {
1370            return null;
1371        }
1372    }
1373
1374    /**
1375     * @return true if the current device is "voice capable".
1376     * <p>
1377     * "Voice capable" means that this device supports circuit-switched
1378     * (i.e. voice) phone calls over the telephony network, and is allowed
1379     * to display the in-call UI while a cellular voice call is active.
1380     * This will be false on "data only" devices which can't make voice
1381     * calls and don't support any in-call UI.
1382     * <p>
1383     * Note: the meaning of this flag is subtly different from the
1384     * PackageManager.FEATURE_TELEPHONY system feature, which is available
1385     * on any device with a telephony radio, even if the device is
1386     * data-only.
1387     *
1388     * @hide pending API review
1389     */
1390    public boolean isVoiceCapable() {
1391        if (mContext == null) return true;
1392        return mContext.getResources().getBoolean(
1393                com.android.internal.R.bool.config_voice_capable);
1394    }
1395
1396    /**
1397     * @return true if the current device supports sms service.
1398     * <p>
1399     * If true, this means that the device supports both sending and
1400     * receiving sms via the telephony network.
1401     * <p>
1402     * Note: Voicemail waiting sms, cell broadcasting sms, and MMS are
1403     *       disabled when device doesn't support sms.
1404     *
1405     * @hide pending API review
1406     */
1407    public boolean isSmsCapable() {
1408        if (mContext == null) return true;
1409        return mContext.getResources().getBoolean(
1410                com.android.internal.R.bool.config_sms_capable);
1411    }
1412
1413    /**
1414     * Returns all observed cell information from all radios on the
1415     * device including the primary and neighboring cells. This does
1416     * not cause or change the rate of PhoneStateListner#onCellInfoChanged.
1417     *<p>
1418     * The list can include one or more of {@link android.telephony.CellInfoGsm CellInfoGsm},
1419     * {@link android.telephony.CellInfoCdma CellInfoCdma},
1420     * {@link android.telephony.CellInfoLte CellInfoLte} and
1421     * {@link android.telephony.CellInfoWcdma CellInfoCdma} in any combination.
1422     * Specifically on devices with multiple radios it is typical to see instances of
1423     * one or more of any these in the list. In addition 0, 1 or more CellInfo
1424     * objects may return isRegistered() true.
1425     *<p>
1426     * This is preferred over using getCellLocation although for older
1427     * devices this may return null in which case getCellLocation should
1428     * be called.
1429     *<p>
1430     * @return List of CellInfo or null if info unavailable.
1431     *
1432     * <p>Requires Permission: {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}
1433     */
1434    public List<CellInfo> getAllCellInfo() {
1435        try {
1436            return getITelephony().getAllCellInfo();
1437        } catch (RemoteException ex) {
1438            return null;
1439        } catch (NullPointerException ex) {
1440            return null;
1441        }
1442    }
1443
1444    /**
1445     * Sets the minimum time in milli-seconds between {@link PhoneStateListener#onCellInfoChanged
1446     * PhoneStateListener.onCellInfoChanged} will be invoked.
1447     *<p>
1448     * The default, 0, means invoke onCellInfoChanged when any of the reported
1449     * information changes. Setting the value to INT_MAX(0x7fffffff) means never issue
1450     * A onCellInfoChanged.
1451     *<p>
1452     * @param rateInMillis the rate
1453     *
1454     * @hide
1455     */
1456    public void setCellInfoListRate(int rateInMillis) {
1457        try {
1458            getITelephony().setCellInfoListRate(rateInMillis);
1459        } catch (RemoteException ex) {
1460        } catch (NullPointerException ex) {
1461        }
1462    }
1463
1464    /**
1465     * Returns the MMS user agent.
1466     */
1467    public String getMmsUserAgent() {
1468        if (mContext == null) return null;
1469        return mContext.getResources().getString(
1470                com.android.internal.R.string.config_mms_user_agent);
1471    }
1472
1473    /**
1474     * Returns the MMS user agent profile URL.
1475     */
1476    public String getMmsUAProfUrl() {
1477        if (mContext == null) return null;
1478        return mContext.getResources().getString(
1479                com.android.internal.R.string.config_mms_user_agent_profile_url);
1480    }
1481
1482    /** @hide */
1483    @PrivateApi
1484    public void dial(String number) {
1485        try {
1486            getITelephony().dial(number);
1487        } catch (RemoteException e) {
1488            Log.e(TAG, "Error calling ITelephony#dial", e);
1489        }
1490    }
1491
1492    /** @hide */
1493    @PrivateApi
1494    public void call(String callingPackage, String number) {
1495        try {
1496            getITelephony().call(callingPackage, number);
1497        } catch (RemoteException e) {
1498            Log.e(TAG, "Error calling ITelephony#call", e);
1499        }
1500    }
1501
1502    /** @hide */
1503    @PrivateApi
1504    public boolean showCallScreen() {
1505        try {
1506            return getITelephony().showCallScreen();
1507        } catch (RemoteException e) {
1508            Log.e(TAG, "Error calling ITelephony#showCallScreen", e);
1509        }
1510        return false;
1511    }
1512
1513    /** @hide */
1514    @PrivateApi
1515    public boolean showCallScreenWithDialpad(boolean showDialpad) {
1516        try {
1517            return getITelephony().showCallScreenWithDialpad(showDialpad);
1518        } catch (RemoteException e) {
1519            Log.e(TAG, "Error calling ITelephony#showCallScreenWithDialpad", e);
1520        }
1521        return false;
1522    }
1523
1524    /** @hide */
1525    @PrivateApi
1526    public boolean endCall() {
1527        try {
1528            return getITelephony().endCall();
1529        } catch (RemoteException e) {
1530            Log.e(TAG, "Error calling ITelephony#endCall", e);
1531        }
1532        return false;
1533    }
1534
1535    /** @hide */
1536    @PrivateApi
1537    public void answerRingingCall() {
1538        try {
1539            getITelephony().answerRingingCall();
1540        } catch (RemoteException e) {
1541            Log.e(TAG, "Error calling ITelephony#answerRingingCall", e);
1542        }
1543    }
1544
1545    /** @hide */
1546    @PrivateApi
1547    public void toggleHold() {
1548        try {
1549            getITelephony().toggleHold();
1550        } catch (RemoteException e) {
1551            Log.e(TAG, "Error calling ITelephony#toggleHold", e);
1552        }
1553    }
1554
1555    /** @hide */
1556    @PrivateApi
1557    public void merge() {
1558        try {
1559            getITelephony().merge();
1560        } catch (RemoteException e) {
1561            Log.e(TAG, "Error calling ITelephony#merge", e);
1562        }
1563    }
1564
1565    /** @hide */
1566    @PrivateApi
1567    public void swap() {
1568        try {
1569            getITelephony().swap();
1570        } catch (RemoteException e) {
1571            Log.e(TAG, "Error calling ITelephony#swap", e);
1572        }
1573    }
1574
1575    /** @hide */
1576    @PrivateApi
1577    public void mute(boolean mute) {
1578        try {
1579            getITelephony().mute(mute);
1580        } catch (RemoteException e) {
1581            Log.e(TAG, "Error calling ITelephony#mute", e);
1582        }
1583    }
1584
1585    /** @hide */
1586    @PrivateApi
1587    public void silenceRinger() {
1588        try {
1589            getITelephony().silenceRinger();
1590        } catch (RemoteException e) {
1591            Log.e(TAG, "Error calling ITelephony#silenceRinger", e);
1592        }
1593    }
1594
1595    /** @hide */
1596    @PrivateApi
1597    public boolean isOffhook() {
1598        try {
1599            return getITelephony().isOffhook();
1600        } catch (RemoteException e) {
1601            Log.e(TAG, "Error calling ITelephony#isOffhook", e);
1602        }
1603        return false;
1604    }
1605
1606    /** @hide */
1607    @PrivateApi
1608    public boolean isRinging() {
1609        try {
1610            return getITelephony().isRinging();
1611        } catch (RemoteException e) {
1612            Log.e(TAG, "Error calling ITelephony#isRinging", e);
1613        }
1614        return false;
1615    }
1616
1617    /** @hide */
1618    @PrivateApi
1619    public boolean isIdle() {
1620        try {
1621            return getITelephony().isIdle();
1622        } catch (RemoteException e) {
1623            Log.e(TAG, "Error calling ITelephony#isIdle", e);
1624        }
1625        return true;
1626    }
1627
1628    /** @hide */
1629    @PrivateApi
1630    public boolean isRadioOn() {
1631        try {
1632            return getITelephony().isRadioOn();
1633        } catch (RemoteException e) {
1634            Log.e(TAG, "Error calling ITelephony#isRadioOn", e);
1635        }
1636        return false;
1637    }
1638
1639    /** @hide */
1640    @PrivateApi
1641    public boolean isSimPinEnabled() {
1642        try {
1643            return getITelephony().isSimPinEnabled();
1644        } catch (RemoteException e) {
1645            Log.e(TAG, "Error calling ITelephony#isSimPinEnabled", e);
1646        }
1647        return false;
1648    }
1649
1650    /** @hide */
1651    @PrivateApi
1652    public void cancelMissedCallsNotification() {
1653        try {
1654            getITelephony().cancelMissedCallsNotification();
1655        } catch (RemoteException e) {
1656            Log.e(TAG, "Error calling ITelephony#cancelMissedCallsNotification", e);
1657        }
1658    }
1659
1660    /** @hide */
1661    @PrivateApi
1662    public boolean supplyPin(String pin) {
1663        try {
1664            return getITelephony().supplyPin(pin);
1665        } catch (RemoteException e) {
1666            Log.e(TAG, "Error calling ITelephony#supplyPin", e);
1667        }
1668        return false;
1669    }
1670
1671    /** @hide */
1672    @PrivateApi
1673    public boolean supplyPuk(String puk, String pin) {
1674        try {
1675            return getITelephony().supplyPuk(puk, pin);
1676        } catch (RemoteException e) {
1677            Log.e(TAG, "Error calling ITelephony#supplyPuk", e);
1678        }
1679        return false;
1680    }
1681
1682    /** @hide */
1683    @PrivateApi
1684    public int[] supplyPinReportResult(String pin) {
1685        try {
1686            return getITelephony().supplyPinReportResult(pin);
1687        } catch (RemoteException e) {
1688            Log.e(TAG, "Error calling ITelephony#supplyPinReportResult", e);
1689        }
1690        return new int[0];
1691    }
1692
1693    /** @hide */
1694    @PrivateApi
1695    public int[] supplyPukReportResult(String puk, String pin) {
1696        try {
1697            return getITelephony().supplyPukReportResult(puk, pin);
1698        } catch (RemoteException e) {
1699            Log.e(TAG, "Error calling ITelephony#]", e);
1700        }
1701        return new int[0];
1702    }
1703
1704    /** @hide */
1705    @PrivateApi
1706    public boolean handlePinMmi(String dialString) {
1707        try {
1708            return getITelephony().handlePinMmi(dialString);
1709        } catch (RemoteException e) {
1710            Log.e(TAG, "Error calling ITelephony#handlePinMmi", e);
1711        }
1712        return false;
1713    }
1714
1715    /** @hide */
1716    @PrivateApi
1717    public void toggleRadioOnOff() {
1718        try {
1719            getITelephony().toggleRadioOnOff();
1720        } catch (RemoteException e) {
1721            Log.e(TAG, "Error calling ITelephony#toggleRadioOnOff", e);
1722        }
1723    }
1724
1725    /** @hide */
1726    @PrivateApi
1727    public boolean setRadio(boolean turnOn) {
1728        try {
1729            return getITelephony().setRadio(turnOn);
1730        } catch (RemoteException e) {
1731            Log.e(TAG, "Error calling ITelephony#setRadio", e);
1732        }
1733        return false;
1734    }
1735
1736    /** @hide */
1737    @PrivateApi
1738    public boolean setRadioPower(boolean turnOn) {
1739        try {
1740            return getITelephony().setRadioPower(turnOn);
1741        } catch (RemoteException e) {
1742            Log.e(TAG, "Error calling ITelephony#setRadioPower", e);
1743        }
1744        return false;
1745    }
1746
1747    /** @hide */
1748    @PrivateApi
1749    public void updateServiceLocation() {
1750        try {
1751            getITelephony().updateServiceLocation();
1752        } catch (RemoteException e) {
1753            Log.e(TAG, "Error calling ITelephony#updateServiceLocation", e);
1754        }
1755    }
1756
1757    /** @hide */
1758    @PrivateApi
1759    public int enableApnType(String type) {
1760        try {
1761            return getITelephony().enableApnType(type);
1762        } catch (RemoteException e) {
1763            Log.e(TAG, "Error calling ITelephony#enableApnType", e);
1764        }
1765        return PhoneConstants.APN_REQUEST_FAILED;
1766    }
1767
1768    /** @hide */
1769    @PrivateApi
1770    public int disableApnType(String type) {
1771        try {
1772            return getITelephony().disableApnType(type);
1773        } catch (RemoteException e) {
1774            Log.e(TAG, "Error calling ITelephony#disableApnType", e);
1775        }
1776        return PhoneConstants.APN_REQUEST_FAILED;
1777    }
1778
1779    /** @hide */
1780    @PrivateApi
1781    public boolean enableDataConnectivity() {
1782        try {
1783            return getITelephony().enableDataConnectivity();
1784        } catch (RemoteException e) {
1785            Log.e(TAG, "Error calling ITelephony#enableDataConnectivity", e);
1786        }
1787        return false;
1788    }
1789
1790    /** @hide */
1791    @PrivateApi
1792    public boolean disableDataConnectivity() {
1793        try {
1794            return getITelephony().disableDataConnectivity();
1795        } catch (RemoteException e) {
1796            Log.e(TAG, "Error calling ITelephony#disableDataConnectivity", e);
1797        }
1798        return false;
1799    }
1800
1801    /** @hide */
1802    @PrivateApi
1803    public boolean isDataConnectivityPossible() {
1804        try {
1805            return getITelephony().isDataConnectivityPossible();
1806        } catch (RemoteException e) {
1807            Log.e(TAG, "Error calling ITelephony#isDataConnectivityPossible", e);
1808        }
1809        return false;
1810    }
1811
1812    /** @hide */
1813    @PrivateApi
1814    public boolean needsOtaServiceProvisioning() {
1815        try {
1816            return getITelephony().needsOtaServiceProvisioning();
1817        } catch (RemoteException e) {
1818            Log.e(TAG, "Error calling ITelephony#needsOtaServiceProvisioning", e);
1819        }
1820        return false;
1821    }
1822
1823    /** @hide */
1824    @PrivateApi
1825    public void playDtmfTone(char digit, boolean timedShortCode) {
1826        try {
1827            getITelephony().playDtmfTone(digit, timedShortCode);
1828        } catch (RemoteException e) {
1829            Log.e(TAG, "Error calling ITelephony#playDtmfTone", e);
1830        }
1831    }
1832
1833    /** @hide */
1834    @PrivateApi
1835    public void stopDtmfTone() {
1836        try {
1837            getITelephony().stopDtmfTone();
1838        } catch (RemoteException e) {
1839            Log.e(TAG, "Error calling ITelephony#stopDtmfTone", e);
1840        }
1841    }
1842
1843    /** @hide */
1844    @PrivateApi
1845    public void addCallStateListener(CallStateListener listener) {
1846        try {
1847            if (listener == null) {
1848                throw new RuntimeException("Listener can't be null");
1849            }
1850            if (!mListeners.containsKey(listener)) {
1851                final Listener l = new Listener(listener);
1852                mListeners.put(listener, l);
1853                getITelephony().addListener(l);
1854            }
1855        } catch (RemoteException e) {
1856            Log.e(TAG, "Error calling ITelephony#addListener", e);
1857        }
1858    }
1859
1860    /** @hide */
1861    @PrivateApi
1862    public void removeCallStateListener(CallStateListener listener) {
1863        try {
1864            final Listener l = mListeners.remove(listener);
1865            if (l != null) {
1866                // Make sure that no callbacks that are already in flight come.
1867                l.clearQueue();
1868                getITelephony().removeListener(l);
1869            }
1870        } catch (RemoteException e) {
1871            Log.e(TAG, "Error calling ITelephony#removeListener", e);
1872        }
1873    }
1874}
1875