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