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