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