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