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