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