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