SubscriptionManager.java revision f5bca080a231e45e1694651c012c74ba52436635
1/*
2 * Copyright (C) 2014 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.SdkConstant;
20import android.annotation.SdkConstant.SdkConstantType;
21import android.content.Intent;
22import android.net.Uri;
23import android.provider.BaseColumns;
24import android.telephony.Rlog;
25import android.os.ServiceManager;
26import android.os.RemoteException;
27
28import com.android.internal.telephony.ISub;
29import com.android.internal.telephony.PhoneConstants;
30import java.util.List;
31
32/**
33 * SubscriptionManager is the application interface to SubscriptionController
34 * and provides information about the current Telephony Subscriptions.
35 *
36 * @hide
37 */
38public class SubscriptionManager implements BaseColumns {
39    private static final String LOG_TAG = "SUB";
40    private static final boolean DBG = true;
41    private static final boolean VDBG = false;
42
43    // An invalid phone identifier
44    /** @hide */
45    public static final int INVALID_PHONE_ID = -1000;
46
47    // Indicates the caller wants the default phone id.
48    /** @hide */
49    public static final int DEFAULT_PHONE_ID = Integer.MAX_VALUE;
50
51    // An invalid slot identifier
52    /** @hide */
53    public static final int INVALID_SLOT_ID = -1000;
54
55    // Indicates the caller wants the default slot id.
56    /** @hide */
57    public static final int DEFAULT_SLOT_ID = Integer.MAX_VALUE;
58
59    // An invalid subscription identifier
60    /** @hide */
61    public static final long INVALID_SUB_ID = -1000;
62
63    // Indicates the user should be asked which sub to use.
64    /** @hide */
65    public static final long ASK_USER_SUB_ID = -1001;
66
67    // Indicates the caller wants the default sub id.
68    /** @hide */
69    public static final long DEFAULT_SUB_ID = Long.MAX_VALUE;
70
71    /** @hide */
72    public static final Uri CONTENT_URI = Uri.parse("content://telephony/siminfo");
73
74    /** @hide */
75    public static final int DEFAULT_INT_VALUE = -100;
76
77    /** @hide */
78    public static final String DEFAULT_STRING_VALUE = "N/A";
79
80    /** @hide */
81    public static final int EXTRA_VALUE_NEW_SIM = 1;
82
83    /** @hide */
84    public static final int EXTRA_VALUE_REMOVE_SIM = 2;
85    /** @hide */
86    public static final int EXTRA_VALUE_REPOSITION_SIM = 3;
87    /** @hide */
88    public static final int EXTRA_VALUE_NOCHANGE = 4;
89
90    /** @hide */
91    public static final String INTENT_KEY_DETECT_STATUS = "simDetectStatus";
92    /** @hide */
93    public static final String INTENT_KEY_SIM_COUNT = "simCount";
94    /** @hide */
95    public static final String INTENT_KEY_NEW_SIM_SLOT = "newSIMSlot";
96    /** @hide */
97    public static final String INTENT_KEY_NEW_SIM_STATUS = "newSIMStatus";
98
99    /**
100     * The ICC ID of a SIM.
101     * <P>Type: TEXT (String)</P>
102     */
103    /** @hide */
104    public static final String ICC_ID = "icc_id";
105
106    /**
107     * <P>Type: INTEGER (int)</P>
108     */
109    /** @hide */
110    public static final String SIM_ID = "sim_id";
111    /** @hide */
112    public static final int SIM_NOT_INSERTED = -1;
113
114    /**
115     * The display name of a SIM.
116     * <P>Type: TEXT (String)</P>
117     */
118    /** @hide */
119    public static final String DISPLAY_NAME = "display_name";
120
121    /** @hide */
122    public static final int DEFAULT_NAME_RES = com.android.internal.R.string.unknownName;
123
124    /**
125     * The display name source of a SIM.
126     * <P>Type: INT (int)</P>
127     */
128    /** @hide */
129    public static final String NAME_SOURCE = "name_source";
130
131    /** @hide */
132    public static final int NAME_SOURCE_UNDEFINDED = -1;
133
134    /** @hide */
135    public static final int NAME_SOURCE_DEFAULT_SOURCE = 0;
136
137    /** @hide */
138    public static final int NAME_SOURCE_SIM_SOURCE = 1;
139
140    /** @hide */
141    public static final int NAME_SOURCE_USER_INPUT = 2;
142
143    /**
144     * The color of a SIM.
145     * <P>Type: INTEGER (int)</P>
146     */
147    /** @hide */
148    public static final String COLOR = "color";
149
150    /** @hide */
151    public static final int COLOR_1 = 0;
152
153    /** @hide */
154    public static final int COLOR_2 = 1;
155
156    /** @hide */
157    public static final int COLOR_3 = 2;
158
159    /** @hide */
160    public static final int COLOR_4 = 3;
161
162    /** @hide */
163    public static final int COLOR_DEFAULT = COLOR_1;
164
165    /**
166     * The phone number of a SIM.
167     * <P>Type: TEXT (String)</P>
168     */
169    /** @hide */
170    public static final String NUMBER = "number";
171
172    /**
173     * The number display format of a SIM.
174     * <P>Type: INTEGER (int)</P>
175     */
176    /** @hide */
177    public static final String DISPLAY_NUMBER_FORMAT = "display_number_format";
178
179    /** @hide */
180    public static final int DISPLAY_NUMBER_NONE = 0;
181
182    /** @hide */
183    public static final int DISPLAY_NUMBER_FIRST = 1;
184
185    /** @hide */
186    public static final int DISPLAY_NUMBER_LAST = 2;
187
188    /** @hide */
189    public static final int DISLPAY_NUMBER_DEFAULT = DISPLAY_NUMBER_FIRST;
190
191    /**
192     * Permission for data roaming of a SIM.
193     * <P>Type: INTEGER (int)</P>
194     */
195    /** @hide */
196    public static final String DATA_ROAMING = "data_roaming";
197
198    /** @hide */
199    public static final int DATA_ROAMING_ENABLE = 1;
200
201    /** @hide */
202    public static final int DATA_ROAMING_DISABLE = 0;
203
204    /** @hide */
205    public static final int DATA_ROAMING_DEFAULT = DATA_ROAMING_DISABLE;
206
207    private static final int RES_TYPE_BACKGROUND_DARK = 0;
208
209    private static final int RES_TYPE_BACKGROUND_LIGHT = 1;
210
211    private static final int[] sSimBackgroundDarkRes = setSimResource(RES_TYPE_BACKGROUND_DARK);
212
213    /**
214     * Broadcast Action: The user has changed one of the default subs related to
215     * data, phone calls, or sms</p>
216     * @hide
217     */
218    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
219    public static final String SUB_DEFAULT_CHANGED_ACTION =
220        "android.intent.action.SUB_DEFAULT_CHANGED";
221
222    /** @hide */
223    public SubscriptionManager() {
224        if (DBG) logd("SubscriptionManager created");
225    }
226
227    /**
228     * Get the SubInfoRecord according to an index
229     * @param subId The unique SubInfoRecord index in database
230     * @return SubInfoRecord, maybe null
231     * @hide
232     */
233    public static SubInfoRecord getSubInfoUsingSubId(long subId) {
234        if (!isValidSubId(subId)) {
235            logd("[getSubInfoUsingSubIdx]- invalid subId");
236            return null;
237        }
238
239        SubInfoRecord subInfo = null;
240
241        try {
242            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
243            if (iSub != null) {
244                subInfo = iSub.getSubInfoUsingSubId(subId);
245            }
246        } catch (RemoteException ex) {
247            // ignore it
248        }
249
250        return subInfo;
251
252    }
253
254    /**
255     * Get the SubInfoRecord according to an IccId
256     * @param iccId the IccId of SIM card
257     * @return SubInfoRecord, maybe null
258     * @hide
259     */
260    public static List<SubInfoRecord> getSubInfoUsingIccId(String iccId) {
261        if (VDBG) logd("[getSubInfoUsingIccId]+ iccId=" + iccId);
262        if (iccId == null) {
263            logd("[getSubInfoUsingIccId]- null iccid");
264            return null;
265        }
266
267        List<SubInfoRecord> result = null;
268
269        try {
270            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
271            if (iSub != null) {
272                result = iSub.getSubInfoUsingIccId(iccId);
273            }
274        } catch (RemoteException ex) {
275            // ignore it
276        }
277
278        return result;
279    }
280
281    /**
282     * Get the SubInfoRecord according to slotId
283     * @param slotId the slot which the SIM is inserted
284     * @return SubInfoRecord, maybe null
285     * @hide
286     */
287    public static List<SubInfoRecord> getSubInfoUsingSlotId(int slotId) {
288        // FIXME: Consider never returning null
289        if (!isValidSlotId(slotId)) {
290            logd("[getSubInfoUsingSlotId]- invalid slotId");
291            return null;
292        }
293
294        List<SubInfoRecord> result = null;
295
296        try {
297            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
298            if (iSub != null) {
299                result = iSub.getSubInfoUsingSlotId(slotId);
300            }
301        } catch (RemoteException ex) {
302            // ignore it
303        }
304
305        return result;
306    }
307
308    /**
309     * Get all the SubInfoRecord(s) in subinfo database
310     * @return Array list of all SubInfoRecords in database, include thsoe that were inserted before
311     * @hide
312     */
313    public static List<SubInfoRecord> getAllSubInfoList() {
314        if (VDBG) logd("[getAllSubInfoList]+");
315
316        List<SubInfoRecord> result = null;
317
318        try {
319            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
320            if (iSub != null) {
321                result = iSub.getAllSubInfoList();
322            }
323        } catch (RemoteException ex) {
324            // ignore it
325        }
326
327        return result;
328    }
329
330    /**
331     * Get the SubInfoRecord(s) of the currently inserted SIM(s)
332     * @return Array list of currently inserted SubInfoRecord(s)
333     * @hide
334     */
335    public static List<SubInfoRecord> getActiveSubInfoList() {
336        List<SubInfoRecord> result = null;
337
338        try {
339            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
340            if (iSub != null) {
341                result = iSub.getActiveSubInfoList();
342            }
343        } catch (RemoteException ex) {
344            // ignore it
345        }
346
347        return result;
348    }
349
350    /**
351     * Get the SUB count of all SUB(s) in subinfo database
352     * @return all SIM count in database, include what was inserted before
353     * @hide
354     */
355    public static int getAllSubInfoCount() {
356        if (VDBG) logd("[getAllSubInfoCount]+");
357
358        int result = 0;
359
360        try {
361            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
362            if (iSub != null) {
363                result = iSub.getAllSubInfoCount();
364            }
365        } catch (RemoteException ex) {
366            // ignore it
367        }
368
369        return result;
370    }
371
372    /**
373     * Get the count of active SUB(s)
374     * @return active SIM count
375     * @hide
376     */
377    public static int getActiveSubInfoCount() {
378        int result = 0;
379
380        try {
381            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
382            if (iSub != null) {
383                result = iSub.getActiveSubInfoCount();
384            }
385        } catch (RemoteException ex) {
386            // ignore it
387        }
388
389        return result;
390    }
391
392    /**
393     * Add a new SubInfoRecord to subinfo database if needed
394     * @param iccId the IccId of the SIM card
395     * @param slotId the slot which the SIM is inserted
396     * @return the URL of the newly created row or the updated row
397     * @hide
398     */
399    public static Uri addSubInfoRecord(String iccId, int slotId) {
400        if (VDBG) logd("[addSubInfoRecord]+ iccId:" + iccId + " slotId:" + slotId);
401        if (iccId == null) {
402            logd("[addSubInfoRecord]- null iccId");
403        }
404        if (!isValidSlotId(slotId)) {
405            logd("[addSubInfoRecord]- invalid slotId");
406        }
407
408        try {
409            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
410            if (iSub != null) {
411                // FIXME: This returns 1 on success, 0 on error should should we return it?
412                iSub.addSubInfoRecord(iccId, slotId);
413            }
414        } catch (RemoteException ex) {
415            // ignore it
416        }
417
418        // FIXME: Always returns null?
419        return null;
420
421    }
422
423    /**
424     * Set SIM color by simInfo index
425     * @param color the color of the SIM
426     * @param subId the unique SubInfoRecord index in database
427     * @return the number of records updated
428     * @hide
429     */
430    public static int setColor(int color, long subId) {
431        if (VDBG) logd("[setColor]+ color:" + color + " subId:" + subId);
432        int size = sSimBackgroundDarkRes.length;
433        if (!isValidSubId(subId) || color < 0 || color >= size) {
434            logd("[setColor]- fail");
435            return -1;
436        }
437
438        int result = 0;
439
440        try {
441            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
442            if (iSub != null) {
443                result = iSub.setColor(color, subId);
444            }
445        } catch (RemoteException ex) {
446            // ignore it
447        }
448
449        return result;
450
451    }
452
453    /**
454     * Set display name by simInfo index
455     * @param displayName the display name of SIM card
456     * @param subId the unique SubInfoRecord index in database
457     * @return the number of records updated
458     * @hide
459     */
460    public static int setDisplayName(String displayName, long subId) {
461        return setDisplayName(displayName, subId, NAME_SOURCE_UNDEFINDED);
462    }
463
464    /**
465     * Set display name by simInfo index with name source
466     * @param displayName the display name of SIM card
467     * @param subId the unique SubInfoRecord index in database
468     * @param nameSource 0: NAME_SOURCE_DEFAULT_SOURCE, 1: NAME_SOURCE_SIM_SOURCE,
469     *                   2: NAME_SOURCE_USER_INPUT, -1 NAME_SOURCE_UNDEFINED
470     * @return the number of records updated or -1 if invalid subId
471     * @hide
472     */
473    public static int setDisplayName(String displayName, long subId, long nameSource) {
474        if (VDBG) {
475            logd("[setDisplayName]+  displayName:" + displayName + " subId:" + subId
476                    + " nameSource:" + nameSource);
477        }
478        if (!isValidSubId(subId)) {
479            logd("[setDisplayName]- fail");
480            return -1;
481        }
482
483        int result = 0;
484
485        try {
486            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
487            if (iSub != null) {
488                result = iSub.setDisplayNameUsingSrc(displayName, subId, nameSource);
489            }
490        } catch (RemoteException ex) {
491            // ignore it
492        }
493
494        return result;
495
496    }
497
498    /**
499     * Set phone number by subId
500     * @param number the phone number of the SIM
501     * @param subId the unique SubInfoRecord index in database
502     * @return the number of records updated
503     * @hide
504     */
505    public static int setDisplayNumber(String number, long subId) {
506        if (number == null || !isValidSubId(subId)) {
507            logd("[setDisplayNumber]- fail");
508            return -1;
509        }
510
511        int result = 0;
512
513        try {
514            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
515            if (iSub != null) {
516                result = iSub.setDisplayNumber(number, subId);
517            }
518        } catch (RemoteException ex) {
519            // ignore it
520        }
521
522        return result;
523
524    }
525
526    /**
527     * Set number display format. 0: none, 1: the first four digits, 2: the last four digits
528     * @param format the display format of phone number
529     * @param subId the unique SubInfoRecord index in database
530     * @return the number of records updated
531     * @hide
532     */
533    public static int setDisplayNumberFormat(int format, long subId) {
534        if (VDBG) logd("[setDisplayNumberFormat]+ format:" + format + " subId:" + subId);
535        if (format < 0 || !isValidSubId(subId)) {
536            logd("[setDisplayNumberFormat]- fail, return -1");
537            return -1;
538        }
539
540        int result = 0;
541
542        try {
543            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
544            if (iSub != null) {
545                result = iSub.setDisplayNumberFormat(format, subId);
546            }
547        } catch (RemoteException ex) {
548            // ignore it
549        }
550
551        return result;
552
553    }
554
555    /**
556     * Set data roaming by simInfo index
557     * @param roaming 0:Don't allow data when roaming, 1:Allow data when roaming
558     * @param subId the unique SubInfoRecord index in database
559     * @return the number of records updated
560     * @hide
561     */
562    public static int setDataRoaming(int roaming, long subId) {
563        if (VDBG) logd("[setDataRoaming]+ roaming:" + roaming + " subId:" + subId);
564        if (roaming < 0 || !isValidSubId(subId)) {
565            logd("[setDataRoaming]- fail");
566            return -1;
567        }
568
569        int result = 0;
570
571        try {
572            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
573            if (iSub != null) {
574                result = iSub.setDataRoaming(roaming, subId);
575            }
576        } catch (RemoteException ex) {
577            // ignore it
578        }
579
580        return result;
581    }
582
583    /** @hide */
584    public static int getSlotId(long subId) {
585        if (!isValidSubId(subId)) {
586            logd("[getSlotId]- fail");
587        }
588
589        int result = INVALID_SLOT_ID;
590
591        try {
592            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
593            if (iSub != null) {
594                result = iSub.getSlotId(subId);
595            }
596        } catch (RemoteException ex) {
597            // ignore it
598        }
599
600        return result;
601
602    }
603
604    /** @hide */
605    public static long[] getSubId(int slotId) {
606        if (!isValidSlotId(slotId)) {
607            logd("[getSubId]- fail");
608            return null;
609        }
610
611        long[] subId = null;
612
613        try {
614            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
615            if (iSub != null) {
616                subId = iSub.getSubId(slotId);
617            }
618        } catch (RemoteException ex) {
619            // ignore it
620        }
621
622        return subId;
623    }
624
625    /** @hide */
626    public static int getPhoneId(long subId) {
627        if (!isValidSubId(subId)) {
628            logd("[getPhoneId]- fail");
629            return INVALID_PHONE_ID;
630        }
631
632        int result = INVALID_PHONE_ID;
633
634        try {
635            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
636            if (iSub != null) {
637                result = iSub.getPhoneId(subId);
638            }
639        } catch (RemoteException ex) {
640            // ignore it
641        }
642
643        if (VDBG) logd("[getPhoneId]- phoneId=" + result);
644        return result;
645
646    }
647
648    private static int[] setSimResource(int type) {
649        int[] simResource = null;
650
651        switch (type) {
652            case RES_TYPE_BACKGROUND_DARK:
653                simResource = new int[] {
654                    com.android.internal.R.drawable.sim_dark_blue,
655                    com.android.internal.R.drawable.sim_dark_orange,
656                    com.android.internal.R.drawable.sim_dark_green,
657                    com.android.internal.R.drawable.sim_dark_purple
658                };
659                break;
660            case RES_TYPE_BACKGROUND_LIGHT:
661                simResource = new int[] {
662                    com.android.internal.R.drawable.sim_light_blue,
663                    com.android.internal.R.drawable.sim_light_orange,
664                    com.android.internal.R.drawable.sim_light_green,
665                    com.android.internal.R.drawable.sim_light_purple
666                };
667                break;
668        }
669
670        return simResource;
671    }
672
673    private static void logd(String msg) {
674        Rlog.d(LOG_TAG, "[SubManager] " + msg);
675    }
676
677    /**
678     * @return the "system" defaultSubId on a voice capable device this
679     * will be getDefaultVoiceSubId() and on a data only device it will be
680     * getDefaultDataSubId().
681     * @hide
682     */
683    public static long getDefaultSubId() {
684        long subId = INVALID_SUB_ID;
685
686        try {
687            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
688            if (iSub != null) {
689                subId = iSub.getDefaultSubId();
690            }
691        } catch (RemoteException ex) {
692            // ignore it
693        }
694
695        if (VDBG) logd("getDefaultSubId=" + subId);
696        return subId;
697    }
698
699    /** @hide */
700    public static long getDefaultVoiceSubId() {
701        long subId = INVALID_SUB_ID;
702
703        try {
704            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
705            if (iSub != null) {
706                subId = iSub.getDefaultVoiceSubId();
707            }
708        } catch (RemoteException ex) {
709            // ignore it
710        }
711
712        if (VDBG) logd("getDefaultVoiceSubId, sub id = " + subId);
713        return subId;
714    }
715
716    /** @hide */
717    public static void setDefaultVoiceSubId(long subId) {
718        if (VDBG) logd("setDefaultVoiceSubId sub id = " + subId);
719        try {
720            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
721            if (iSub != null) {
722                iSub.setDefaultVoiceSubId(subId);
723            }
724        } catch (RemoteException ex) {
725            // ignore it
726        }
727    }
728
729    /** @hide */
730    public static SubInfoRecord getDefaultVoiceSubInfo() {
731        return getSubInfoUsingSubId(getDefaultVoiceSubId());
732    }
733
734    /** @hide */
735    public static int getDefaultVoicePhoneId() {
736        return getPhoneId(getDefaultVoiceSubId());
737    }
738
739    /** @hide */
740    public static long getDefaultSmsSubId() {
741        long subId = INVALID_SUB_ID;
742
743        try {
744            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
745            if (iSub != null) {
746                subId = iSub.getDefaultSmsSubId();
747            }
748        } catch (RemoteException ex) {
749            // ignore it
750        }
751
752        if (VDBG) logd("getDefaultSmsSubId, sub id = " + subId);
753        return subId;
754    }
755
756    /** @hide */
757    public static void setDefaultSmsSubId(long subId) {
758        if (VDBG) logd("setDefaultSmsSubId sub id = " + subId);
759        try {
760            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
761            if (iSub != null) {
762                iSub.setDefaultSmsSubId(subId);
763            }
764        } catch (RemoteException ex) {
765            // ignore it
766        }
767    }
768
769    /** @hide */
770    public static SubInfoRecord getDefaultSmsSubInfo() {
771        return getSubInfoUsingSubId(getDefaultSmsSubId());
772    }
773
774    /** @hide */
775    public static int getDefaultSmsPhoneId() {
776        return getPhoneId(getDefaultSmsSubId());
777    }
778
779    /** @hide */
780    public static long getDefaultDataSubId() {
781        long subId = INVALID_SUB_ID;
782
783        try {
784            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
785            if (iSub != null) {
786                subId = iSub.getDefaultDataSubId();
787            }
788        } catch (RemoteException ex) {
789            // ignore it
790        }
791
792        if (VDBG) logd("getDefaultDataSubId, sub id = " + subId);
793        return subId;
794    }
795
796    /** @hide */
797    public static void setDefaultDataSubId(long subId) {
798        if (VDBG) logd("setDataSubscription sub id = " + subId);
799        try {
800            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
801            if (iSub != null) {
802                iSub.setDefaultDataSubId(subId);
803            }
804        } catch (RemoteException ex) {
805            // ignore it
806        }
807    }
808
809    /** @hide */
810    public static SubInfoRecord getDefaultDataSubInfo() {
811        return getSubInfoUsingSubId(getDefaultDataSubId());
812    }
813
814    /** @hide */
815    public static int getDefaultDataPhoneId() {
816        return getPhoneId(getDefaultDataSubId());
817    }
818
819    /** @hide */
820    public static void clearSubInfo() {
821        try {
822            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
823            if (iSub != null) {
824                iSub.clearSubInfo();
825            }
826        } catch (RemoteException ex) {
827            // ignore it
828        }
829
830        return;
831    }
832
833    //FIXME this is vulnerable to race conditions
834    /** @hide */
835    public static boolean allDefaultsSelected() {
836        if (getDefaultDataSubId() == INVALID_SUB_ID) {
837            return false;
838        }
839        if (getDefaultSmsSubId() == INVALID_SUB_ID) {
840            return false;
841        }
842        if (getDefaultVoiceSubId() == INVALID_SUB_ID) {
843            return false;
844        }
845        return true;
846    }
847
848    /**
849     * If a default is set to subscription which is not active, this will reset that default back to
850     * INVALID_SUB_ID.
851     * @hide
852     */
853    public static void clearDefaultsForInactiveSubIds() {
854        if (VDBG) logd("clearDefaultsForInactiveSubIds");
855        try {
856            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
857            if (iSub != null) {
858                iSub.clearDefaultsForInactiveSubIds();
859            }
860        } catch (RemoteException ex) {
861            // ignore it
862        }
863    }
864
865    /** @hide */
866    public static boolean isValidSubId(long subId) {
867        return subId > INVALID_SUB_ID ;
868    }
869
870    /** @hide */
871    public static boolean isValidSlotId(int slotId) {
872        return slotId > INVALID_SLOT_ID && slotId < TelephonyManager.getDefault().getSimCount();
873    }
874
875    /** @hide */
876    public static boolean isValidPhoneId(int phoneId) {
877        return phoneId > INVALID_PHONE_ID
878                && phoneId < TelephonyManager.getDefault().getPhoneCount();
879    }
880
881    /** @hide */
882    public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId) {
883        long[] subIds = SubscriptionManager.getSubId(phoneId);
884        if (subIds != null && subIds.length > 0) {
885            putPhoneIdAndSubIdExtra(intent, phoneId, subIds[0]);
886        } else {
887            logd("putPhoneIdAndSubIdExtra: no valid subs");
888        }
889    }
890
891    /** @hide */
892    public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId, long subId) {
893        if (VDBG) logd("putPhoneIdAndSubIdExtra: phoneId=" + phoneId + " subId=" + subId);
894        intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
895        intent.putExtra(PhoneConstants.PHONE_KEY, phoneId);
896        //FIXME this is using phoneId and slotId interchangeably
897        //Eventually, this should be removed as it is not the slot id
898        intent.putExtra(PhoneConstants.SLOT_KEY, phoneId);
899    }
900
901    /**
902     * @return the list of subId's that are active,
903     *         is never null but the length maybe 0.
904     * @hide
905     */
906    public static long[] getActiveSubIdList() {
907        long[] subId = null;
908
909        try {
910            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
911            if (iSub != null) {
912                subId = iSub.getActiveSubIdList();
913            }
914        } catch (RemoteException ex) {
915            // ignore it
916        }
917
918        if (subId == null) {
919            subId = new long[0];
920        }
921
922        return subId;
923
924    }
925}
926
927