-->handleMessage(EVENT_SIM_LOADED)caseEVENT_SIM_LOADED:handleSimLoaded(msg.arg1);break;--> handleSimLoaded
protectedvoidhandleSimLoaded(int phoneId){logd("handleSimLoaded: phoneId: "+ phoneId);// The SIM should be loaded at this state, but it is possible in cases such as SIM being// removed or a refresh RESET that the IccRecords could be null. The right behavior is to// not broadcast the SIM loaded.IccCard iccCard =PhoneFactory.getPhone(phoneId).getIccCard();if(iccCard ==null){// Possibly a race condition.logd("handleSimLoaded: IccCard null");return;}IccRecords records = iccCard.getIccRecords();if(records ==null){// Possibly a race condition.logd("handleSimLoaded: IccRecords null");return;}if(IccUtils.stripTrailingFs(records.getFullIccId())==null){logd("handleSimLoaded: IccID null");return;}// Call updateSubscriptionInfoByIccId() only if was not done earlier from SIM READY eventif(sIccId[phoneId]==null){
sIccId[phoneId]=IccUtils.stripTrailingFs(records.getFullIccId());updateSubscriptionInfoByIccId(phoneId,true/* updateEmbeddedSubs */);//更新}List<SubscriptionInfo> subscriptionInfos =
mSubscriptionController.getSubInfoUsingSlotIndexPrivileged(phoneId);//获取subinfoif(subscriptionInfos ==null|| subscriptionInfos.isEmpty()){loge("empty subinfo for phoneId: "+ phoneId +"could not update ContentResolver");}else{for(SubscriptionInfo sub : subscriptionInfos){int subId = sub.getSubscriptionId();TelephonyManager tm =(TelephonyManager)
sContext.getSystemService(Context.TELEPHONY_SERVICE);String operator = tm.getSimOperatorNumeric(subId);if(!TextUtils.isEmpty(operator)){if(subId == mSubscriptionController.getDefaultSubId()){MccTable.updateMccMncConfiguration(sContext, operator);}
mSubscriptionController.setMccMnc(operator, subId);}else{logd("EVENT_RECORDS_LOADED Operator name is null");}String iso = tm.getSimCountryIsoForPhone(phoneId);if(!TextUtils.isEmpty(iso)){
mSubscriptionController.setCountryIso(iso, subId);}else{logd("EVENT_RECORDS_LOADED sim country iso is null");}String msisdn = tm.getLine1Number(subId);if(msisdn !=null){
mSubscriptionController.setDisplayNumber(msisdn, subId);}String imsi = tm.createForSubscriptionId(subId).getSubscriberId();if(imsi !=null){
mSubscriptionController.setImsi(imsi, subId);}String[] ehplmns = records.getEhplmns();String[] hplmns = records.getPlmnsFromHplmnActRecord();if(ehplmns !=null|| hplmns !=null){
mSubscriptionController.setAssociatedPlmns(ehplmns, hplmns, subId);}/* Update preferred network type and network selection mode on SIM change.
* Storing last subId in SharedPreference for now to detect SIM change.
*/SharedPreferences sp =PreferenceManager.getDefaultSharedPreferences(sContext);int storedSubId = sp.getInt(CURR_SUBID+ phoneId,-1);if(storedSubId != subId){// Only support automatic selection mode on SIM change.PhoneFactory.getPhone(phoneId).getNetworkSelectionMode(obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE,newInteger(phoneId)));// Update stored subIdSharedPreferences.Editor editor = sp.edit();
editor.putInt(CURR_SUBID+ phoneId, subId);
editor.apply();}}}/**
* The sim loading sequence will be
* 1. ACTION_SUBINFO_CONTENT_CHANGE happens through updateSubscriptionInfoByIccId() above.
* 2. ACTION_SIM_STATE_CHANGED/ACTION_SIM_CARD_STATE_CHANGED
* /ACTION_SIM_APPLICATION_STATE_CHANGED
* 3. ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED
* 4. restore sim-specific settings
* 5. ACTION_CARRIER_CONFIG_CHANGED
*/broadcastSimStateChanged(phoneId,IccCardConstants.INTENT_VALUE_ICC_LOADED,null);broadcastSimCardStateChanged(phoneId,TelephonyManager.SIM_STATE_PRESENT);broadcastSimApplicationStateChanged(phoneId,TelephonyManager.SIM_STATE_LOADED);updateSubscriptionCarrierId(phoneId,IccCardConstants.INTENT_VALUE_ICC_LOADED);/* Sim-specific settings restore depends on knowing both the mccmnc and the carrierId of the
sim which is why it must be done after #updateSubscriptionCarrierId(). It is done before
carrier config update to avoid any race conditions with user settings that depend on
carrier config*/restoreSimSpecificSettingsForPhone(phoneId);updateCarrierServices(phoneId,IccCardConstants.INTENT_VALUE_ICC_LOADED);}
--> 看一下更新 updateSubscriptionInfoByIccId()protectedsynchronizedvoidupdateSubscriptionInfoByIccId(int phoneId,boolean updateEmbeddedSubs){logd("updateSubscriptionInfoByIccId:+ Start - phoneId: "+ phoneId);if(!SubscriptionManager.isValidPhoneId(phoneId)){loge("[updateSubscriptionInfoByIccId]- invalid phoneId="+ phoneId);return;}logd("updateSubscriptionInfoByIccId: removing subscription info record: phoneId "+ phoneId);// Clear phoneId only when sim absent is not enough. It's possible to switch SIM profile// within the same slot. Need to clear the slot index of the previous sub. Thus always clear// for the changing slot first.
mSubscriptionController.clearSubInfoRecord(phoneId);// If SIM is not absent, insert new record or update existing record.if(!ICCID_STRING_FOR_NO_SIM.equals(sIccId[phoneId])&& sIccId[phoneId]!=null){logd("updateSubscriptionInfoByIccId: adding subscription info record: iccid: "+ sIccId[phoneId]+", phoneId:"+ phoneId);
mSubscriptionManager.addSubscriptionInfoRecord(sIccId[phoneId], phoneId);}List<SubscriptionInfo> subInfos =
mSubscriptionController.getSubInfoUsingSlotIndexPrivileged(phoneId);if(subInfos !=null){boolean changed =false;for(int i =0; i < subInfos.size(); i++){SubscriptionInfo temp = subInfos.get(i);ContentValues value =newContentValues(1);String msisdn =TelephonyManager.getDefault().getLine1Number(
temp.getSubscriptionId());if(!TextUtils.equals(msisdn, temp.getNumber())){
value.put(SubscriptionManager.NUMBER, msisdn);
sContext.getContentResolver().update(SubscriptionManager.getUriForSubscriptionId(temp.getSubscriptionId()), value,null,null);
changed =true;}}if(changed){// refresh Cached Active Subscription Info List
mSubscriptionController.refreshCachedActiveSubscriptionInfoList();}}// TODO investigate if we can update for each slot separately.if(isAllIccIdQueryDone()){// Ensure the modems are mapped correctlyif(mSubscriptionManager.isActiveSubId(
mSubscriptionManager.getDefaultDataSubscriptionId())){
mSubscriptionManager.setDefaultDataSubId(
mSubscriptionManager.getDefaultDataSubscriptionId());}else{logd("bypass reset default data sub if inactive");}setSubInfoInitialized();}UiccController uiccController =UiccController.getInstance();UiccSlot[] uiccSlots = uiccController.getUiccSlots();if(uiccSlots !=null&& updateEmbeddedSubs){List<Integer> cardIds =newArrayList<>();for(UiccSlot uiccSlot : uiccSlots){if(uiccSlot !=null&& uiccSlot.getUiccCard()!=null){int cardId = uiccController.convertToPublicCardId(
uiccSlot.getUiccCard().getCardId());
cardIds.add(cardId);}}updateEmbeddedSubscriptions(cardIds,(hasChanges)->{if(hasChanges){
mSubscriptionController.notifySubscriptionInfoChanged();}if(DBG)logd("updateSubscriptionInfoByIccId: SubscriptionInfo update complete");});}
mSubscriptionController.notifySubscriptionInfoChanged();if(DBG)logd("updateSubscriptionInfoByIccId: SubscriptionInfo update complete");}
--> 查询TelephonySQLite数据库的siminfo表
SubscriptionController.getSubInfoUsingSlotIndexPrivileged
publicList<SubscriptionInfo>getSubInfoUsingSlotIndexPrivileged(int slotIndex){if(DBG)logd("[getSubInfoUsingSlotIndexPrivileged]+ slotIndex:"+ slotIndex);if(slotIndex ==SubscriptionManager.DEFAULT_SIM_SLOT_INDEX){
slotIndex =getSlotIndex(getDefaultSubId());}if(!SubscriptionManager.isValidSlotIndex(slotIndex)){if(DBG)logd("[getSubInfoUsingSlotIndexPrivileged]- invalid slotIndex");returnnull;}Cursor cursor = mContext.getContentResolver().query(SubscriptionManager.CONTENT_URI,null,SubscriptionManager.SIM_SLOT_INDEX+"=?",newString[]{String.valueOf(slotIndex)},null);ArrayList<SubscriptionInfo> subList =null;try{if(cursor !=null){while(cursor.moveToNext()){SubscriptionInfo subInfo =getSubInfoRecord(cursor);if(subInfo !=null){if(subList ==null){
subList =newArrayList<SubscriptionInfo>();}
subList.add(subInfo);}}}}finally{if(cursor !=null){
cursor.close();}}if(DBG)logd("[getSubInfoUsingSlotIndex]- null info return");return subList;}--> 将siminfo表中的字段值封装到SubscriptionInfo对象的属性中,然后返回对象。
getSubInfoRecord()privateSubscriptionInfogetSubInfoRecord(Cursor cursor){int id = cursor.getInt(cursor.getColumnIndexOrThrow(SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID));String iccId = cursor.getString(cursor.getColumnIndexOrThrow(SubscriptionManager.ICC_ID));int simSlotIndex = cursor.getInt(cursor.getColumnIndexOrThrow(SubscriptionManager.SIM_SLOT_INDEX));String displayName = cursor.getString(cursor.getColumnIndexOrThrow(SubscriptionManager.DISPLAY_NAME));String carrierName = cursor.getString(cursor.getColumnIndexOrThrow(SubscriptionManager.CARRIER_NAME));int nameSource = cursor.getInt(cursor.getColumnIndexOrThrow(SubscriptionManager.NAME_SOURCE));int iconTint = cursor.getInt(cursor.getColumnIndexOrThrow(SubscriptionManager.HUE));String number = cursor.getString(cursor.getColumnIndexOrThrow(SubscriptionManager.NUMBER));int dataRoaming = cursor.getInt(cursor.getColumnIndexOrThrow(SubscriptionManager.DATA_ROAMING));String mcc = cursor.getString(cursor.getColumnIndexOrThrow(SubscriptionManager.MCC_STRING));String mnc = cursor.getString(cursor.getColumnIndexOrThrow(SubscriptionManager.MNC_STRING));String ehplmnsRaw = cursor.getString(cursor.getColumnIndexOrThrow(SubscriptionManager.EHPLMNS));String hplmnsRaw = cursor.getString(cursor.getColumnIndexOrThrow(SubscriptionManager.HPLMNS));String[] ehplmns = ehplmnsRaw ==null?null: ehplmnsRaw.split(",");String[] hplmns = hplmnsRaw ==null?null: hplmnsRaw.split(",");// cardId is the private ICCID/EID string, also known as the card stringString cardId = cursor.getString(cursor.getColumnIndexOrThrow(SubscriptionManager.CARD_ID));String countryIso = cursor.getString(cursor.getColumnIndexOrThrow(SubscriptionManager.ISO_COUNTRY_CODE));// publicCardId is the publicly exposed int card IDint publicCardId = mUiccController.convertToPublicCardId(cardId);boolean isEmbedded = cursor.getInt(cursor.getColumnIndexOrThrow(SubscriptionManager.IS_EMBEDDED))==1;int carrierId = cursor.getInt(cursor.getColumnIndexOrThrow(SubscriptionManager.CARRIER_ID));UiccAccessRule[] accessRules;if(isEmbedded){
accessRules =UiccAccessRule.decodeRules(cursor.getBlob(
cursor.getColumnIndexOrThrow(SubscriptionManager.ACCESS_RULES)));}else{
accessRules =null;}UiccAccessRule[] carrierConfigAccessRules =UiccAccessRule.decodeRules(cursor.getBlob(
cursor.getColumnIndexOrThrow(SubscriptionManager.ACCESS_RULES_FROM_CARRIER_CONFIGS)));boolean isOpportunistic = cursor.getInt(cursor.getColumnIndexOrThrow(SubscriptionManager.IS_OPPORTUNISTIC))==1;String groupUUID = cursor.getString(cursor.getColumnIndexOrThrow(SubscriptionManager.GROUP_UUID));int profileClass = cursor.getInt(cursor.getColumnIndexOrThrow(SubscriptionManager.PROFILE_CLASS));int portIndex = cursor.getInt(cursor.getColumnIndexOrThrow(SubscriptionManager.PORT_INDEX));int subType = cursor.getInt(cursor.getColumnIndexOrThrow(SubscriptionManager.SUBSCRIPTION_TYPE));String groupOwner =getOptionalStringFromCursor(cursor,SubscriptionManager.GROUP_OWNER,/*defaultVal*/null);boolean areUiccApplicationsEnabled = cursor.getInt(cursor.getColumnIndexOrThrow(SubscriptionManager.UICC_APPLICATIONS_ENABLED))==1;int usageSetting = cursor.getInt(cursor.getColumnIndexOrThrow(SubscriptionManager.USAGE_SETTING));if(VDBG){String iccIdToPrint =SubscriptionInfo.givePrintableIccid(iccId);String cardIdToPrint =SubscriptionInfo.givePrintableIccid(cardId);logd("[getSubInfoRecord] id:"+ id +" iccid:"+ iccIdToPrint +" simSlotIndex:"+ simSlotIndex +" carrierid:"+ carrierId +" displayName:"+ displayName
+" nameSource:"+ nameSource +" iconTint:"+ iconTint
+" dataRoaming:"+ dataRoaming +" mcc:"+ mcc +" mnc:"+ mnc
+" countIso:"+ countryIso +" isEmbedded:"+ isEmbedded +" accessRules:"+Arrays.toString(accessRules)+" carrierConfigAccessRules: "+Arrays.toString(carrierConfigAccessRules)+" cardId:"+ cardIdToPrint +" portIndex:"+ portIndex
+" publicCardId:"+ publicCardId
+" isOpportunistic:"+ isOpportunistic +" groupUUID:"+ groupUUID
+" profileClass:"+ profileClass +" subscriptionType: "+ subType
+" carrierConfigAccessRules:"+ carrierConfigAccessRules
+" areUiccApplicationsEnabled: "+ areUiccApplicationsEnabled
+" usageSetting: "+ usageSetting);}// If line1number has been set to a different number, use it instead.String line1Number = mTelephonyManager.getLine1Number(id);if(!TextUtils.isEmpty(line1Number)&&!line1Number.equals(number)){
number = line1Number;}// FIXME(b/210771052): constructing a complete SubscriptionInfo requires a port index,// but the port index isn't available here. Should it actually be part of SubscriptionInfo?SubscriptionInfo info =newSubscriptionInfo(id, iccId, simSlotIndex, displayName,
carrierName, nameSource, iconTint, number, dataRoaming,/* icon= */null,
mcc, mnc, countryIso, isEmbedded, accessRules, cardId, publicCardId,
isOpportunistic, groupUUID,/* isGroupDisabled= */false, carrierId, profileClass,
subType, groupOwner, carrierConfigAccessRules, areUiccApplicationsEnabled,
portIndex, usageSetting);
info.setAssociatedPlmns(ehplmns, hplmns);return info;}