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