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