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