1. isub系统服务的创建和发布
开机启动
--> PhoneApp.onCreate()
--> PhoneGlobal.onCreate()
--> PhoneFactory.makeDefaultPhones(this);
--> TelephonyComponentFactory.getInstance().inject(SubscriptionController.class.getName())
.initSubscriptionController(context);
--> SubscriptionController.init()
public static SubscriptionController init(Context c) {
synchronized (SubscriptionController.class) {
if (sInstance == null) {
sInstance = new SubscriptionController(c);
} else {
Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance);
}
return sInstance;
}
}
--> new SubscriptionController()
protected SubscriptionController(Context c) {
internalInit(c);
migrateImsSettings();
}
--> internalInit()
protected void internalInit(Context c) {
mContext = c;
mTelephonyManager = TelephonyManager.from(mContext);
try {
mUiccController = UiccController.getInstance();
} catch(RuntimeException ex) {
throw new RuntimeException(
"UiccController has to be initialised before SubscriptionController init");
}
mAppOps = (AppOpsManager)mContext.getSystemService(Context.APP_OPS_SERVICE);
ServiceRegisterer subscriptionServiceRegisterer = TelephonyFrameworkInitializer
.getTelephonyServiceManager()
.getSubscriptionServiceRegisterer();
if (subscriptionServiceRegisterer.get() == null) {
subscriptionServiceRegisterer.register(this);
mLastISubServiceRegTime = System.currentTimeMillis();
}
clearSlotIndexForSubInfoRecords();
cacheSettingValues();
invalidateDefaultSubIdCaches();
invalidateDefaultDataSubIdCaches();
invalidateDefaultSmsSubIdCaches();
invalidateActiveDataSubIdCaches();
invalidateSlotIndexCaches();
mContext.getContentResolver().registerContentObserver(
SubscriptionManager.SIM_INFO_SUW_RESTORE_CONTENT_URI, false,
new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange, Uri uri) {
if (uri.equals(SubscriptionManager.SIM_INFO_SUW_RESTORE_CONTENT_URI)) {
refreshCachedActiveSubscriptionInfoList();
notifySubscriptionInfoChanged();
SubscriptionManager subManager = SubscriptionManager.from(mContext);
for (SubscriptionInfo subInfo : getActiveSubscriptionInfoList(
mContext.getOpPackageName(), mContext.getAttributionTag())) {
if (SubscriptionController.getInstance()
.isActiveSubId(subInfo.getSubscriptionId())) {
ImsManager imsManager = ImsManager.getInstance(mContext,
subInfo.getSimSlotIndex());
imsManager.updateImsServiceConfig();
}
}
}
}
});
if (DBG) logdl("[SubscriptionController] init by Context");
}
--> subscriptionServiceRegisterer.register(this);
2. SIM卡加载
--> SubscriptionInfoUpdater.updateInternalIccState()
public void updateInternalIccState(String simStatus, String reason, int phoneId) {
logd("updateInternalIccState to simStatus " + simStatus + " reason " + reason
+ " phoneId " + phoneId);
int message = internalIccStateToMessage(simStatus);
if (message != EVENT_INVALID) {
sendMessage(obtainMessage(message, phoneId, 0, reason));
}
}
--> internalIccStateToMessage(simStatus)
private int internalIccStateToMessage(String simStatus) {
switch(simStatus) {
case IccCardConstants.INTENT_VALUE_ICC_ABSENT: return EVENT_SIM_ABSENT;
case IccCardConstants.INTENT_VALUE_ICC_UNKNOWN: return EVENT_SIM_UNKNOWN;
case IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR: return EVENT_SIM_IO_ERROR;
case IccCardConstants.INTENT_VALUE_ICC_CARD_RESTRICTED: return EVENT_SIM_RESTRICTED;
case IccCardConstants.INTENT_VALUE_ICC_NOT_READY: return EVENT_SIM_NOT_READY;
case IccCardConstants.INTENT_VALUE_ICC_LOCKED: return EVENT_SIM_LOCKED;
case IccCardConstants.INTENT_VALUE_ICC_LOADED: return EVENT_SIM_LOADED;
case IccCardConstants.INTENT_VALUE_ICC_READY: return EVENT_SIM_READY;
case IccCardConstants.INTENT_VALUE_ICC_IMSI: return EVENT_SIM_IMSI;
default:
logd("Ignoring simStatus: " + simStatus);
return EVENT_INVALID;
}
}
--> handleMessage(EVENT_SIM_LOADED)
case EVENT_SIM_LOADED:
handleSimLoaded(msg.arg1);
break;
--> handleSimLoaded
protected void handleSimLoaded(int phoneId) {
logd("handleSimLoaded: phoneId: " + phoneId);
IccCard iccCard = PhoneFactory.getPhone(phoneId).getIccCard();
if (iccCard == null) {
logd("handleSimLoaded: IccCard null");
return;
}
IccRecords records = iccCard.getIccRecords();
if (records == null) {
logd("handleSimLoaded: IccRecords null");
return;
}
if (IccUtils.stripTrailingFs(records.getFullIccId()) == null) {
logd("handleSimLoaded: IccID null");
return;
}
if (sIccId[phoneId] == null) {
sIccId[phoneId] = IccUtils.stripTrailingFs(records.getFullIccId());
updateSubscriptionInfoByIccId(phoneId, true );
}
List<SubscriptionInfo> subscriptionInfos =
mSubscriptionController.getSubInfoUsingSlotIndexPrivileged(phoneId);
if (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);
}
SharedPreferences sp =
PreferenceManager.getDefaultSharedPreferences(sContext);
int storedSubId = sp.getInt(CURR_SUBID + phoneId, -1);
if (storedSubId != subId) {
PhoneFactory.getPhone(phoneId).getNetworkSelectionMode(
obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE,
new Integer(phoneId)));
SharedPreferences.Editor editor = sp.edit();
editor.putInt(CURR_SUBID + phoneId, subId);
editor.apply();
}
}
}
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);
restoreSimSpecificSettingsForPhone(phoneId);
updateCarrierServices(phoneId, IccCardConstants.INTENT_VALUE_ICC_LOADED);
}
--> 看一下更新 updateSubscriptionInfoByIccId()
protected synchronized void updateSubscriptionInfoByIccId(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);
mSubscriptionController.clearSubInfoRecord(phoneId);
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 = new ContentValues(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) {
mSubscriptionController.refreshCachedActiveSubscriptionInfoList();
}
}
if (isAllIccIdQueryDone()) {
if (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 = new ArrayList<>();
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");
}
--> 查询Telephony SQLite数据库的siminfo表
SubscriptionController.getSubInfoUsingSlotIndexPrivileged
public List<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");
return null;
}
Cursor cursor = mContext.getContentResolver().query(SubscriptionManager.CONTENT_URI,
null, SubscriptionManager.SIM_SLOT_INDEX + "=?",
new String[]{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 = new ArrayList<SubscriptionInfo>();
}
subList.add(subInfo);
}
}
}
} finally {
if (cursor != null) {
cursor.close();
}
}
if (DBG) logd("[getSubInfoUsingSlotIndex]- null info return");
return subList;
}
--> 将siminfo表中的字段值封装到SubscriptionInfo对象的属性中,然后返回对象。
getSubInfoRecord()
private SubscriptionInfo getSubInfoRecord(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(",");
String cardId = cursor.getString(cursor.getColumnIndexOrThrow(
SubscriptionManager.CARD_ID));
String countryIso = cursor.getString(cursor.getColumnIndexOrThrow(
SubscriptionManager.ISO_COUNTRY_CODE));
int 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,
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);
}
String line1Number = mTelephonyManager.getLine1Number(id);
if (!TextUtils.isEmpty(line1Number) && !line1Number.equals(number)) {
number = line1Number;
}
SubscriptionInfo info = new SubscriptionInfo(id, iccId, simSlotIndex, displayName,
carrierName, nameSource, iconTint, number, dataRoaming, null,
mcc, mnc, countryIso, isEmbedded, accessRules, cardId, publicCardId,
isOpportunistic, groupUUID, false , carrierId, profileClass,
subType, groupOwner, carrierConfigAccessRules, areUiccApplicationsEnabled,
portIndex, usageSetting);
info.setAssociatedPlmns(ehplmns, hplmns);
return info;
}