TelephonyManager.java revision 63c4c06be44fe8bd4506e6f9f57361d31e947c21
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.SystemApi;
20import android.annotation.SdkConstant;
21import android.annotation.SdkConstant.SdkConstantType;
22import android.content.Context;
23import android.content.Intent;
24import android.os.Bundle;
25import android.os.RemoteException;
26import android.os.ServiceManager;
27import android.os.SystemProperties;
28import android.util.Log;
29
30import com.android.internal.telecomm.ITelecommService;
31import com.android.internal.telephony.IPhoneSubInfo;
32import com.android.internal.telephony.ITelephony;
33import com.android.internal.telephony.ITelephonyRegistry;
34import com.android.internal.telephony.PhoneConstants;
35import com.android.internal.telephony.RILConstants;
36import com.android.internal.telephony.TelephonyProperties;
37
38import java.io.FileInputStream;
39import java.io.IOException;
40import java.util.List;
41import java.util.regex.Matcher;
42import java.util.regex.Pattern;
43
44/**
45 * Provides access to information about the telephony services on
46 * the device. Applications can use the methods in this class to
47 * determine telephony services and states, as well as to access some
48 * types of subscriber information. Applications can also register
49 * a listener to receive notification of telephony state changes.
50 * <p>
51 * You do not instantiate this class directly; instead, you retrieve
52 * a reference to an instance through
53 * {@link android.content.Context#getSystemService
54 * Context.getSystemService(Context.TELEPHONY_SERVICE)}.
55 * <p>
56 * Note that access to some telephony information is
57 * permission-protected. Your application cannot access the protected
58 * information unless it has the appropriate permissions declared in
59 * its manifest file. Where permissions apply, they are noted in the
60 * the methods through which you access the protected information.
61 */
62public class TelephonyManager {
63    private static final String TAG = "TelephonyManager";
64
65    private static final String TELECOMM_SERVICE_NAME = "telecomm";
66
67    private static ITelephonyRegistry sRegistry;
68
69    /**
70     * The allowed states of Wi-Fi calling.
71     *
72     * @hide
73     */
74    public interface WifiCallingChoices {
75        /** Always use Wi-Fi calling */
76        static final int ALWAYS_USE = 0;
77        /** Ask the user whether to use Wi-Fi on every call */
78        static final int ASK_EVERY_TIME = 1;
79        /** Never use Wi-Fi calling */
80        static final int NEVER_USE = 2;
81    }
82
83    private final Context mContext;
84
85    private static String multiSimConfig =
86            SystemProperties.get(TelephonyProperties.PROPERTY_MULTI_SIM_CONFIG);
87
88    /** Enum indicating multisim variants
89     *  DSDS - Dual SIM Dual Standby
90     *  DSDA - Dual SIM Dual Active
91     *  TSTS - Triple SIM Triple Standby
92     **/
93    /** @hide */
94    public enum MultiSimVariants {
95        DSDS,
96        DSDA,
97        TSTS,
98        UNKNOWN
99    };
100
101    /** @hide */
102    public TelephonyManager(Context context) {
103        Context appContext = context.getApplicationContext();
104        if (appContext != null) {
105            mContext = appContext;
106        } else {
107            mContext = context;
108        }
109
110        if (sRegistry == null) {
111            sRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
112                    "telephony.registry"));
113        }
114    }
115
116    /** @hide */
117    private TelephonyManager() {
118        mContext = null;
119    }
120
121    private static TelephonyManager sInstance = new TelephonyManager();
122
123    /** @hide
124    /* @deprecated - use getSystemService as described above */
125    public static TelephonyManager getDefault() {
126        return sInstance;
127    }
128
129
130    /**
131     * Returns the multi SIM variant
132     * Returns DSDS for Dual SIM Dual Standby
133     * Returns DSDA for Dual SIM Dual Active
134     * Returns TSTS for Triple SIM Triple Standby
135     * Returns UNKNOWN for others
136     */
137    /** {@hide} */
138    public MultiSimVariants getMultiSimConfiguration() {
139        String mSimConfig =
140            SystemProperties.get(TelephonyProperties.PROPERTY_MULTI_SIM_CONFIG);
141        if (mSimConfig.equals("dsds")) {
142            return MultiSimVariants.DSDS;
143        } else if (mSimConfig.equals("dsda")) {
144            return MultiSimVariants.DSDA;
145        } else if (mSimConfig.equals("tsts")) {
146            return MultiSimVariants.TSTS;
147        } else {
148            return MultiSimVariants.UNKNOWN;
149        }
150    }
151
152
153    /**
154     * Returns the number of phones available.
155     * Returns 1 for Single standby mode (Single SIM functionality)
156     * Returns 2 for Dual standby mode.(Dual SIM functionality)
157     */
158    /** {@hide} */
159    public int getPhoneCount() {
160        int phoneCount = 1;
161        switch (getMultiSimConfiguration()) {
162            case DSDS:
163            case DSDA:
164                phoneCount = PhoneConstants.MAX_PHONE_COUNT_DUAL_SIM;
165                break;
166            case TSTS:
167                phoneCount = PhoneConstants.MAX_PHONE_COUNT_TRI_SIM;
168                break;
169        }
170        return phoneCount;
171    }
172
173    /** {@hide} */
174    public static TelephonyManager from(Context context) {
175        return (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
176    }
177
178    /** {@hide} */
179    public boolean isMultiSimEnabled() {
180        return (multiSimConfig.equals("dsds") || multiSimConfig.equals("dsda") ||
181            multiSimConfig.equals("tsts"));
182    }
183
184    //
185    // Broadcast Intent actions
186    //
187
188    /**
189     * Broadcast intent action indicating that the call state (cellular)
190     * on the device has changed.
191     *
192     * <p>
193     * The {@link #EXTRA_STATE} extra indicates the new call state.
194     * If the new state is RINGING, a second extra
195     * {@link #EXTRA_INCOMING_NUMBER} provides the incoming phone number as
196     * a String.
197     *
198     * <p class="note">
199     * Requires the READ_PHONE_STATE permission.
200     *
201     * <p class="note">
202     * This was a {@link android.content.Context#sendStickyBroadcast sticky}
203     * broadcast in version 1.0, but it is no longer sticky.
204     * Instead, use {@link #getCallState} to synchronously query the current call state.
205     *
206     * @see #EXTRA_STATE
207     * @see #EXTRA_INCOMING_NUMBER
208     * @see #getCallState
209     */
210    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
211    public static final String ACTION_PHONE_STATE_CHANGED =
212            "android.intent.action.PHONE_STATE";
213
214    /**
215     * The Phone app sends this intent when a user opts to respond-via-message during an incoming
216     * call. By default, the device's default SMS app consumes this message and sends a text message
217     * to the caller. A third party app can also provide this functionality by consuming this Intent
218     * with a {@link android.app.Service} and sending the message using its own messaging system.
219     * <p>The intent contains a URI (available from {@link android.content.Intent#getData})
220     * describing the recipient, using either the {@code sms:}, {@code smsto:}, {@code mms:},
221     * or {@code mmsto:} URI schema. Each of these URI schema carry the recipient information the
222     * same way: the path part of the URI contains the recipient's phone number or a comma-separated
223     * set of phone numbers if there are multiple recipients. For example, {@code
224     * smsto:2065551234}.</p>
225     *
226     * <p>The intent may also contain extras for the message text (in {@link
227     * android.content.Intent#EXTRA_TEXT}) and a message subject
228     * (in {@link android.content.Intent#EXTRA_SUBJECT}).</p>
229     *
230     * <p class="note"><strong>Note:</strong>
231     * The intent-filter that consumes this Intent needs to be in a {@link android.app.Service}
232     * that requires the
233     * permission {@link android.Manifest.permission#SEND_RESPOND_VIA_MESSAGE}.</p>
234     * <p>For example, the service that receives this intent can be declared in the manifest file
235     * with an intent filter like this:</p>
236     * <pre>
237     * &lt;!-- Service that delivers SMS messages received from the phone "quick response" -->
238     * &lt;service android:name=".HeadlessSmsSendService"
239     *          android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE"
240     *          android:exported="true" >
241     *   &lt;intent-filter>
242     *     &lt;action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />
243     *     &lt;category android:name="android.intent.category.DEFAULT" />
244     *     &lt;data android:scheme="sms" />
245     *     &lt;data android:scheme="smsto" />
246     *     &lt;data android:scheme="mms" />
247     *     &lt;data android:scheme="mmsto" />
248     *   &lt;/intent-filter>
249     * &lt;/service></pre>
250     * <p>
251     * Output: nothing.
252     */
253    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
254    public static final String ACTION_RESPOND_VIA_MESSAGE =
255            "android.intent.action.RESPOND_VIA_MESSAGE";
256
257    /**
258     * The lookup key used with the {@link #ACTION_PHONE_STATE_CHANGED} broadcast
259     * for a String containing the new call state.
260     *
261     * @see #EXTRA_STATE_IDLE
262     * @see #EXTRA_STATE_RINGING
263     * @see #EXTRA_STATE_OFFHOOK
264     *
265     * <p class="note">
266     * Retrieve with
267     * {@link android.content.Intent#getStringExtra(String)}.
268     */
269    public static final String EXTRA_STATE = PhoneConstants.STATE_KEY;
270
271    /**
272     * Value used with {@link #EXTRA_STATE} corresponding to
273     * {@link #CALL_STATE_IDLE}.
274     */
275    public static final String EXTRA_STATE_IDLE = PhoneConstants.State.IDLE.toString();
276
277    /**
278     * Value used with {@link #EXTRA_STATE} corresponding to
279     * {@link #CALL_STATE_RINGING}.
280     */
281    public static final String EXTRA_STATE_RINGING = PhoneConstants.State.RINGING.toString();
282
283    /**
284     * Value used with {@link #EXTRA_STATE} corresponding to
285     * {@link #CALL_STATE_OFFHOOK}.
286     */
287    public static final String EXTRA_STATE_OFFHOOK = PhoneConstants.State.OFFHOOK.toString();
288
289    /**
290     * The lookup key used with the {@link #ACTION_PHONE_STATE_CHANGED} broadcast
291     * for a String containing the incoming phone number.
292     * Only valid when the new call state is RINGING.
293     *
294     * <p class="note">
295     * Retrieve with
296     * {@link android.content.Intent#getStringExtra(String)}.
297     */
298    public static final String EXTRA_INCOMING_NUMBER = "incoming_number";
299
300    /**
301     * Broadcast intent action indicating that a precise call state
302     * (cellular) on the device has changed.
303     *
304     * <p>
305     * The {@link #EXTRA_RINGING_CALL_STATE} extra indicates the ringing call state.
306     * The {@link #EXTRA_FOREGROUND_CALL_STATE} extra indicates the foreground call state.
307     * The {@link #EXTRA_BACKGROUND_CALL_STATE} extra indicates the background call state.
308     * The {@link #EXTRA_DISCONNECT_CAUSE} extra indicates the disconnect cause.
309     * The {@link #EXTRA_PRECISE_DISCONNECT_CAUSE} extra indicates the precise disconnect cause.
310     *
311     * <p class="note">
312     * Requires the READ_PRECISE_PHONE_STATE permission.
313     *
314     * @see #EXTRA_RINGING_CALL_STATE
315     * @see #EXTRA_FOREGROUND_CALL_STATE
316     * @see #EXTRA_BACKGROUND_CALL_STATE
317     * @see #EXTRA_DISCONNECT_CAUSE
318     * @see #EXTRA_PRECISE_DISCONNECT_CAUSE
319     *
320     * <p class="note">
321     * Requires the READ_PRECISE_PHONE_STATE permission.
322     *
323     * @hide
324     */
325    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
326    public static final String ACTION_PRECISE_CALL_STATE_CHANGED =
327            "android.intent.action.PRECISE_CALL_STATE";
328
329    /**
330     * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast
331     * for an integer containing the state of the current ringing call.
332     *
333     * @see PreciseCallState#PRECISE_CALL_STATE_NOT_VALID
334     * @see PreciseCallState#PRECISE_CALL_STATE_IDLE
335     * @see PreciseCallState#PRECISE_CALL_STATE_ACTIVE
336     * @see PreciseCallState#PRECISE_CALL_STATE_HOLDING
337     * @see PreciseCallState#PRECISE_CALL_STATE_DIALING
338     * @see PreciseCallState#PRECISE_CALL_STATE_ALERTING
339     * @see PreciseCallState#PRECISE_CALL_STATE_INCOMING
340     * @see PreciseCallState#PRECISE_CALL_STATE_WAITING
341     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTED
342     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTING
343     *
344     * <p class="note">
345     * Retrieve with
346     * {@link android.content.Intent#getIntExtra(String name, int defaultValue)}.
347     *
348     * @hide
349     */
350    public static final String EXTRA_RINGING_CALL_STATE = "ringing_state";
351
352    /**
353     * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast
354     * for an integer containing the state of the current foreground call.
355     *
356     * @see PreciseCallState#PRECISE_CALL_STATE_NOT_VALID
357     * @see PreciseCallState#PRECISE_CALL_STATE_IDLE
358     * @see PreciseCallState#PRECISE_CALL_STATE_ACTIVE
359     * @see PreciseCallState#PRECISE_CALL_STATE_HOLDING
360     * @see PreciseCallState#PRECISE_CALL_STATE_DIALING
361     * @see PreciseCallState#PRECISE_CALL_STATE_ALERTING
362     * @see PreciseCallState#PRECISE_CALL_STATE_INCOMING
363     * @see PreciseCallState#PRECISE_CALL_STATE_WAITING
364     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTED
365     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTING
366     *
367     * <p class="note">
368     * Retrieve with
369     * {@link android.content.Intent#getIntExtra(String name, int defaultValue)}.
370     *
371     * @hide
372     */
373    public static final String EXTRA_FOREGROUND_CALL_STATE = "foreground_state";
374
375    /**
376     * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast
377     * for an integer containing the state of the current background call.
378     *
379     * @see PreciseCallState#PRECISE_CALL_STATE_NOT_VALID
380     * @see PreciseCallState#PRECISE_CALL_STATE_IDLE
381     * @see PreciseCallState#PRECISE_CALL_STATE_ACTIVE
382     * @see PreciseCallState#PRECISE_CALL_STATE_HOLDING
383     * @see PreciseCallState#PRECISE_CALL_STATE_DIALING
384     * @see PreciseCallState#PRECISE_CALL_STATE_ALERTING
385     * @see PreciseCallState#PRECISE_CALL_STATE_INCOMING
386     * @see PreciseCallState#PRECISE_CALL_STATE_WAITING
387     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTED
388     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTING
389     *
390     * <p class="note">
391     * Retrieve with
392     * {@link android.content.Intent#getIntExtra(String name, int defaultValue)}.
393     *
394     * @hide
395     */
396    public static final String EXTRA_BACKGROUND_CALL_STATE = "background_state";
397
398    /**
399     * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast
400     * for an integer containing the disconnect cause.
401     *
402     * @see DisconnectCause
403     *
404     * <p class="note">
405     * Retrieve with
406     * {@link android.content.Intent#getIntExtra(String name, int defaultValue)}.
407     *
408     * @hide
409     */
410    public static final String EXTRA_DISCONNECT_CAUSE = "disconnect_cause";
411
412    /**
413     * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast
414     * for an integer containing the disconnect cause provided by the RIL.
415     *
416     * @see PreciseDisconnectCause
417     *
418     * <p class="note">
419     * Retrieve with
420     * {@link android.content.Intent#getIntExtra(String name, int defaultValue)}.
421     *
422     * @hide
423     */
424    public static final String EXTRA_PRECISE_DISCONNECT_CAUSE = "precise_disconnect_cause";
425
426    /**
427     * Broadcast intent action indicating a data connection has changed,
428     * providing precise information about the connection.
429     *
430     * <p>
431     * The {@link #EXTRA_DATA_STATE} extra indicates the connection state.
432     * The {@link #EXTRA_DATA_NETWORK_TYPE} extra indicates the connection network type.
433     * The {@link #EXTRA_DATA_APN_TYPE} extra indicates the APN type.
434     * The {@link #EXTRA_DATA_APN} extra indicates the APN.
435     * The {@link #EXTRA_DATA_CHANGE_REASON} extra indicates the connection change reason.
436     * The {@link #EXTRA_DATA_IFACE_PROPERTIES} extra indicates the connection interface.
437     * The {@link #EXTRA_DATA_FAILURE_CAUSE} extra indicates the connection fail cause.
438     *
439     * <p class="note">
440     * Requires the READ_PRECISE_PHONE_STATE permission.
441     *
442     * @see #EXTRA_DATA_STATE
443     * @see #EXTRA_DATA_NETWORK_TYPE
444     * @see #EXTRA_DATA_APN_TYPE
445     * @see #EXTRA_DATA_APN
446     * @see #EXTRA_DATA_CHANGE_REASON
447     * @see #EXTRA_DATA_IFACE
448     * @see #EXTRA_DATA_FAILURE_CAUSE
449     * @hide
450     */
451    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
452    public static final String ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED =
453            "android.intent.action.PRECISE_DATA_CONNECTION_STATE_CHANGED";
454
455    /**
456     * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast
457     * for an integer containing the state of the current data connection.
458     *
459     * @see TelephonyManager#DATA_UNKNOWN
460     * @see TelephonyManager#DATA_DISCONNECTED
461     * @see TelephonyManager#DATA_CONNECTING
462     * @see TelephonyManager#DATA_CONNECTED
463     * @see TelephonyManager#DATA_SUSPENDED
464     *
465     * <p class="note">
466     * Retrieve with
467     * {@link android.content.Intent#getIntExtra(String name, int defaultValue)}.
468     *
469     * @hide
470     */
471    public static final String EXTRA_DATA_STATE = PhoneConstants.STATE_KEY;
472
473    /**
474     * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast
475     * for an integer containing the network type.
476     *
477     * @see TelephonyManager#NETWORK_TYPE_UNKNOWN
478     * @see TelephonyManager#NETWORK_TYPE_GPRS
479     * @see TelephonyManager#NETWORK_TYPE_EDGE
480     * @see TelephonyManager#NETWORK_TYPE_UMTS
481     * @see TelephonyManager#NETWORK_TYPE_CDMA
482     * @see TelephonyManager#NETWORK_TYPE_EVDO_0
483     * @see TelephonyManager#NETWORK_TYPE_EVDO_A
484     * @see TelephonyManager#NETWORK_TYPE_1xRTT
485     * @see TelephonyManager#NETWORK_TYPE_HSDPA
486     * @see TelephonyManager#NETWORK_TYPE_HSUPA
487     * @see TelephonyManager#NETWORK_TYPE_HSPA
488     * @see TelephonyManager#NETWORK_TYPE_IDEN
489     * @see TelephonyManager#NETWORK_TYPE_EVDO_B
490     * @see TelephonyManager#NETWORK_TYPE_LTE
491     * @see TelephonyManager#NETWORK_TYPE_EHRPD
492     * @see TelephonyManager#NETWORK_TYPE_HSPAP
493     *
494     * <p class="note">
495     * Retrieve with
496     * {@link android.content.Intent#getIntExtra(String name, int defaultValue)}.
497     *
498     * @hide
499     */
500    public static final String EXTRA_DATA_NETWORK_TYPE = PhoneConstants.DATA_NETWORK_TYPE_KEY;
501
502    /**
503     * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast
504     * for an String containing the data APN type.
505     *
506     * <p class="note">
507     * Retrieve with
508     * {@link android.content.Intent#getStringExtra(String name)}.
509     *
510     * @hide
511     */
512    public static final String EXTRA_DATA_APN_TYPE = PhoneConstants.DATA_APN_TYPE_KEY;
513
514    /**
515     * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast
516     * for an String containing the data APN.
517     *
518     * <p class="note">
519     * Retrieve with
520     * {@link android.content.Intent#getStringExtra(String name)}.
521     *
522     * @hide
523     */
524    public static final String EXTRA_DATA_APN = PhoneConstants.DATA_APN_KEY;
525
526    /**
527     * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast
528     * for an String representation of the change reason.
529     *
530     * <p class="note">
531     * Retrieve with
532     * {@link android.content.Intent#getStringExtra(String name)}.
533     *
534     * @hide
535     */
536    public static final String EXTRA_DATA_CHANGE_REASON = PhoneConstants.STATE_CHANGE_REASON_KEY;
537
538    /**
539     * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast
540     * for an String representation of the data interface.
541     *
542     * <p class="note">
543     * Retrieve with
544     * {@link android.content.Intent#getParcelableExtra(String name)}.
545     *
546     * @hide
547     */
548    public static final String EXTRA_DATA_LINK_PROPERTIES_KEY = PhoneConstants.DATA_LINK_PROPERTIES_KEY;
549
550    /**
551     * The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast
552     * for the data connection fail cause.
553     *
554     * <p class="note">
555     * Retrieve with
556     * {@link android.content.Intent#getStringExtra(String name)}.
557     *
558     * @hide
559     */
560    public static final String EXTRA_DATA_FAILURE_CAUSE = PhoneConstants.DATA_FAILURE_CAUSE_KEY;
561
562    //
563    //
564    // Device Info
565    //
566    //
567
568    /**
569     * Returns the software version number for the device, for example,
570     * the IMEI/SV for GSM phones. Return null if the software version is
571     * not available.
572     *
573     * <p>Requires Permission:
574     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
575     */
576    public String getDeviceSoftwareVersion() {
577        try {
578            return getSubscriberInfo().getDeviceSvn();
579        } catch (RemoteException ex) {
580            return null;
581        } catch (NullPointerException ex) {
582            return null;
583        }
584    }
585
586    /**
587     * Returns the unique device ID, for example, the IMEI for GSM and the MEID
588     * or ESN for CDMA phones. Return null if device ID is not available.
589     *
590     * <p>Requires Permission:
591     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
592     */
593    public String getDeviceId() {
594        return getDeviceId(getDefaultSim());
595    }
596
597    /**
598     * Returns the unique device ID of a subscription, for example, the IMEI for
599     * GSM and the MEID for CDMA phones. Return null if device ID is not available.
600     *
601     * <p>Requires Permission:
602     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
603     *
604     * @param slotId of which deviceID is returned
605     */
606    /** {@hide} */
607    public String getDeviceId(int slotId) {
608        long[] subId = SubscriptionManager.getSubId(slotId);
609        try {
610            return getSubscriberInfo().getDeviceIdUsingSubId(subId[0]);
611        } catch (RemoteException ex) {
612            return null;
613        } catch (NullPointerException ex) {
614            return null;
615        }
616    }
617
618    /**
619     * Returns the current location of the device.
620     *<p>
621     * If there is only one radio in the device and that radio has an LTE connection,
622     * this method will return null. The implementation must not to try add LTE
623     * identifiers into the existing cdma/gsm classes.
624     *<p>
625     * In the future this call will be deprecated.
626     *<p>
627     * @return Current location of the device or null if not available.
628     *
629     * <p>Requires Permission:
630     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
631     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_FINE_LOCATION}.
632     */
633    public CellLocation getCellLocation() {
634        try {
635            Bundle bundle = getITelephony().getCellLocation();
636            if (bundle.isEmpty()) return null;
637            CellLocation cl = CellLocation.newFromBundle(bundle);
638            if (cl.isEmpty())
639                return null;
640            return cl;
641        } catch (RemoteException ex) {
642            return null;
643        } catch (NullPointerException ex) {
644            return null;
645        }
646    }
647
648    /**
649     * Enables location update notifications.  {@link PhoneStateListener#onCellLocationChanged
650     * PhoneStateListener.onCellLocationChanged} will be called on location updates.
651     *
652     * <p>Requires Permission: {@link android.Manifest.permission#CONTROL_LOCATION_UPDATES
653     * CONTROL_LOCATION_UPDATES}
654     *
655     * @hide
656     */
657    public void enableLocationUpdates() {
658            enableLocationUpdates(getDefaultSubscription());
659    }
660
661    /**
662     * Enables location update notifications for a subscription.
663     * {@link PhoneStateListener#onCellLocationChanged
664     * PhoneStateListener.onCellLocationChanged} will be called on location updates.
665     *
666     * <p>Requires Permission: {@link android.Manifest.permission#CONTROL_LOCATION_UPDATES
667     * CONTROL_LOCATION_UPDATES}
668     *
669     * @param subId for which the location updates are enabled
670     */
671    /** @hide */
672    public void enableLocationUpdates(long subId) {
673        try {
674            getITelephony().enableLocationUpdatesUsingSubId(subId);
675        } catch (RemoteException ex) {
676        } catch (NullPointerException ex) {
677        }
678    }
679
680    /**
681     * Disables location update notifications.  {@link PhoneStateListener#onCellLocationChanged
682     * PhoneStateListener.onCellLocationChanged} will be called on location updates.
683     *
684     * <p>Requires Permission: {@link android.Manifest.permission#CONTROL_LOCATION_UPDATES
685     * CONTROL_LOCATION_UPDATES}
686     *
687     * @hide
688     */
689    public void disableLocationUpdates() {
690            disableLocationUpdates(getDefaultSubscription());
691    }
692
693    /** @hide */
694    public void disableLocationUpdates(long subId) {
695        try {
696            getITelephony().disableLocationUpdatesUsingSubId(subId);
697        } catch (RemoteException ex) {
698        } catch (NullPointerException ex) {
699        }
700    }
701
702    /**
703     * Returns the neighboring cell information of the device. The getAllCellInfo is preferred
704     * and use this only if getAllCellInfo return nulls or an empty list.
705     *<p>
706     * In the future this call will be deprecated.
707     *<p>
708     * @return List of NeighboringCellInfo or null if info unavailable.
709     *
710     * <p>Requires Permission:
711     * (@link android.Manifest.permission#ACCESS_COARSE_UPDATES}
712     */
713    public List<NeighboringCellInfo> getNeighboringCellInfo() {
714        try {
715            return getITelephony().getNeighboringCellInfo(mContext.getOpPackageName());
716        } catch (RemoteException ex) {
717            return null;
718        } catch (NullPointerException ex) {
719            return null;
720        }
721    }
722
723    /** No phone radio. */
724    public static final int PHONE_TYPE_NONE = PhoneConstants.PHONE_TYPE_NONE;
725    /** Phone radio is GSM. */
726    public static final int PHONE_TYPE_GSM = PhoneConstants.PHONE_TYPE_GSM;
727    /** Phone radio is CDMA. */
728    public static final int PHONE_TYPE_CDMA = PhoneConstants.PHONE_TYPE_CDMA;
729    /** Phone is via SIP. */
730    public static final int PHONE_TYPE_SIP = PhoneConstants.PHONE_TYPE_SIP;
731
732    /**
733     * Returns the current phone type.
734     * TODO: This is a last minute change and hence hidden.
735     *
736     * @see #PHONE_TYPE_NONE
737     * @see #PHONE_TYPE_GSM
738     * @see #PHONE_TYPE_CDMA
739     * @see #PHONE_TYPE_SIP
740     *
741     * {@hide}
742     */
743    public int getCurrentPhoneType() {
744        return getCurrentPhoneType(getDefaultSubscription());
745    }
746
747    /**
748     * Returns a constant indicating the device phone type for a subscription.
749     *
750     * @see #PHONE_TYPE_NONE
751     * @see #PHONE_TYPE_GSM
752     * @see #PHONE_TYPE_CDMA
753     *
754     * @param subId for which phone type is returned
755     */
756    /** {@hide} */
757    public int getCurrentPhoneType(long subId) {
758
759        try{
760            ITelephony telephony = getITelephony();
761            if (telephony != null) {
762                return telephony.getActivePhoneTypeUsingSubId(subId);
763            } else {
764                // This can happen when the ITelephony interface is not up yet.
765                return getPhoneTypeFromProperty(subId);
766            }
767        } catch (RemoteException ex) {
768            // This shouldn't happen in the normal case, as a backup we
769            // read from the system property.
770            return getPhoneTypeFromProperty(subId);
771        } catch (NullPointerException ex) {
772            // This shouldn't happen in the normal case, as a backup we
773            // read from the system property.
774            return getPhoneTypeFromProperty(subId);
775        }
776    }
777
778    /**
779     * Returns a constant indicating the device phone type.  This
780     * indicates the type of radio used to transmit voice calls.
781     *
782     * @see #PHONE_TYPE_NONE
783     * @see #PHONE_TYPE_GSM
784     * @see #PHONE_TYPE_CDMA
785     * @see #PHONE_TYPE_SIP
786     */
787    public int getPhoneType() {
788        if (!isVoiceCapable()) {
789            return PHONE_TYPE_NONE;
790        }
791        return getCurrentPhoneType();
792    }
793
794    private int getPhoneTypeFromProperty() {
795        return getPhoneTypeFromProperty(getDefaultSubscription());
796    }
797
798    /** {@hide} */
799    private int getPhoneTypeFromProperty(long subId) {
800        String type =
801            getTelephonyProperty
802                (TelephonyProperties.CURRENT_ACTIVE_PHONE, subId, null);
803        if (type != null) {
804            return (Integer.parseInt(type));
805        } else {
806            return getPhoneTypeFromNetworkType(subId);
807        }
808    }
809
810    private int getPhoneTypeFromNetworkType() {
811        return getPhoneTypeFromNetworkType(getDefaultSubscription());
812    }
813
814    /** {@hide} */
815    private int getPhoneTypeFromNetworkType(long subId) {
816        // When the system property CURRENT_ACTIVE_PHONE, has not been set,
817        // use the system property for default network type.
818        // This is a fail safe, and can only happen at first boot.
819        String mode = getTelephonyProperty("ro.telephony.default_network", subId, null);
820        if (mode != null) {
821            return TelephonyManager.getPhoneType(Integer.parseInt(mode));
822        }
823        return TelephonyManager.PHONE_TYPE_NONE;
824    }
825
826    /**
827     * This function returns the type of the phone, depending
828     * on the network mode.
829     *
830     * @param networkMode
831     * @return Phone Type
832     *
833     * @hide
834     */
835    public static int getPhoneType(int networkMode) {
836        switch(networkMode) {
837        case RILConstants.NETWORK_MODE_CDMA:
838        case RILConstants.NETWORK_MODE_CDMA_NO_EVDO:
839        case RILConstants.NETWORK_MODE_EVDO_NO_CDMA:
840            return PhoneConstants.PHONE_TYPE_CDMA;
841
842        case RILConstants.NETWORK_MODE_WCDMA_PREF:
843        case RILConstants.NETWORK_MODE_GSM_ONLY:
844        case RILConstants.NETWORK_MODE_WCDMA_ONLY:
845        case RILConstants.NETWORK_MODE_GSM_UMTS:
846        case RILConstants.NETWORK_MODE_LTE_GSM_WCDMA:
847        case RILConstants.NETWORK_MODE_LTE_WCDMA:
848        case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
849            return PhoneConstants.PHONE_TYPE_GSM;
850
851        // Use CDMA Phone for the global mode including CDMA
852        case RILConstants.NETWORK_MODE_GLOBAL:
853        case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO:
854            return PhoneConstants.PHONE_TYPE_CDMA;
855
856        case RILConstants.NETWORK_MODE_LTE_ONLY:
857            if (getLteOnCdmaModeStatic() == PhoneConstants.LTE_ON_CDMA_TRUE) {
858                return PhoneConstants.PHONE_TYPE_CDMA;
859            } else {
860                return PhoneConstants.PHONE_TYPE_GSM;
861            }
862        default:
863            return PhoneConstants.PHONE_TYPE_GSM;
864        }
865    }
866
867    /**
868     * The contents of the /proc/cmdline file
869     */
870    private static String getProcCmdLine()
871    {
872        String cmdline = "";
873        FileInputStream is = null;
874        try {
875            is = new FileInputStream("/proc/cmdline");
876            byte [] buffer = new byte[2048];
877            int count = is.read(buffer);
878            if (count > 0) {
879                cmdline = new String(buffer, 0, count);
880            }
881        } catch (IOException e) {
882            Rlog.d(TAG, "No /proc/cmdline exception=" + e);
883        } finally {
884            if (is != null) {
885                try {
886                    is.close();
887                } catch (IOException e) {
888                }
889            }
890        }
891        Rlog.d(TAG, "/proc/cmdline=" + cmdline);
892        return cmdline;
893    }
894
895    /** Kernel command line */
896    private static final String sKernelCmdLine = getProcCmdLine();
897
898    /** Pattern for selecting the product type from the kernel command line */
899    private static final Pattern sProductTypePattern =
900        Pattern.compile("\\sproduct_type\\s*=\\s*(\\w+)");
901
902    /** The ProductType used for LTE on CDMA devices */
903    private static final String sLteOnCdmaProductType =
904        SystemProperties.get(TelephonyProperties.PROPERTY_LTE_ON_CDMA_PRODUCT_TYPE, "");
905
906    /**
907     * Return if the current radio is LTE on CDMA. This
908     * is a tri-state return value as for a period of time
909     * the mode may be unknown.
910     *
911     * @return {@link PhoneConstants#LTE_ON_CDMA_UNKNOWN}, {@link PhoneConstants#LTE_ON_CDMA_FALSE}
912     * or {@link PhoneConstants#LTE_ON_CDMA_TRUE}
913     *
914     * @hide
915     */
916    public static int getLteOnCdmaModeStatic() {
917        int retVal;
918        int curVal;
919        String productType = "";
920
921        curVal = SystemProperties.getInt(TelephonyProperties.PROPERTY_LTE_ON_CDMA_DEVICE,
922                    PhoneConstants.LTE_ON_CDMA_UNKNOWN);
923        retVal = curVal;
924        if (retVal == PhoneConstants.LTE_ON_CDMA_UNKNOWN) {
925            Matcher matcher = sProductTypePattern.matcher(sKernelCmdLine);
926            if (matcher.find()) {
927                productType = matcher.group(1);
928                if (sLteOnCdmaProductType.equals(productType)) {
929                    retVal = PhoneConstants.LTE_ON_CDMA_TRUE;
930                } else {
931                    retVal = PhoneConstants.LTE_ON_CDMA_FALSE;
932                }
933            } else {
934                retVal = PhoneConstants.LTE_ON_CDMA_FALSE;
935            }
936        }
937
938        Rlog.d(TAG, "getLteOnCdmaMode=" + retVal + " curVal=" + curVal +
939                " product_type='" + productType +
940                "' lteOnCdmaProductType='" + sLteOnCdmaProductType + "'");
941        return retVal;
942    }
943
944    //
945    //
946    // Current Network
947    //
948    //
949
950    /**
951     * Returns the alphabetic name of current registered operator.
952     * <p>
953     * Availability: Only when user is registered to a network. Result may be
954     * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
955     * on a CDMA network).
956     */
957    public String getNetworkOperatorName() {
958        return getNetworkOperatorName(getDefaultSubscription());
959    }
960
961    /**
962     * Returns the alphabetic name of current registered operator
963     * for a particular subscription.
964     * <p>
965     * Availability: Only when user is registered to a network. Result may be
966     * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
967     * on a CDMA network).
968     * @param subId
969     */
970    /** {@hide} */
971    public String getNetworkOperatorName(long subId) {
972
973        return getTelephonyProperty(TelephonyProperties.PROPERTY_OPERATOR_ALPHA,
974                subId, "");
975    }
976
977    /**
978     * Returns the numeric name (MCC+MNC) of current registered operator.
979     * <p>
980     * Availability: Only when user is registered to a network. Result may be
981     * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
982     * on a CDMA network).
983     */
984    public String getNetworkOperator() {
985        return getNetworkOperator(getDefaultSubscription());
986    }
987
988    /**
989     * Returns the numeric name (MCC+MNC) of current registered operator
990     * for a particular subscription.
991     * <p>
992     * Availability: Only when user is registered to a network. Result may be
993     * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
994     * on a CDMA network).
995     *
996     * @param subId
997     */
998    /** {@hide} */
999   public String getNetworkOperator(long subId) {
1000
1001        return getTelephonyProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC,
1002                subId, "");
1003     }
1004
1005    /**
1006     * Returns true if the device is considered roaming on the current
1007     * network, for GSM purposes.
1008     * <p>
1009     * Availability: Only when user registered to a network.
1010     */
1011    public boolean isNetworkRoaming() {
1012        return isNetworkRoaming(getDefaultSubscription());
1013    }
1014
1015    /**
1016     * Returns true if the device is considered roaming on the current
1017     * network for a subscription.
1018     * <p>
1019     * Availability: Only when user registered to a network.
1020     *
1021     * @param subId
1022     */
1023    /** {@hide} */
1024    public boolean isNetworkRoaming(long subId) {
1025        return "true".equals(getTelephonyProperty(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING,
1026                subId, null));
1027    }
1028
1029    /**
1030     * Returns the ISO country code equivalent of the current registered
1031     * operator's MCC (Mobile Country Code).
1032     * <p>
1033     * Availability: Only when user is registered to a network. Result may be
1034     * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
1035     * on a CDMA network).
1036     */
1037    public String getNetworkCountryIso() {
1038        return getNetworkCountryIso(getDefaultSubscription());
1039    }
1040
1041    /**
1042     * Returns the ISO country code equivalent of the current registered
1043     * operator's MCC (Mobile Country Code) of a subscription.
1044     * <p>
1045     * Availability: Only when user is registered to a network. Result may be
1046     * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if
1047     * on a CDMA network).
1048     *
1049     * @param subId for which Network CountryIso is returned
1050     */
1051    /** {@hide} */
1052    public String getNetworkCountryIso(long subId) {
1053        return getTelephonyProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY,
1054                subId, "");
1055    }
1056
1057    /** Network type is unknown */
1058    public static final int NETWORK_TYPE_UNKNOWN = 0;
1059    /** Current network is GPRS */
1060    public static final int NETWORK_TYPE_GPRS = 1;
1061    /** Current network is EDGE */
1062    public static final int NETWORK_TYPE_EDGE = 2;
1063    /** Current network is UMTS */
1064    public static final int NETWORK_TYPE_UMTS = 3;
1065    /** Current network is CDMA: Either IS95A or IS95B*/
1066    public static final int NETWORK_TYPE_CDMA = 4;
1067    /** Current network is EVDO revision 0*/
1068    public static final int NETWORK_TYPE_EVDO_0 = 5;
1069    /** Current network is EVDO revision A*/
1070    public static final int NETWORK_TYPE_EVDO_A = 6;
1071    /** Current network is 1xRTT*/
1072    public static final int NETWORK_TYPE_1xRTT = 7;
1073    /** Current network is HSDPA */
1074    public static final int NETWORK_TYPE_HSDPA = 8;
1075    /** Current network is HSUPA */
1076    public static final int NETWORK_TYPE_HSUPA = 9;
1077    /** Current network is HSPA */
1078    public static final int NETWORK_TYPE_HSPA = 10;
1079    /** Current network is iDen */
1080    public static final int NETWORK_TYPE_IDEN = 11;
1081    /** Current network is EVDO revision B*/
1082    public static final int NETWORK_TYPE_EVDO_B = 12;
1083    /** Current network is LTE */
1084    public static final int NETWORK_TYPE_LTE = 13;
1085    /** Current network is eHRPD */
1086    public static final int NETWORK_TYPE_EHRPD = 14;
1087    /** Current network is HSPA+ */
1088    public static final int NETWORK_TYPE_HSPAP = 15;
1089    /** Current network is GSM {@hide} */
1090    public static final int NETWORK_TYPE_GSM = 16;
1091
1092    /**
1093     * @return the NETWORK_TYPE_xxxx for current data connection.
1094     */
1095    public int getNetworkType() {
1096        return getDataNetworkType();
1097    }
1098
1099    /**
1100     * Returns a constant indicating the radio technology (network type)
1101     * currently in use on the device for a subscription.
1102     * @return the network type
1103     *
1104     * @param subId for which network type is returned
1105     *
1106     * @see #NETWORK_TYPE_UNKNOWN
1107     * @see #NETWORK_TYPE_GPRS
1108     * @see #NETWORK_TYPE_EDGE
1109     * @see #NETWORK_TYPE_UMTS
1110     * @see #NETWORK_TYPE_HSDPA
1111     * @see #NETWORK_TYPE_HSUPA
1112     * @see #NETWORK_TYPE_HSPA
1113     * @see #NETWORK_TYPE_CDMA
1114     * @see #NETWORK_TYPE_EVDO_0
1115     * @see #NETWORK_TYPE_EVDO_A
1116     * @see #NETWORK_TYPE_EVDO_B
1117     * @see #NETWORK_TYPE_1xRTT
1118     * @see #NETWORK_TYPE_IDEN
1119     * @see #NETWORK_TYPE_LTE
1120     * @see #NETWORK_TYPE_EHRPD
1121     * @see #NETWORK_TYPE_HSPAP
1122     */
1123    /** {@hide} */
1124   public int getNetworkType(long subId) {
1125       try {
1126           ITelephony telephony = getITelephony();
1127           if (telephony != null) {
1128               return telephony.getNetworkTypeUsingSubId(subId);
1129           } else {
1130               // This can happen when the ITelephony interface is not up yet.
1131               return NETWORK_TYPE_UNKNOWN;
1132           }
1133       } catch(RemoteException ex) {
1134           // This shouldn't happen in the normal case
1135           return NETWORK_TYPE_UNKNOWN;
1136       } catch (NullPointerException ex) {
1137           // This could happen before phone restarts due to crashing
1138           return NETWORK_TYPE_UNKNOWN;
1139       }
1140   }
1141
1142    /**
1143     * Returns a constant indicating the radio technology (network type)
1144     * currently in use on the device for data transmission.
1145     * @return the network type
1146     *
1147     * @see #NETWORK_TYPE_UNKNOWN
1148     * @see #NETWORK_TYPE_GPRS
1149     * @see #NETWORK_TYPE_EDGE
1150     * @see #NETWORK_TYPE_UMTS
1151     * @see #NETWORK_TYPE_HSDPA
1152     * @see #NETWORK_TYPE_HSUPA
1153     * @see #NETWORK_TYPE_HSPA
1154     * @see #NETWORK_TYPE_CDMA
1155     * @see #NETWORK_TYPE_EVDO_0
1156     * @see #NETWORK_TYPE_EVDO_A
1157     * @see #NETWORK_TYPE_EVDO_B
1158     * @see #NETWORK_TYPE_1xRTT
1159     * @see #NETWORK_TYPE_IDEN
1160     * @see #NETWORK_TYPE_LTE
1161     * @see #NETWORK_TYPE_EHRPD
1162     * @see #NETWORK_TYPE_HSPAP
1163     *
1164     * @hide
1165     */
1166    public int getDataNetworkType() {
1167        return getDataNetworkType(getDefaultSubscription());
1168    }
1169
1170    /**
1171     * Returns a constant indicating the radio technology (network type)
1172     * currently in use on the device for data transmission for a subscription
1173     * @return the network type
1174     *
1175     * @param subId for which network type is returned
1176     */
1177    /** {@hide} */
1178    public int getDataNetworkType(long subId) {
1179        try{
1180            ITelephony telephony = getITelephony();
1181            if (telephony != null) {
1182                return telephony.getDataNetworkTypeUsingSubId(subId);
1183            } else {
1184                // This can happen when the ITelephony interface is not up yet.
1185                return NETWORK_TYPE_UNKNOWN;
1186            }
1187        } catch(RemoteException ex) {
1188            // This shouldn't happen in the normal case
1189            return NETWORK_TYPE_UNKNOWN;
1190        } catch (NullPointerException ex) {
1191            // This could happen before phone restarts due to crashing
1192            return NETWORK_TYPE_UNKNOWN;
1193        }
1194    }
1195
1196    /**
1197     * Returns the NETWORK_TYPE_xxxx for voice
1198     *
1199     * @hide
1200     */
1201    public int getVoiceNetworkType() {
1202        return getVoiceNetworkType(getDefaultSubscription());
1203    }
1204
1205    /**
1206     * Returns the NETWORK_TYPE_xxxx for voice for a subId
1207     *
1208     */
1209    /** {@hide} */
1210    public int getVoiceNetworkType(long subId) {
1211        try{
1212            ITelephony telephony = getITelephony();
1213            if (telephony != null) {
1214                return telephony.getVoiceNetworkTypeUsingSubId(subId);
1215            } else {
1216                // This can happen when the ITelephony interface is not up yet.
1217                return NETWORK_TYPE_UNKNOWN;
1218            }
1219        } catch(RemoteException ex) {
1220            // This shouldn't happen in the normal case
1221            return NETWORK_TYPE_UNKNOWN;
1222        } catch (NullPointerException ex) {
1223            // This could happen before phone restarts due to crashing
1224            return NETWORK_TYPE_UNKNOWN;
1225        }
1226    }
1227
1228    /** Unknown network class. {@hide} */
1229    public static final int NETWORK_CLASS_UNKNOWN = 0;
1230    /** Class of broadly defined "2G" networks. {@hide} */
1231    public static final int NETWORK_CLASS_2_G = 1;
1232    /** Class of broadly defined "3G" networks. {@hide} */
1233    public static final int NETWORK_CLASS_3_G = 2;
1234    /** Class of broadly defined "4G" networks. {@hide} */
1235    public static final int NETWORK_CLASS_4_G = 3;
1236
1237    /**
1238     * Return general class of network type, such as "3G" or "4G". In cases
1239     * where classification is contentious, this method is conservative.
1240     *
1241     * @hide
1242     */
1243    public static int getNetworkClass(int networkType) {
1244        switch (networkType) {
1245            case NETWORK_TYPE_GPRS:
1246            case NETWORK_TYPE_GSM:
1247            case NETWORK_TYPE_EDGE:
1248            case NETWORK_TYPE_CDMA:
1249            case NETWORK_TYPE_1xRTT:
1250            case NETWORK_TYPE_IDEN:
1251                return NETWORK_CLASS_2_G;
1252            case NETWORK_TYPE_UMTS:
1253            case NETWORK_TYPE_EVDO_0:
1254            case NETWORK_TYPE_EVDO_A:
1255            case NETWORK_TYPE_HSDPA:
1256            case NETWORK_TYPE_HSUPA:
1257            case NETWORK_TYPE_HSPA:
1258            case NETWORK_TYPE_EVDO_B:
1259            case NETWORK_TYPE_EHRPD:
1260            case NETWORK_TYPE_HSPAP:
1261                return NETWORK_CLASS_3_G;
1262            case NETWORK_TYPE_LTE:
1263                return NETWORK_CLASS_4_G;
1264            default:
1265                return NETWORK_CLASS_UNKNOWN;
1266        }
1267    }
1268
1269    /**
1270     * Returns a string representation of the radio technology (network type)
1271     * currently in use on the device.
1272     * @return the name of the radio technology
1273     *
1274     * @hide pending API council review
1275     */
1276    public String getNetworkTypeName() {
1277        return getNetworkTypeName(getNetworkType());
1278    }
1279
1280    /**
1281     * Returns a string representation of the radio technology (network type)
1282     * currently in use on the device.
1283     * @param subId for which network type is returned
1284     * @return the name of the radio technology
1285     *
1286     */
1287    /** {@hide} */
1288    public static String getNetworkTypeName(int type) {
1289        switch (type) {
1290            case NETWORK_TYPE_GPRS:
1291                return "GPRS";
1292            case NETWORK_TYPE_EDGE:
1293                return "EDGE";
1294            case NETWORK_TYPE_UMTS:
1295                return "UMTS";
1296            case NETWORK_TYPE_HSDPA:
1297                return "HSDPA";
1298            case NETWORK_TYPE_HSUPA:
1299                return "HSUPA";
1300            case NETWORK_TYPE_HSPA:
1301                return "HSPA";
1302            case NETWORK_TYPE_CDMA:
1303                return "CDMA";
1304            case NETWORK_TYPE_EVDO_0:
1305                return "CDMA - EvDo rev. 0";
1306            case NETWORK_TYPE_EVDO_A:
1307                return "CDMA - EvDo rev. A";
1308            case NETWORK_TYPE_EVDO_B:
1309                return "CDMA - EvDo rev. B";
1310            case NETWORK_TYPE_1xRTT:
1311                return "CDMA - 1xRTT";
1312            case NETWORK_TYPE_LTE:
1313                return "LTE";
1314            case NETWORK_TYPE_EHRPD:
1315                return "CDMA - eHRPD";
1316            case NETWORK_TYPE_IDEN:
1317                return "iDEN";
1318            case NETWORK_TYPE_HSPAP:
1319                return "HSPA+";
1320            case NETWORK_TYPE_GSM:
1321                return "GSM";
1322            default:
1323                return "UNKNOWN";
1324        }
1325    }
1326
1327    //
1328    //
1329    // SIM Card
1330    //
1331    //
1332
1333    /** SIM card state: Unknown. Signifies that the SIM is in transition
1334     *  between states. For example, when the user inputs the SIM pin
1335     *  under PIN_REQUIRED state, a query for sim status returns
1336     *  this state before turning to SIM_STATE_READY. */
1337    public static final int SIM_STATE_UNKNOWN = 0;
1338    /** SIM card state: no SIM card is available in the device */
1339    public static final int SIM_STATE_ABSENT = 1;
1340    /** SIM card state: Locked: requires the user's SIM PIN to unlock */
1341    public static final int SIM_STATE_PIN_REQUIRED = 2;
1342    /** SIM card state: Locked: requires the user's SIM PUK to unlock */
1343    public static final int SIM_STATE_PUK_REQUIRED = 3;
1344    /** SIM card state: Locked: requries a network PIN to unlock */
1345    public static final int SIM_STATE_NETWORK_LOCKED = 4;
1346    /** SIM card state: Ready */
1347    public static final int SIM_STATE_READY = 5;
1348    /** SIM card state: SIM Card Error, Sim Card is present but faulty
1349     *@hide
1350     */
1351    public static final int SIM_STATE_CARD_IO_ERROR = 6;
1352
1353    /**
1354     * @return true if a ICC card is present
1355     */
1356    public boolean hasIccCard() {
1357        return hasIccCard(getDefaultSim());
1358    }
1359
1360    /**
1361     * @return true if a ICC card is present for a subscription
1362     *
1363     * @param slotId for which icc card presence is checked
1364     */
1365    /** {@hide} */
1366    // FIXME Input argument slotId should be of type int
1367    public boolean hasIccCard(long slotId) {
1368
1369        try {
1370            return getITelephony().hasIccCardUsingSlotId(slotId);
1371        } catch (RemoteException ex) {
1372            // Assume no ICC card if remote exception which shouldn't happen
1373            return false;
1374        } catch (NullPointerException ex) {
1375            // This could happen before phone restarts due to crashing
1376            return false;
1377        }
1378    }
1379
1380    /**
1381     * Returns a constant indicating the state of the
1382     * device SIM card.
1383     *
1384     * @see #SIM_STATE_UNKNOWN
1385     * @see #SIM_STATE_ABSENT
1386     * @see #SIM_STATE_PIN_REQUIRED
1387     * @see #SIM_STATE_PUK_REQUIRED
1388     * @see #SIM_STATE_NETWORK_LOCKED
1389     * @see #SIM_STATE_READY
1390     * @see #SIM_STATE_CARD_IO_ERROR
1391     */
1392    public int getSimState() {
1393        return getSimState(getDefaultSim());
1394    }
1395
1396    /**
1397     * Returns a constant indicating the state of the
1398     * device SIM card in a slot.
1399     *
1400     * @param slotId
1401     *
1402     * @see #SIM_STATE_UNKNOWN
1403     * @see #SIM_STATE_ABSENT
1404     * @see #SIM_STATE_PIN_REQUIRED
1405     * @see #SIM_STATE_PUK_REQUIRED
1406     * @see #SIM_STATE_NETWORK_LOCKED
1407     * @see #SIM_STATE_READY
1408     */
1409    /** {@hide} */
1410    // FIXME the argument to pass is subId ??
1411    public int getSimState(int slotId) {
1412        long[] subId = SubscriptionManager.getSubId(slotId);
1413        if (subId == null) {
1414            return SIM_STATE_ABSENT;
1415        }
1416        // FIXME Do not use a property to determine SIM_STATE, call
1417        // appropriate method on some object.
1418        String prop =
1419            getTelephonyProperty(TelephonyProperties.PROPERTY_SIM_STATE, subId[0], "");
1420        if ("ABSENT".equals(prop)) {
1421            return SIM_STATE_ABSENT;
1422        }
1423        else if ("PIN_REQUIRED".equals(prop)) {
1424            return SIM_STATE_PIN_REQUIRED;
1425        }
1426        else if ("PUK_REQUIRED".equals(prop)) {
1427            return SIM_STATE_PUK_REQUIRED;
1428        }
1429        else if ("NETWORK_LOCKED".equals(prop)) {
1430            return SIM_STATE_NETWORK_LOCKED;
1431        }
1432        else if ("READY".equals(prop)) {
1433            return SIM_STATE_READY;
1434        }
1435        else if ("CARD_IO_ERROR".equals(prop)) {
1436            return SIM_STATE_CARD_IO_ERROR;
1437        }
1438        else {
1439            return SIM_STATE_UNKNOWN;
1440        }
1441    }
1442
1443    /**
1444     * Returns the MCC+MNC (mobile country code + mobile network code) of the
1445     * provider of the SIM. 5 or 6 decimal digits.
1446     * <p>
1447     * Availability: SIM state must be {@link #SIM_STATE_READY}
1448     *
1449     * @see #getSimState
1450     */
1451    public String getSimOperator() {
1452        long subId = getDefaultSubscription();
1453        Rlog.d(TAG, "getSimOperator(): default subId=" + subId);
1454        return getSimOperator(subId);
1455    }
1456
1457    /**
1458     * Returns the MCC+MNC (mobile country code + mobile network code) of the
1459     * provider of the SIM for a particular subscription. 5 or 6 decimal digits.
1460     * <p>
1461     * Availability: SIM state must be {@link #SIM_STATE_READY}
1462     *
1463     * @see #getSimState
1464     *
1465     * @param subId for which SimOperator is returned
1466     */
1467    /** {@hide} */
1468    public String getSimOperator(long subId) {
1469        String operator = getTelephonyProperty(TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC,
1470                subId, "");
1471        Rlog.d(TAG, "getSimOperator: subId=" + subId + " operator=" + operator);
1472        return operator;
1473    }
1474
1475    /**
1476     * Returns the Service Provider Name (SPN).
1477     * <p>
1478     * Availability: SIM state must be {@link #SIM_STATE_READY}
1479     *
1480     * @see #getSimState
1481     */
1482    public String getSimOperatorName() {
1483        return getSimOperatorName(getDefaultSubscription());
1484    }
1485
1486    /**
1487     * Returns the Service Provider Name (SPN).
1488     * <p>
1489     * Availability: SIM state must be {@link #SIM_STATE_READY}
1490     *
1491     * @see #getSimState
1492     *
1493     * @param subId for which SimOperatorName is returned
1494     */
1495    /** {@hide} */
1496    public String getSimOperatorName(long subId) {
1497        return getTelephonyProperty(TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA,
1498                subId, "");
1499    }
1500
1501    /**
1502     * Returns the ISO country code equivalent for the SIM provider's country code.
1503     */
1504    public String getSimCountryIso() {
1505        return getSimCountryIso(getDefaultSubscription());
1506    }
1507
1508    /**
1509     * Returns the ISO country code equivalent for the SIM provider's country code.
1510     *
1511     * @param subId for which SimCountryIso is returned
1512     */
1513    /** {@hide} */
1514    public String getSimCountryIso(long subId) {
1515        return getTelephonyProperty(TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY,
1516                subId, "");
1517    }
1518
1519    /**
1520     * Returns the serial number of the SIM, if applicable. Return null if it is
1521     * unavailable.
1522     * <p>
1523     * Requires Permission:
1524     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1525     */
1526    public String getSimSerialNumber() {
1527         return getSimSerialNumber(getDefaultSubscription());
1528    }
1529
1530    /**
1531     * Returns the serial number for the given subscription, if applicable. Return null if it is
1532     * unavailable.
1533     * <p>
1534     * @param subId for which Sim Serial number is returned
1535     * Requires Permission:
1536     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1537     */
1538    /** {@hide} */
1539    public String getSimSerialNumber(long subId) {
1540        try {
1541            return getSubscriberInfo().getIccSerialNumberUsingSubId(subId);
1542        } catch (RemoteException ex) {
1543            return null;
1544        } catch (NullPointerException ex) {
1545            // This could happen before phone restarts due to crashing
1546            return null;
1547        }
1548    }
1549
1550    /**
1551     * Return if the current radio is LTE on CDMA. This
1552     * is a tri-state return value as for a period of time
1553     * the mode may be unknown.
1554     *
1555     * @return {@link PhoneConstants#LTE_ON_CDMA_UNKNOWN}, {@link PhoneConstants#LTE_ON_CDMA_FALSE}
1556     * or {@link PhoneConstants#LTE_ON_CDMA_TRUE}
1557     *
1558     * @hide
1559     */
1560    public int getLteOnCdmaMode() {
1561        return getLteOnCdmaMode(getDefaultSubscription());
1562    }
1563
1564    /**
1565     * Return if the current radio is LTE on CDMA for Subscription. This
1566     * is a tri-state return value as for a period of time
1567     * the mode may be unknown.
1568     *
1569     * @param subId for which radio is LTE on CDMA is returned
1570     * @return {@link PhoneConstants#LTE_ON_CDMA_UNKNOWN}, {@link PhoneConstants#LTE_ON_CDMA_FALSE}
1571     * or {@link PhoneConstants#LTE_ON_CDMA_TRUE}
1572     *
1573     */
1574    /** {@hide} */
1575    public int getLteOnCdmaMode(long subId) {
1576        try {
1577            return getITelephony().getLteOnCdmaModeUsingSubId(subId);
1578        } catch (RemoteException ex) {
1579            // Assume no ICC card if remote exception which shouldn't happen
1580            return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
1581        } catch (NullPointerException ex) {
1582            // This could happen before phone restarts due to crashing
1583            return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
1584        }
1585    }
1586
1587    //
1588    //
1589    // Subscriber Info
1590    //
1591    //
1592
1593    /**
1594     * Returns the unique subscriber ID, for example, the IMSI for a GSM phone.
1595     * Return null if it is unavailable.
1596     * <p>
1597     * Requires Permission:
1598     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1599     */
1600    public String getSubscriberId() {
1601        return getSubscriberId(getDefaultSubscription());
1602    }
1603
1604    /**
1605     * Returns the unique subscriber ID, for example, the IMSI for a GSM phone
1606     * for a subscription.
1607     * Return null if it is unavailable.
1608     * <p>
1609     * Requires Permission:
1610     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1611     *
1612     * @param subId whose subscriber id is returned
1613     */
1614    /** {@hide} */
1615    public String getSubscriberId(long subId) {
1616        try {
1617            return getSubscriberInfo().getSubscriberIdUsingSubId(subId);
1618        } catch (RemoteException ex) {
1619            return null;
1620        } catch (NullPointerException ex) {
1621            // This could happen before phone restarts due to crashing
1622            return null;
1623        }
1624    }
1625
1626    /**
1627     * Returns the Group Identifier Level1 for a GSM phone.
1628     * Return null if it is unavailable.
1629     * <p>
1630     * Requires Permission:
1631     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1632     */
1633    public String getGroupIdLevel1() {
1634        try {
1635            return getSubscriberInfo().getGroupIdLevel1();
1636        } catch (RemoteException ex) {
1637            return null;
1638        } catch (NullPointerException ex) {
1639            // This could happen before phone restarts due to crashing
1640            return null;
1641        }
1642    }
1643
1644    /**
1645     * Returns the Group Identifier Level1 for a GSM phone for a particular subscription.
1646     * Return null if it is unavailable.
1647     * <p>
1648     * Requires Permission:
1649     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1650     *
1651     * @param subscription whose subscriber id is returned
1652     */
1653    /** {@hide} */
1654    public String getGroupIdLevel1(long subId) {
1655        try {
1656            return getSubscriberInfo().getGroupIdLevel1UsingSubId(subId);
1657        } catch (RemoteException ex) {
1658            return null;
1659        } catch (NullPointerException ex) {
1660            // This could happen before phone restarts due to crashing
1661            return null;
1662        }
1663    }
1664
1665    /**
1666     * Returns the phone number string for line 1, for example, the MSISDN
1667     * for a GSM phone. Return null if it is unavailable.
1668     * <p>
1669     * Requires Permission:
1670     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1671     */
1672    public String getLine1Number() {
1673        return getLine1Number(getDefaultSubscription());
1674    }
1675
1676    /**
1677     * Returns the phone number string for line 1, for example, the MSISDN
1678     * for a GSM phone for a particular subscription. Return null if it is unavailable.
1679     * <p>
1680     * Requires Permission:
1681     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1682     *
1683     * @param subId whose phone number for line 1 is returned
1684     */
1685    /** {@hide} */
1686    public String getLine1Number(long subId) {
1687        String number = null;
1688        try {
1689            number = getITelephony().getLine1NumberForDisplay(subId);
1690        } catch (RemoteException ex) {
1691        } catch (NullPointerException ex) {
1692        }
1693        if (number != null) {
1694            return number;
1695        }
1696        try {
1697            return getSubscriberInfo().getLine1NumberUsingSubId(subId);
1698        } catch (RemoteException ex) {
1699            return null;
1700        } catch (NullPointerException ex) {
1701            // This could happen before phone restarts due to crashing
1702            return null;
1703        }
1704    }
1705
1706    /**
1707     * Set the phone number string and its alphatag for line 1 for display
1708     * purpose only, for example, displayed in Phone Status. It won't change
1709     * the actual MSISDN/MDN. This setting won't be persisted during power cycle
1710     * and it should be set again after reboot.
1711     * <p>
1712     * Requires Permission:
1713     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
1714     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
1715     *
1716     * @param alphaTag alpha-tagging of the dailing nubmer
1717     * @param number The dialing number
1718     */
1719    public void setLine1NumberForDisplay(String alphaTag, String number) {
1720        setLine1NumberForDisplay(getDefaultSubscription(), alphaTag, number);
1721    }
1722
1723    /**
1724     * Set the phone number string and its alphatag for line 1 for display
1725     * purpose only, for example, displayed in Phone Status. It won't change
1726     * the actual MSISDN/MDN. This setting won't be persisted during power cycle
1727     * and it should be set again after reboot.
1728     * <p>
1729     * Requires Permission:
1730     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
1731     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
1732     *
1733     * @param subId the subscriber that the alphatag and dialing number belongs to.
1734     * @param alphaTag alpha-tagging of the dailing nubmer
1735     * @param number The dialing number
1736     */
1737    public void setLine1NumberForDisplay(long subId, String alphaTag, String number) {
1738        try {
1739            getITelephony().setLine1NumberForDisplay(subId, alphaTag, number);
1740        } catch (RemoteException ex) {
1741        } catch (NullPointerException ex) {
1742        }
1743    }
1744
1745    /**
1746     * Returns the alphabetic identifier associated with the line 1 number.
1747     * Return null if it is unavailable.
1748     * <p>
1749     * Requires Permission:
1750     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1751     * @hide
1752     * nobody seems to call this.
1753     */
1754    public String getLine1AlphaTag() {
1755        return getLine1AlphaTag(getDefaultSubscription());
1756    }
1757
1758    /**
1759     * Returns the alphabetic identifier associated with the line 1 number
1760     * for a subscription.
1761     * Return null if it is unavailable.
1762     * <p>
1763     * Requires Permission:
1764     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1765     * @param subId whose alphabetic identifier associated with line 1 is returned
1766     * nobody seems to call this.
1767     */
1768    /** {@hide} */
1769    public String getLine1AlphaTag(long subId) {
1770        String alphaTag = null;
1771        try {
1772            alphaTag = getITelephony().getLine1AlphaTagForDisplay(subId);
1773        } catch (RemoteException ex) {
1774        } catch (NullPointerException ex) {
1775        }
1776        if (alphaTag != null) {
1777            return alphaTag;
1778        }
1779        try {
1780            return getSubscriberInfo().getLine1AlphaTagUsingSubId(subId);
1781        } catch (RemoteException ex) {
1782            return null;
1783        } catch (NullPointerException ex) {
1784            // This could happen before phone restarts due to crashing
1785            return null;
1786        }
1787    }
1788
1789    /**
1790     * Returns the MSISDN string.
1791     * for a GSM phone. Return null if it is unavailable.
1792     * <p>
1793     * Requires Permission:
1794     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1795     *
1796     * @hide
1797     */
1798    public String getMsisdn() {
1799        return getMsisdn(getDefaultSubscription());
1800    }
1801
1802    /**
1803     * Returns the MSISDN string.
1804     * for a GSM phone. Return null if it is unavailable.
1805     * <p>
1806     * Requires Permission:
1807     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1808     *
1809     * @param subId for which msisdn is returned
1810     */
1811    /** {@hide} */
1812    public String getMsisdn(long subId) {
1813        try {
1814            return getSubscriberInfo().getMsisdnUsingSubId(subId);
1815        } catch (RemoteException ex) {
1816            return null;
1817        } catch (NullPointerException ex) {
1818            // This could happen before phone restarts due to crashing
1819            return null;
1820        }
1821    }
1822
1823    /**
1824     * Returns the voice mail number. Return null if it is unavailable.
1825     * <p>
1826     * Requires Permission:
1827     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1828     */
1829    public String getVoiceMailNumber() {
1830        return getVoiceMailNumber(getDefaultSubscription());
1831    }
1832
1833    /**
1834     * Returns the voice mail number for a subscription.
1835     * Return null if it is unavailable.
1836     * <p>
1837     * Requires Permission:
1838     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1839     * @param subId whose voice mail number is returned
1840     */
1841    /** {@hide} */
1842    public String getVoiceMailNumber(long subId) {
1843        try {
1844            return getSubscriberInfo().getVoiceMailNumberUsingSubId(subId);
1845        } catch (RemoteException ex) {
1846            return null;
1847        } catch (NullPointerException ex) {
1848            // This could happen before phone restarts due to crashing
1849            return null;
1850        }
1851    }
1852
1853    /**
1854     * Returns the complete voice mail number. Return null if it is unavailable.
1855     * <p>
1856     * Requires Permission:
1857     *   {@link android.Manifest.permission#CALL_PRIVILEGED CALL_PRIVILEGED}
1858     *
1859     * @hide
1860     */
1861    public String getCompleteVoiceMailNumber() {
1862        return getCompleteVoiceMailNumber(getDefaultSubscription());
1863    }
1864
1865    /**
1866     * Returns the complete voice mail number. Return null if it is unavailable.
1867     * <p>
1868     * Requires Permission:
1869     *   {@link android.Manifest.permission#CALL_PRIVILEGED CALL_PRIVILEGED}
1870     *
1871     * @param subId
1872     */
1873    /** {@hide} */
1874    public String getCompleteVoiceMailNumber(long subId) {
1875        try {
1876            return getSubscriberInfo().getCompleteVoiceMailNumberUsingSubId(subId);
1877        } catch (RemoteException ex) {
1878            return null;
1879        } catch (NullPointerException ex) {
1880            // This could happen before phone restarts due to crashing
1881            return null;
1882        }
1883    }
1884
1885    /**
1886     * Returns the voice mail count. Return 0 if unavailable.
1887     * <p>
1888     * Requires Permission:
1889     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1890     * @hide
1891     */
1892    public int getVoiceMessageCount() {
1893        return getVoiceMessageCount(getDefaultSubscription());
1894    }
1895
1896    /**
1897     * Returns the voice mail count for a subscription. Return 0 if unavailable.
1898     * <p>
1899     * Requires Permission:
1900     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1901     * @param subId whose voice message count is returned
1902     */
1903    /** {@hide} */
1904    public int getVoiceMessageCount(long subId) {
1905        try {
1906            return getITelephony().getVoiceMessageCountUsingSubId(subId);
1907        } catch (RemoteException ex) {
1908            return 0;
1909        } catch (NullPointerException ex) {
1910            // This could happen before phone restarts due to crashing
1911            return 0;
1912        }
1913    }
1914
1915    /**
1916     * Retrieves the alphabetic identifier associated with the voice
1917     * mail number.
1918     * <p>
1919     * Requires Permission:
1920     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1921     */
1922    public String getVoiceMailAlphaTag() {
1923        return getVoiceMailAlphaTag(getDefaultSubscription());
1924    }
1925
1926    /**
1927     * Retrieves the alphabetic identifier associated with the voice
1928     * mail number for a subscription.
1929     * <p>
1930     * Requires Permission:
1931     * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
1932     * @param subId whose alphabetic identifier associated with the
1933     * voice mail number is returned
1934     */
1935    /** {@hide} */
1936    public String getVoiceMailAlphaTag(long subId) {
1937        try {
1938            return getSubscriberInfo().getVoiceMailAlphaTagUsingSubId(subId);
1939        } catch (RemoteException ex) {
1940            return null;
1941        } catch (NullPointerException ex) {
1942            // This could happen before phone restarts due to crashing
1943            return null;
1944        }
1945    }
1946
1947    /**
1948     * Returns the IMS private user identity (IMPI) that was loaded from the ISIM.
1949     * @return the IMPI, or null if not present or not loaded
1950     * @hide
1951     */
1952    public String getIsimImpi() {
1953        try {
1954            return getSubscriberInfo().getIsimImpi();
1955        } catch (RemoteException ex) {
1956            return null;
1957        } catch (NullPointerException ex) {
1958            // This could happen before phone restarts due to crashing
1959            return null;
1960        }
1961    }
1962
1963    /**
1964     * Returns the IMS home network domain name that was loaded from the ISIM.
1965     * @return the IMS domain name, or null if not present or not loaded
1966     * @hide
1967     */
1968    public String getIsimDomain() {
1969        try {
1970            return getSubscriberInfo().getIsimDomain();
1971        } catch (RemoteException ex) {
1972            return null;
1973        } catch (NullPointerException ex) {
1974            // This could happen before phone restarts due to crashing
1975            return null;
1976        }
1977    }
1978
1979    /**
1980     * Returns the IMS public user identities (IMPU) that were loaded from the ISIM.
1981     * @return an array of IMPU strings, with one IMPU per string, or null if
1982     *      not present or not loaded
1983     * @hide
1984     */
1985    public String[] getIsimImpu() {
1986        try {
1987            return getSubscriberInfo().getIsimImpu();
1988        } catch (RemoteException ex) {
1989            return null;
1990        } catch (NullPointerException ex) {
1991            // This could happen before phone restarts due to crashing
1992            return null;
1993        }
1994    }
1995
1996    private IPhoneSubInfo getSubscriberInfo() {
1997        // get it each time because that process crashes a lot
1998        return IPhoneSubInfo.Stub.asInterface(ServiceManager.getService("iphonesubinfo"));
1999    }
2000
2001    /** Device call state: No activity. */
2002    public static final int CALL_STATE_IDLE = 0;
2003    /** Device call state: Ringing. A new call arrived and is
2004     *  ringing or waiting. In the latter case, another call is
2005     *  already active. */
2006    public static final int CALL_STATE_RINGING = 1;
2007    /** Device call state: Off-hook. At least one call exists
2008      * that is dialing, active, or on hold, and no calls are ringing
2009      * or waiting. */
2010    public static final int CALL_STATE_OFFHOOK = 2;
2011
2012    /**
2013     * Returns a constant indicating the call state (cellular) on the device.
2014     */
2015    public int getCallState() {
2016        return getCallState(getDefaultSubscription());
2017    }
2018
2019    /**
2020     * Returns a constant indicating the call state (cellular) on the device
2021     * for a subscription.
2022     *
2023     * @param subId whose call state is returned
2024     */
2025    /** {@hide} */
2026    public int getCallState(long subId) {
2027        try {
2028            return getITelephony().getCallStateUsingSubId(subId);
2029        } catch (RemoteException ex) {
2030            // the phone process is restarting.
2031            return CALL_STATE_IDLE;
2032        } catch (NullPointerException ex) {
2033          // the phone process is restarting.
2034          return CALL_STATE_IDLE;
2035      }
2036    }
2037
2038    /** Data connection activity: No traffic. */
2039    public static final int DATA_ACTIVITY_NONE = 0x00000000;
2040    /** Data connection activity: Currently receiving IP PPP traffic. */
2041    public static final int DATA_ACTIVITY_IN = 0x00000001;
2042    /** Data connection activity: Currently sending IP PPP traffic. */
2043    public static final int DATA_ACTIVITY_OUT = 0x00000002;
2044    /** Data connection activity: Currently both sending and receiving
2045     *  IP PPP traffic. */
2046    public static final int DATA_ACTIVITY_INOUT = DATA_ACTIVITY_IN | DATA_ACTIVITY_OUT;
2047    /**
2048     * Data connection is active, but physical link is down
2049     */
2050    public static final int DATA_ACTIVITY_DORMANT = 0x00000004;
2051
2052    /**
2053     * Returns a constant indicating the type of activity on a data connection
2054     * (cellular).
2055     *
2056     * @see #DATA_ACTIVITY_NONE
2057     * @see #DATA_ACTIVITY_IN
2058     * @see #DATA_ACTIVITY_OUT
2059     * @see #DATA_ACTIVITY_INOUT
2060     * @see #DATA_ACTIVITY_DORMANT
2061     */
2062    public int getDataActivity() {
2063        try {
2064            return getITelephony().getDataActivity();
2065        } catch (RemoteException ex) {
2066            // the phone process is restarting.
2067            return DATA_ACTIVITY_NONE;
2068        } catch (NullPointerException ex) {
2069          // the phone process is restarting.
2070          return DATA_ACTIVITY_NONE;
2071      }
2072    }
2073
2074    /** Data connection state: Unknown.  Used before we know the state.
2075     * @hide
2076     */
2077    public static final int DATA_UNKNOWN        = -1;
2078    /** Data connection state: Disconnected. IP traffic not available. */
2079    public static final int DATA_DISCONNECTED   = 0;
2080    /** Data connection state: Currently setting up a data connection. */
2081    public static final int DATA_CONNECTING     = 1;
2082    /** Data connection state: Connected. IP traffic should be available. */
2083    public static final int DATA_CONNECTED      = 2;
2084    /** Data connection state: Suspended. The connection is up, but IP
2085     * traffic is temporarily unavailable. For example, in a 2G network,
2086     * data activity may be suspended when a voice call arrives. */
2087    public static final int DATA_SUSPENDED      = 3;
2088
2089    /**
2090     * Returns a constant indicating the current data connection state
2091     * (cellular).
2092     *
2093     * @see #DATA_DISCONNECTED
2094     * @see #DATA_CONNECTING
2095     * @see #DATA_CONNECTED
2096     * @see #DATA_SUSPENDED
2097     */
2098    public int getDataState() {
2099        try {
2100            return getITelephony().getDataState();
2101        } catch (RemoteException ex) {
2102            // the phone process is restarting.
2103            return DATA_DISCONNECTED;
2104        } catch (NullPointerException ex) {
2105            return DATA_DISCONNECTED;
2106        }
2107    }
2108
2109    private ITelephony getITelephony() {
2110        return ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE));
2111    }
2112
2113    private ITelecommService getTelecommService() {
2114        return ITelecommService.Stub.asInterface(ServiceManager.getService(TELECOMM_SERVICE_NAME));
2115    }
2116
2117    //
2118    //
2119    // PhoneStateListener
2120    //
2121    //
2122
2123    /**
2124     * Registers a listener object to receive notification of changes
2125     * in specified telephony states.
2126     * <p>
2127     * To register a listener, pass a {@link PhoneStateListener}
2128     * and specify at least one telephony state of interest in
2129     * the events argument.
2130     *
2131     * At registration, and when a specified telephony state
2132     * changes, the telephony manager invokes the appropriate
2133     * callback method on the listener object and passes the
2134     * current (updated) values.
2135     * <p>
2136     * To unregister a listener, pass the listener object and set the
2137     * events argument to
2138     * {@link PhoneStateListener#LISTEN_NONE LISTEN_NONE} (0).
2139     *
2140     * @param listener The {@link PhoneStateListener} object to register
2141     *                 (or unregister)
2142     * @param events The telephony state(s) of interest to the listener,
2143     *               as a bitwise-OR combination of {@link PhoneStateListener}
2144     *               LISTEN_ flags.
2145     */
2146    public void listen(PhoneStateListener listener, int events) {
2147        String pkgForDebug = mContext != null ? mContext.getPackageName() : "<unknown>";
2148        try {
2149            Boolean notifyNow = (getITelephony() != null);
2150            sRegistry.listenUsingSubId(listener.mSubId, pkgForDebug, listener.callback, events, notifyNow);
2151        } catch (RemoteException ex) {
2152            // system process dead
2153        } catch (NullPointerException ex) {
2154            // system process dead
2155        }
2156    }
2157
2158    /**
2159     * Returns the CDMA ERI icon index to display
2160     *
2161     * @hide
2162     */
2163    public int getCdmaEriIconIndex() {
2164        return getCdmaEriIconIndex(getDefaultSubscription());
2165    }
2166
2167    /**
2168     * Returns the CDMA ERI icon index to display for a subscription
2169     */
2170    /** {@hide} */
2171    public int getCdmaEriIconIndex(long subId) {
2172        try {
2173            return getITelephony().getCdmaEriIconIndexUsingSubId(subId);
2174        } catch (RemoteException ex) {
2175            // the phone process is restarting.
2176            return -1;
2177        } catch (NullPointerException ex) {
2178            return -1;
2179        }
2180    }
2181
2182    /**
2183     * Returns the CDMA ERI icon mode,
2184     * 0 - ON
2185     * 1 - FLASHING
2186     *
2187     * @hide
2188     */
2189    public int getCdmaEriIconMode() {
2190        return getCdmaEriIconMode(getDefaultSubscription());
2191    }
2192
2193    /**
2194     * Returns the CDMA ERI icon mode for a subscription.
2195     * 0 - ON
2196     * 1 - FLASHING
2197     */
2198    /** {@hide} */
2199    public int getCdmaEriIconMode(long subId) {
2200        try {
2201            return getITelephony().getCdmaEriIconModeUsingSubId(subId);
2202        } catch (RemoteException ex) {
2203            // the phone process is restarting.
2204            return -1;
2205        } catch (NullPointerException ex) {
2206            return -1;
2207        }
2208    }
2209
2210    /**
2211     * Returns the CDMA ERI text,
2212     *
2213     * @hide
2214     */
2215    public String getCdmaEriText() {
2216        return getCdmaEriText(getDefaultSubscription());
2217    }
2218
2219    /**
2220     * Returns the CDMA ERI text, of a subscription
2221     *
2222     */
2223    /** {@hide} */
2224    public String getCdmaEriText(long subId) {
2225        try {
2226            return getITelephony().getCdmaEriTextUsingSubId(subId);
2227        } catch (RemoteException ex) {
2228            // the phone process is restarting.
2229            return null;
2230        } catch (NullPointerException ex) {
2231            return null;
2232        }
2233    }
2234
2235    /**
2236     * @return true if the current device is "voice capable".
2237     * <p>
2238     * "Voice capable" means that this device supports circuit-switched
2239     * (i.e. voice) phone calls over the telephony network, and is allowed
2240     * to display the in-call UI while a cellular voice call is active.
2241     * This will be false on "data only" devices which can't make voice
2242     * calls and don't support any in-call UI.
2243     * <p>
2244     * Note: the meaning of this flag is subtly different from the
2245     * PackageManager.FEATURE_TELEPHONY system feature, which is available
2246     * on any device with a telephony radio, even if the device is
2247     * data-only.
2248     *
2249     * @hide pending API review
2250     */
2251    public boolean isVoiceCapable() {
2252        if (mContext == null) return true;
2253        return mContext.getResources().getBoolean(
2254                com.android.internal.R.bool.config_voice_capable);
2255    }
2256
2257    /**
2258     * @return true if the current device supports sms service.
2259     * <p>
2260     * If true, this means that the device supports both sending and
2261     * receiving sms via the telephony network.
2262     * <p>
2263     * Note: Voicemail waiting sms, cell broadcasting sms, and MMS are
2264     *       disabled when device doesn't support sms.
2265     */
2266    public boolean isSmsCapable() {
2267        if (mContext == null) return true;
2268        return mContext.getResources().getBoolean(
2269                com.android.internal.R.bool.config_sms_capable);
2270    }
2271
2272    /**
2273     * Returns all observed cell information from all radios on the
2274     * device including the primary and neighboring cells. This does
2275     * not cause or change the rate of PhoneStateListner#onCellInfoChanged.
2276     *<p>
2277     * The list can include one or more of {@link android.telephony.CellInfoGsm CellInfoGsm},
2278     * {@link android.telephony.CellInfoCdma CellInfoCdma},
2279     * {@link android.telephony.CellInfoLte CellInfoLte} and
2280     * {@link android.telephony.CellInfoWcdma CellInfoCdma} in any combination.
2281     * Specifically on devices with multiple radios it is typical to see instances of
2282     * one or more of any these in the list. In addition 0, 1 or more CellInfo
2283     * objects may return isRegistered() true.
2284     *<p>
2285     * This is preferred over using getCellLocation although for older
2286     * devices this may return null in which case getCellLocation should
2287     * be called.
2288     *<p>
2289     * @return List of CellInfo or null if info unavailable.
2290     *
2291     * <p>Requires Permission: {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}
2292     */
2293    public List<CellInfo> getAllCellInfo() {
2294        try {
2295            return getITelephony().getAllCellInfo();
2296        } catch (RemoteException ex) {
2297            return null;
2298        } catch (NullPointerException ex) {
2299            return null;
2300        }
2301    }
2302
2303    /**
2304     * Sets the minimum time in milli-seconds between {@link PhoneStateListener#onCellInfoChanged
2305     * PhoneStateListener.onCellInfoChanged} will be invoked.
2306     *<p>
2307     * The default, 0, means invoke onCellInfoChanged when any of the reported
2308     * information changes. Setting the value to INT_MAX(0x7fffffff) means never issue
2309     * A onCellInfoChanged.
2310     *<p>
2311     * @param rateInMillis the rate
2312     *
2313     * @hide
2314     */
2315    public void setCellInfoListRate(int rateInMillis) {
2316        try {
2317            getITelephony().setCellInfoListRate(rateInMillis);
2318        } catch (RemoteException ex) {
2319        } catch (NullPointerException ex) {
2320        }
2321    }
2322
2323    /**
2324     * Returns the MMS user agent.
2325     */
2326    public String getMmsUserAgent() {
2327        if (mContext == null) return null;
2328        return mContext.getResources().getString(
2329                com.android.internal.R.string.config_mms_user_agent);
2330    }
2331
2332    /**
2333     * Returns the MMS user agent profile URL.
2334     */
2335    public String getMmsUAProfUrl() {
2336        if (mContext == null) return null;
2337        return mContext.getResources().getString(
2338                com.android.internal.R.string.config_mms_user_agent_profile_url);
2339    }
2340
2341    /**
2342     * Opens a logical channel to the ICC card.
2343     *
2344     * Input parameters equivalent to TS 27.007 AT+CCHO command.
2345     *
2346     * <p>Requires Permission:
2347     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
2348     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
2349     *
2350     * @param AID Application id. See ETSI 102.221 and 101.220.
2351     * @return The logical channel id which is negative on error.
2352     */
2353    public int iccOpenLogicalChannel(String AID) {
2354        try {
2355            return getITelephony().iccOpenLogicalChannel(AID);
2356        } catch (RemoteException ex) {
2357        } catch (NullPointerException ex) {
2358        }
2359        return -1;
2360    }
2361
2362    /**
2363     * Closes a previously opened logical channel to the ICC card.
2364     *
2365     * Input parameters equivalent to TS 27.007 AT+CCHC command.
2366     *
2367     * <p>Requires Permission:
2368     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
2369     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
2370     *
2371     * @param channel is the channel id to be closed as retruned by a successful
2372     *            iccOpenLogicalChannel.
2373     * @return true if the channel was closed successfully.
2374     */
2375    public boolean iccCloseLogicalChannel(int channel) {
2376        try {
2377            return getITelephony().iccCloseLogicalChannel(channel);
2378        } catch (RemoteException ex) {
2379        } catch (NullPointerException ex) {
2380        }
2381        return false;
2382    }
2383
2384    /**
2385     * Transmit an APDU to the ICC card over a logical channel.
2386     *
2387     * Input parameters equivalent to TS 27.007 AT+CGLA command.
2388     *
2389     * <p>Requires Permission:
2390     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
2391     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
2392     *
2393     * @param channel is the channel id to be closed as returned by a successful
2394     *            iccOpenLogicalChannel.
2395     * @param cla Class of the APDU command.
2396     * @param instruction Instruction of the APDU command.
2397     * @param p1 P1 value of the APDU command.
2398     * @param p2 P2 value of the APDU command.
2399     * @param p3 P3 value of the APDU command. If p3 is negative a 4 byte APDU
2400     *            is sent to the SIM.
2401     * @param data Data to be sent with the APDU.
2402     * @return The APDU response from the ICC card with the status appended at
2403     *            the end. If an error occurs, an empty string is returned.
2404     */
2405    public String iccTransmitApduLogicalChannel(int channel, int cla,
2406            int instruction, int p1, int p2, int p3, String data) {
2407        try {
2408            return getITelephony().iccTransmitApduLogicalChannel(channel, cla,
2409                    instruction, p1, p2, p3, data);
2410        } catch (RemoteException ex) {
2411        } catch (NullPointerException ex) {
2412        }
2413        return "";
2414    }
2415
2416    /**
2417     * Send ENVELOPE to the SIM and return the response.
2418     *
2419     * <p>Requires Permission:
2420     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
2421     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
2422     *
2423     * @param content String containing SAT/USAT response in hexadecimal
2424     *                format starting with command tag. See TS 102 223 for
2425     *                details.
2426     * @return The APDU response from the ICC card, with the last 4 bytes
2427     *         being the status word. If the command fails, returns an empty
2428     *         string.
2429     */
2430    public String sendEnvelopeWithStatus(String content) {
2431        try {
2432            return getITelephony().sendEnvelopeWithStatus(content);
2433        } catch (RemoteException ex) {
2434        } catch (NullPointerException ex) {
2435        }
2436        return "";
2437    }
2438
2439    /**
2440     * Read one of the NV items defined in com.android.internal.telephony.RadioNVItems.
2441     * Used for device configuration by some CDMA operators.
2442     * <p>
2443     * Requires Permission:
2444     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
2445     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
2446     *
2447     * @param itemID the ID of the item to read.
2448     * @return the NV item as a String, or null on any failure.
2449     *
2450     * @hide
2451     */
2452    public String nvReadItem(int itemID) {
2453        try {
2454            return getITelephony().nvReadItem(itemID);
2455        } catch (RemoteException ex) {
2456            Rlog.e(TAG, "nvReadItem RemoteException", ex);
2457        } catch (NullPointerException ex) {
2458            Rlog.e(TAG, "nvReadItem NPE", ex);
2459        }
2460        return "";
2461    }
2462
2463    /**
2464     * Write one of the NV items defined in com.android.internal.telephony.RadioNVItems.
2465     * Used for device configuration by some CDMA operators.
2466     * <p>
2467     * Requires Permission:
2468     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
2469     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
2470     *
2471     * @param itemID the ID of the item to read.
2472     * @param itemValue the value to write, as a String.
2473     * @return true on success; false on any failure.
2474     *
2475     * @hide
2476     */
2477    public boolean nvWriteItem(int itemID, String itemValue) {
2478        try {
2479            return getITelephony().nvWriteItem(itemID, itemValue);
2480        } catch (RemoteException ex) {
2481            Rlog.e(TAG, "nvWriteItem RemoteException", ex);
2482        } catch (NullPointerException ex) {
2483            Rlog.e(TAG, "nvWriteItem NPE", ex);
2484        }
2485        return false;
2486    }
2487
2488    /**
2489     * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
2490     * Used for device configuration by some CDMA operators.
2491     * <p>
2492     * Requires Permission:
2493     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
2494     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
2495     *
2496     * @param preferredRoamingList byte array containing the new PRL.
2497     * @return true on success; false on any failure.
2498     *
2499     * @hide
2500     */
2501    public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
2502        try {
2503            return getITelephony().nvWriteCdmaPrl(preferredRoamingList);
2504        } catch (RemoteException ex) {
2505            Rlog.e(TAG, "nvWriteCdmaPrl RemoteException", ex);
2506        } catch (NullPointerException ex) {
2507            Rlog.e(TAG, "nvWriteCdmaPrl NPE", ex);
2508        }
2509        return false;
2510    }
2511
2512    /**
2513     * Perform the specified type of NV config reset. The radio will be taken offline
2514     * and the device must be rebooted after the operation. Used for device
2515     * configuration by some CDMA operators.
2516     * <p>
2517     * Requires Permission:
2518     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
2519     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
2520     *
2521     * @param resetType reset type: 1: reload NV reset, 2: erase NV reset, 3: factory NV reset
2522     * @return true on success; false on any failure.
2523     *
2524     * @hide
2525     */
2526    public boolean nvResetConfig(int resetType) {
2527        try {
2528            return getITelephony().nvResetConfig(resetType);
2529        } catch (RemoteException ex) {
2530            Rlog.e(TAG, "nvResetConfig RemoteException", ex);
2531        } catch (NullPointerException ex) {
2532            Rlog.e(TAG, "nvResetConfig NPE", ex);
2533        }
2534        return false;
2535    }
2536
2537    /**
2538     * Returns Default subscription.
2539     */
2540    private static long getDefaultSubscription() {
2541        return SubscriptionManager.getDefaultSubId();
2542    }
2543
2544    /** {@hide} */
2545    public int getDefaultSim() {
2546        //TODO Need to get it from Telephony Devcontroller
2547        return 0;
2548    }
2549
2550    /**
2551     * Sets the telephony property with the value specified.
2552     *
2553     * @hide
2554     */
2555    public static void setTelephonyProperty(String property, long subId, String value) {
2556        String propVal = "";
2557        String p[] = null;
2558        String prop = SystemProperties.get(property);
2559        int phoneId = SubscriptionManager.getPhoneId(subId);
2560
2561        if (value == null) {
2562            value = "";
2563        }
2564
2565        if (prop != null) {
2566            p = prop.split(",");
2567        }
2568
2569        if (phoneId < 0) return;
2570
2571        for (int i = 0; i < phoneId; i++) {
2572            String str = "";
2573            if ((p != null) && (i < p.length)) {
2574                str = p[i];
2575            }
2576            propVal = propVal + str + ",";
2577        }
2578
2579        propVal = propVal + value;
2580        if (p != null) {
2581            for (int i = phoneId + 1; i < p.length; i++) {
2582                propVal = propVal + "," + p[i];
2583            }
2584        }
2585
2586        // TODO: workaround for QC
2587        if (property.length() > SystemProperties.PROP_NAME_MAX || propVal.length() > SystemProperties.PROP_VALUE_MAX) {
2588            Rlog.d(TAG, "setTelephonyProperty length too long:" + property + ", " + propVal);
2589            return;
2590        }
2591
2592        Rlog.d(TAG, "setTelephonyProperty property=" + property + " propVal=" + propVal);
2593        SystemProperties.set(property, propVal);
2594    }
2595
2596    /**
2597     * Convenience function for retrieving a value from the secure settings
2598     * value list as an integer.  Note that internally setting values are
2599     * always stored as strings; this function converts the string to an
2600     * integer for you.
2601     * <p>
2602     * This version does not take a default value.  If the setting has not
2603     * been set, or the string value is not a number,
2604     * it throws {@link SettingNotFoundException}.
2605     *
2606     * @param cr The ContentResolver to access.
2607     * @param name The name of the setting to retrieve.
2608     * @param index The index of the list
2609     *
2610     * @throws SettingNotFoundException Thrown if a setting by the given
2611     * name can't be found or the setting value is not an integer.
2612     *
2613     * @return The value at the given index of settings.
2614     * @hide
2615     */
2616    public static int getIntAtIndex(android.content.ContentResolver cr,
2617            String name, int index)
2618            throws android.provider.Settings.SettingNotFoundException {
2619        String v = android.provider.Settings.Global.getString(cr, name);
2620        if (v != null) {
2621            String valArray[] = v.split(",");
2622            if ((index >= 0) && (index < valArray.length) && (valArray[index] != null)) {
2623                try {
2624                    return Integer.parseInt(valArray[index]);
2625                } catch (NumberFormatException e) {
2626                    //Log.e(TAG, "Exception while parsing Integer: ", e);
2627                }
2628            }
2629        }
2630        throw new android.provider.Settings.SettingNotFoundException(name);
2631    }
2632
2633    /**
2634     * Convenience function for updating settings value as coma separated
2635     * integer values. This will either create a new entry in the table if the
2636     * given name does not exist, or modify the value of the existing row
2637     * with that name.  Note that internally setting values are always
2638     * stored as strings, so this function converts the given value to a
2639     * string before storing it.
2640     *
2641     * @param cr The ContentResolver to access.
2642     * @param name The name of the setting to modify.
2643     * @param index The index of the list
2644     * @param value The new value for the setting to be added to the list.
2645     * @return true if the value was set, false on database errors
2646     * @hide
2647     */
2648    public static boolean putIntAtIndex(android.content.ContentResolver cr,
2649            String name, int index, int value) {
2650        String data = "";
2651        String valArray[] = null;
2652        String v = android.provider.Settings.Global.getString(cr, name);
2653
2654        if (v != null) {
2655            valArray = v.split(",");
2656        }
2657
2658        // Copy the elements from valArray till index
2659        for (int i = 0; i < index; i++) {
2660            String str = "";
2661            if ((valArray != null) && (i < valArray.length)) {
2662                str = valArray[i];
2663            }
2664            data = data + str + ",";
2665        }
2666
2667        data = data + value;
2668
2669        // Copy the remaining elements from valArray if any.
2670        if (valArray != null) {
2671            for (int i = index+1; i < valArray.length; i++) {
2672                data = data + "," + valArray[i];
2673            }
2674        }
2675        return android.provider.Settings.Global.putString(cr, name, data);
2676    }
2677
2678    /**
2679     * Gets the telephony property.
2680     *
2681     * @hide
2682     */
2683    public static String getTelephonyProperty(String property, long subId, String defaultVal) {
2684        String propVal = null;
2685        int phoneId = SubscriptionManager.getPhoneId(subId);
2686        String prop = SystemProperties.get(property);
2687        if ((prop != null) && (prop.length() > 0)) {
2688            String values[] = prop.split(",");
2689            if ((phoneId >= 0) && (phoneId < values.length) && (values[phoneId] != null)) {
2690                propVal = values[phoneId];
2691            }
2692        }
2693        return propVal == null ? defaultVal : propVal;
2694    }
2695
2696    /** @hide */
2697    public int getSimCount() {
2698        if(isMultiSimEnabled()) {
2699        //TODO Need to get it from Telephony Devcontroller
2700            return 2;
2701        } else {
2702           return 1;
2703        }
2704    }
2705
2706    /**
2707     * Returns the IMS Service Table (IST) that was loaded from the ISIM.
2708     * @return IMS Service Table or null if not present or not loaded
2709     * @hide
2710     */
2711    public String getIsimIst() {
2712        try {
2713            return getSubscriberInfo().getIsimIst();
2714        } catch (RemoteException ex) {
2715            return null;
2716        } catch (NullPointerException ex) {
2717            // This could happen before phone restarts due to crashing
2718            return null;
2719        }
2720    }
2721
2722    /**
2723     * Returns the IMS Proxy Call Session Control Function(PCSCF) that were loaded from the ISIM.
2724     * @return an array of PCSCF strings with one PCSCF per string, or null if
2725     *         not present or not loaded
2726     * @hide
2727     */
2728    public String[] getIsimPcscf() {
2729        try {
2730            return getSubscriberInfo().getIsimPcscf();
2731        } catch (RemoteException ex) {
2732            return null;
2733        } catch (NullPointerException ex) {
2734            // This could happen before phone restarts due to crashing
2735            return null;
2736        }
2737    }
2738
2739    /**
2740     * Returns the response of ISIM Authetification through RIL.
2741     * Returns null if the Authentification hasn't been successed or isn't present iphonesubinfo.
2742     * @return the response of ISIM Authetification, or null if not available
2743     * @hide
2744     * @deprecated
2745     * @see getIccSimChallengeResponse with appType=PhoneConstants.APPTYPE_ISIM
2746     */
2747    public String getIsimChallengeResponse(String nonce){
2748        try {
2749            return getSubscriberInfo().getIsimChallengeResponse(nonce);
2750        } catch (RemoteException ex) {
2751            return null;
2752        } catch (NullPointerException ex) {
2753            // This could happen before phone restarts due to crashing
2754            return null;
2755        }
2756    }
2757
2758    /**
2759     * Returns the response of SIM Authentication through RIL.
2760     * Returns null if the Authentication hasn't been successful
2761     * @param subId subscription ID to be queried
2762     * @param appType ICC application type (@see com.android.internal.telephony.PhoneConstants#APPTYPE_xxx)
2763     * @param data authentication challenge data
2764     * @return the response of SIM Authentication, or null if not available
2765     * @hide
2766     */
2767    public String getIccSimChallengeResponse(long subId, int appType, String data) {
2768        try {
2769            return getSubscriberInfo().getIccSimChallengeResponse(subId, appType, data);
2770        } catch (RemoteException ex) {
2771            return null;
2772        } catch (NullPointerException ex) {
2773            // This could happen before phone starts
2774            return null;
2775        }
2776    }
2777
2778    /**
2779     * Returns the response of SIM Authentication through RIL for the default subscription.
2780     * Returns null if the Authentication hasn't been successful
2781     * @param appType ICC application type (@see com.android.internal.telephony.PhoneConstants#APPTYPE_xxx)
2782     * @param data authentication challenge data
2783     * @return the response of SIM Authentication, or null if not available
2784     * @hide
2785     */
2786    public String getIccSimChallengeResponse(int appType, String data) {
2787        return getIccSimChallengeResponse(getDefaultSubscription(), appType, data);
2788    }
2789
2790    /**
2791     * Get P-CSCF address from PCO after data connection is established or modified.
2792     *
2793     * @return array of P-CSCF address
2794     * @hide
2795     */
2796    public String[] getPcscfAddress() {
2797        try {
2798            return getITelephony().getPcscfAddress();
2799        } catch (RemoteException e) {
2800            return new String[0];
2801        }
2802    }
2803
2804    /**
2805     * Set IMS registration state
2806     *
2807     * @param Registration state
2808     * @hide
2809     */
2810    public void setImsRegistrationState(boolean registered) {
2811        try {
2812            getITelephony().setImsRegistrationState(registered);
2813        } catch (RemoteException e) {
2814        }
2815    }
2816
2817    /**
2818     * Get the calculated preferred network type.
2819     * Used for debugging incorrect network type.
2820     * <p>
2821     * Requires Permission:
2822     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
2823     *
2824     * @return the preferred network type, defined in RILConstants.java or -1 if
2825     *         none available.
2826     */
2827    public int getCalculatedPreferredNetworkType() {
2828        try {
2829            return getITelephony().getCalculatedPreferredNetworkType();
2830        } catch (RemoteException ex) {
2831            Rlog.e(TAG, "getCalculatedPreferredNetworkType RemoteException", ex);
2832        } catch (NullPointerException ex) {
2833            Rlog.e(TAG, "getCalculatedPreferredNetworkType NPE", ex);
2834        }
2835        return -1;
2836    }
2837
2838    /**
2839     * Get the preferred network type.
2840     * Used for device configuration by some CDMA operators.
2841     * <p>
2842     * Requires Permission:
2843     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
2844     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
2845     *
2846     * @return the preferred network type, defined in RILConstants.java.
2847     */
2848    public int getPreferredNetworkType() {
2849        try {
2850            return getITelephony().getPreferredNetworkType();
2851        } catch (RemoteException ex) {
2852            Rlog.e(TAG, "getPreferredNetworkType RemoteException", ex);
2853        } catch (NullPointerException ex) {
2854            Rlog.e(TAG, "getPreferredNetworkType NPE", ex);
2855        }
2856        return -1;
2857    }
2858
2859    /**
2860     * Set the preferred network type.
2861     * Used for device configuration by some CDMA operators.
2862     * <p>
2863     * Requires Permission:
2864     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
2865     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
2866     *
2867     * @param networkType the preferred network type, defined in RILConstants.java.
2868     * @return true on success; false on any failure.
2869     */
2870    public boolean setPreferredNetworkType(int networkType) {
2871        try {
2872            return getITelephony().setPreferredNetworkType(networkType);
2873        } catch (RemoteException ex) {
2874            Rlog.e(TAG, "setPreferredNetworkType RemoteException", ex);
2875        } catch (NullPointerException ex) {
2876            Rlog.e(TAG, "setPreferredNetworkType NPE", ex);
2877        }
2878        return false;
2879    }
2880
2881    /**
2882     * Set the CDMA subscription source.
2883     * Used for device supporting both NV and RUIM for CDMA.
2884     * <p>
2885     * Requires Permission:
2886     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
2887     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
2888     *
2889     * @param subscriptionType the subscription type, 0 for RUIM, 1 for NV.
2890     * @return true on success; false on any failure.
2891     */
2892    public boolean setCdmaSubscription(int subscriptionType) {
2893        try {
2894            return getITelephony().setCdmaSubscription(subscriptionType);
2895        } catch (RemoteException ex) {
2896            Rlog.e(TAG, "setCdmaSubscription RemoteException", ex);
2897        } catch (NullPointerException ex) {
2898            Rlog.e(TAG, "setCdmaSubscription NPE", ex);
2899        }
2900        return false;
2901    }
2902
2903    /**
2904     * Values used to return status for hasCarrierPrivileges call.
2905     */
2906    public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1;
2907    public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0;
2908    public static final int CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED = -1;
2909    public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2;
2910
2911    /**
2912     * Has the calling application been granted carrier privileges by the carrier.
2913     *
2914     * If any of the packages in the calling UID has carrier privileges, the
2915     * call will return true. This access is granted by the owner of the UICC
2916     * card and does not depend on the registered carrier.
2917     *
2918     * TODO: Add a link to documentation.
2919     *
2920     * @return CARRIER_PRIVILEGE_STATUS_HAS_ACCESS if the app has carrier privileges.
2921     *         CARRIER_PRIVILEGE_STATUS_NO_ACCESS if the app does not have carrier privileges.
2922     *         CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED if the carrier rules are not loaded.
2923     *         CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES if there was an error loading carrier
2924     *             rules (or if there are no rules).
2925     */
2926    public int hasCarrierPrivileges() {
2927        try {
2928            return getITelephony().hasCarrierPrivileges();
2929        } catch (RemoteException ex) {
2930            Rlog.e(TAG, "hasCarrierPrivileges RemoteException", ex);
2931        } catch (NullPointerException ex) {
2932            Rlog.e(TAG, "hasCarrierPrivileges NPE", ex);
2933        }
2934        return CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
2935    }
2936
2937    /**
2938     * Override the branding for the input ICCID.
2939     *
2940     * Once set, whenever the ICCID is inserted into the device, the service
2941     * provider name (SPN) and the operator name will both be replaced by the
2942     * brand value input. To unset the value, the same function should be
2943     * called with a null brand value.
2944     *
2945     * <p>Requires Permission:
2946     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
2947     *  or has to be carrier app - see #hasCarrierPrivileges.
2948     *
2949     * @param iccId The ICCID of that the branding applies to.
2950     * @param brand The brand name to display/set.
2951     * @return true if the operation was executed correctly.
2952     */
2953    public boolean setOperatorBrandOverride(String iccId, String brand) {
2954        // TODO: Validate ICCID format.
2955        try {
2956            return getITelephony().setOperatorBrandOverride(iccId, brand);
2957        } catch (RemoteException ex) {
2958            Rlog.e(TAG, "setOperatorBrandOverride RemoteException", ex);
2959        } catch (NullPointerException ex) {
2960            Rlog.e(TAG, "setOperatorBrandOverride NPE", ex);
2961        }
2962        return false;
2963    }
2964
2965    /**
2966     * Expose the rest of ITelephony to @SystemApi
2967     */
2968
2969    /** @hide */
2970    @SystemApi
2971    public int checkCarrierPrivilegesForPackage(String pkgname) {
2972        try {
2973            return getITelephony().checkCarrierPrivilegesForPackage(pkgname);
2974        } catch (RemoteException ex) {
2975            Rlog.e(TAG, "hasCarrierPrivileges RemoteException", ex);
2976        } catch (NullPointerException ex) {
2977            Rlog.e(TAG, "hasCarrierPrivileges NPE", ex);
2978        }
2979        return CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
2980    }
2981
2982    /** @hide */
2983    @SystemApi
2984    public List<String> getCarrierPackageNamesForBroadcastIntent(Intent intent) {
2985        try {
2986            return getITelephony().getCarrierPackageNamesForBroadcastIntent(intent);
2987        } catch (RemoteException ex) {
2988            Rlog.e(TAG, "getCarrierPackageNamesForBroadcastIntent RemoteException", ex);
2989        } catch (NullPointerException ex) {
2990            Rlog.e(TAG, "getCarrierPackageNamesForBroadcastIntent NPE", ex);
2991        }
2992        return null;
2993    }
2994
2995    /** @hide */
2996    @SystemApi
2997    public void dial(String number) {
2998        try {
2999            getITelephony().dial(number);
3000        } catch (RemoteException e) {
3001            Log.e(TAG, "Error calling ITelephony#dial", e);
3002        }
3003    }
3004
3005    /** @hide */
3006    @SystemApi
3007    public void call(String callingPackage, String number) {
3008        try {
3009            getITelephony().call(callingPackage, number);
3010        } catch (RemoteException e) {
3011            Log.e(TAG, "Error calling ITelephony#call", e);
3012        }
3013    }
3014
3015    /** @hide */
3016    @SystemApi
3017    public boolean endCall() {
3018        try {
3019            return getITelephony().endCall();
3020        } catch (RemoteException e) {
3021            Log.e(TAG, "Error calling ITelephony#endCall", e);
3022        }
3023        return false;
3024    }
3025
3026    /** @hide */
3027    @SystemApi
3028    public void answerRingingCall() {
3029        try {
3030            getITelephony().answerRingingCall();
3031        } catch (RemoteException e) {
3032            Log.e(TAG, "Error calling ITelephony#answerRingingCall", e);
3033        }
3034    }
3035
3036    /** @hide */
3037    @SystemApi
3038    public void silenceRinger() {
3039        try {
3040            getTelecommService().silenceRinger();
3041        } catch (RemoteException e) {
3042            Log.e(TAG, "Error calling ITelecommService#silenceRinger", e);
3043        }
3044    }
3045
3046    /** @hide */
3047    @SystemApi
3048    public boolean isOffhook() {
3049        try {
3050            return getITelephony().isOffhook();
3051        } catch (RemoteException e) {
3052            Log.e(TAG, "Error calling ITelephony#isOffhook", e);
3053        }
3054        return false;
3055    }
3056
3057    /** @hide */
3058    @SystemApi
3059    public boolean isRinging() {
3060        try {
3061            return getITelephony().isRinging();
3062        } catch (RemoteException e) {
3063            Log.e(TAG, "Error calling ITelephony#isRinging", e);
3064        }
3065        return false;
3066    }
3067
3068    /** @hide */
3069    @SystemApi
3070    public boolean isIdle() {
3071        try {
3072            return getITelephony().isIdle();
3073        } catch (RemoteException e) {
3074            Log.e(TAG, "Error calling ITelephony#isIdle", e);
3075        }
3076        return true;
3077    }
3078
3079    /** @hide */
3080    @SystemApi
3081    public boolean isRadioOn() {
3082        try {
3083            return getITelephony().isRadioOn();
3084        } catch (RemoteException e) {
3085            Log.e(TAG, "Error calling ITelephony#isRadioOn", e);
3086        }
3087        return false;
3088    }
3089
3090    /** @hide */
3091    @SystemApi
3092    public boolean isSimPinEnabled() {
3093        try {
3094            return getITelephony().isSimPinEnabled();
3095        } catch (RemoteException e) {
3096            Log.e(TAG, "Error calling ITelephony#isSimPinEnabled", e);
3097        }
3098        return false;
3099    }
3100
3101    /** @hide */
3102    @SystemApi
3103    public boolean supplyPin(String pin) {
3104        try {
3105            return getITelephony().supplyPin(pin);
3106        } catch (RemoteException e) {
3107            Log.e(TAG, "Error calling ITelephony#supplyPin", e);
3108        }
3109        return false;
3110    }
3111
3112    /** @hide */
3113    @SystemApi
3114    public boolean supplyPuk(String puk, String pin) {
3115        try {
3116            return getITelephony().supplyPuk(puk, pin);
3117        } catch (RemoteException e) {
3118            Log.e(TAG, "Error calling ITelephony#supplyPuk", e);
3119        }
3120        return false;
3121    }
3122
3123    /** @hide */
3124    @SystemApi
3125    public int[] supplyPinReportResult(String pin) {
3126        try {
3127            return getITelephony().supplyPinReportResult(pin);
3128        } catch (RemoteException e) {
3129            Log.e(TAG, "Error calling ITelephony#supplyPinReportResult", e);
3130        }
3131        return new int[0];
3132    }
3133
3134    /** @hide */
3135    @SystemApi
3136    public int[] supplyPukReportResult(String puk, String pin) {
3137        try {
3138            return getITelephony().supplyPukReportResult(puk, pin);
3139        } catch (RemoteException e) {
3140            Log.e(TAG, "Error calling ITelephony#]", e);
3141        }
3142        return new int[0];
3143    }
3144
3145    /** @hide */
3146    @SystemApi
3147    public boolean handlePinMmi(String dialString) {
3148        try {
3149            return getITelephony().handlePinMmi(dialString);
3150        } catch (RemoteException e) {
3151            Log.e(TAG, "Error calling ITelephony#handlePinMmi", e);
3152        }
3153        return false;
3154    }
3155
3156    /** @hide */
3157    @SystemApi
3158    public void toggleRadioOnOff() {
3159        try {
3160            getITelephony().toggleRadioOnOff();
3161        } catch (RemoteException e) {
3162            Log.e(TAG, "Error calling ITelephony#toggleRadioOnOff", e);
3163        }
3164    }
3165
3166    /** @hide */
3167    @SystemApi
3168    public boolean setRadio(boolean turnOn) {
3169        try {
3170            return getITelephony().setRadio(turnOn);
3171        } catch (RemoteException e) {
3172            Log.e(TAG, "Error calling ITelephony#setRadio", e);
3173        }
3174        return false;
3175    }
3176
3177    /** @hide */
3178    @SystemApi
3179    public boolean setRadioPower(boolean turnOn) {
3180        try {
3181            return getITelephony().setRadioPower(turnOn);
3182        } catch (RemoteException e) {
3183            Log.e(TAG, "Error calling ITelephony#setRadioPower", e);
3184        }
3185        return false;
3186    }
3187
3188    /** @hide */
3189    @SystemApi
3190    public void updateServiceLocation() {
3191        try {
3192            getITelephony().updateServiceLocation();
3193        } catch (RemoteException e) {
3194            Log.e(TAG, "Error calling ITelephony#updateServiceLocation", e);
3195        }
3196    }
3197
3198    /** @hide */
3199    @SystemApi
3200    public boolean enableDataConnectivity() {
3201        try {
3202            return getITelephony().enableDataConnectivity();
3203        } catch (RemoteException e) {
3204            Log.e(TAG, "Error calling ITelephony#enableDataConnectivity", e);
3205        }
3206        return false;
3207    }
3208
3209    /** @hide */
3210    @SystemApi
3211    public boolean disableDataConnectivity() {
3212        try {
3213            return getITelephony().disableDataConnectivity();
3214        } catch (RemoteException e) {
3215            Log.e(TAG, "Error calling ITelephony#disableDataConnectivity", e);
3216        }
3217        return false;
3218    }
3219
3220    /** @hide */
3221    @SystemApi
3222    public boolean isDataConnectivityPossible() {
3223        try {
3224            return getITelephony().isDataConnectivityPossible();
3225        } catch (RemoteException e) {
3226            Log.e(TAG, "Error calling ITelephony#isDataConnectivityPossible", e);
3227        }
3228        return false;
3229    }
3230
3231    /** @hide */
3232    @SystemApi
3233    public boolean needsOtaServiceProvisioning() {
3234        try {
3235            return getITelephony().needsOtaServiceProvisioning();
3236        } catch (RemoteException e) {
3237            Log.e(TAG, "Error calling ITelephony#needsOtaServiceProvisioning", e);
3238        }
3239        return false;
3240    }
3241
3242    /** @hide */
3243    @SystemApi
3244    public void setDataEnabled(boolean enable) {
3245        try {
3246            getITelephony().setDataEnabled(enable);
3247        } catch (RemoteException e) {
3248            Log.e(TAG, "Error calling ITelephony#setDataEnabled", e);
3249        }
3250    }
3251
3252    /** @hide */
3253    @SystemApi
3254    public boolean getDataEnabled() {
3255        try {
3256            return getITelephony().getDataEnabled();
3257        } catch (RemoteException e) {
3258            Log.e(TAG, "Error calling ITelephony#getDataEnabled", e);
3259        }
3260        return false;
3261    }
3262
3263    /**
3264     * Set whether Android should display a simplified Mobile Network Settings UI.
3265     * The setting won't be persisted during power cycle.
3266     * <p>
3267     * Requires Permission:
3268     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
3269     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
3270     *
3271     * @param enable true means enabling the simplified UI.
3272     */
3273    public void enableSimplifiedNetworkSettings(boolean enable) {
3274        enableSimplifiedNetworkSettings(getDefaultSubscription(), enable);
3275    }
3276
3277    /**
3278     * Set whether Android should display a simplified Mobile Network Settings UI.
3279     * The setting won't be persisted during power cycle.
3280     * <p>
3281     * Requires Permission:
3282     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
3283     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
3284     *
3285     * @param subId for which the simplified UI should be enabled or disabled.
3286     * @param enable true means enabling the simplified UI.
3287     */
3288    public void enableSimplifiedNetworkSettings(long subId, boolean enable) {
3289        try {
3290            getITelephony().enableSimplifiedNetworkSettings(subId, enable);
3291        } catch (RemoteException ex) {
3292        } catch (NullPointerException ex) {
3293        }
3294    }
3295
3296    /**
3297     * Get whether a simplified Mobile Network Settings UI is enabled.
3298     * <p>
3299     * Requires Permission:
3300     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
3301     *
3302     * @return true if the simplified UI is enabled.
3303     */
3304    public boolean getSimplifiedNetworkSettingsEnabled() {
3305        return getSimplifiedNetworkSettingsEnabled(getDefaultSubscription());
3306    }
3307
3308    /**
3309     * Get whether a simplified Mobile Network Settings UI is enabled.
3310     * <p>
3311     * Requires Permission:
3312     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
3313     *
3314     * @param subId for which the simplified UI should be enabled or disabled.
3315     * @return true if the simplified UI is enabled.
3316     */
3317    public boolean getSimplifiedNetworkSettingsEnabled(long subId) {
3318        try {
3319            return getITelephony().getSimplifiedNetworkSettingsEnabled(subId);
3320        } catch (RemoteException ex) {
3321        } catch (NullPointerException ex) {
3322        }
3323        return false;
3324    }
3325}
3326