TelephonyManager.java revision 6c1dc315aaf68676c56cc00b13f6937ef5592f8d
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.Nullable;
20import android.annotation.SystemApi;
21import android.annotation.SdkConstant;
22import android.annotation.SdkConstant.SdkConstantType;
23import android.content.ContentResolver;
24import android.content.Context;
25import android.content.Intent;
26import android.provider.Settings;
27import android.provider.Settings.SettingNotFoundException;
28import android.os.Bundle;
29import android.os.RemoteException;
30import android.os.ServiceManager;
31import android.os.SystemProperties;
32import android.telecom.PhoneAccount;
33import android.util.Log;
34
35import com.android.internal.telecom.ITelecomService;
36import com.android.internal.telephony.IPhoneSubInfo;
37import com.android.internal.telephony.ITelephony;
38import com.android.internal.telephony.ITelephonyRegistry;
39import com.android.internal.telephony.PhoneConstants;
40import com.android.internal.telephony.RILConstants;
41import com.android.internal.telephony.TelephonyProperties;
42
43import java.io.FileInputStream;
44import java.io.IOException;
45import java.util.List;
46import java.util.regex.Matcher;
47import java.util.regex.Pattern;
48
49/**
50 * Provides access to information about the telephony services on
51 * the device. Applications can use the methods in this class to
52 * determine telephony services and states, as well as to access some
53 * types of subscriber information. Applications can also register
54 * a listener to receive notification of telephony state changes.
55 * <p>
56 * You do not instantiate this class directly; instead, you retrieve
57 * a reference to an instance through
58 * {@link android.content.Context#getSystemService
59 * Context.getSystemService(Context.TELEPHONY_SERVICE)}.
60 * <p>
61 * Note that access to some telephony information is
62 * permission-protected. Your application cannot access the protected
63 * information unless it has the appropriate permissions declared in
64 * its manifest file. Where permissions apply, they are noted in the
65 * the methods through which you access the protected information.
66 */
67public class TelephonyManager {
68    private static final String TAG = "TelephonyManager";
69
70    private static ITelephonyRegistry sRegistry;
71
72    /**
73     * The allowed states of Wi-Fi calling.
74     *
75     * @hide
76     */
77    public interface WifiCallingChoices {
78        /** Always use Wi-Fi calling */
79        static final int ALWAYS_USE = 0;
80        /** Ask the user whether to use Wi-Fi on every call */
81        static final int ASK_EVERY_TIME = 1;
82        /** Never use Wi-Fi calling */
83        static final int NEVER_USE = 2;
84    }
85
86    private final Context mContext;
87    private SubscriptionManager mSubscriptionManager;
88
89    private static String multiSimConfig =
90            SystemProperties.get(TelephonyProperties.PROPERTY_MULTI_SIM_CONFIG);
91
92    /** Enum indicating multisim variants
93     *  DSDS - Dual SIM Dual Standby
94     *  DSDA - Dual SIM Dual Active
95     *  TSTS - Triple SIM Triple Standby
96     **/
97    /** @hide */
98    public enum MultiSimVariants {
99        DSDS,
100        DSDA,
101        TSTS,
102        UNKNOWN
103    };
104
105    /** @hide */
106    public TelephonyManager(Context context) {
107        Context appContext = context.getApplicationContext();
108        if (appContext != null) {
109            mContext = appContext;
110        } else {
111            mContext = context;
112        }
113        mSubscriptionManager = SubscriptionManager.from(mContext);
114
115        if (sRegistry == null) {
116            sRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
117                    "telephony.registry"));
118        }
119    }
120
121    /** @hide */
122    private TelephonyManager() {
123        mContext = null;
124    }
125
126    private static TelephonyManager sInstance = new TelephonyManager();
127
128    /** @hide
129    /* @deprecated - use getSystemService as described above */
130    public static TelephonyManager getDefault() {
131        return sInstance;
132    }
133
134
135    /**
136     * Returns the multi SIM variant
137     * Returns DSDS for Dual SIM Dual Standby
138     * Returns DSDA for Dual SIM Dual Active
139     * Returns TSTS for Triple SIM Triple Standby
140     * Returns UNKNOWN for others
141     */
142    /** {@hide} */
143    public MultiSimVariants getMultiSimConfiguration() {
144        String mSimConfig =
145            SystemProperties.get(TelephonyProperties.PROPERTY_MULTI_SIM_CONFIG);
146        if (mSimConfig.equals("dsds")) {
147            return MultiSimVariants.DSDS;
148        } else if (mSimConfig.equals("dsda")) {
149            return MultiSimVariants.DSDA;
150        } else if (mSimConfig.equals("tsts")) {
151            return MultiSimVariants.TSTS;
152        } else {
153            return MultiSimVariants.UNKNOWN;
154        }
155    }
156
157
158    /**
159     * Returns the number of phones available.
160     * Returns 1 for Single standby mode (Single SIM functionality)
161     * Returns 2 for Dual standby mode.(Dual SIM functionality)
162     */
163    public int getPhoneCount() {
164        int phoneCount = 1;
165        switch (getMultiSimConfiguration()) {
166            case UNKNOWN:
167                phoneCount = 1;
168                break;
169            case DSDS:
170            case DSDA:
171                phoneCount = PhoneConstants.MAX_PHONE_COUNT_DUAL_SIM;
172                break;
173            case TSTS:
174                phoneCount = PhoneConstants.MAX_PHONE_COUNT_TRI_SIM;
175                break;
176        }
177        return phoneCount;
178    }
179
180    /** {@hide} */
181    public static TelephonyManager from(Context context) {
182        return (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
183    }
184
185    /** {@hide} */
186    public boolean isMultiSimEnabled() {
187        return (multiSimConfig.equals("dsds") || multiSimConfig.equals("dsda") ||
188            multiSimConfig.equals("tsts"));
189    }
190
191    //
192    // Broadcast Intent actions
193    //
194
195    /**
196     * Broadcast intent action indicating that the call state
197     * on the device has changed.
198     *
199     * <p>
200     * The {@link #EXTRA_STATE} extra indicates the new call state.
201     * If the new state is RINGING, a second extra
202     * {@link #EXTRA_INCOMING_NUMBER} provides the incoming phone number as
203     * a String.
204     *
205     * <p class="note">
206     * Requires the READ_PHONE_STATE permission.
207     *
208     * <p class="note">
209     * This was a {@link android.content.Context#sendStickyBroadcast sticky}
210     * broadcast in version 1.0, but it is no longer sticky.
211     * Instead, use {@link #getCallState} to synchronously query the current call state.
212     *
213     * @see #EXTRA_STATE
214     * @see #EXTRA_INCOMING_NUMBER
215     * @see #getCallState
216     */
217    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
218    public static final String ACTION_PHONE_STATE_CHANGED =
219            "android.intent.action.PHONE_STATE";
220
221    /**
222     * The Phone app sends this intent when a user opts to respond-via-message during an incoming
223     * call. By default, the device's default SMS app consumes this message and sends a text message
224     * to the caller. A third party app can also provide this functionality by consuming this Intent
225     * with a {@link android.app.Service} and sending the message using its own messaging system.
226     * <p>The intent contains a URI (available from {@link android.content.Intent#getData})
227     * describing the recipient, using either the {@code sms:}, {@code smsto:}, {@code mms:},
228     * or {@code mmsto:} URI schema. Each of these URI schema carry the recipient information the
229     * same way: the path part of the URI contains the recipient's phone number or a comma-separated
230     * set of phone numbers if there are multiple recipients. For example, {@code
231     * smsto:2065551234}.</p>
232     *
233     * <p>The intent may also contain extras for the message text (in {@link
234     * android.content.Intent#EXTRA_TEXT}) and a message subject
235     * (in {@link android.content.Intent#EXTRA_SUBJECT}).</p>
236     *
237     * <p class="note"><strong>Note:</strong>
238     * The intent-filter that consumes this Intent needs to be in a {@link android.app.Service}
239     * that requires the
240     * permission {@link android.Manifest.permission#SEND_RESPOND_VIA_MESSAGE}.</p>
241     * <p>For example, the service that receives this intent can be declared in the manifest file
242     * with an intent filter like this:</p>
243     * <pre>
244     * &lt;!-- Service that delivers SMS messages received from the phone "quick response" -->
245     * &lt;service android:name=".HeadlessSmsSendService"
246     *          android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE"
247     *          android:exported="true" >
248     *   &lt;intent-filter>
249     *     &lt;action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />
250     *     &lt;category android:name="android.intent.category.DEFAULT" />
251     *     &lt;data android:scheme="sms" />
252     *     &lt;data android:scheme="smsto" />
253     *     &lt;data android:scheme="mms" />
254     *     &lt;data android:scheme="mmsto" />
255     *   &lt;/intent-filter>
256     * &lt;/service></pre>
257     * <p>
258     * Output: nothing.
259     */
260    @SdkConstant(SdkConstantType.SERVICE_ACTION)
261    public static final String ACTION_RESPOND_VIA_MESSAGE =
262            "android.intent.action.RESPOND_VIA_MESSAGE";
263
264    /**
265     * The emergency dialer may choose to present activities with intent filters for this
266     * action as emergency assistance buttons that launch the activity when clicked.
267     *
268     * @hide
269     */
270    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
271    public static final String ACTION_EMERGENCY_ASSISTANCE =
272            "android.telephony.action.EMERGENCY_ASSISTANCE";
273
274    /**
275     * @hide
276     */
277    public static final boolean EMERGENCY_ASSISTANCE_ENABLED = false;
278
279    /**
280     * The lookup key used with the {@link #ACTION_PHONE_STATE_CHANGED} broadcast
281     * for a String containing the new call state.
282     *
283     * @see #EXTRA_STATE_IDLE
284     * @see #EXTRA_STATE_RINGING
285     * @see #EXTRA_STATE_OFFHOOK
286     *
287     * <p class="note">
288     * Retrieve with
289     * {@link android.content.Intent#getStringExtra(String)}.
290     */
291    public static final String EXTRA_STATE = PhoneConstants.STATE_KEY;
292
293    /**
294     * Value used with {@link #EXTRA_STATE} corresponding to
295     * {@link #CALL_STATE_IDLE}.
296     */
297    public static final String EXTRA_STATE_IDLE = PhoneConstants.State.IDLE.toString();
298
299    /**
300     * Value used with {@link #EXTRA_STATE} corresponding to
301     * {@link #CALL_STATE_RINGING}.
302     */
303    public static final String EXTRA_STATE_RINGING = PhoneConstants.State.RINGING.toString();
304
305    /**
306     * Value used with {@link #EXTRA_STATE} corresponding to
307     * {@link #CALL_STATE_OFFHOOK}.
308     */
309    public static final String EXTRA_STATE_OFFHOOK = PhoneConstants.State.OFFHOOK.toString();
310
311    /**
312     * The lookup key used with the {@link #ACTION_PHONE_STATE_CHANGED} broadcast
313     * for a String containing the incoming phone number.
314     * Only valid when the new call state is RINGING.
315     *
316     * <p class="note">
317     * Retrieve with
318     * {@link android.content.Intent#getStringExtra(String)}.
319     */
320    public static final String EXTRA_INCOMING_NUMBER = "incoming_number";
321
322    /**
323     * Broadcast intent action indicating that a precise call state
324     * (cellular) on the device has changed.
325     *
326     * <p>
327     * The {@link #EXTRA_RINGING_CALL_STATE} extra indicates the ringing call state.
328     * The {@link #EXTRA_FOREGROUND_CALL_STATE} extra indicates the foreground call state.
329     * The {@link #EXTRA_BACKGROUND_CALL_STATE} extra indicates the background call state.
330     * The {@link #EXTRA_DISCONNECT_CAUSE} extra indicates the disconnect cause.
331     * The {@link #EXTRA_PRECISE_DISCONNECT_CAUSE} extra indicates the precise disconnect cause.
332     *
333     * <p class="note">
334     * Requires the READ_PRECISE_PHONE_STATE permission.
335     *
336     * @see #EXTRA_RINGING_CALL_STATE
337     * @see #EXTRA_FOREGROUND_CALL_STATE
338     * @see #EXTRA_BACKGROUND_CALL_STATE
339     * @see #EXTRA_DISCONNECT_CAUSE
340     * @see #EXTRA_PRECISE_DISCONNECT_CAUSE
341     *
342     * <p class="note">
343     * Requires the READ_PRECISE_PHONE_STATE permission.
344     *
345     * @hide
346     */
347    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
348    public static final String ACTION_PRECISE_CALL_STATE_CHANGED =
349            "android.intent.action.PRECISE_CALL_STATE";
350
351    /**
352     * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast
353     * for an integer containing the state of the current ringing call.
354     *
355     * @see PreciseCallState#PRECISE_CALL_STATE_NOT_VALID
356     * @see PreciseCallState#PRECISE_CALL_STATE_IDLE
357     * @see PreciseCallState#PRECISE_CALL_STATE_ACTIVE
358     * @see PreciseCallState#PRECISE_CALL_STATE_HOLDING
359     * @see PreciseCallState#PRECISE_CALL_STATE_DIALING
360     * @see PreciseCallState#PRECISE_CALL_STATE_ALERTING
361     * @see PreciseCallState#PRECISE_CALL_STATE_INCOMING
362     * @see PreciseCallState#PRECISE_CALL_STATE_WAITING
363     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTED
364     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTING
365     *
366     * <p class="note">
367     * Retrieve with
368     * {@link android.content.Intent#getIntExtra(String name, int defaultValue)}.
369     *
370     * @hide
371     */
372    public static final String EXTRA_RINGING_CALL_STATE = "ringing_state";
373
374    /**
375     * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast
376     * for an integer containing the state of the current foreground call.
377     *
378     * @see PreciseCallState#PRECISE_CALL_STATE_NOT_VALID
379     * @see PreciseCallState#PRECISE_CALL_STATE_IDLE
380     * @see PreciseCallState#PRECISE_CALL_STATE_ACTIVE
381     * @see PreciseCallState#PRECISE_CALL_STATE_HOLDING
382     * @see PreciseCallState#PRECISE_CALL_STATE_DIALING
383     * @see PreciseCallState#PRECISE_CALL_STATE_ALERTING
384     * @see PreciseCallState#PRECISE_CALL_STATE_INCOMING
385     * @see PreciseCallState#PRECISE_CALL_STATE_WAITING
386     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTED
387     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTING
388     *
389     * <p class="note">
390     * Retrieve with
391     * {@link android.content.Intent#getIntExtra(String name, int defaultValue)}.
392     *
393     * @hide
394     */
395    public static final String EXTRA_FOREGROUND_CALL_STATE = "foreground_state";
396
397    /**
398     * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast
399     * for an integer containing the state of the current background call.
400     *
401     * @see PreciseCallState#PRECISE_CALL_STATE_NOT_VALID
402     * @see PreciseCallState#PRECISE_CALL_STATE_IDLE
403     * @see PreciseCallState#PRECISE_CALL_STATE_ACTIVE
404     * @see PreciseCallState#PRECISE_CALL_STATE_HOLDING
405     * @see PreciseCallState#PRECISE_CALL_STATE_DIALING
406     * @see PreciseCallState#PRECISE_CALL_STATE_ALERTING
407     * @see PreciseCallState#PRECISE_CALL_STATE_INCOMING
408     * @see PreciseCallState#PRECISE_CALL_STATE_WAITING
409     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTED
410     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTING
411     *
412     * <p class="note">
413     * Retrieve with
414     * {@link android.content.Intent#getIntExtra(String name, int defaultValue)}.
415     *
416     * @hide
417     */
418    public static final String EXTRA_BACKGROUND_CALL_STATE = "background_state";
419
420    /**
421     * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast
422     * for an integer containing the disconnect cause.
423     *
424     * @see DisconnectCause
425     *
426     * <p class="note">
427     * Retrieve with
428     * {@link android.content.Intent#getIntExtra(String name, int defaultValue)}.
429     *
430     * @hide
431     */
432    public static final String EXTRA_DISCONNECT_CAUSE = "disconnect_cause";
433
434    /**
435     * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast
436     * for an integer containing the disconnect cause provided by the RIL.
437     *
438     * @see PreciseDisconnectCause
439     *
440     * <p class="note">
441     * Retrieve with
442     * {@link android.content.Intent#getIntExtra(String name, int defaultValue)}.
443     *
444     * @hide
445     */
446    public static final String EXTRA_PRECISE_DISCONNECT_CAUSE = "precise_disconnect_cause";
447
448    /**
449     * Broadcast intent action indicating a data connection has changed,
450     * providing precise information about the connection.
451     *
452     * <p>
453     * The {@link #EXTRA_DATA_STATE} extra indicates the connection state.
454     * The {@link #EXTRA_DATA_NETWORK_TYPE} extra indicates the connection network type.
455     * The {@link #EXTRA_DATA_APN_TYPE} extra indicates the APN type.
456     * The {@link #EXTRA_DATA_APN} extra indicates the APN.
457     * The {@link #EXTRA_DATA_CHANGE_REASON} extra indicates the connection change reason.
458     * The {@link #EXTRA_DATA_IFACE_PROPERTIES} extra indicates the connection interface.
459     * The {@link #EXTRA_DATA_FAILURE_CAUSE} extra indicates the connection fail cause.
460     *
461     * <p class="note">
462     * Requires the READ_PRECISE_PHONE_STATE permission.
463     *
464     * @see #EXTRA_DATA_STATE
465     * @see #EXTRA_DATA_NETWORK_TYPE
466     * @see #EXTRA_DATA_APN_TYPE
467     * @see #EXTRA_DATA_APN
468     * @see #EXTRA_DATA_CHANGE_REASON
469     * @see #EXTRA_DATA_IFACE
470     * @see #EXTRA_DATA_FAILURE_CAUSE
471     * @hide
472     */
473    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
474    public static final String ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED =
475            "android.intent.action.PRECISE_DATA_CONNECTION_STATE_CHANGED";
476
477    /**
478     * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast
479     * for an integer containing the state of the current data connection.
480     *
481     * @see TelephonyManager#DATA_UNKNOWN
482     * @see TelephonyManager#DATA_DISCONNECTED
483     * @see TelephonyManager#DATA_CONNECTING
484     * @see TelephonyManager#DATA_CONNECTED
485     * @see TelephonyManager#DATA_SUSPENDED
486     *
487     * <p class="note">
488     * Retrieve with
489     * {@link android.content.Intent#getIntExtra(String name, int defaultValue)}.
490     *
491     * @hide
492     */
493    public static final String EXTRA_DATA_STATE = PhoneConstants.STATE_KEY;
494
495    /**
496     * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast
497     * for an integer containing the network type.
498     *
499     * @see TelephonyManager#NETWORK_TYPE_UNKNOWN
500     * @see TelephonyManager#NETWORK_TYPE_GPRS
501     * @see TelephonyManager#NETWORK_TYPE_EDGE
502     * @see TelephonyManager#NETWORK_TYPE_UMTS
503     * @see TelephonyManager#NETWORK_TYPE_CDMA
504     * @see TelephonyManager#NETWORK_TYPE_EVDO_0
505     * @see TelephonyManager#NETWORK_TYPE_EVDO_A
506     * @see TelephonyManager#NETWORK_TYPE_1xRTT
507     * @see TelephonyManager#NETWORK_TYPE_HSDPA
508     * @see TelephonyManager#NETWORK_TYPE_HSUPA
509     * @see TelephonyManager#NETWORK_TYPE_HSPA
510     * @see TelephonyManager#NETWORK_TYPE_IDEN
511     * @see TelephonyManager#NETWORK_TYPE_EVDO_B
512     * @see TelephonyManager#NETWORK_TYPE_LTE
513     * @see TelephonyManager#NETWORK_TYPE_EHRPD
514     * @see TelephonyManager#NETWORK_TYPE_HSPAP
515     *
516     * <p class="note">
517     * Retrieve with
518     * {@link android.content.Intent#getIntExtra(String name, int defaultValue)}.
519     *
520     * @hide
521     */
522    public static final String EXTRA_DATA_NETWORK_TYPE = PhoneConstants.DATA_NETWORK_TYPE_KEY;
523
524    /**
525     * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast
526     * for an String containing the data APN type.
527     *
528     * <p class="note">
529     * Retrieve with
530     * {@link android.content.Intent#getStringExtra(String name)}.
531     *
532     * @hide
533     */
534    public static final String EXTRA_DATA_APN_TYPE = PhoneConstants.DATA_APN_TYPE_KEY;
535
536    /**
537     * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast
538     * for an String containing the data APN.
539     *
540     * <p class="note">
541     * Retrieve with
542     * {@link android.content.Intent#getStringExtra(String name)}.
543     *
544     * @hide
545     */
546    public static final String EXTRA_DATA_APN = PhoneConstants.DATA_APN_KEY;
547
548    /**
549     * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast
550     * for an String representation of the change reason.
551     *
552     * <p class="note">
553     * Retrieve with
554     * {@link android.content.Intent#getStringExtra(String name)}.
555     *
556     * @hide
557     */
558    public static final String EXTRA_DATA_CHANGE_REASON = PhoneConstants.STATE_CHANGE_REASON_KEY;
559
560    /**
561     * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast
562     * for an String representation of the data interface.
563     *
564     * <p class="note">
565     * Retrieve with
566     * {@link android.content.Intent#getParcelableExtra(String name)}.
567     *
568     * @hide
569     */
570    public static final String EXTRA_DATA_LINK_PROPERTIES_KEY = PhoneConstants.DATA_LINK_PROPERTIES_KEY;
571
572    /**
573     * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast
574     * for the data connection fail cause.
575     *
576     * <p class="note">
577     * Retrieve with
578     * {@link android.content.Intent#getStringExtra(String name)}.
579     *
580     * @hide
581     */
582    public static final String EXTRA_DATA_FAILURE_CAUSE = PhoneConstants.DATA_FAILURE_CAUSE_KEY;
583
584    /**
585     * Response codes for sim activation. Activation completed successfully.
586     * @hide
587     */
588    @SystemApi
589    public static final int SIM_ACTIVATION_RESULT_COMPLETE = 0;
590    /**
591     * Response codes for sim activation. Activation not supported (device has no SIM).
592     * @hide
593     */
594    @SystemApi
595    public static final int SIM_ACTIVATION_RESULT_NOT_SUPPORTED = 1;
596    /**
597     * Response codes for sim activation. Activation is in progress.
598     * @hide
599     */
600    @SystemApi
601    public static final int SIM_ACTIVATION_RESULT_IN_PROGRESS = 2;
602    /**
603     * Response codes for sim activation. Activation failed to complete.
604     * @hide
605     */
606    @SystemApi
607    public static final int SIM_ACTIVATION_RESULT_FAILED = 3;
608    /**
609     * Response codes for sim activation. Activation canceled by user.
610     * @hide
611     */
612    @SystemApi
613    public static final int SIM_ACTIVATION_RESULT_CANCELED = 4;
614
615    /* Visual voicemail protocols */
616
617    /**
618     * The OMTP protocol.
619     */
620    public static final String VVM_TYPE_OMTP = "vvm_type_omtp";
621
622    /**
623     * A flavor of OMTP protocol with a different mobile originated (MO) format
624     */
625    public static final String VVM_TYPE_CVVM = "vvm_type_cvvm";
626
627    //
628    //
629    // Device Info
630    //
631    //
632
633    /**
634     * Returns the software version number for the device, for example,
635     * the IMEI/SV for GSM phones. Return null if the software version is
636     * not available.
637     *
638     * <p>Requires Permission:
639     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
640     */
641    public String getDeviceSoftwareVersion() {
642        return getDeviceSoftwareVersion(getDefaultSim());
643    }
644
645    /**
646     * Returns the software version number for the device, for example,
647     * the IMEI/SV for GSM phones. Return null if the software version is
648     * not available.
649     *
650     * <p>Requires Permission:
651     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
652     *
653     * @param slotId of which deviceID is returned
654     */
655    /** {@hide} */
656    public String getDeviceSoftwareVersion(int slotId) {
657        // FIXME methods taking slot id should not use subscription, instead us Uicc directly
658        int[] subId = SubscriptionManager.getSubId(slotId);
659        if (subId == null || subId.length == 0) {
660            return null;
661        }
662        try {
663            IPhoneSubInfo info = getSubscriberInfo();
664            if (info == null)
665                return null;
666            return info.getDeviceSvnUsingSubId(subId[0], mContext.getOpPackageName());
667        } catch (RemoteException ex) {
668            return null;
669        } catch (NullPointerException ex) {
670            return null;
671        }
672    }
673
674    /**
675     * Returns the unique device ID, for example, the IMEI for GSM and the MEID
676     * or ESN for CDMA phones. Return null if device ID is not available.
677     *
678     * <p>Requires Permission:
679     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
680     */
681    public String getDeviceId() {
682        try {
683            ITelephony telephony = getITelephony();
684            if (telephony == null)
685                return null;
686            return telephony.getDeviceId(mContext.getOpPackageName());
687        } catch (RemoteException ex) {
688            return null;
689        } catch (NullPointerException ex) {
690            return null;
691        }
692    }
693
694    /**
695     * Returns the unique device ID of a subscription, for example, the IMEI for
696     * GSM and the MEID for CDMA phones. Return null if device ID is not available.
697     *
698     * <p>Requires Permission:
699     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
700     *
701     * @param slotId of which deviceID is returned
702     */
703    public String getDeviceId(int slotId) {
704        // FIXME this assumes phoneId == slotId
705        try {
706            IPhoneSubInfo info = getSubscriberInfo();
707            if (info == null)
708                return null;
709            return info.getDeviceIdForPhone(slotId);
710        } catch (RemoteException ex) {
711            return null;
712        } catch (NullPointerException ex) {
713            return null;
714        }
715    }
716
717    /**
718     * Returns the IMEI. Return null if IMEI is not available.
719     *
720     * <p>Requires Permission:
721     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
722     */
723    /** {@hide} */
724    public String getImei() {
725        return getImei(getDefaultSim());
726    }
727
728    /**
729     * Returns the IMEI. Return null if IMEI is not available.
730     *
731     * <p>Requires Permission:
732     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
733     *
734     * @param slotId of which deviceID is returned
735     */
736    /** {@hide} */
737    public String getImei(int slotId) {
738        int[] subId = SubscriptionManager.getSubId(slotId);
739        try {
740            IPhoneSubInfo info = getSubscriberInfo();
741            if (info == null)
742                return null;
743            return info.getImeiForSubscriber(subId[0], mContext.getOpPackageName());
744        } catch (RemoteException ex) {
745            return null;
746        } catch (NullPointerException ex) {
747            return null;
748        }
749    }
750
751    /**
752     * Returns the NAI. Return null if NAI is not available.
753     *
754     */
755    /** {@hide}*/
756    public String getNai() {
757        return getNai(getDefaultSim());
758    }
759
760    /**
761     * Returns the NAI. Return null if NAI is not available.
762     *
763     *  @param slotId of which Nai is returned
764     */
765    /** {@hide}*/
766    public String getNai(int slotId) {
767        int[] subId = SubscriptionManager.getSubId(slotId);
768        try {
769            IPhoneSubInfo info = getSubscriberInfo();
770            if (info == null)
771                return null;
772            String nai = info.getNaiForSubscriber(subId[0], mContext.getOpPackageName());
773            if (Log.isLoggable(TAG, Log.VERBOSE)) {
774                Rlog.v(TAG, "Nai = " + nai);
775            }
776            return nai;
777        } catch (RemoteException ex) {
778            return null;
779        } catch (NullPointerException ex) {
780            return null;
781        }
782    }
783
784    /**
785     * Returns the current location of the device.
786     *<p>
787     * If there is only one radio in the device and that radio has an LTE connection,
788     * this method will return null. The implementation must not to try add LTE
789     * identifiers into the existing cdma/gsm classes.
790     *<p>
791     * In the future this call will be deprecated.
792     *<p>
793     * @return Current location of the device or null if not available.
794     *
795     * <p>Requires Permission:
796     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
797     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_FINE_LOCATION}.
798     */
799    public CellLocation getCellLocation() {
800        try {
801            ITelephony telephony = getITelephony();
802            if (telephony == null) {
803                Rlog.d(TAG, "getCellLocation returning null because telephony is null");
804                return null;
805            }
806            Bundle bundle = telephony.getCellLocation(mContext.getOpPackageName());
807            if (bundle.isEmpty()) {
808                Rlog.d(TAG, "getCellLocation returning null because bundle is empty");
809                return null;
810            }
811            CellLocation cl = CellLocation.newFromBundle(bundle);
812            if (cl.isEmpty()) {
813                Rlog.d(TAG, "getCellLocation returning null because CellLocation is empty");
814                return null;
815            }
816            return cl;
817        } catch (RemoteException ex) {
818            Rlog.d(TAG, "getCellLocation returning null due to RemoteException " + ex);
819            return null;
820        } catch (NullPointerException ex) {
821            Rlog.d(TAG, "getCellLocation returning null due to NullPointerException " + ex);
822            return null;
823        }
824    }
825
826    /**
827     * Enables location update notifications.  {@link PhoneStateListener#onCellLocationChanged
828     * PhoneStateListener.onCellLocationChanged} will be called on location updates.
829     *
830     * <p>Requires Permission: {@link android.Manifest.permission#CONTROL_LOCATION_UPDATES
831     * CONTROL_LOCATION_UPDATES}
832     *
833     * @hide
834     */
835    public void enableLocationUpdates() {
836            enableLocationUpdates(getDefaultSubscription());
837    }
838
839    /**
840     * Enables location update notifications for a subscription.
841     * {@link PhoneStateListener#onCellLocationChanged
842     * PhoneStateListener.onCellLocationChanged} will be called on location updates.
843     *
844     * <p>Requires Permission: {@link android.Manifest.permission#CONTROL_LOCATION_UPDATES
845     * CONTROL_LOCATION_UPDATES}
846     *
847     * @param subId for which the location updates are enabled
848     */
849    /** @hide */
850    public void enableLocationUpdates(int subId) {
851        try {
852            ITelephony telephony = getITelephony();
853            if (telephony != null)
854                telephony.enableLocationUpdatesForSubscriber(subId);
855        } catch (RemoteException ex) {
856        } catch (NullPointerException ex) {
857        }
858    }
859
860    /**
861     * Disables location update notifications.  {@link PhoneStateListener#onCellLocationChanged
862     * PhoneStateListener.onCellLocationChanged} will be called on location updates.
863     *
864     * <p>Requires Permission: {@link android.Manifest.permission#CONTROL_LOCATION_UPDATES
865     * CONTROL_LOCATION_UPDATES}
866     *
867     * @hide
868     */
869    public void disableLocationUpdates() {
870            disableLocationUpdates(getDefaultSubscription());
871    }
872
873    /** @hide */
874    public void disableLocationUpdates(int subId) {
875        try {
876            ITelephony telephony = getITelephony();
877            if (telephony != null)
878                telephony.disableLocationUpdatesForSubscriber(subId);
879        } catch (RemoteException ex) {
880        } catch (NullPointerException ex) {
881        }
882    }
883
884    /**
885     * Returns the neighboring cell information of the device. The getAllCellInfo is preferred
886     * and use this only if getAllCellInfo return nulls or an empty list.
887     *<p>
888     * In the future this call will be deprecated.
889     *<p>
890     * @return List of NeighboringCellInfo or null if info unavailable.
891     *
892     * <p>Requires Permission:
893     * (@link android.Manifest.permission#ACCESS_COARSE_UPDATES}
894     */
895    public List<NeighboringCellInfo> getNeighboringCellInfo() {
896        try {
897            ITelephony telephony = getITelephony();
898            if (telephony == null)
899                return null;
900            return telephony.getNeighboringCellInfo(mContext.getOpPackageName());
901        } catch (RemoteException ex) {
902            return null;
903        } catch (NullPointerException ex) {
904            return null;
905        }
906    }
907
908    /** No phone radio. */
909    public static final int PHONE_TYPE_NONE = PhoneConstants.PHONE_TYPE_NONE;
910    /** Phone radio is GSM. */
911    public static final int PHONE_TYPE_GSM = PhoneConstants.PHONE_TYPE_GSM;
912    /** Phone radio is CDMA. */
913    public static final int PHONE_TYPE_CDMA = PhoneConstants.PHONE_TYPE_CDMA;
914    /** Phone is via SIP. */
915    public static final int PHONE_TYPE_SIP = PhoneConstants.PHONE_TYPE_SIP;
916
917    /**
918     * Returns the current phone type.
919     * TODO: This is a last minute change and hence hidden.
920     *
921     * @see #PHONE_TYPE_NONE
922     * @see #PHONE_TYPE_GSM
923     * @see #PHONE_TYPE_CDMA
924     * @see #PHONE_TYPE_SIP
925     *
926     * {@hide}
927     */
928    @SystemApi
929    public int getCurrentPhoneType() {
930        return getCurrentPhoneType(getDefaultSubscription());
931    }
932
933    /**
934     * Returns a constant indicating the device phone type for a subscription.
935     *
936     * @see #PHONE_TYPE_NONE
937     * @see #PHONE_TYPE_GSM
938     * @see #PHONE_TYPE_CDMA
939     *
940     * @param subId for which phone type is returned
941     */
942    /** {@hide} */
943    @SystemApi
944    public int getCurrentPhoneType(int subId) {
945        int phoneId = SubscriptionManager.getPhoneId(subId);
946        try{
947            ITelephony telephony = getITelephony();
948            if (telephony != null) {
949                return telephony.getActivePhoneTypeForSubscriber(subId);
950            } else {
951                // This can happen when the ITelephony interface is not up yet.
952                return getPhoneTypeFromProperty(phoneId);
953            }
954        } catch (RemoteException ex) {
955            // This shouldn't happen in the normal case, as a backup we
956            // read from the system property.
957            return getPhoneTypeFromProperty(phoneId);
958        } catch (NullPointerException ex) {
959            // This shouldn't happen in the normal case, as a backup we
960            // read from the system property.
961            return getPhoneTypeFromProperty(phoneId);
962        }
963    }
964
965    /**
966     * Returns a constant indicating the device phone type.  This
967     * indicates the type of radio used to transmit voice calls.
968     *
969     * @see #PHONE_TYPE_NONE
970     * @see #PHONE_TYPE_GSM
971     * @see #PHONE_TYPE_CDMA
972     * @see #PHONE_TYPE_SIP
973     */
974    public int getPhoneType() {
975        if (!isVoiceCapable()) {
976            return PHONE_TYPE_NONE;
977        }
978        return getCurrentPhoneType();
979    }
980
981    private int getPhoneTypeFromProperty() {
982        return getPhoneTypeFromProperty(getDefaultPhone());
983    }
984
985    /** {@hide} */
986    private int getPhoneTypeFromProperty(int phoneId) {
987        String type = getTelephonyProperty(phoneId,
988                TelephonyProperties.CURRENT_ACTIVE_PHONE, null);
989        if (type == null || type.equals("")) {
990            return getPhoneTypeFromNetworkType(phoneId);
991        }
992        return Integer.parseInt(type);
993    }
994
995    private int getPhoneTypeFromNetworkType() {
996        return getPhoneTypeFromNetworkType(getDefaultPhone());
997    }
998
999    /** {@hide} */
1000    private int getPhoneTypeFromNetworkType(int phoneId) {
1001        // When the system property CURRENT_ACTIVE_PHONE, has not been set,
1002        // use the system property for default network type.
1003        // This is a fail safe, and can only happen at first boot.
1004        String mode = getTelephonyProperty(phoneId, "ro.telephony.default_network", null);
1005        if (mode != null) {
1006            return TelephonyManager.getPhoneType(Integer.parseInt(mode));
1007        }
1008        return TelephonyManager.PHONE_TYPE_NONE;
1009    }
1010
1011    /**
1012     * This function returns the type of the phone, depending
1013     * on the network mode.
1014     *
1015     * @param networkMode
1016     * @return Phone Type
1017     *
1018     * @hide
1019     */
1020    public static int getPhoneType(int networkMode) {
1021        switch(networkMode) {
1022        case RILConstants.NETWORK_MODE_CDMA:
1023        case RILConstants.NETWORK_MODE_CDMA_NO_EVDO:
1024        case RILConstants.NETWORK_MODE_EVDO_NO_CDMA:
1025            return PhoneConstants.PHONE_TYPE_CDMA;
1026
1027        case RILConstants.NETWORK_MODE_WCDMA_PREF:
1028        case RILConstants.NETWORK_MODE_GSM_ONLY:
1029        case RILConstants.NETWORK_MODE_WCDMA_ONLY:
1030        case RILConstants.NETWORK_MODE_GSM_UMTS:
1031        case RILConstants.NETWORK_MODE_LTE_GSM_WCDMA:
1032        case RILConstants.NETWORK_MODE_LTE_WCDMA:
1033        case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
1034            return PhoneConstants.PHONE_TYPE_GSM;
1035
1036        // Use CDMA Phone for the global mode including CDMA
1037        case RILConstants.NETWORK_MODE_GLOBAL:
1038        case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO:
1039            return PhoneConstants.PHONE_TYPE_CDMA;
1040
1041        case RILConstants.NETWORK_MODE_LTE_ONLY:
1042            if (getLteOnCdmaModeStatic() == PhoneConstants.LTE_ON_CDMA_TRUE) {
1043                return PhoneConstants.PHONE_TYPE_CDMA;
1044            } else {
1045                return PhoneConstants.PHONE_TYPE_GSM;
1046            }
1047        default:
1048            return PhoneConstants.PHONE_TYPE_GSM;
1049        }
1050    }
1051
1052    /**
1053     * The contents of the /proc/cmdline file
1054     */
1055    private static String getProcCmdLine()
1056    {
1057        String cmdline = "";
1058        FileInputStream is = null;
1059        try {
1060            is = new FileInputStream("/proc/cmdline");
1061            byte [] buffer = new byte[2048];
1062            int count = is.read(buffer);
1063            if (count > 0) {
1064                cmdline = new String(buffer, 0, count);
1065            }
1066        } catch (IOException e) {
1067            Rlog.d(TAG, "No /proc/cmdline exception=" + e);
1068        } finally {
1069            if (is != null) {
1070                try {
1071                    is.close();
1072                } catch (IOException e) {
1073                }
1074            }
1075        }
1076        Rlog.d(TAG, "/proc/cmdline=" + cmdline);
1077        return cmdline;
1078    }
1079
1080    /** Kernel command line */
1081    private static final String sKernelCmdLine = getProcCmdLine();
1082
1083    /** Pattern for selecting the product type from the kernel command line */
1084    private static final Pattern sProductTypePattern =
1085        Pattern.compile("\\sproduct_type\\s*=\\s*(\\w+)");
1086
1087    /** The ProductType used for LTE on CDMA devices */
1088    private static final String sLteOnCdmaProductType =
1089        SystemProperties.get(TelephonyProperties.PROPERTY_LTE_ON_CDMA_PRODUCT_TYPE, "");
1090
1091    /**
1092     * Return if the current radio is LTE on CDMA. This
1093     * is a tri-state return value as for a period of time
1094     * the mode may be unknown.
1095     *
1096     * @return {@link PhoneConstants#LTE_ON_CDMA_UNKNOWN}, {@link PhoneConstants#LTE_ON_CDMA_FALSE}
1097     * or {@link PhoneConstants#LTE_ON_CDMA_TRUE}
1098     *
1099     * @hide
1100     */
1101    public static int getLteOnCdmaModeStatic() {
1102        int retVal;
1103        int curVal;
1104        String productType = "";
1105
1106        curVal = SystemProperties.getInt(TelephonyProperties.PROPERTY_LTE_ON_CDMA_DEVICE,
1107                    PhoneConstants.LTE_ON_CDMA_UNKNOWN);
1108        retVal = curVal;
1109        if (retVal == PhoneConstants.LTE_ON_CDMA_UNKNOWN) {
1110            Matcher matcher = sProductTypePattern.matcher(sKernelCmdLine);
1111            if (matcher.find()) {
1112                productType = matcher.group(1);
1113                if (sLteOnCdmaProductType.equals(productType)) {
1114                    retVal = PhoneConstants.LTE_ON_CDMA_TRUE;
1115                } else {
1116                    retVal = PhoneConstants.LTE_ON_CDMA_FALSE;
1117                }
1118            } else {
1119                retVal = PhoneConstants.LTE_ON_CDMA_FALSE;
1120            }
1121        }
1122
1123        Rlog.d(TAG, "getLteOnCdmaMode=" + retVal + " curVal=" + curVal +
1124                " product_type='" + productType +
1125                "' lteOnCdmaProductType='" + sLteOnCdmaProductType + "'");
1126        return retVal;
1127    }
1128
1129    //
1130    //
1131    // Current Network
1132    //
1133    //
1134
1135    /**
1136     * Returns the alphabetic name of current registered operator.
1137     * <p>
1138     * Availability: Only when user is registered to a network. Result may be
1139     * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
1140     * on a CDMA network).
1141     */
1142    public String getNetworkOperatorName() {
1143        return getNetworkOperatorName(getDefaultSubscription());
1144    }
1145
1146    /**
1147     * Returns the alphabetic name of current registered operator
1148     * for a particular subscription.
1149     * <p>
1150     * Availability: Only when user is registered to a network. Result may be
1151     * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
1152     * on a CDMA network).
1153     * @param subId
1154     */
1155    /** {@hide} */
1156    public String getNetworkOperatorName(int subId) {
1157        int phoneId = SubscriptionManager.getPhoneId(subId);
1158        return getTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_ALPHA, "");
1159    }
1160
1161    /**
1162     * Returns the numeric name (MCC+MNC) of current registered operator.
1163     * <p>
1164     * Availability: Only when user is registered to a network. Result may be
1165     * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
1166     * on a CDMA network).
1167     */
1168    public String getNetworkOperator() {
1169        return getNetworkOperatorForPhone(getDefaultPhone());
1170    }
1171
1172    /**
1173     * Returns the numeric name (MCC+MNC) of current registered operator
1174     * for a particular subscription.
1175     * <p>
1176     * Availability: Only when user is registered to a network. Result may be
1177     * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
1178     * on a CDMA network).
1179     *
1180     * @param subId
1181     */
1182    /** {@hide} */
1183   public String getNetworkOperatorForSubscription(int subId) {
1184        int phoneId = SubscriptionManager.getPhoneId(subId);
1185        return getNetworkOperatorForPhone(phoneId);
1186     }
1187
1188    /**
1189     * Returns the numeric name (MCC+MNC) of current registered operator
1190     * for a particular subscription.
1191     * <p>
1192     * Availability: Only when user is registered to a network. Result may be
1193     * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
1194     * on a CDMA network).
1195     *
1196     * @param phoneId
1197     * @hide
1198     **/
1199   public String getNetworkOperatorForPhone(int phoneId) {
1200        return getTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, "");
1201     }
1202
1203    /**
1204     * Returns true if the device is considered roaming on the current
1205     * network, for GSM purposes.
1206     * <p>
1207     * Availability: Only when user registered to a network.
1208     */
1209    public boolean isNetworkRoaming() {
1210        return isNetworkRoaming(getDefaultSubscription());
1211    }
1212
1213    /**
1214     * Returns true if the device is considered roaming on the current
1215     * network for a subscription.
1216     * <p>
1217     * Availability: Only when user registered to a network.
1218     *
1219     * @param subId
1220     */
1221    /** {@hide} */
1222    public boolean isNetworkRoaming(int subId) {
1223        int phoneId = SubscriptionManager.getPhoneId(subId);
1224        return Boolean.parseBoolean(getTelephonyProperty(phoneId,
1225                TelephonyProperties.PROPERTY_OPERATOR_ISROAMING, null));
1226    }
1227
1228    /**
1229     * Returns the ISO country code equivalent of the current registered
1230     * operator's MCC (Mobile Country Code).
1231     * <p>
1232     * Availability: Only when user is registered to a network. Result may be
1233     * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
1234     * on a CDMA network).
1235     */
1236    public String getNetworkCountryIso() {
1237        return getNetworkCountryIsoForPhone(getDefaultPhone());
1238    }
1239
1240    /**
1241     * Returns the ISO country code equivalent of the current registered
1242     * operator's MCC (Mobile Country Code) of a subscription.
1243     * <p>
1244     * Availability: Only when user is registered to a network. Result may be
1245     * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
1246     * on a CDMA network).
1247     *
1248     * @param subId for which Network CountryIso is returned
1249     */
1250    /** {@hide} */
1251    public String getNetworkCountryIsoForSubscription(int subId) {
1252        int phoneId = SubscriptionManager.getPhoneId(subId);
1253        return getNetworkCountryIsoForPhone(phoneId);
1254    }
1255
1256    /**
1257     * Returns the ISO country code equivalent of the current registered
1258     * operator's MCC (Mobile Country Code) of a subscription.
1259     * <p>
1260     * Availability: Only when user is registered to a network. Result may be
1261     * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
1262     * on a CDMA network).
1263     *
1264     * @param phoneId for which Network CountryIso is returned
1265     */
1266    /** {@hide} */
1267    public String getNetworkCountryIsoForPhone(int phoneId) {
1268        return getTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, "");
1269    }
1270
1271    /** Network type is unknown */
1272    public static final int NETWORK_TYPE_UNKNOWN = 0;
1273    /** Current network is GPRS */
1274    public static final int NETWORK_TYPE_GPRS = 1;
1275    /** Current network is EDGE */
1276    public static final int NETWORK_TYPE_EDGE = 2;
1277    /** Current network is UMTS */
1278    public static final int NETWORK_TYPE_UMTS = 3;
1279    /** Current network is CDMA: Either IS95A or IS95B*/
1280    public static final int NETWORK_TYPE_CDMA = 4;
1281    /** Current network is EVDO revision 0*/
1282    public static final int NETWORK_TYPE_EVDO_0 = 5;
1283    /** Current network is EVDO revision A*/
1284    public static final int NETWORK_TYPE_EVDO_A = 6;
1285    /** Current network is 1xRTT*/
1286    public static final int NETWORK_TYPE_1xRTT = 7;
1287    /** Current network is HSDPA */
1288    public static final int NETWORK_TYPE_HSDPA = 8;
1289    /** Current network is HSUPA */
1290    public static final int NETWORK_TYPE_HSUPA = 9;
1291    /** Current network is HSPA */
1292    public static final int NETWORK_TYPE_HSPA = 10;
1293    /** Current network is iDen */
1294    public static final int NETWORK_TYPE_IDEN = 11;
1295    /** Current network is EVDO revision B*/
1296    public static final int NETWORK_TYPE_EVDO_B = 12;
1297    /** Current network is LTE */
1298    public static final int NETWORK_TYPE_LTE = 13;
1299    /** Current network is eHRPD */
1300    public static final int NETWORK_TYPE_EHRPD = 14;
1301    /** Current network is HSPA+ */
1302    public static final int NETWORK_TYPE_HSPAP = 15;
1303    /** Current network is GSM {@hide} */
1304    public static final int NETWORK_TYPE_GSM = 16;
1305     /** Current network is TD_SCDMA {@hide} */
1306    public static final int NETWORK_TYPE_TD_SCDMA = 17;
1307   /** Current network is IWLAN {@hide} */
1308    public static final int NETWORK_TYPE_IWLAN = 18;
1309
1310    /**
1311     * @return the NETWORK_TYPE_xxxx for current data connection.
1312     */
1313    public int getNetworkType() {
1314        return getDataNetworkType();
1315    }
1316
1317    /**
1318     * Returns a constant indicating the radio technology (network type)
1319     * currently in use on the device for a subscription.
1320     * @return the network type
1321     *
1322     * @param subId for which network type is returned
1323     *
1324     * @see #NETWORK_TYPE_UNKNOWN
1325     * @see #NETWORK_TYPE_GPRS
1326     * @see #NETWORK_TYPE_EDGE
1327     * @see #NETWORK_TYPE_UMTS
1328     * @see #NETWORK_TYPE_HSDPA
1329     * @see #NETWORK_TYPE_HSUPA
1330     * @see #NETWORK_TYPE_HSPA
1331     * @see #NETWORK_TYPE_CDMA
1332     * @see #NETWORK_TYPE_EVDO_0
1333     * @see #NETWORK_TYPE_EVDO_A
1334     * @see #NETWORK_TYPE_EVDO_B
1335     * @see #NETWORK_TYPE_1xRTT
1336     * @see #NETWORK_TYPE_IDEN
1337     * @see #NETWORK_TYPE_LTE
1338     * @see #NETWORK_TYPE_EHRPD
1339     * @see #NETWORK_TYPE_HSPAP
1340     */
1341    /** {@hide} */
1342   public int getNetworkType(int subId) {
1343       try {
1344           ITelephony telephony = getITelephony();
1345           if (telephony != null) {
1346               return telephony.getNetworkTypeForSubscriber(subId);
1347           } else {
1348               // This can happen when the ITelephony interface is not up yet.
1349               return NETWORK_TYPE_UNKNOWN;
1350           }
1351       } catch(RemoteException ex) {
1352           // This shouldn't happen in the normal case
1353           return NETWORK_TYPE_UNKNOWN;
1354       } catch (NullPointerException ex) {
1355           // This could happen before phone restarts due to crashing
1356           return NETWORK_TYPE_UNKNOWN;
1357       }
1358   }
1359
1360    /**
1361     * Returns a constant indicating the radio technology (network type)
1362     * currently in use on the device for data transmission.
1363     * @return the network type
1364     *
1365     * @see #NETWORK_TYPE_UNKNOWN
1366     * @see #NETWORK_TYPE_GPRS
1367     * @see #NETWORK_TYPE_EDGE
1368     * @see #NETWORK_TYPE_UMTS
1369     * @see #NETWORK_TYPE_HSDPA
1370     * @see #NETWORK_TYPE_HSUPA
1371     * @see #NETWORK_TYPE_HSPA
1372     * @see #NETWORK_TYPE_CDMA
1373     * @see #NETWORK_TYPE_EVDO_0
1374     * @see #NETWORK_TYPE_EVDO_A
1375     * @see #NETWORK_TYPE_EVDO_B
1376     * @see #NETWORK_TYPE_1xRTT
1377     * @see #NETWORK_TYPE_IDEN
1378     * @see #NETWORK_TYPE_LTE
1379     * @see #NETWORK_TYPE_EHRPD
1380     * @see #NETWORK_TYPE_HSPAP
1381     *
1382     * @hide
1383     */
1384    public int getDataNetworkType() {
1385        return getDataNetworkType(getDefaultSubscription());
1386    }
1387
1388    /**
1389     * Returns a constant indicating the radio technology (network type)
1390     * currently in use on the device for data transmission for a subscription
1391     * @return the network type
1392     *
1393     * @param subId for which network type is returned
1394     */
1395    /** {@hide} */
1396    public int getDataNetworkType(int subId) {
1397        try{
1398            ITelephony telephony = getITelephony();
1399            if (telephony != null) {
1400                return telephony.getDataNetworkTypeForSubscriber(subId);
1401            } else {
1402                // This can happen when the ITelephony interface is not up yet.
1403                return NETWORK_TYPE_UNKNOWN;
1404            }
1405        } catch(RemoteException ex) {
1406            // This shouldn't happen in the normal case
1407            return NETWORK_TYPE_UNKNOWN;
1408        } catch (NullPointerException ex) {
1409            // This could happen before phone restarts due to crashing
1410            return NETWORK_TYPE_UNKNOWN;
1411        }
1412    }
1413
1414    /**
1415     * Returns the NETWORK_TYPE_xxxx for voice
1416     *
1417     * @hide
1418     */
1419    public int getVoiceNetworkType() {
1420        return getVoiceNetworkType(getDefaultSubscription());
1421    }
1422
1423    /**
1424     * Returns the NETWORK_TYPE_xxxx for voice for a subId
1425     *
1426     */
1427    /** {@hide} */
1428    public int getVoiceNetworkType(int subId) {
1429        try{
1430            ITelephony telephony = getITelephony();
1431            if (telephony != null) {
1432                return telephony.getVoiceNetworkTypeForSubscriber(subId);
1433            } else {
1434                // This can happen when the ITelephony interface is not up yet.
1435                return NETWORK_TYPE_UNKNOWN;
1436            }
1437        } catch(RemoteException ex) {
1438            // This shouldn't happen in the normal case
1439            return NETWORK_TYPE_UNKNOWN;
1440        } catch (NullPointerException ex) {
1441            // This could happen before phone restarts due to crashing
1442            return NETWORK_TYPE_UNKNOWN;
1443        }
1444    }
1445
1446    /** Unknown network class. {@hide} */
1447    public static final int NETWORK_CLASS_UNKNOWN = 0;
1448    /** Class of broadly defined "2G" networks. {@hide} */
1449    public static final int NETWORK_CLASS_2_G = 1;
1450    /** Class of broadly defined "3G" networks. {@hide} */
1451    public static final int NETWORK_CLASS_3_G = 2;
1452    /** Class of broadly defined "4G" networks. {@hide} */
1453    public static final int NETWORK_CLASS_4_G = 3;
1454
1455    /**
1456     * Return general class of network type, such as "3G" or "4G". In cases
1457     * where classification is contentious, this method is conservative.
1458     *
1459     * @hide
1460     */
1461    public static int getNetworkClass(int networkType) {
1462        switch (networkType) {
1463            case NETWORK_TYPE_GPRS:
1464            case NETWORK_TYPE_GSM:
1465            case NETWORK_TYPE_EDGE:
1466            case NETWORK_TYPE_CDMA:
1467            case NETWORK_TYPE_1xRTT:
1468            case NETWORK_TYPE_IDEN:
1469                return NETWORK_CLASS_2_G;
1470            case NETWORK_TYPE_UMTS:
1471            case NETWORK_TYPE_EVDO_0:
1472            case NETWORK_TYPE_EVDO_A:
1473            case NETWORK_TYPE_HSDPA:
1474            case NETWORK_TYPE_HSUPA:
1475            case NETWORK_TYPE_HSPA:
1476            case NETWORK_TYPE_EVDO_B:
1477            case NETWORK_TYPE_EHRPD:
1478            case NETWORK_TYPE_HSPAP:
1479            case NETWORK_TYPE_TD_SCDMA:
1480                return NETWORK_CLASS_3_G;
1481            case NETWORK_TYPE_LTE:
1482            case NETWORK_TYPE_IWLAN:
1483                return NETWORK_CLASS_4_G;
1484            default:
1485                return NETWORK_CLASS_UNKNOWN;
1486        }
1487    }
1488
1489    /**
1490     * Returns a string representation of the radio technology (network type)
1491     * currently in use on the device.
1492     * @return the name of the radio technology
1493     *
1494     * @hide pending API council review
1495     */
1496    public String getNetworkTypeName() {
1497        return getNetworkTypeName(getNetworkType());
1498    }
1499
1500    /**
1501     * Returns a string representation of the radio technology (network type)
1502     * currently in use on the device.
1503     * @param subId for which network type is returned
1504     * @return the name of the radio technology
1505     *
1506     */
1507    /** {@hide} */
1508    public static String getNetworkTypeName(int type) {
1509        switch (type) {
1510            case NETWORK_TYPE_GPRS:
1511                return "GPRS";
1512            case NETWORK_TYPE_EDGE:
1513                return "EDGE";
1514            case NETWORK_TYPE_UMTS:
1515                return "UMTS";
1516            case NETWORK_TYPE_HSDPA:
1517                return "HSDPA";
1518            case NETWORK_TYPE_HSUPA:
1519                return "HSUPA";
1520            case NETWORK_TYPE_HSPA:
1521                return "HSPA";
1522            case NETWORK_TYPE_CDMA:
1523                return "CDMA";
1524            case NETWORK_TYPE_EVDO_0:
1525                return "CDMA - EvDo rev. 0";
1526            case NETWORK_TYPE_EVDO_A:
1527                return "CDMA - EvDo rev. A";
1528            case NETWORK_TYPE_EVDO_B:
1529                return "CDMA - EvDo rev. B";
1530            case NETWORK_TYPE_1xRTT:
1531                return "CDMA - 1xRTT";
1532            case NETWORK_TYPE_LTE:
1533                return "LTE";
1534            case NETWORK_TYPE_EHRPD:
1535                return "CDMA - eHRPD";
1536            case NETWORK_TYPE_IDEN:
1537                return "iDEN";
1538            case NETWORK_TYPE_HSPAP:
1539                return "HSPA+";
1540            case NETWORK_TYPE_GSM:
1541                return "GSM";
1542            case NETWORK_TYPE_TD_SCDMA:
1543                return "TD_SCDMA";
1544            case NETWORK_TYPE_IWLAN:
1545                return "IWLAN";
1546            default:
1547                return "UNKNOWN";
1548        }
1549    }
1550
1551    //
1552    //
1553    // SIM Card
1554    //
1555    //
1556
1557    /**
1558     * SIM card state: Unknown. Signifies that the SIM is in transition
1559     * between states. For example, when the user inputs the SIM pin
1560     * under PIN_REQUIRED state, a query for sim status returns
1561     * this state before turning to SIM_STATE_READY.
1562     *
1563     * These are the ordinal value of IccCardConstants.State.
1564     */
1565    public static final int SIM_STATE_UNKNOWN = 0;
1566    /** SIM card state: no SIM card is available in the device */
1567    public static final int SIM_STATE_ABSENT = 1;
1568    /** SIM card state: Locked: requires the user's SIM PIN to unlock */
1569    public static final int SIM_STATE_PIN_REQUIRED = 2;
1570    /** SIM card state: Locked: requires the user's SIM PUK to unlock */
1571    public static final int SIM_STATE_PUK_REQUIRED = 3;
1572    /** SIM card state: Locked: requires a network PIN to unlock */
1573    public static final int SIM_STATE_NETWORK_LOCKED = 4;
1574    /** SIM card state: Ready */
1575    public static final int SIM_STATE_READY = 5;
1576    /** SIM card state: SIM Card is NOT READY
1577     *@hide
1578     */
1579    public static final int SIM_STATE_NOT_READY = 6;
1580    /** SIM card state: SIM Card Error, permanently disabled
1581     *@hide
1582     */
1583    public static final int SIM_STATE_PERM_DISABLED = 7;
1584    /** SIM card state: SIM Card Error, present but faulty
1585     *@hide
1586     */
1587    public static final int SIM_STATE_CARD_IO_ERROR = 8;
1588
1589    /**
1590     * @return true if a ICC card is present
1591     */
1592    public boolean hasIccCard() {
1593        return hasIccCard(getDefaultSim());
1594    }
1595
1596    /**
1597     * @return true if a ICC card is present for a subscription
1598     *
1599     * @param slotId for which icc card presence is checked
1600     */
1601    /** {@hide} */
1602    // FIXME Input argument slotId should be of type int
1603    public boolean hasIccCard(int slotId) {
1604
1605        try {
1606            ITelephony telephony = getITelephony();
1607            if (telephony == null)
1608                return false;
1609            return telephony.hasIccCardUsingSlotId(slotId);
1610        } catch (RemoteException ex) {
1611            // Assume no ICC card if remote exception which shouldn't happen
1612            return false;
1613        } catch (NullPointerException ex) {
1614            // This could happen before phone restarts due to crashing
1615            return false;
1616        }
1617    }
1618
1619    /**
1620     * Returns a constant indicating the state of the default SIM card.
1621     *
1622     * @see #SIM_STATE_UNKNOWN
1623     * @see #SIM_STATE_ABSENT
1624     * @see #SIM_STATE_PIN_REQUIRED
1625     * @see #SIM_STATE_PUK_REQUIRED
1626     * @see #SIM_STATE_NETWORK_LOCKED
1627     * @see #SIM_STATE_READY
1628     * @see #SIM_STATE_NOT_READY
1629     * @see #SIM_STATE_PERM_DISABLED
1630     * @see #SIM_STATE_CARD_IO_ERROR
1631     */
1632    public int getSimState() {
1633        int slotIdx = getDefaultSim();
1634        // slotIdx may be invalid due to sim being absent. In that case query all slots to get
1635        // sim state
1636        if (slotIdx < 0) {
1637            // query for all slots and return absent if all sim states are absent, otherwise
1638            // return unknown
1639            for (int i = 0; i < getPhoneCount(); i++) {
1640                int simState = getSimState(i);
1641                if (simState != SIM_STATE_ABSENT) {
1642                    Rlog.d(TAG, "getSimState: default sim:" + slotIdx + ", sim state for " +
1643                            "slotIdx=" + i + " is " + simState + ", return state as unknown");
1644                    return SIM_STATE_UNKNOWN;
1645                }
1646            }
1647            Rlog.d(TAG, "getSimState: default sim:" + slotIdx + ", all SIMs absent, return " +
1648                    "state as absent");
1649            return SIM_STATE_ABSENT;
1650        }
1651        return getSimState(slotIdx);
1652    }
1653
1654    /**
1655     * Returns a constant indicating the state of the device SIM card in a slot.
1656     *
1657     * @param slotIdx
1658     *
1659     * @see #SIM_STATE_UNKNOWN
1660     * @see #SIM_STATE_ABSENT
1661     * @see #SIM_STATE_PIN_REQUIRED
1662     * @see #SIM_STATE_PUK_REQUIRED
1663     * @see #SIM_STATE_NETWORK_LOCKED
1664     * @see #SIM_STATE_READY
1665     * @see #SIM_STATE_NOT_READY
1666     * @see #SIM_STATE_PERM_DISABLED
1667     * @see #SIM_STATE_CARD_IO_ERROR
1668     */
1669    /** {@hide} */
1670    public int getSimState(int slotIdx) {
1671        int simState = SubscriptionManager.getSimStateForSlotIdx(slotIdx);
1672        return simState;
1673    }
1674
1675    /**
1676     * Returns the MCC+MNC (mobile country code + mobile network code) of the
1677     * provider of the SIM. 5 or 6 decimal digits.
1678     * <p>
1679     * Availability: SIM state must be {@link #SIM_STATE_READY}
1680     *
1681     * @see #getSimState
1682     */
1683    public String getSimOperator() {
1684        return getSimOperatorNumeric();
1685    }
1686
1687    /**
1688     * Returns the MCC+MNC (mobile country code + mobile network code) of the
1689     * provider of the SIM. 5 or 6 decimal digits.
1690     * <p>
1691     * Availability: SIM state must be {@link #SIM_STATE_READY}
1692     *
1693     * @see #getSimState
1694     *
1695     * @param subId for which SimOperator is returned
1696     * @hide
1697     */
1698    public String getSimOperator(int subId) {
1699        return getSimOperatorNumericForSubscription(subId);
1700    }
1701
1702    /**
1703     * Returns the MCC+MNC (mobile country code + mobile network code) of the
1704     * provider of the SIM. 5 or 6 decimal digits.
1705     * <p>
1706     * Availability: SIM state must be {@link #SIM_STATE_READY}
1707     *
1708     * @see #getSimState
1709     * @hide
1710     */
1711    public String getSimOperatorNumeric() {
1712        int subId = SubscriptionManager.getDefaultDataSubId();
1713        if (!SubscriptionManager.isUsableSubIdValue(subId)) {
1714            subId = SubscriptionManager.getDefaultSmsSubId();
1715            if (!SubscriptionManager.isUsableSubIdValue(subId)) {
1716                subId = SubscriptionManager.getDefaultVoiceSubId();
1717                if (!SubscriptionManager.isUsableSubIdValue(subId)) {
1718                    subId = SubscriptionManager.getDefaultSubId();
1719                }
1720            }
1721        }
1722        return getSimOperatorNumericForSubscription(subId);
1723    }
1724
1725    /**
1726     * Returns the MCC+MNC (mobile country code + mobile network code) of the
1727     * provider of the SIM for a particular subscription. 5 or 6 decimal digits.
1728     * <p>
1729     * Availability: SIM state must be {@link #SIM_STATE_READY}
1730     *
1731     * @see #getSimState
1732     *
1733     * @param subId for which SimOperator is returned
1734     * @hide
1735     */
1736    public String getSimOperatorNumericForSubscription(int subId) {
1737        int phoneId = SubscriptionManager.getPhoneId(subId);
1738        return getSimOperatorNumericForPhone(phoneId);
1739    }
1740
1741   /**
1742     * Returns the MCC+MNC (mobile country code + mobile network code) of the
1743     * provider of the SIM for a particular subscription. 5 or 6 decimal digits.
1744     * <p>
1745     *
1746     * @param phoneId for which SimOperator is returned
1747     * @hide
1748     */
1749    public String getSimOperatorNumericForPhone(int phoneId) {
1750        return getTelephonyProperty(phoneId,
1751                TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "");
1752    }
1753
1754    /**
1755     * Returns the Service Provider Name (SPN).
1756     * <p>
1757     * Availability: SIM state must be {@link #SIM_STATE_READY}
1758     *
1759     * @see #getSimState
1760     */
1761    public String getSimOperatorName() {
1762        return getSimOperatorNameForPhone(getDefaultPhone());
1763    }
1764
1765    /**
1766     * Returns the Service Provider Name (SPN).
1767     * <p>
1768     * Availability: SIM state must be {@link #SIM_STATE_READY}
1769     *
1770     * @see #getSimState
1771     *
1772     * @param subId for which SimOperatorName is returned
1773     * @hide
1774     */
1775    public String getSimOperatorNameForSubscription(int subId) {
1776        int phoneId = SubscriptionManager.getPhoneId(subId);
1777        return getSimOperatorNameForPhone(phoneId);
1778    }
1779
1780    /**
1781     * Returns the Service Provider Name (SPN).
1782     *
1783     * @hide
1784     */
1785    public String getSimOperatorNameForPhone(int phoneId) {
1786         return getTelephonyProperty(phoneId,
1787                TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA, "");
1788    }
1789
1790    /**
1791     * Returns the ISO country code equivalent for the SIM provider's country code.
1792     */
1793    public String getSimCountryIso() {
1794        return getSimCountryIsoForPhone(getDefaultPhone());
1795    }
1796
1797    /**
1798     * Returns the ISO country code equivalent for the SIM provider's country code.
1799     *
1800     * @param subId for which SimCountryIso is returned
1801     *
1802     * @hide
1803     */
1804    public String getSimCountryIso(int subId) {
1805        return getSimCountryIsoForSubscription(subId);
1806    }
1807
1808    /**
1809     * Returns the ISO country code equivalent for the SIM provider's country code.
1810     *
1811     * @param subId for which SimCountryIso is returned
1812     *
1813     * @hide
1814     */
1815    public String getSimCountryIsoForSubscription(int subId) {
1816        int phoneId = SubscriptionManager.getPhoneId(subId);
1817        return getSimCountryIsoForPhone(phoneId);
1818    }
1819
1820    /**
1821     * Returns the ISO country code equivalent for the SIM provider's country code.
1822     *
1823     * @hide
1824     */
1825    public String getSimCountryIsoForPhone(int phoneId) {
1826        return getTelephonyProperty(phoneId,
1827                TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY, "");
1828    }
1829
1830    /**
1831     * Returns the serial number of the SIM, if applicable. Return null if it is
1832     * unavailable.
1833     * <p>
1834     * Requires Permission:
1835     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1836     */
1837    public String getSimSerialNumber() {
1838         return getSimSerialNumber(getDefaultSubscription());
1839    }
1840
1841    /**
1842     * Returns the serial number for the given subscription, if applicable. Return null if it is
1843     * unavailable.
1844     * <p>
1845     * @param subId for which Sim Serial number is returned
1846     * Requires Permission:
1847     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1848     */
1849    /** {@hide} */
1850    public String getSimSerialNumber(int subId) {
1851        try {
1852            IPhoneSubInfo info = getSubscriberInfo();
1853            if (info == null)
1854                return null;
1855            return info.getIccSerialNumberForSubscriber(subId, mContext.getOpPackageName());
1856        } catch (RemoteException ex) {
1857            return null;
1858        } catch (NullPointerException ex) {
1859            // This could happen before phone restarts due to crashing
1860            return null;
1861        }
1862    }
1863
1864    /**
1865     * Return if the current radio is LTE on CDMA. This
1866     * is a tri-state return value as for a period of time
1867     * the mode may be unknown.
1868     *
1869     * @return {@link PhoneConstants#LTE_ON_CDMA_UNKNOWN}, {@link PhoneConstants#LTE_ON_CDMA_FALSE}
1870     * or {@link PhoneConstants#LTE_ON_CDMA_TRUE}
1871     *
1872     * @hide
1873     */
1874    public int getLteOnCdmaMode() {
1875        return getLteOnCdmaMode(getDefaultSubscription());
1876    }
1877
1878    /**
1879     * Return if the current radio is LTE on CDMA for Subscription. This
1880     * is a tri-state return value as for a period of time
1881     * the mode may be unknown.
1882     *
1883     * @param subId for which radio is LTE on CDMA is returned
1884     * @return {@link PhoneConstants#LTE_ON_CDMA_UNKNOWN}, {@link PhoneConstants#LTE_ON_CDMA_FALSE}
1885     * or {@link PhoneConstants#LTE_ON_CDMA_TRUE}
1886     *
1887     */
1888    /** {@hide} */
1889    public int getLteOnCdmaMode(int subId) {
1890        try {
1891            ITelephony telephony = getITelephony();
1892            if (telephony == null)
1893                return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
1894            return telephony.getLteOnCdmaModeForSubscriber(subId);
1895        } catch (RemoteException ex) {
1896            // Assume no ICC card if remote exception which shouldn't happen
1897            return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
1898        } catch (NullPointerException ex) {
1899            // This could happen before phone restarts due to crashing
1900            return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
1901        }
1902    }
1903
1904    //
1905    //
1906    // Subscriber Info
1907    //
1908    //
1909
1910    /**
1911     * Returns the unique subscriber ID, for example, the IMSI for a GSM phone.
1912     * Return null if it is unavailable.
1913     * <p>
1914     * Requires Permission:
1915     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1916     */
1917    public String getSubscriberId() {
1918        return getSubscriberId(getDefaultSubscription());
1919    }
1920
1921    /**
1922     * Returns the unique subscriber ID, for example, the IMSI for a GSM phone
1923     * for a subscription.
1924     * Return null if it is unavailable.
1925     * <p>
1926     * Requires Permission:
1927     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1928     *
1929     * @param subId whose subscriber id is returned
1930     */
1931    /** {@hide} */
1932    public String getSubscriberId(int subId) {
1933        try {
1934            IPhoneSubInfo info = getSubscriberInfo();
1935            if (info == null)
1936                return null;
1937            return info.getSubscriberIdForSubscriber(subId, mContext.getOpPackageName());
1938        } catch (RemoteException ex) {
1939            return null;
1940        } catch (NullPointerException ex) {
1941            // This could happen before phone restarts due to crashing
1942            return null;
1943        }
1944    }
1945
1946    /**
1947     * Returns the Group Identifier Level1 for a GSM phone.
1948     * Return null if it is unavailable.
1949     * <p>
1950     * Requires Permission:
1951     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1952     */
1953    public String getGroupIdLevel1() {
1954        try {
1955            IPhoneSubInfo info = getSubscriberInfo();
1956            if (info == null)
1957                return null;
1958            return info.getGroupIdLevel1(mContext.getOpPackageName());
1959        } catch (RemoteException ex) {
1960            return null;
1961        } catch (NullPointerException ex) {
1962            // This could happen before phone restarts due to crashing
1963            return null;
1964        }
1965    }
1966
1967    /**
1968     * Returns the Group Identifier Level1 for a GSM phone for a particular subscription.
1969     * Return null if it is unavailable.
1970     * <p>
1971     * Requires Permission:
1972     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1973     *
1974     * @param subscription whose subscriber id is returned
1975     */
1976    /** {@hide} */
1977    public String getGroupIdLevel1(int subId) {
1978        try {
1979            IPhoneSubInfo info = getSubscriberInfo();
1980            if (info == null)
1981                return null;
1982            return info.getGroupIdLevel1ForSubscriber(subId, mContext.getOpPackageName());
1983        } catch (RemoteException ex) {
1984            return null;
1985        } catch (NullPointerException ex) {
1986            // This could happen before phone restarts due to crashing
1987            return null;
1988        }
1989    }
1990
1991    /**
1992     * Returns the phone number string for line 1, for example, the MSISDN
1993     * for a GSM phone. Return null if it is unavailable.
1994     * <p>
1995     * Requires Permission:
1996     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1997     */
1998    public String getLine1Number() {
1999        return getLine1NumberForSubscriber(getDefaultSubscription());
2000    }
2001
2002    /**
2003     * Returns the phone number string for line 1, for example, the MSISDN
2004     * for a GSM phone for a particular subscription. Return null if it is unavailable.
2005     * <p>
2006     * Requires Permission:
2007     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
2008     *
2009     * @param subId whose phone number for line 1 is returned
2010     */
2011    /** {@hide} */
2012    public String getLine1NumberForSubscriber(int subId) {
2013        String number = null;
2014        try {
2015            ITelephony telephony = getITelephony();
2016            if (telephony != null)
2017                number = telephony.getLine1NumberForDisplay(subId, mContext.getOpPackageName());
2018        } catch (RemoteException ex) {
2019        } catch (NullPointerException ex) {
2020        }
2021        if (number != null) {
2022            return number;
2023        }
2024        try {
2025            IPhoneSubInfo info = getSubscriberInfo();
2026            if (info == null)
2027                return null;
2028            return info.getLine1NumberForSubscriber(subId, mContext.getOpPackageName());
2029        } catch (RemoteException ex) {
2030            return null;
2031        } catch (NullPointerException ex) {
2032            // This could happen before phone restarts due to crashing
2033            return null;
2034        }
2035    }
2036
2037    /**
2038     * Set the line 1 phone number string and its alphatag for the current ICCID
2039     * for display purpose only, for example, displayed in Phone Status. It won't
2040     * change the actual MSISDN/MDN. To unset alphatag or number, pass in a null
2041     * value.
2042     *
2043     * <p>Requires that the calling app has carrier privileges.
2044     * @see #hasCarrierPrivileges
2045     *
2046     * @param alphaTag alpha-tagging of the dailing nubmer
2047     * @param number The dialing number
2048     * @return true if the operation was executed correctly.
2049     */
2050    public boolean setLine1NumberForDisplay(String alphaTag, String number) {
2051        return setLine1NumberForDisplayForSubscriber(getDefaultSubscription(), alphaTag, number);
2052    }
2053
2054    /**
2055     * Set the line 1 phone number string and its alphatag for the current ICCID
2056     * for display purpose only, for example, displayed in Phone Status. It won't
2057     * change the actual MSISDN/MDN. To unset alphatag or number, pass in a null
2058     * value.
2059     *
2060     * <p>Requires that the calling app has carrier privileges.
2061     * @see #hasCarrierPrivileges
2062     *
2063     * @param subId the subscriber that the alphatag and dialing number belongs to.
2064     * @param alphaTag alpha-tagging of the dailing nubmer
2065     * @param number The dialing number
2066     * @return true if the operation was executed correctly.
2067     * @hide
2068     */
2069    public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag, String number) {
2070        try {
2071            ITelephony telephony = getITelephony();
2072            if (telephony != null)
2073                return telephony.setLine1NumberForDisplayForSubscriber(subId, alphaTag, number);
2074        } catch (RemoteException ex) {
2075        } catch (NullPointerException ex) {
2076        }
2077        return false;
2078    }
2079
2080    /**
2081     * Returns the alphabetic identifier associated with the line 1 number.
2082     * Return null if it is unavailable.
2083     * <p>
2084     * Requires Permission:
2085     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
2086     * @hide
2087     * nobody seems to call this.
2088     */
2089    public String getLine1AlphaTag() {
2090        return getLine1AlphaTagForSubscriber(getDefaultSubscription());
2091    }
2092
2093    /**
2094     * Returns the alphabetic identifier associated with the line 1 number
2095     * for a subscription.
2096     * Return null if it is unavailable.
2097     * <p>
2098     * Requires Permission:
2099     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
2100     * @param subId whose alphabetic identifier associated with line 1 is returned
2101     * nobody seems to call this.
2102     */
2103    /** {@hide} */
2104    public String getLine1AlphaTagForSubscriber(int subId) {
2105        String alphaTag = null;
2106        try {
2107            ITelephony telephony = getITelephony();
2108            if (telephony != null)
2109                alphaTag = telephony.getLine1AlphaTagForDisplay(subId,
2110                        mContext.getOpPackageName());
2111        } catch (RemoteException ex) {
2112        } catch (NullPointerException ex) {
2113        }
2114        if (alphaTag != null) {
2115            return alphaTag;
2116        }
2117        try {
2118            IPhoneSubInfo info = getSubscriberInfo();
2119            if (info == null)
2120                return null;
2121            return info.getLine1AlphaTagForSubscriber(subId, mContext.getOpPackageName());
2122        } catch (RemoteException ex) {
2123            return null;
2124        } catch (NullPointerException ex) {
2125            // This could happen before phone restarts due to crashing
2126            return null;
2127        }
2128    }
2129
2130    /**
2131     * Return the set of subscriber IDs that should be considered as "merged
2132     * together" for data usage purposes. This is commonly {@code null} to
2133     * indicate no merging is required. Any returned subscribers are sorted in a
2134     * deterministic order.
2135     *
2136     * @hide
2137     */
2138    public @Nullable String[] getMergedSubscriberIds() {
2139        try {
2140            ITelephony telephony = getITelephony();
2141            if (telephony != null)
2142                return telephony.getMergedSubscriberIds();
2143        } catch (RemoteException ex) {
2144        } catch (NullPointerException ex) {
2145        }
2146        return null;
2147    }
2148
2149    /**
2150     * Returns the MSISDN string.
2151     * for a GSM phone. Return null if it is unavailable.
2152     * <p>
2153     * Requires Permission:
2154     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
2155     *
2156     * @hide
2157     */
2158    public String getMsisdn() {
2159        return getMsisdn(getDefaultSubscription());
2160    }
2161
2162    /**
2163     * Returns the MSISDN string.
2164     * for a GSM phone. Return null if it is unavailable.
2165     * <p>
2166     * Requires Permission:
2167     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
2168     *
2169     * @param subId for which msisdn is returned
2170     */
2171    /** {@hide} */
2172    public String getMsisdn(int subId) {
2173        try {
2174            IPhoneSubInfo info = getSubscriberInfo();
2175            if (info == null)
2176                return null;
2177            return info.getMsisdnForSubscriber(subId, mContext.getOpPackageName());
2178        } catch (RemoteException ex) {
2179            return null;
2180        } catch (NullPointerException ex) {
2181            // This could happen before phone restarts due to crashing
2182            return null;
2183        }
2184    }
2185
2186    /**
2187     * Returns the voice mail number. Return null if it is unavailable.
2188     * <p>
2189     * Requires Permission:
2190     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
2191     */
2192    public String getVoiceMailNumber() {
2193        return getVoiceMailNumber(getDefaultSubscription());
2194    }
2195
2196    /**
2197     * Returns the voice mail number for a subscription.
2198     * Return null if it is unavailable.
2199     * <p>
2200     * Requires Permission:
2201     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
2202     * @param subId whose voice mail number is returned
2203     */
2204    /** {@hide} */
2205    public String getVoiceMailNumber(int subId) {
2206        try {
2207            IPhoneSubInfo info = getSubscriberInfo();
2208            if (info == null)
2209                return null;
2210            return info.getVoiceMailNumberForSubscriber(subId, mContext.getOpPackageName());
2211        } catch (RemoteException ex) {
2212            return null;
2213        } catch (NullPointerException ex) {
2214            // This could happen before phone restarts due to crashing
2215            return null;
2216        }
2217    }
2218
2219    /**
2220     * Returns the complete voice mail number. Return null if it is unavailable.
2221     * <p>
2222     * Requires Permission:
2223     *   {@link android.Manifest.permission#CALL_PRIVILEGED CALL_PRIVILEGED}
2224     *
2225     * @hide
2226     */
2227    public String getCompleteVoiceMailNumber() {
2228        return getCompleteVoiceMailNumber(getDefaultSubscription());
2229    }
2230
2231    /**
2232     * Returns the complete voice mail number. Return null if it is unavailable.
2233     * <p>
2234     * Requires Permission:
2235     *   {@link android.Manifest.permission#CALL_PRIVILEGED CALL_PRIVILEGED}
2236     *
2237     * @param subId
2238     */
2239    /** {@hide} */
2240    public String getCompleteVoiceMailNumber(int subId) {
2241        try {
2242            IPhoneSubInfo info = getSubscriberInfo();
2243            if (info == null)
2244                return null;
2245            return info.getCompleteVoiceMailNumberForSubscriber(subId);
2246        } catch (RemoteException ex) {
2247            return null;
2248        } catch (NullPointerException ex) {
2249            // This could happen before phone restarts due to crashing
2250            return null;
2251        }
2252    }
2253
2254    /**
2255     * Sets the voice mail number.
2256     *
2257     * <p>Requires that the calling app has carrier privileges.
2258     * @see #hasCarrierPrivileges
2259     *
2260     * @param alphaTag The alpha tag to display.
2261     * @param number The voicemail number.
2262     */
2263    public boolean setVoiceMailNumber(String alphaTag, String number) {
2264        return setVoiceMailNumber(getDefaultSubscription(), alphaTag, number);
2265    }
2266
2267    /**
2268     * Sets the voicemail number for the given subscriber.
2269     *
2270     * <p>Requires that the calling app has carrier privileges.
2271     * @see #hasCarrierPrivileges
2272     *
2273     * @param subId The subscription id.
2274     * @param alphaTag The alpha tag to display.
2275     * @param number The voicemail number.
2276     */
2277    /** {@hide} */
2278    public boolean setVoiceMailNumber(int subId, String alphaTag, String number) {
2279        try {
2280            ITelephony telephony = getITelephony();
2281            if (telephony != null)
2282                return telephony.setVoiceMailNumber(subId, alphaTag, number);
2283        } catch (RemoteException ex) {
2284        } catch (NullPointerException ex) {
2285        }
2286        return false;
2287    }
2288
2289    /**
2290     * Returns the voice mail count. Return 0 if unavailable, -1 if there are unread voice messages
2291     * but the count is unknown.
2292     * <p>
2293     * Requires Permission:
2294     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
2295     * @hide
2296     */
2297    public int getVoiceMessageCount() {
2298        return getVoiceMessageCount(getDefaultSubscription());
2299    }
2300
2301    /**
2302     * Returns the voice mail count for a subscription. Return 0 if unavailable.
2303     * <p>
2304     * Requires Permission:
2305     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
2306     * @param subId whose voice message count is returned
2307     */
2308    /** {@hide} */
2309    public int getVoiceMessageCount(int subId) {
2310        try {
2311            ITelephony telephony = getITelephony();
2312            if (telephony == null)
2313                return 0;
2314            return telephony.getVoiceMessageCountForSubscriber(subId);
2315        } catch (RemoteException ex) {
2316            return 0;
2317        } catch (NullPointerException ex) {
2318            // This could happen before phone restarts due to crashing
2319            return 0;
2320        }
2321    }
2322
2323    /**
2324     * Retrieves the alphabetic identifier associated with the voice
2325     * mail number.
2326     * <p>
2327     * Requires Permission:
2328     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
2329     */
2330    public String getVoiceMailAlphaTag() {
2331        return getVoiceMailAlphaTag(getDefaultSubscription());
2332    }
2333
2334    /**
2335     * Retrieves the alphabetic identifier associated with the voice
2336     * mail number for a subscription.
2337     * <p>
2338     * Requires Permission:
2339     * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
2340     * @param subId whose alphabetic identifier associated with the
2341     * voice mail number is returned
2342     */
2343    /** {@hide} */
2344    public String getVoiceMailAlphaTag(int subId) {
2345        try {
2346            IPhoneSubInfo info = getSubscriberInfo();
2347            if (info == null)
2348                return null;
2349            return info.getVoiceMailAlphaTagForSubscriber(subId, mContext.getOpPackageName());
2350        } catch (RemoteException ex) {
2351            return null;
2352        } catch (NullPointerException ex) {
2353            // This could happen before phone restarts due to crashing
2354            return null;
2355        }
2356    }
2357
2358    /**
2359     * Returns the IMS private user identity (IMPI) that was loaded from the ISIM.
2360     * @return the IMPI, or null if not present or not loaded
2361     * @hide
2362     */
2363    public String getIsimImpi() {
2364        try {
2365            IPhoneSubInfo info = getSubscriberInfo();
2366            if (info == null)
2367                return null;
2368            return info.getIsimImpi();
2369        } catch (RemoteException ex) {
2370            return null;
2371        } catch (NullPointerException ex) {
2372            // This could happen before phone restarts due to crashing
2373            return null;
2374        }
2375    }
2376
2377    /**
2378     * Returns the IMS home network domain name that was loaded from the ISIM.
2379     * @return the IMS domain name, or null if not present or not loaded
2380     * @hide
2381     */
2382    public String getIsimDomain() {
2383        try {
2384            IPhoneSubInfo info = getSubscriberInfo();
2385            if (info == null)
2386                return null;
2387            return info.getIsimDomain();
2388        } catch (RemoteException ex) {
2389            return null;
2390        } catch (NullPointerException ex) {
2391            // This could happen before phone restarts due to crashing
2392            return null;
2393        }
2394    }
2395
2396    /**
2397     * Returns the IMS public user identities (IMPU) that were loaded from the ISIM.
2398     * @return an array of IMPU strings, with one IMPU per string, or null if
2399     *      not present or not loaded
2400     * @hide
2401     */
2402    public String[] getIsimImpu() {
2403        try {
2404            IPhoneSubInfo info = getSubscriberInfo();
2405            if (info == null)
2406                return null;
2407            return info.getIsimImpu();
2408        } catch (RemoteException ex) {
2409            return null;
2410        } catch (NullPointerException ex) {
2411            // This could happen before phone restarts due to crashing
2412            return null;
2413        }
2414    }
2415
2416   /**
2417    * @hide
2418    */
2419    private IPhoneSubInfo getSubscriberInfo() {
2420        // get it each time because that process crashes a lot
2421        return IPhoneSubInfo.Stub.asInterface(ServiceManager.getService("iphonesubinfo"));
2422    }
2423
2424    /** Device call state: No activity. */
2425    public static final int CALL_STATE_IDLE = 0;
2426    /** Device call state: Ringing. A new call arrived and is
2427     *  ringing or waiting. In the latter case, another call is
2428     *  already active. */
2429    public static final int CALL_STATE_RINGING = 1;
2430    /** Device call state: Off-hook. At least one call exists
2431      * that is dialing, active, or on hold, and no calls are ringing
2432      * or waiting. */
2433    public static final int CALL_STATE_OFFHOOK = 2;
2434
2435    /**
2436     * Returns one of the following constants that represents the current state of all
2437     * phone calls.
2438     *
2439     * {@link TelephonyManager#CALL_STATE_RINGING}
2440     * {@link TelephonyManager#CALL_STATE_OFFHOOK}
2441     * {@link TelephonyManager#CALL_STATE_IDLE}
2442     */
2443    public int getCallState() {
2444        try {
2445            ITelecomService telecom = getTelecomService();
2446            if (telecom != null) {
2447                return telecom.getCallState();
2448            }
2449        } catch (RemoteException e) {
2450            Log.e(TAG, "Error calling ITelecomService#getCallState", e);
2451        }
2452        return CALL_STATE_IDLE;
2453    }
2454
2455    /**
2456     * Returns a constant indicating the call state (cellular) on the device
2457     * for a subscription.
2458     *
2459     * @param subId whose call state is returned
2460     */
2461    /** {@hide} */
2462    public int getCallState(int subId) {
2463        try {
2464            ITelephony telephony = getITelephony();
2465            if (telephony == null)
2466                return CALL_STATE_IDLE;
2467            return telephony.getCallStateForSubscriber(subId);
2468        } catch (RemoteException ex) {
2469            // the phone process is restarting.
2470            return CALL_STATE_IDLE;
2471        } catch (NullPointerException ex) {
2472          // the phone process is restarting.
2473          return CALL_STATE_IDLE;
2474      }
2475    }
2476
2477    /** Data connection activity: No traffic. */
2478    public static final int DATA_ACTIVITY_NONE = 0x00000000;
2479    /** Data connection activity: Currently receiving IP PPP traffic. */
2480    public static final int DATA_ACTIVITY_IN = 0x00000001;
2481    /** Data connection activity: Currently sending IP PPP traffic. */
2482    public static final int DATA_ACTIVITY_OUT = 0x00000002;
2483    /** Data connection activity: Currently both sending and receiving
2484     *  IP PPP traffic. */
2485    public static final int DATA_ACTIVITY_INOUT = DATA_ACTIVITY_IN | DATA_ACTIVITY_OUT;
2486    /**
2487     * Data connection is active, but physical link is down
2488     */
2489    public static final int DATA_ACTIVITY_DORMANT = 0x00000004;
2490
2491    /**
2492     * Returns a constant indicating the type of activity on a data connection
2493     * (cellular).
2494     *
2495     * @see #DATA_ACTIVITY_NONE
2496     * @see #DATA_ACTIVITY_IN
2497     * @see #DATA_ACTIVITY_OUT
2498     * @see #DATA_ACTIVITY_INOUT
2499     * @see #DATA_ACTIVITY_DORMANT
2500     */
2501    public int getDataActivity() {
2502        try {
2503            ITelephony telephony = getITelephony();
2504            if (telephony == null)
2505                return DATA_ACTIVITY_NONE;
2506            return telephony.getDataActivity();
2507        } catch (RemoteException ex) {
2508            // the phone process is restarting.
2509            return DATA_ACTIVITY_NONE;
2510        } catch (NullPointerException ex) {
2511          // the phone process is restarting.
2512          return DATA_ACTIVITY_NONE;
2513      }
2514    }
2515
2516    /** Data connection state: Unknown.  Used before we know the state.
2517     * @hide
2518     */
2519    public static final int DATA_UNKNOWN        = -1;
2520    /** Data connection state: Disconnected. IP traffic not available. */
2521    public static final int DATA_DISCONNECTED   = 0;
2522    /** Data connection state: Currently setting up a data connection. */
2523    public static final int DATA_CONNECTING     = 1;
2524    /** Data connection state: Connected. IP traffic should be available. */
2525    public static final int DATA_CONNECTED      = 2;
2526    /** Data connection state: Suspended. The connection is up, but IP
2527     * traffic is temporarily unavailable. For example, in a 2G network,
2528     * data activity may be suspended when a voice call arrives. */
2529    public static final int DATA_SUSPENDED      = 3;
2530
2531    /**
2532     * Returns a constant indicating the current data connection state
2533     * (cellular).
2534     *
2535     * @see #DATA_DISCONNECTED
2536     * @see #DATA_CONNECTING
2537     * @see #DATA_CONNECTED
2538     * @see #DATA_SUSPENDED
2539     */
2540    public int getDataState() {
2541        try {
2542            ITelephony telephony = getITelephony();
2543            if (telephony == null)
2544                return DATA_DISCONNECTED;
2545            return telephony.getDataState();
2546        } catch (RemoteException ex) {
2547            // the phone process is restarting.
2548            return DATA_DISCONNECTED;
2549        } catch (NullPointerException ex) {
2550            return DATA_DISCONNECTED;
2551        }
2552    }
2553
2554   /**
2555    * @hide
2556    */
2557    private ITelephony getITelephony() {
2558        return ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE));
2559    }
2560
2561    /**
2562    * @hide
2563    */
2564    private ITelecomService getTelecomService() {
2565        return ITelecomService.Stub.asInterface(ServiceManager.getService(Context.TELECOM_SERVICE));
2566    }
2567
2568    //
2569    //
2570    // PhoneStateListener
2571    //
2572    //
2573
2574    /**
2575     * Registers a listener object to receive notification of changes
2576     * in specified telephony states.
2577     * <p>
2578     * To register a listener, pass a {@link PhoneStateListener}
2579     * and specify at least one telephony state of interest in
2580     * the events argument.
2581     *
2582     * At registration, and when a specified telephony state
2583     * changes, the telephony manager invokes the appropriate
2584     * callback method on the listener object and passes the
2585     * current (updated) values.
2586     * <p>
2587     * To unregister a listener, pass the listener object and set the
2588     * events argument to
2589     * {@link PhoneStateListener#LISTEN_NONE LISTEN_NONE} (0).
2590     *
2591     * @param listener The {@link PhoneStateListener} object to register
2592     *                 (or unregister)
2593     * @param events The telephony state(s) of interest to the listener,
2594     *               as a bitwise-OR combination of {@link PhoneStateListener}
2595     *               LISTEN_ flags.
2596     */
2597    public void listen(PhoneStateListener listener, int events) {
2598        if (mContext == null) return;
2599        try {
2600            Boolean notifyNow = (getITelephony() != null);
2601            sRegistry.listenForSubscriber(listener.mSubId, mContext.getOpPackageName(),
2602                    listener.callback, events, notifyNow);
2603        } catch (RemoteException ex) {
2604            // system process dead
2605        } catch (NullPointerException ex) {
2606            // system process dead
2607        }
2608    }
2609
2610    /**
2611     * Returns the CDMA ERI icon index to display
2612     *
2613     * @hide
2614     */
2615    public int getCdmaEriIconIndex() {
2616        return getCdmaEriIconIndex(getDefaultSubscription());
2617    }
2618
2619    /**
2620     * Returns the CDMA ERI icon index to display for a subscription
2621     */
2622    /** {@hide} */
2623    public int getCdmaEriIconIndex(int subId) {
2624        try {
2625            ITelephony telephony = getITelephony();
2626            if (telephony == null)
2627                return -1;
2628            return telephony.getCdmaEriIconIndexForSubscriber(subId);
2629        } catch (RemoteException ex) {
2630            // the phone process is restarting.
2631            return -1;
2632        } catch (NullPointerException ex) {
2633            return -1;
2634        }
2635    }
2636
2637    /**
2638     * Returns the CDMA ERI icon mode,
2639     * 0 - ON
2640     * 1 - FLASHING
2641     *
2642     * @hide
2643     */
2644    public int getCdmaEriIconMode() {
2645        return getCdmaEriIconMode(getDefaultSubscription());
2646    }
2647
2648    /**
2649     * Returns the CDMA ERI icon mode for a subscription.
2650     * 0 - ON
2651     * 1 - FLASHING
2652     */
2653    /** {@hide} */
2654    public int getCdmaEriIconMode(int subId) {
2655        try {
2656            ITelephony telephony = getITelephony();
2657            if (telephony == null)
2658                return -1;
2659            return telephony.getCdmaEriIconModeForSubscriber(subId);
2660        } catch (RemoteException ex) {
2661            // the phone process is restarting.
2662            return -1;
2663        } catch (NullPointerException ex) {
2664            return -1;
2665        }
2666    }
2667
2668    /**
2669     * Returns the CDMA ERI text,
2670     *
2671     * @hide
2672     */
2673    public String getCdmaEriText() {
2674        return getCdmaEriText(getDefaultSubscription());
2675    }
2676
2677    /**
2678     * Returns the CDMA ERI text, of a subscription
2679     *
2680     */
2681    /** {@hide} */
2682    public String getCdmaEriText(int subId) {
2683        try {
2684            ITelephony telephony = getITelephony();
2685            if (telephony == null)
2686                return null;
2687            return telephony.getCdmaEriTextForSubscriber(subId);
2688        } catch (RemoteException ex) {
2689            // the phone process is restarting.
2690            return null;
2691        } catch (NullPointerException ex) {
2692            return null;
2693        }
2694    }
2695
2696    /**
2697     * @return true if the current device is "voice capable".
2698     * <p>
2699     * "Voice capable" means that this device supports circuit-switched
2700     * (i.e. voice) phone calls over the telephony network, and is allowed
2701     * to display the in-call UI while a cellular voice call is active.
2702     * This will be false on "data only" devices which can't make voice
2703     * calls and don't support any in-call UI.
2704     * <p>
2705     * Note: the meaning of this flag is subtly different from the
2706     * PackageManager.FEATURE_TELEPHONY system feature, which is available
2707     * on any device with a telephony radio, even if the device is
2708     * data-only.
2709     */
2710    public boolean isVoiceCapable() {
2711        if (mContext == null) return true;
2712        return mContext.getResources().getBoolean(
2713                com.android.internal.R.bool.config_voice_capable);
2714    }
2715
2716    /**
2717     * @return true if the current device supports sms service.
2718     * <p>
2719     * If true, this means that the device supports both sending and
2720     * receiving sms via the telephony network.
2721     * <p>
2722     * Note: Voicemail waiting sms, cell broadcasting sms, and MMS are
2723     *       disabled when device doesn't support sms.
2724     */
2725    public boolean isSmsCapable() {
2726        if (mContext == null) return true;
2727        return mContext.getResources().getBoolean(
2728                com.android.internal.R.bool.config_sms_capable);
2729    }
2730
2731    /**
2732     * Returns all observed cell information from all radios on the
2733     * device including the primary and neighboring cells. This does
2734     * not cause or change the rate of PhoneStateListner#onCellInfoChanged.
2735     *<p>
2736     * The list can include one or more of {@link android.telephony.CellInfoGsm CellInfoGsm},
2737     * {@link android.telephony.CellInfoCdma CellInfoCdma},
2738     * {@link android.telephony.CellInfoLte CellInfoLte} and
2739     * {@link android.telephony.CellInfoWcdma CellInfoWcdma} in any combination.
2740     * Specifically on devices with multiple radios it is typical to see instances of
2741     * one or more of any these in the list. In addition 0, 1 or more CellInfo
2742     * objects may return isRegistered() true.
2743     *<p>
2744     * This is preferred over using getCellLocation although for older
2745     * devices this may return null in which case getCellLocation should
2746     * be called.
2747     *<p>
2748     * @return List of CellInfo or null if info unavailable.
2749     *
2750     * <p>Requires Permission: {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}
2751     */
2752    public List<CellInfo> getAllCellInfo() {
2753        try {
2754            ITelephony telephony = getITelephony();
2755            if (telephony == null)
2756                return null;
2757            return telephony.getAllCellInfo(mContext.getOpPackageName());
2758        } catch (RemoteException ex) {
2759            return null;
2760        } catch (NullPointerException ex) {
2761            return null;
2762        }
2763    }
2764
2765    /**
2766     * Sets the minimum time in milli-seconds between {@link PhoneStateListener#onCellInfoChanged
2767     * PhoneStateListener.onCellInfoChanged} will be invoked.
2768     *<p>
2769     * The default, 0, means invoke onCellInfoChanged when any of the reported
2770     * information changes. Setting the value to INT_MAX(0x7fffffff) means never issue
2771     * A onCellInfoChanged.
2772     *<p>
2773     * @param rateInMillis the rate
2774     *
2775     * @hide
2776     */
2777    public void setCellInfoListRate(int rateInMillis) {
2778        try {
2779            ITelephony telephony = getITelephony();
2780            if (telephony != null)
2781                telephony.setCellInfoListRate(rateInMillis);
2782        } catch (RemoteException ex) {
2783        } catch (NullPointerException ex) {
2784        }
2785    }
2786
2787    /**
2788     * Returns the MMS user agent.
2789     */
2790    public String getMmsUserAgent() {
2791        if (mContext == null) return null;
2792        return mContext.getResources().getString(
2793                com.android.internal.R.string.config_mms_user_agent);
2794    }
2795
2796    /**
2797     * Returns the MMS user agent profile URL.
2798     */
2799    public String getMmsUAProfUrl() {
2800        if (mContext == null) return null;
2801        return mContext.getResources().getString(
2802                com.android.internal.R.string.config_mms_user_agent_profile_url);
2803    }
2804
2805    /**
2806     * Opens a logical channel to the ICC card.
2807     *
2808     * Input parameters equivalent to TS 27.007 AT+CCHO command.
2809     *
2810     * <p>Requires Permission:
2811     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
2812     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
2813     *
2814     * @param AID Application id. See ETSI 102.221 and 101.220.
2815     * @return an IccOpenLogicalChannelResponse object.
2816     */
2817    public IccOpenLogicalChannelResponse iccOpenLogicalChannel(String AID) {
2818        try {
2819            ITelephony telephony = getITelephony();
2820            if (telephony != null)
2821                return telephony.iccOpenLogicalChannel(AID);
2822        } catch (RemoteException ex) {
2823        } catch (NullPointerException ex) {
2824        }
2825        return null;
2826    }
2827
2828    /**
2829     * Closes a previously opened logical channel to the ICC card.
2830     *
2831     * Input parameters equivalent to TS 27.007 AT+CCHC command.
2832     *
2833     * <p>Requires Permission:
2834     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
2835     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
2836     *
2837     * @param channel is the channel id to be closed as retruned by a successful
2838     *            iccOpenLogicalChannel.
2839     * @return true if the channel was closed successfully.
2840     */
2841    public boolean iccCloseLogicalChannel(int channel) {
2842        try {
2843            ITelephony telephony = getITelephony();
2844            if (telephony != null)
2845                return telephony.iccCloseLogicalChannel(channel);
2846        } catch (RemoteException ex) {
2847        } catch (NullPointerException ex) {
2848        }
2849        return false;
2850    }
2851
2852    /**
2853     * Transmit an APDU to the ICC card over a logical channel.
2854     *
2855     * Input parameters equivalent to TS 27.007 AT+CGLA command.
2856     *
2857     * <p>Requires Permission:
2858     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
2859     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
2860     *
2861     * @param channel is the channel id to be closed as returned by a successful
2862     *            iccOpenLogicalChannel.
2863     * @param cla Class of the APDU command.
2864     * @param instruction Instruction of the APDU command.
2865     * @param p1 P1 value of the APDU command.
2866     * @param p2 P2 value of the APDU command.
2867     * @param p3 P3 value of the APDU command. If p3 is negative a 4 byte APDU
2868     *            is sent to the SIM.
2869     * @param data Data to be sent with the APDU.
2870     * @return The APDU response from the ICC card with the status appended at
2871     *            the end.
2872     */
2873    public String iccTransmitApduLogicalChannel(int channel, int cla,
2874            int instruction, int p1, int p2, int p3, String data) {
2875        try {
2876            ITelephony telephony = getITelephony();
2877            if (telephony != null)
2878                return telephony.iccTransmitApduLogicalChannel(channel, cla,
2879                    instruction, p1, p2, p3, data);
2880        } catch (RemoteException ex) {
2881        } catch (NullPointerException ex) {
2882        }
2883        return "";
2884    }
2885
2886    /**
2887     * Transmit an APDU to the ICC card over the basic channel.
2888     *
2889     * Input parameters equivalent to TS 27.007 AT+CSIM command.
2890     *
2891     * <p>Requires Permission:
2892     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
2893     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
2894     *
2895     * @param cla Class of the APDU command.
2896     * @param instruction Instruction of the APDU command.
2897     * @param p1 P1 value of the APDU command.
2898     * @param p2 P2 value of the APDU command.
2899     * @param p3 P3 value of the APDU command. If p3 is negative a 4 byte APDU
2900     *            is sent to the SIM.
2901     * @param data Data to be sent with the APDU.
2902     * @return The APDU response from the ICC card with the status appended at
2903     *            the end.
2904     */
2905    public String iccTransmitApduBasicChannel(int cla,
2906            int instruction, int p1, int p2, int p3, String data) {
2907        try {
2908            ITelephony telephony = getITelephony();
2909            if (telephony != null)
2910                return telephony.iccTransmitApduBasicChannel(cla,
2911                    instruction, p1, p2, p3, data);
2912        } catch (RemoteException ex) {
2913        } catch (NullPointerException ex) {
2914        }
2915        return "";
2916    }
2917
2918    /**
2919     * Returns the response APDU for a command APDU sent through SIM_IO.
2920     *
2921     * <p>Requires Permission:
2922     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
2923     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
2924     *
2925     * @param fileID
2926     * @param command
2927     * @param p1 P1 value of the APDU command.
2928     * @param p2 P2 value of the APDU command.
2929     * @param p3 P3 value of the APDU command.
2930     * @param filePath
2931     * @return The APDU response.
2932     */
2933    public byte[] iccExchangeSimIO(int fileID, int command, int p1, int p2, int p3,
2934            String filePath) {
2935        try {
2936            ITelephony telephony = getITelephony();
2937            if (telephony != null)
2938                return telephony.iccExchangeSimIO(fileID, command, p1, p2, p3, filePath);
2939        } catch (RemoteException ex) {
2940        } catch (NullPointerException ex) {
2941        }
2942        return null;
2943    }
2944
2945    /**
2946     * Send ENVELOPE to the SIM and return the response.
2947     *
2948     * <p>Requires Permission:
2949     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
2950     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
2951     *
2952     * @param content String containing SAT/USAT response in hexadecimal
2953     *                format starting with command tag. See TS 102 223 for
2954     *                details.
2955     * @return The APDU response from the ICC card in hexadecimal format
2956     *         with the last 4 bytes being the status word. If the command fails,
2957     *         returns an empty string.
2958     */
2959    public String sendEnvelopeWithStatus(String content) {
2960        try {
2961            ITelephony telephony = getITelephony();
2962            if (telephony != null)
2963                return telephony.sendEnvelopeWithStatus(content);
2964        } catch (RemoteException ex) {
2965        } catch (NullPointerException ex) {
2966        }
2967        return "";
2968    }
2969
2970    /**
2971     * Read one of the NV items defined in com.android.internal.telephony.RadioNVItems.
2972     * Used for device configuration by some CDMA operators.
2973     * <p>
2974     * Requires Permission:
2975     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
2976     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
2977     *
2978     * @param itemID the ID of the item to read.
2979     * @return the NV item as a String, or null on any failure.
2980     *
2981     * @hide
2982     */
2983    public String nvReadItem(int itemID) {
2984        try {
2985            ITelephony telephony = getITelephony();
2986            if (telephony != null)
2987                return telephony.nvReadItem(itemID);
2988        } catch (RemoteException ex) {
2989            Rlog.e(TAG, "nvReadItem RemoteException", ex);
2990        } catch (NullPointerException ex) {
2991            Rlog.e(TAG, "nvReadItem NPE", ex);
2992        }
2993        return "";
2994    }
2995
2996    /**
2997     * Write one of the NV items defined in com.android.internal.telephony.RadioNVItems.
2998     * Used for device configuration by some CDMA operators.
2999     * <p>
3000     * Requires Permission:
3001     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
3002     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
3003     *
3004     * @param itemID the ID of the item to read.
3005     * @param itemValue the value to write, as a String.
3006     * @return true on success; false on any failure.
3007     *
3008     * @hide
3009     */
3010    public boolean nvWriteItem(int itemID, String itemValue) {
3011        try {
3012            ITelephony telephony = getITelephony();
3013            if (telephony != null)
3014                return telephony.nvWriteItem(itemID, itemValue);
3015        } catch (RemoteException ex) {
3016            Rlog.e(TAG, "nvWriteItem RemoteException", ex);
3017        } catch (NullPointerException ex) {
3018            Rlog.e(TAG, "nvWriteItem NPE", ex);
3019        }
3020        return false;
3021    }
3022
3023    /**
3024     * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
3025     * Used for device configuration by some CDMA operators.
3026     * <p>
3027     * Requires Permission:
3028     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
3029     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
3030     *
3031     * @param preferredRoamingList byte array containing the new PRL.
3032     * @return true on success; false on any failure.
3033     *
3034     * @hide
3035     */
3036    public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
3037        try {
3038            ITelephony telephony = getITelephony();
3039            if (telephony != null)
3040                return telephony.nvWriteCdmaPrl(preferredRoamingList);
3041        } catch (RemoteException ex) {
3042            Rlog.e(TAG, "nvWriteCdmaPrl RemoteException", ex);
3043        } catch (NullPointerException ex) {
3044            Rlog.e(TAG, "nvWriteCdmaPrl NPE", ex);
3045        }
3046        return false;
3047    }
3048
3049    /**
3050     * Perform the specified type of NV config reset. The radio will be taken offline
3051     * and the device must be rebooted after the operation. Used for device
3052     * configuration by some CDMA operators.
3053     * <p>
3054     * Requires Permission:
3055     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
3056     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
3057     *
3058     * @param resetType reset type: 1: reload NV reset, 2: erase NV reset, 3: factory NV reset
3059     * @return true on success; false on any failure.
3060     *
3061     * @hide
3062     */
3063    public boolean nvResetConfig(int resetType) {
3064        try {
3065            ITelephony telephony = getITelephony();
3066            if (telephony != null)
3067                return telephony.nvResetConfig(resetType);
3068        } catch (RemoteException ex) {
3069            Rlog.e(TAG, "nvResetConfig RemoteException", ex);
3070        } catch (NullPointerException ex) {
3071            Rlog.e(TAG, "nvResetConfig NPE", ex);
3072        }
3073        return false;
3074    }
3075
3076    /**
3077     * Returns Default subscription.
3078     */
3079    private static int getDefaultSubscription() {
3080        return SubscriptionManager.getDefaultSubId();
3081    }
3082
3083    /**
3084     * Returns Default phone.
3085     */
3086    private static int getDefaultPhone() {
3087        return SubscriptionManager.getPhoneId(SubscriptionManager.getDefaultSubId());
3088    }
3089
3090    /** {@hide} */
3091    public int getDefaultSim() {
3092        return SubscriptionManager.getSlotId(SubscriptionManager.getDefaultSubId());
3093    }
3094
3095    /**
3096     * Sets the telephony property with the value specified.
3097     *
3098     * @hide
3099     */
3100    public static void setTelephonyProperty(int phoneId, String property, String value) {
3101        String propVal = "";
3102        String p[] = null;
3103        String prop = SystemProperties.get(property);
3104
3105        if (value == null) {
3106            value = "";
3107        }
3108
3109        if (prop != null) {
3110            p = prop.split(",");
3111        }
3112
3113        if (!SubscriptionManager.isValidPhoneId(phoneId)) {
3114            Rlog.d(TAG, "setTelephonyProperty: invalid phoneId=" + phoneId +
3115                    " property=" + property + " value: " + value + " prop=" + prop);
3116            return;
3117        }
3118
3119        for (int i = 0; i < phoneId; i++) {
3120            String str = "";
3121            if ((p != null) && (i < p.length)) {
3122                str = p[i];
3123            }
3124            propVal = propVal + str + ",";
3125        }
3126
3127        propVal = propVal + value;
3128        if (p != null) {
3129            for (int i = phoneId + 1; i < p.length; i++) {
3130                propVal = propVal + "," + p[i];
3131            }
3132        }
3133
3134        if (property.length() > SystemProperties.PROP_NAME_MAX
3135                || propVal.length() > SystemProperties.PROP_VALUE_MAX) {
3136            Rlog.d(TAG, "setTelephonyProperty: property to long phoneId=" + phoneId +
3137                    " property=" + property + " value: " + value + " propVal=" + propVal);
3138            return;
3139        }
3140
3141        Rlog.d(TAG, "setTelephonyProperty: success phoneId=" + phoneId +
3142                " property=" + property + " value: " + value + " propVal=" + propVal);
3143        SystemProperties.set(property, propVal);
3144    }
3145
3146    /**
3147     * Convenience function for retrieving a value from the secure settings
3148     * value list as an integer.  Note that internally setting values are
3149     * always stored as strings; this function converts the string to an
3150     * integer for you.
3151     * <p>
3152     * This version does not take a default value.  If the setting has not
3153     * been set, or the string value is not a number,
3154     * it throws {@link SettingNotFoundException}.
3155     *
3156     * @param cr The ContentResolver to access.
3157     * @param name The name of the setting to retrieve.
3158     * @param index The index of the list
3159     *
3160     * @throws SettingNotFoundException Thrown if a setting by the given
3161     * name can't be found or the setting value is not an integer.
3162     *
3163     * @return The value at the given index of settings.
3164     * @hide
3165     */
3166    public static int getIntAtIndex(android.content.ContentResolver cr,
3167            String name, int index)
3168            throws android.provider.Settings.SettingNotFoundException {
3169        String v = android.provider.Settings.Global.getString(cr, name);
3170        if (v != null) {
3171            String valArray[] = v.split(",");
3172            if ((index >= 0) && (index < valArray.length) && (valArray[index] != null)) {
3173                try {
3174                    return Integer.parseInt(valArray[index]);
3175                } catch (NumberFormatException e) {
3176                    //Log.e(TAG, "Exception while parsing Integer: ", e);
3177                }
3178            }
3179        }
3180        throw new android.provider.Settings.SettingNotFoundException(name);
3181    }
3182
3183    /**
3184     * Convenience function for updating settings value as coma separated
3185     * integer values. This will either create a new entry in the table if the
3186     * given name does not exist, or modify the value of the existing row
3187     * with that name.  Note that internally setting values are always
3188     * stored as strings, so this function converts the given value to a
3189     * string before storing it.
3190     *
3191     * @param cr The ContentResolver to access.
3192     * @param name The name of the setting to modify.
3193     * @param index The index of the list
3194     * @param value The new value for the setting to be added to the list.
3195     * @return true if the value was set, false on database errors
3196     * @hide
3197     */
3198    public static boolean putIntAtIndex(android.content.ContentResolver cr,
3199            String name, int index, int value) {
3200        String data = "";
3201        String valArray[] = null;
3202        String v = android.provider.Settings.Global.getString(cr, name);
3203
3204        if (index == Integer.MAX_VALUE) {
3205            throw new RuntimeException("putIntAtIndex index == MAX_VALUE index=" + index);
3206        }
3207        if (index < 0) {
3208            throw new RuntimeException("putIntAtIndex index < 0 index=" + index);
3209        }
3210        if (v != null) {
3211            valArray = v.split(",");
3212        }
3213
3214        // Copy the elements from valArray till index
3215        for (int i = 0; i < index; i++) {
3216            String str = "";
3217            if ((valArray != null) && (i < valArray.length)) {
3218                str = valArray[i];
3219            }
3220            data = data + str + ",";
3221        }
3222
3223        data = data + value;
3224
3225        // Copy the remaining elements from valArray if any.
3226        if (valArray != null) {
3227            for (int i = index+1; i < valArray.length; i++) {
3228                data = data + "," + valArray[i];
3229            }
3230        }
3231        return android.provider.Settings.Global.putString(cr, name, data);
3232    }
3233
3234    /**
3235     * Gets the telephony property.
3236     *
3237     * @hide
3238     */
3239    public static String getTelephonyProperty(int phoneId, String property, String defaultVal) {
3240        String propVal = null;
3241        String prop = SystemProperties.get(property);
3242        if ((prop != null) && (prop.length() > 0)) {
3243            String values[] = prop.split(",");
3244            if ((phoneId >= 0) && (phoneId < values.length) && (values[phoneId] != null)) {
3245                propVal = values[phoneId];
3246            }
3247        }
3248        return propVal == null ? defaultVal : propVal;
3249    }
3250
3251    /** @hide */
3252    public int getSimCount() {
3253        // FIXME Need to get it from Telephony Dev Controller when that gets implemented!
3254        // and then this method shouldn't be used at all!
3255        if(isMultiSimEnabled()) {
3256            return 2;
3257        } else {
3258            return 1;
3259        }
3260    }
3261
3262    /**
3263     * Returns the IMS Service Table (IST) that was loaded from the ISIM.
3264     * @return IMS Service Table or null if not present or not loaded
3265     * @hide
3266     */
3267    public String getIsimIst() {
3268        try {
3269            IPhoneSubInfo info = getSubscriberInfo();
3270            if (info == null)
3271                return null;
3272            return info.getIsimIst();
3273        } catch (RemoteException ex) {
3274            return null;
3275        } catch (NullPointerException ex) {
3276            // This could happen before phone restarts due to crashing
3277            return null;
3278        }
3279    }
3280
3281    /**
3282     * Returns the IMS Proxy Call Session Control Function(PCSCF) that were loaded from the ISIM.
3283     * @return an array of PCSCF strings with one PCSCF per string, or null if
3284     *         not present or not loaded
3285     * @hide
3286     */
3287    public String[] getIsimPcscf() {
3288        try {
3289            IPhoneSubInfo info = getSubscriberInfo();
3290            if (info == null)
3291                return null;
3292            return info.getIsimPcscf();
3293        } catch (RemoteException ex) {
3294            return null;
3295        } catch (NullPointerException ex) {
3296            // This could happen before phone restarts due to crashing
3297            return null;
3298        }
3299    }
3300
3301    /**
3302     * Returns the response of ISIM Authetification through RIL.
3303     * Returns null if the Authentification hasn't been successed or isn't present iphonesubinfo.
3304     * @return the response of ISIM Authetification, or null if not available
3305     * @hide
3306     * @deprecated
3307     * @see getIccSimChallengeResponse with appType=PhoneConstants.APPTYPE_ISIM
3308     */
3309    public String getIsimChallengeResponse(String nonce){
3310        try {
3311            IPhoneSubInfo info = getSubscriberInfo();
3312            if (info == null)
3313                return null;
3314            return info.getIsimChallengeResponse(nonce);
3315        } catch (RemoteException ex) {
3316            return null;
3317        } catch (NullPointerException ex) {
3318            // This could happen before phone restarts due to crashing
3319            return null;
3320        }
3321    }
3322
3323    /**
3324     * Returns the response of SIM Authentication through RIL.
3325     * Returns null if the Authentication hasn't been successful
3326     * @param subId subscription ID to be queried
3327     * @param appType ICC application type (@see com.android.internal.telephony.PhoneConstants#APPTYPE_xxx)
3328     * @param data authentication challenge data
3329     * @return the response of SIM Authentication, or null if not available
3330     * @hide
3331     */
3332    public String getIccSimChallengeResponse(int subId, int appType, String data) {
3333        try {
3334            IPhoneSubInfo info = getSubscriberInfo();
3335            if (info == null)
3336                return null;
3337            return info.getIccSimChallengeResponse(subId, appType, data);
3338        } catch (RemoteException ex) {
3339            return null;
3340        } catch (NullPointerException ex) {
3341            // This could happen before phone starts
3342            return null;
3343        }
3344    }
3345
3346    /**
3347     * Returns the response of SIM Authentication through RIL for the default subscription.
3348     * Returns null if the Authentication hasn't been successful
3349     * @param appType ICC application type (@see com.android.internal.telephony.PhoneConstants#APPTYPE_xxx)
3350     * @param data authentication challenge data
3351     * @return the response of SIM Authentication, or null if not available
3352     * @hide
3353     */
3354    public String getIccSimChallengeResponse(int appType, String data) {
3355        return getIccSimChallengeResponse(getDefaultSubscription(), appType, data);
3356    }
3357
3358    /**
3359     * Get P-CSCF address from PCO after data connection is established or modified.
3360     * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN
3361     * @return array of P-CSCF address
3362     * @hide
3363     */
3364    public String[] getPcscfAddress(String apnType) {
3365        try {
3366            ITelephony telephony = getITelephony();
3367            if (telephony == null)
3368                return new String[0];
3369            return telephony.getPcscfAddress(apnType, mContext.getOpPackageName());
3370        } catch (RemoteException e) {
3371            return new String[0];
3372        }
3373    }
3374
3375    /**
3376     * Set IMS registration state
3377     *
3378     * @param Registration state
3379     * @hide
3380     */
3381    public void setImsRegistrationState(boolean registered) {
3382        try {
3383            ITelephony telephony = getITelephony();
3384            if (telephony != null)
3385                telephony.setImsRegistrationState(registered);
3386        } catch (RemoteException e) {
3387        }
3388    }
3389
3390    /**
3391     * Get the preferred network type.
3392     * Used for device configuration by some CDMA operators.
3393     * <p>
3394     * Requires Permission:
3395     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
3396     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
3397     *
3398     * @return the preferred network type, defined in RILConstants.java.
3399     * @hide
3400     */
3401    public int getPreferredNetworkType(int subId) {
3402        try {
3403            ITelephony telephony = getITelephony();
3404            if (telephony != null)
3405                return telephony.getPreferredNetworkType(subId);
3406        } catch (RemoteException ex) {
3407            Rlog.e(TAG, "getPreferredNetworkType RemoteException", ex);
3408        } catch (NullPointerException ex) {
3409            Rlog.e(TAG, "getPreferredNetworkType NPE", ex);
3410        }
3411        return -1;
3412    }
3413
3414    /**
3415     * Sets the network selection mode to automatic.
3416     * <p>
3417     * Requires Permission:
3418     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
3419     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
3420     *
3421     * @hide
3422     */
3423    public void setNetworkSelectionModeAutomatic(int subId) {
3424        try {
3425            ITelephony telephony = getITelephony();
3426            if (telephony != null)
3427                telephony.setNetworkSelectionModeAutomatic(subId);
3428        } catch (RemoteException ex) {
3429            Rlog.e(TAG, "setNetworkSelectionModeAutomatic RemoteException", ex);
3430        } catch (NullPointerException ex) {
3431            Rlog.e(TAG, "setNetworkSelectionModeAutomatic NPE", ex);
3432        }
3433    }
3434
3435    /**
3436     * Set the preferred network type.
3437     * Used for device configuration by some CDMA operators.
3438     * <p>
3439     * Requires Permission:
3440     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
3441     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
3442     *
3443     * @param subId the id of the subscription to set the preferred network type for.
3444     * @param networkType the preferred network type, defined in RILConstants.java.
3445     * @return true on success; false on any failure.
3446     * @hide
3447     */
3448    public boolean setPreferredNetworkType(int subId, int networkType) {
3449        try {
3450            ITelephony telephony = getITelephony();
3451            if (telephony != null)
3452                return telephony.setPreferredNetworkType(subId, networkType);
3453        } catch (RemoteException ex) {
3454            Rlog.e(TAG, "setPreferredNetworkType RemoteException", ex);
3455        } catch (NullPointerException ex) {
3456            Rlog.e(TAG, "setPreferredNetworkType NPE", ex);
3457        }
3458        return false;
3459    }
3460
3461    /**
3462     * Set the preferred network type to global mode which includes LTE, CDMA, EvDo and GSM/WCDMA.
3463     *
3464     * <p>
3465     * Requires that the calling app has carrier privileges.
3466     * @see #hasCarrierPrivileges
3467     *
3468     * @return true on success; false on any failure.
3469     */
3470    public boolean setPreferredNetworkTypeToGlobal() {
3471        return setPreferredNetworkType(getDefaultSubscription(),
3472                RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA);
3473    }
3474
3475    /**
3476     * Check TETHER_DUN_REQUIRED and TETHER_DUN_APN settings, net.tethering.noprovisioning
3477     * SystemProperty, and config_tether_apndata to decide whether DUN APN is required for
3478     * tethering.
3479     *
3480     * @return 0: Not required. 1: required. 2: Not set.
3481     * @hide
3482     */
3483    public int getTetherApnRequired() {
3484        try {
3485            ITelephony telephony = getITelephony();
3486            if (telephony != null)
3487                return telephony.getTetherApnRequired();
3488        } catch (RemoteException ex) {
3489            Rlog.e(TAG, "hasMatchedTetherApnSetting RemoteException", ex);
3490        } catch (NullPointerException ex) {
3491            Rlog.e(TAG, "hasMatchedTetherApnSetting NPE", ex);
3492        }
3493        return 2;
3494    }
3495
3496
3497    /**
3498     * Values used to return status for hasCarrierPrivileges call.
3499     */
3500    /** @hide */ @SystemApi
3501    public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1;
3502    /** @hide */ @SystemApi
3503    public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0;
3504    /** @hide */ @SystemApi
3505    public static final int CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED = -1;
3506    /** @hide */ @SystemApi
3507    public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2;
3508
3509    /**
3510     * Has the calling application been granted carrier privileges by the carrier.
3511     *
3512     * If any of the packages in the calling UID has carrier privileges, the
3513     * call will return true. This access is granted by the owner of the UICC
3514     * card and does not depend on the registered carrier.
3515     *
3516     * @return true if the app has carrier privileges.
3517     */
3518    public boolean hasCarrierPrivileges() {
3519        try {
3520            ITelephony telephony = getITelephony();
3521            if (telephony != null)
3522                return telephony.getCarrierPrivilegeStatus() == CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
3523        } catch (RemoteException ex) {
3524            Rlog.e(TAG, "hasCarrierPrivileges RemoteException", ex);
3525        } catch (NullPointerException ex) {
3526            Rlog.e(TAG, "hasCarrierPrivileges NPE", ex);
3527        }
3528        return false;
3529    }
3530
3531    /**
3532     * Override the branding for the current ICCID.
3533     *
3534     * Once set, whenever the SIM is present in the device, the service
3535     * provider name (SPN) and the operator name will both be replaced by the
3536     * brand value input. To unset the value, the same function should be
3537     * called with a null brand value.
3538     *
3539     * <p>Requires that the calling app has carrier privileges.
3540     * @see #hasCarrierPrivileges
3541     *
3542     * @param brand The brand name to display/set.
3543     * @return true if the operation was executed correctly.
3544     */
3545    public boolean setOperatorBrandOverride(String brand) {
3546        try {
3547            ITelephony telephony = getITelephony();
3548            if (telephony != null)
3549                return telephony.setOperatorBrandOverride(brand);
3550        } catch (RemoteException ex) {
3551            Rlog.e(TAG, "setOperatorBrandOverride RemoteException", ex);
3552        } catch (NullPointerException ex) {
3553            Rlog.e(TAG, "setOperatorBrandOverride NPE", ex);
3554        }
3555        return false;
3556    }
3557
3558    /**
3559     * Override the roaming preference for the current ICCID.
3560     *
3561     * Using this call, the carrier app (see #hasCarrierPrivileges) can override
3562     * the platform's notion of a network operator being considered roaming or not.
3563     * The change only affects the ICCID that was active when this call was made.
3564     *
3565     * If null is passed as any of the input, the corresponding value is deleted.
3566     *
3567     * <p>Requires that the caller have carrier privilege. See #hasCarrierPrivileges.
3568     *
3569     * @param gsmRoamingList - List of MCCMNCs to be considered roaming for 3GPP RATs.
3570     * @param gsmNonRoamingList - List of MCCMNCs to be considered not roaming for 3GPP RATs.
3571     * @param cdmaRoamingList - List of SIDs to be considered roaming for 3GPP2 RATs.
3572     * @param cdmaNonRoamingList - List of SIDs to be considered not roaming for 3GPP2 RATs.
3573     * @return true if the operation was executed correctly.
3574     *
3575     * @hide
3576     */
3577    public boolean setRoamingOverride(List<String> gsmRoamingList,
3578            List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
3579            List<String> cdmaNonRoamingList) {
3580        try {
3581            ITelephony telephony = getITelephony();
3582            if (telephony != null)
3583                return telephony.setRoamingOverride(gsmRoamingList, gsmNonRoamingList,
3584                        cdmaRoamingList, cdmaNonRoamingList);
3585        } catch (RemoteException ex) {
3586            Rlog.e(TAG, "setRoamingOverride RemoteException", ex);
3587        } catch (NullPointerException ex) {
3588            Rlog.e(TAG, "setRoamingOverride NPE", ex);
3589        }
3590        return false;
3591    }
3592
3593    /**
3594     * Expose the rest of ITelephony to @SystemApi
3595     */
3596
3597    /** @hide */
3598    @SystemApi
3599    public String getCdmaMdn() {
3600        return getCdmaMdn(getDefaultSubscription());
3601    }
3602
3603    /** @hide */
3604    @SystemApi
3605    public String getCdmaMdn(int subId) {
3606        try {
3607            ITelephony telephony = getITelephony();
3608            if (telephony == null)
3609                return null;
3610            return telephony.getCdmaMdn(subId);
3611        } catch (RemoteException ex) {
3612            return null;
3613        } catch (NullPointerException ex) {
3614            return null;
3615        }
3616    }
3617
3618    /** @hide */
3619    @SystemApi
3620    public String getCdmaMin() {
3621        return getCdmaMin(getDefaultSubscription());
3622    }
3623
3624    /** @hide */
3625    @SystemApi
3626    public String getCdmaMin(int subId) {
3627        try {
3628            ITelephony telephony = getITelephony();
3629            if (telephony == null)
3630                return null;
3631            return telephony.getCdmaMin(subId);
3632        } catch (RemoteException ex) {
3633            return null;
3634        } catch (NullPointerException ex) {
3635            return null;
3636        }
3637    }
3638
3639    /** @hide */
3640    @SystemApi
3641    public int checkCarrierPrivilegesForPackage(String pkgName) {
3642        try {
3643            ITelephony telephony = getITelephony();
3644            if (telephony != null)
3645                return telephony.checkCarrierPrivilegesForPackage(pkgName);
3646        } catch (RemoteException ex) {
3647            Rlog.e(TAG, "checkCarrierPrivilegesForPackage RemoteException", ex);
3648        } catch (NullPointerException ex) {
3649            Rlog.e(TAG, "checkCarrierPrivilegesForPackage NPE", ex);
3650        }
3651        return CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
3652    }
3653
3654    /** @hide */
3655    @SystemApi
3656    public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) {
3657        try {
3658            ITelephony telephony = getITelephony();
3659            if (telephony != null)
3660                return telephony.checkCarrierPrivilegesForPackageAnyPhone(pkgName);
3661        } catch (RemoteException ex) {
3662            Rlog.e(TAG, "checkCarrierPrivilegesForPackageAnyPhone RemoteException", ex);
3663        } catch (NullPointerException ex) {
3664            Rlog.e(TAG, "checkCarrierPrivilegesForPackageAnyPhone NPE", ex);
3665        }
3666        return CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
3667    }
3668
3669    /** @hide */
3670    @SystemApi
3671    public List<String> getCarrierPackageNamesForIntent(Intent intent) {
3672        return getCarrierPackageNamesForIntentAndPhone(intent, getDefaultPhone());
3673    }
3674
3675    /** @hide */
3676    @SystemApi
3677    public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) {
3678        try {
3679            ITelephony telephony = getITelephony();
3680            if (telephony != null)
3681                return telephony.getCarrierPackageNamesForIntentAndPhone(intent, phoneId);
3682        } catch (RemoteException ex) {
3683            Rlog.e(TAG, "getCarrierPackageNamesForIntentAndPhone RemoteException", ex);
3684        } catch (NullPointerException ex) {
3685            Rlog.e(TAG, "getCarrierPackageNamesForIntentAndPhone NPE", ex);
3686        }
3687        return null;
3688    }
3689
3690    /** @hide */
3691    @SystemApi
3692    public void dial(String number) {
3693        try {
3694            ITelephony telephony = getITelephony();
3695            if (telephony != null)
3696                telephony.dial(number);
3697        } catch (RemoteException e) {
3698            Log.e(TAG, "Error calling ITelephony#dial", e);
3699        }
3700    }
3701
3702    /** @hide */
3703    @SystemApi
3704    public void call(String callingPackage, String number) {
3705        try {
3706            ITelephony telephony = getITelephony();
3707            if (telephony != null)
3708                telephony.call(callingPackage, number);
3709        } catch (RemoteException e) {
3710            Log.e(TAG, "Error calling ITelephony#call", e);
3711        }
3712    }
3713
3714    /** @hide */
3715    @SystemApi
3716    public boolean endCall() {
3717        try {
3718            ITelephony telephony = getITelephony();
3719            if (telephony != null)
3720                return telephony.endCall();
3721        } catch (RemoteException e) {
3722            Log.e(TAG, "Error calling ITelephony#endCall", e);
3723        }
3724        return false;
3725    }
3726
3727    /** @hide */
3728    @SystemApi
3729    public void answerRingingCall() {
3730        try {
3731            ITelephony telephony = getITelephony();
3732            if (telephony != null)
3733                telephony.answerRingingCall();
3734        } catch (RemoteException e) {
3735            Log.e(TAG, "Error calling ITelephony#answerRingingCall", e);
3736        }
3737    }
3738
3739    /** @hide */
3740    @SystemApi
3741    public void silenceRinger() {
3742        try {
3743            getTelecomService().silenceRinger(mContext.getOpPackageName());
3744        } catch (RemoteException e) {
3745            Log.e(TAG, "Error calling ITelecomService#silenceRinger", e);
3746        }
3747    }
3748
3749    /** @hide */
3750    @SystemApi
3751    public boolean isOffhook() {
3752        try {
3753            ITelephony telephony = getITelephony();
3754            if (telephony != null)
3755                return telephony.isOffhook();
3756        } catch (RemoteException e) {
3757            Log.e(TAG, "Error calling ITelephony#isOffhook", e);
3758        }
3759        return false;
3760    }
3761
3762    /** @hide */
3763    @SystemApi
3764    public boolean isRinging() {
3765        try {
3766            ITelephony telephony = getITelephony();
3767            if (telephony != null)
3768                return telephony.isRinging();
3769        } catch (RemoteException e) {
3770            Log.e(TAG, "Error calling ITelephony#isRinging", e);
3771        }
3772        return false;
3773    }
3774
3775    /** @hide */
3776    @SystemApi
3777    public boolean isIdle() {
3778        try {
3779            ITelephony telephony = getITelephony();
3780            if (telephony != null)
3781                return telephony.isIdle();
3782        } catch (RemoteException e) {
3783            Log.e(TAG, "Error calling ITelephony#isIdle", e);
3784        }
3785        return true;
3786    }
3787
3788    /** @hide */
3789    @SystemApi
3790    public boolean isRadioOn() {
3791        try {
3792            ITelephony telephony = getITelephony();
3793            if (telephony != null)
3794                return telephony.isRadioOn();
3795        } catch (RemoteException e) {
3796            Log.e(TAG, "Error calling ITelephony#isRadioOn", e);
3797        }
3798        return false;
3799    }
3800
3801    /** @hide */
3802    @SystemApi
3803    public boolean isSimPinEnabled() {
3804        try {
3805            ITelephony telephony = getITelephony();
3806            if (telephony != null)
3807                return telephony.isSimPinEnabled(mContext.getOpPackageName());
3808        } catch (RemoteException e) {
3809            Log.e(TAG, "Error calling ITelephony#isSimPinEnabled", e);
3810        }
3811        return false;
3812    }
3813
3814    /** @hide */
3815    @SystemApi
3816    public boolean supplyPin(String pin) {
3817        try {
3818            ITelephony telephony = getITelephony();
3819            if (telephony != null)
3820                return telephony.supplyPin(pin);
3821        } catch (RemoteException e) {
3822            Log.e(TAG, "Error calling ITelephony#supplyPin", e);
3823        }
3824        return false;
3825    }
3826
3827    /** @hide */
3828    @SystemApi
3829    public boolean supplyPuk(String puk, String pin) {
3830        try {
3831            ITelephony telephony = getITelephony();
3832            if (telephony != null)
3833                return telephony.supplyPuk(puk, pin);
3834        } catch (RemoteException e) {
3835            Log.e(TAG, "Error calling ITelephony#supplyPuk", e);
3836        }
3837        return false;
3838    }
3839
3840    /** @hide */
3841    @SystemApi
3842    public int[] supplyPinReportResult(String pin) {
3843        try {
3844            ITelephony telephony = getITelephony();
3845            if (telephony != null)
3846                return telephony.supplyPinReportResult(pin);
3847        } catch (RemoteException e) {
3848            Log.e(TAG, "Error calling ITelephony#supplyPinReportResult", e);
3849        }
3850        return new int[0];
3851    }
3852
3853    /** @hide */
3854    @SystemApi
3855    public int[] supplyPukReportResult(String puk, String pin) {
3856        try {
3857            ITelephony telephony = getITelephony();
3858            if (telephony != null)
3859                return telephony.supplyPukReportResult(puk, pin);
3860        } catch (RemoteException e) {
3861            Log.e(TAG, "Error calling ITelephony#]", e);
3862        }
3863        return new int[0];
3864    }
3865
3866    /** @hide */
3867    @SystemApi
3868    public boolean handlePinMmi(String dialString) {
3869        try {
3870            ITelephony telephony = getITelephony();
3871            if (telephony != null)
3872                return telephony.handlePinMmi(dialString);
3873        } catch (RemoteException e) {
3874            Log.e(TAG, "Error calling ITelephony#handlePinMmi", e);
3875        }
3876        return false;
3877    }
3878
3879    /** @hide */
3880    @SystemApi
3881    public boolean handlePinMmiForSubscriber(int subId, String dialString) {
3882        try {
3883            ITelephony telephony = getITelephony();
3884            if (telephony != null)
3885                return telephony.handlePinMmiForSubscriber(subId, dialString);
3886        } catch (RemoteException e) {
3887            Log.e(TAG, "Error calling ITelephony#handlePinMmi", e);
3888        }
3889        return false;
3890    }
3891
3892    /** @hide */
3893    @SystemApi
3894    public void toggleRadioOnOff() {
3895        try {
3896            ITelephony telephony = getITelephony();
3897            if (telephony != null)
3898                telephony.toggleRadioOnOff();
3899        } catch (RemoteException e) {
3900            Log.e(TAG, "Error calling ITelephony#toggleRadioOnOff", e);
3901        }
3902    }
3903
3904    /** @hide */
3905    @SystemApi
3906    public boolean setRadio(boolean turnOn) {
3907        try {
3908            ITelephony telephony = getITelephony();
3909            if (telephony != null)
3910                return telephony.setRadio(turnOn);
3911        } catch (RemoteException e) {
3912            Log.e(TAG, "Error calling ITelephony#setRadio", e);
3913        }
3914        return false;
3915    }
3916
3917    /** @hide */
3918    @SystemApi
3919    public boolean setRadioPower(boolean turnOn) {
3920        try {
3921            ITelephony telephony = getITelephony();
3922            if (telephony != null)
3923                return telephony.setRadioPower(turnOn);
3924        } catch (RemoteException e) {
3925            Log.e(TAG, "Error calling ITelephony#setRadioPower", e);
3926        }
3927        return false;
3928    }
3929
3930    /** @hide */
3931    @SystemApi
3932    public void updateServiceLocation() {
3933        try {
3934            ITelephony telephony = getITelephony();
3935            if (telephony != null)
3936                telephony.updateServiceLocation();
3937        } catch (RemoteException e) {
3938            Log.e(TAG, "Error calling ITelephony#updateServiceLocation", e);
3939        }
3940    }
3941
3942    /** @hide */
3943    @SystemApi
3944    public boolean enableDataConnectivity() {
3945        try {
3946            ITelephony telephony = getITelephony();
3947            if (telephony != null)
3948                return telephony.enableDataConnectivity();
3949        } catch (RemoteException e) {
3950            Log.e(TAG, "Error calling ITelephony#enableDataConnectivity", e);
3951        }
3952        return false;
3953    }
3954
3955    /** @hide */
3956    @SystemApi
3957    public boolean disableDataConnectivity() {
3958        try {
3959            ITelephony telephony = getITelephony();
3960            if (telephony != null)
3961                return telephony.disableDataConnectivity();
3962        } catch (RemoteException e) {
3963            Log.e(TAG, "Error calling ITelephony#disableDataConnectivity", e);
3964        }
3965        return false;
3966    }
3967
3968    /** @hide */
3969    @SystemApi
3970    public boolean isDataConnectivityPossible() {
3971        try {
3972            ITelephony telephony = getITelephony();
3973            if (telephony != null)
3974                return telephony.isDataConnectivityPossible();
3975        } catch (RemoteException e) {
3976            Log.e(TAG, "Error calling ITelephony#isDataConnectivityPossible", e);
3977        }
3978        return false;
3979    }
3980
3981    /** @hide */
3982    @SystemApi
3983    public boolean needsOtaServiceProvisioning() {
3984        try {
3985            ITelephony telephony = getITelephony();
3986            if (telephony != null)
3987                return telephony.needsOtaServiceProvisioning();
3988        } catch (RemoteException e) {
3989            Log.e(TAG, "Error calling ITelephony#needsOtaServiceProvisioning", e);
3990        }
3991        return false;
3992    }
3993
3994    /** @hide */
3995    @SystemApi
3996    public void setDataEnabled(boolean enable) {
3997        setDataEnabled(SubscriptionManager.getDefaultDataSubId(), enable);
3998    }
3999
4000    /** @hide */
4001    @SystemApi
4002    public void setDataEnabled(int subId, boolean enable) {
4003        try {
4004            Log.d(TAG, "setDataEnabled: enabled=" + enable);
4005            ITelephony telephony = getITelephony();
4006            if (telephony != null)
4007                telephony.setDataEnabled(subId, enable);
4008        } catch (RemoteException e) {
4009            Log.e(TAG, "Error calling ITelephony#setDataEnabled", e);
4010        }
4011    }
4012
4013    /** @hide */
4014    @SystemApi
4015    public boolean getDataEnabled() {
4016        return getDataEnabled(SubscriptionManager.getDefaultDataSubId());
4017    }
4018
4019    /** @hide */
4020    @SystemApi
4021    public boolean getDataEnabled(int subId) {
4022        boolean retVal = false;
4023        try {
4024            ITelephony telephony = getITelephony();
4025            if (telephony != null)
4026                retVal = telephony.getDataEnabled(subId);
4027        } catch (RemoteException e) {
4028            Log.e(TAG, "Error calling ITelephony#getDataEnabled", e);
4029        } catch (NullPointerException e) {
4030        }
4031        Log.d(TAG, "getDataEnabled: retVal=" + retVal);
4032        return retVal;
4033    }
4034
4035    /**
4036     * Returns the result and response from RIL for oem request
4037     *
4038     * @param oemReq the data is sent to ril.
4039     * @param oemResp the respose data from RIL.
4040     * @return negative value request was not handled or get error
4041     *         0 request was handled succesfully, but no response data
4042     *         positive value success, data length of response
4043     * @hide
4044     */
4045    public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) {
4046        try {
4047            ITelephony telephony = getITelephony();
4048            if (telephony != null)
4049                return telephony.invokeOemRilRequestRaw(oemReq, oemResp);
4050        } catch (RemoteException ex) {
4051        } catch (NullPointerException ex) {
4052        }
4053        return -1;
4054    }
4055
4056    /** @hide */
4057    @SystemApi
4058    public void enableVideoCalling(boolean enable) {
4059        try {
4060            ITelephony telephony = getITelephony();
4061            if (telephony != null)
4062                telephony.enableVideoCalling(enable);
4063        } catch (RemoteException e) {
4064            Log.e(TAG, "Error calling ITelephony#enableVideoCalling", e);
4065        }
4066    }
4067
4068    /** @hide */
4069    @SystemApi
4070    public boolean isVideoCallingEnabled() {
4071        try {
4072            ITelephony telephony = getITelephony();
4073            if (telephony != null)
4074                return telephony.isVideoCallingEnabled(mContext.getOpPackageName());
4075        } catch (RemoteException e) {
4076            Log.e(TAG, "Error calling ITelephony#isVideoCallingEnabled", e);
4077        }
4078        return false;
4079    }
4080
4081    /**
4082     * Whether the device supports configuring the DTMF tone length.
4083     *
4084     * @return {@code true} if the DTMF tone length can be changed, and {@code false} otherwise.
4085     */
4086    public boolean canChangeDtmfToneLength() {
4087        try {
4088            ITelephony telephony = getITelephony();
4089            if (telephony != null) {
4090                return telephony.canChangeDtmfToneLength();
4091            }
4092        } catch (RemoteException e) {
4093            Log.e(TAG, "Error calling ITelephony#canChangeDtmfToneLength", e);
4094        }
4095        return false;
4096    }
4097
4098    /**
4099     * Whether the device is a world phone.
4100     *
4101     * @return {@code true} if the device is a world phone, and {@code false} otherwise.
4102     */
4103    public boolean isWorldPhone() {
4104        try {
4105            ITelephony telephony = getITelephony();
4106            if (telephony != null) {
4107                return telephony.isWorldPhone();
4108            }
4109        } catch (RemoteException e) {
4110            Log.e(TAG, "Error calling ITelephony#isWorldPhone", e);
4111        }
4112        return false;
4113    }
4114
4115    /**
4116     * Whether the phone supports TTY mode.
4117     *
4118     * @return {@code true} if the device supports TTY mode, and {@code false} otherwise.
4119     */
4120    public boolean isTtyModeSupported() {
4121        try {
4122            ITelephony telephony = getITelephony();
4123            if (telephony != null) {
4124                return telephony.isTtyModeSupported();
4125            }
4126        } catch (RemoteException e) {
4127            Log.e(TAG, "Error calling ITelephony#isTtyModeSupported", e);
4128        }
4129        return false;
4130    }
4131
4132    /**
4133     * Whether the phone supports hearing aid compatibility.
4134     *
4135     * @return {@code true} if the device supports hearing aid compatibility, and {@code false}
4136     * otherwise.
4137     */
4138    public boolean isHearingAidCompatibilitySupported() {
4139        try {
4140            ITelephony telephony = getITelephony();
4141            if (telephony != null) {
4142                return telephony.isHearingAidCompatibilitySupported();
4143            }
4144        } catch (RemoteException e) {
4145            Log.e(TAG, "Error calling ITelephony#isHearingAidCompatibilitySupported", e);
4146        }
4147        return false;
4148    }
4149
4150    /**
4151     * This function retrieves value for setting "name+subId", and if that is not found
4152     * retrieves value for setting "name", and if that is not found throws
4153     * SettingNotFoundException
4154     *
4155     * @hide */
4156    public static int getIntWithSubId(ContentResolver cr, String name, int subId)
4157            throws SettingNotFoundException {
4158        try {
4159            return Settings.Global.getInt(cr, name + subId);
4160        } catch (SettingNotFoundException e) {
4161            try {
4162                int val = Settings.Global.getInt(cr, name);
4163                Settings.Global.putInt(cr, name + subId, val);
4164
4165                /* We are now moving from 'setting' to 'setting+subId', and using the value stored
4166                 * for 'setting' as default. Reset the default (since it may have a user set
4167                 * value). */
4168                int default_val = val;
4169                if (name.equals(Settings.Global.MOBILE_DATA)) {
4170                    default_val = "true".equalsIgnoreCase(
4171                            SystemProperties.get("ro.com.android.mobiledata", "true")) ? 1 : 0;
4172                } else if (name.equals(Settings.Global.DATA_ROAMING)) {
4173                    default_val = "true".equalsIgnoreCase(
4174                            SystemProperties.get("ro.com.android.dataroaming", "false")) ? 1 : 0;
4175                }
4176
4177                if (default_val != val) {
4178                    Settings.Global.putInt(cr, name, default_val);
4179                }
4180
4181                return val;
4182            } catch (SettingNotFoundException exc) {
4183                throw new SettingNotFoundException(name);
4184            }
4185        }
4186    }
4187
4188   /**
4189    * Returns the IMS Registration Status
4190    * @hide
4191    */
4192   public boolean isImsRegistered() {
4193       try {
4194           ITelephony telephony = getITelephony();
4195           if (telephony == null)
4196               return false;
4197           return telephony.isImsRegistered();
4198       } catch (RemoteException ex) {
4199           return false;
4200       } catch (NullPointerException ex) {
4201           return false;
4202       }
4203   }
4204
4205   /**
4206    * Returns the Status of Volte
4207    *@hide
4208    */
4209   public boolean isVolteEnabled() {
4210       try {
4211           return getITelephony().isVolteEnabled();
4212       } catch (RemoteException ex) {
4213           return false;
4214       } catch (NullPointerException ex) {
4215           return false;
4216       }
4217   }
4218
4219   /**
4220    * Returns the Status of Wi-Fi Calling
4221    *@hide
4222    */
4223   public boolean isWifiCallingEnabled() {
4224       try {
4225           return getITelephony().isWifiCallingEnabled();
4226       } catch (RemoteException ex) {
4227           return false;
4228       } catch (NullPointerException ex) {
4229           return false;
4230       }
4231   }
4232
4233   /**
4234    * Set TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC for the default phone.
4235    *
4236    * @hide
4237    */
4238    public void setSimOperatorNumeric(String numeric) {
4239        int phoneId = getDefaultPhone();
4240        setSimOperatorNumericForPhone(phoneId, numeric);
4241    }
4242
4243   /**
4244    * Set TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC for the given phone.
4245    *
4246    * @hide
4247    */
4248    public void setSimOperatorNumericForPhone(int phoneId, String numeric) {
4249        setTelephonyProperty(phoneId,
4250                TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, numeric);
4251    }
4252
4253    /**
4254     * Set TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC for the default phone.
4255     *
4256     * @hide
4257     */
4258    public void setSimOperatorName(String name) {
4259        int phoneId = getDefaultPhone();
4260        setSimOperatorNameForPhone(phoneId, name);
4261    }
4262
4263    /**
4264     * Set TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC for the given phone.
4265     *
4266     * @hide
4267     */
4268    public void setSimOperatorNameForPhone(int phoneId, String name) {
4269        setTelephonyProperty(phoneId,
4270                TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA, name);
4271    }
4272
4273   /**
4274    * Set TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY for the default phone.
4275    *
4276    * @hide
4277    */
4278    public void setSimCountryIso(String iso) {
4279        int phoneId = getDefaultPhone();
4280        setSimCountryIsoForPhone(phoneId, iso);
4281    }
4282
4283   /**
4284    * Set TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY for the given phone.
4285    *
4286    * @hide
4287    */
4288    public void setSimCountryIsoForPhone(int phoneId, String iso) {
4289        setTelephonyProperty(phoneId,
4290                TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY, iso);
4291    }
4292
4293    /**
4294     * Set TelephonyProperties.PROPERTY_SIM_STATE for the default phone.
4295     *
4296     * @hide
4297     */
4298    public void setSimState(String state) {
4299        int phoneId = getDefaultPhone();
4300        setSimStateForPhone(phoneId, state);
4301    }
4302
4303    /**
4304     * Set TelephonyProperties.PROPERTY_SIM_STATE for the given phone.
4305     *
4306     * @hide
4307     */
4308    public void setSimStateForPhone(int phoneId, String state) {
4309        setTelephonyProperty(phoneId,
4310                TelephonyProperties.PROPERTY_SIM_STATE, state);
4311    }
4312
4313    /**
4314     * Set baseband version for the default phone.
4315     *
4316     * @param version baseband version
4317     * @hide
4318     */
4319    public void setBasebandVersion(String version) {
4320        int phoneId = getDefaultPhone();
4321        setBasebandVersionForPhone(phoneId, version);
4322    }
4323
4324    /**
4325     * Set baseband version by phone id.
4326     *
4327     * @param phoneId for which baseband version is set
4328     * @param version baseband version
4329     * @hide
4330     */
4331    public void setBasebandVersionForPhone(int phoneId, String version) {
4332        if (SubscriptionManager.isValidPhoneId(phoneId)) {
4333            String prop = TelephonyProperties.PROPERTY_BASEBAND_VERSION +
4334                    ((phoneId == 0) ? "" : Integer.toString(phoneId));
4335            SystemProperties.set(prop, version);
4336        }
4337    }
4338
4339    /**
4340     * Set phone type for the default phone.
4341     *
4342     * @param type phone type
4343     *
4344     * @hide
4345     */
4346    public void setPhoneType(int type) {
4347        int phoneId = getDefaultPhone();
4348        setPhoneType(phoneId, type);
4349    }
4350
4351    /**
4352     * Set phone type by phone id.
4353     *
4354     * @param phoneId for which phone type is set
4355     * @param type phone type
4356     *
4357     * @hide
4358     */
4359    public void setPhoneType(int phoneId, int type) {
4360        if (SubscriptionManager.isValidPhoneId(phoneId)) {
4361            TelephonyManager.setTelephonyProperty(phoneId,
4362                    TelephonyProperties.CURRENT_ACTIVE_PHONE, String.valueOf(type));
4363        }
4364    }
4365
4366    /**
4367     * Get OTASP number schema for the default phone.
4368     *
4369     * @param defaultValue default value
4370     * @return OTA SP number schema
4371     *
4372     * @hide
4373     */
4374    public String getOtaSpNumberSchema(String defaultValue) {
4375        int phoneId = getDefaultPhone();
4376        return getOtaSpNumberSchemaForPhone(phoneId, defaultValue);
4377    }
4378
4379    /**
4380     * Get OTASP number schema by phone id.
4381     *
4382     * @param phoneId for which OTA SP number schema is get
4383     * @param defaultValue default value
4384     * @return OTA SP number schema
4385     *
4386     * @hide
4387     */
4388    public String getOtaSpNumberSchemaForPhone(int phoneId, String defaultValue) {
4389        if (SubscriptionManager.isValidPhoneId(phoneId)) {
4390            return TelephonyManager.getTelephonyProperty(phoneId,
4391                    TelephonyProperties.PROPERTY_OTASP_NUM_SCHEMA, defaultValue);
4392        }
4393
4394        return defaultValue;
4395    }
4396
4397    /**
4398     * Get SMS receive capable from system property for the default phone.
4399     *
4400     * @param defaultValue default value
4401     * @return SMS receive capable
4402     *
4403     * @hide
4404     */
4405    public boolean getSmsReceiveCapable(boolean defaultValue) {
4406        int phoneId = getDefaultPhone();
4407        return getSmsReceiveCapableForPhone(phoneId, defaultValue);
4408    }
4409
4410    /**
4411     * Get SMS receive capable from system property by phone id.
4412     *
4413     * @param phoneId for which SMS receive capable is get
4414     * @param defaultValue default value
4415     * @return SMS receive capable
4416     *
4417     * @hide
4418     */
4419    public boolean getSmsReceiveCapableForPhone(int phoneId, boolean defaultValue) {
4420        if (SubscriptionManager.isValidPhoneId(phoneId)) {
4421            return Boolean.valueOf(TelephonyManager.getTelephonyProperty(phoneId,
4422                    TelephonyProperties.PROPERTY_SMS_RECEIVE, String.valueOf(defaultValue)));
4423        }
4424
4425        return defaultValue;
4426    }
4427
4428    /**
4429     * Get SMS send capable from system property for the default phone.
4430     *
4431     * @param defaultValue default value
4432     * @return SMS send capable
4433     *
4434     * @hide
4435     */
4436    public boolean getSmsSendCapable(boolean defaultValue) {
4437        int phoneId = getDefaultPhone();
4438        return getSmsSendCapableForPhone(phoneId, defaultValue);
4439    }
4440
4441    /**
4442     * Get SMS send capable from system property by phone id.
4443     *
4444     * @param phoneId for which SMS send capable is get
4445     * @param defaultValue default value
4446     * @return SMS send capable
4447     *
4448     * @hide
4449     */
4450    public boolean getSmsSendCapableForPhone(int phoneId, boolean defaultValue) {
4451        if (SubscriptionManager.isValidPhoneId(phoneId)) {
4452            return Boolean.valueOf(TelephonyManager.getTelephonyProperty(phoneId,
4453                    TelephonyProperties.PROPERTY_SMS_SEND, String.valueOf(defaultValue)));
4454        }
4455
4456        return defaultValue;
4457    }
4458
4459    /**
4460     * Set the alphabetic name of current registered operator.
4461     * @param name the alphabetic name of current registered operator.
4462     * @hide
4463     */
4464    public void setNetworkOperatorName(String name) {
4465        int phoneId = getDefaultPhone();
4466        setNetworkOperatorNameForPhone(phoneId, name);
4467    }
4468
4469    /**
4470     * Set the alphabetic name of current registered operator.
4471     * @param phoneId which phone you want to set
4472     * @param name the alphabetic name of current registered operator.
4473     * @hide
4474     */
4475    public void setNetworkOperatorNameForPhone(int phoneId, String name) {
4476        if (SubscriptionManager.isValidPhoneId(phoneId)) {
4477            setTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_ALPHA, name);
4478        }
4479    }
4480
4481    /**
4482     * Set the numeric name (MCC+MNC) of current registered operator.
4483     * @param operator the numeric name (MCC+MNC) of current registered operator
4484     * @hide
4485     */
4486    public void setNetworkOperatorNumeric(String numeric) {
4487        int phoneId = getDefaultPhone();
4488        setNetworkOperatorNumericForPhone(phoneId, numeric);
4489    }
4490
4491    /**
4492     * Set the numeric name (MCC+MNC) of current registered operator.
4493     * @param phoneId for which phone type is set
4494     * @param operator the numeric name (MCC+MNC) of current registered operator
4495     * @hide
4496     */
4497    public void setNetworkOperatorNumericForPhone(int phoneId, String numeric) {
4498        setTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, numeric);
4499    }
4500
4501    /**
4502     * Set roaming state of the current network, for GSM purposes.
4503     * @param isRoaming is network in romaing state or not
4504     * @hide
4505     */
4506    public void setNetworkRoaming(boolean isRoaming) {
4507        int phoneId = getDefaultPhone();
4508        setNetworkRoamingForPhone(phoneId, isRoaming);
4509    }
4510
4511    /**
4512     * Set roaming state of the current network, for GSM purposes.
4513     * @param phoneId which phone you want to set
4514     * @param isRoaming is network in romaing state or not
4515     * @hide
4516     */
4517    public void setNetworkRoamingForPhone(int phoneId, boolean isRoaming) {
4518        if (SubscriptionManager.isValidPhoneId(phoneId)) {
4519            setTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_ISROAMING,
4520                    isRoaming ? "true" : "false");
4521        }
4522    }
4523
4524    /**
4525     * Set the ISO country code equivalent of the current registered
4526     * operator's MCC (Mobile Country Code).
4527     * @param iso the ISO country code equivalent of the current registered
4528     * @hide
4529     */
4530    public void setNetworkCountryIso(String iso) {
4531        int phoneId = getDefaultPhone();
4532        setNetworkCountryIsoForPhone(phoneId, iso);
4533    }
4534
4535    /**
4536     * Set the ISO country code equivalent of the current registered
4537     * operator's MCC (Mobile Country Code).
4538     * @param phoneId which phone you want to set
4539     * @param iso the ISO country code equivalent of the current registered
4540     * @hide
4541     */
4542    public void setNetworkCountryIsoForPhone(int phoneId, String iso) {
4543        if (SubscriptionManager.isValidPhoneId(phoneId)) {
4544            setTelephonyProperty(phoneId,
4545                    TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, iso);
4546        }
4547    }
4548
4549    /**
4550     * Set the network type currently in use on the device for data transmission.
4551     * @param type the network type currently in use on the device for data transmission
4552     * @hide
4553     */
4554    public void setDataNetworkType(int type) {
4555        int phoneId = getDefaultPhone();
4556        setDataNetworkTypeForPhone(phoneId, type);
4557    }
4558
4559    /**
4560     * Set the network type currently in use on the device for data transmission.
4561     * @param phoneId which phone you want to set
4562     * @param type the network type currently in use on the device for data transmission
4563     * @hide
4564     */
4565    public void setDataNetworkTypeForPhone(int phoneId, int type) {
4566        if (SubscriptionManager.isValidPhoneId(phoneId)) {
4567            setTelephonyProperty(phoneId,
4568                    TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
4569                    ServiceState.rilRadioTechnologyToString(type));
4570        }
4571    }
4572
4573    /**
4574     * Returns the subscription ID for the given phone account.
4575     * @hide
4576     */
4577    public int getSubIdForPhoneAccount(PhoneAccount phoneAccount) {
4578        int retval = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
4579        try {
4580            ITelephony service = getITelephony();
4581            if (service != null) {
4582                retval = service.getSubIdForPhoneAccount(phoneAccount);
4583            }
4584        } catch (RemoteException e) {
4585        }
4586
4587        return retval;
4588    }
4589
4590    /**
4591     * Resets telephony manager settings back to factory defaults.
4592     *
4593     * @hide
4594     */
4595    public void factoryReset(int subId) {
4596        try {
4597            Log.d(TAG, "factoryReset: subId=" + subId);
4598            ITelephony telephony = getITelephony();
4599            if (telephony != null)
4600                telephony.factoryReset(subId);
4601        } catch (RemoteException e) {
4602        }
4603    }
4604
4605
4606    /** @hide */
4607    public String getLocaleFromDefaultSim() {
4608        try {
4609            final ITelephony telephony = getITelephony();
4610            if (telephony != null) {
4611                return telephony.getLocaleFromDefaultSim();
4612            }
4613        } catch (RemoteException ex) {
4614        }
4615        return null;
4616    }
4617
4618    /**
4619     * Returns the modem activity info.
4620     * @hide
4621     */
4622    public ModemActivityInfo getModemActivityInfo() {
4623        try {
4624            ITelephony service = getITelephony();
4625            if (service != null) {
4626                return service.getModemActivityInfo();
4627            }
4628        } catch (RemoteException e) {
4629            Log.e(TAG, "Error calling ITelephony#getModemActivityInfo", e);
4630        }
4631        return null;
4632    }
4633}
4634