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