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