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