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