SIM卡加载
程序员文章站
2022-09-16 20:38:24
SIM卡加载流程...
SIM卡加载流程
先了解一下,双卡双待,首先Android手机一般都是双卡的情况
每一张卡都会创建一个Phone,比如两张卡 就会创建两个Phone
一,初始化流程,注册流程
首先来看一下DcTracker构造函数
//***** Constructor
public DcTracker(Phone phone, int transportType) {
super();
//每个Phone对象有自己DcTracker
//每个DcTracker加载各自卡可用的APN
mPhone = phone;
if (DBG) log("DCT.constructor");
mTransportType = transportType;
mDataServiceManager = new DataServiceManager(phone, transportType);
mResolver = mPhone.getContext().getContentResolver();
//监听卡载入
mUiccController = UiccController.getInstance();
mUiccController.registerForIccChanged(this, DctConstants.EVENT_ICC_CHANGED, null);
mAlarmManager =
(AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
mCm = (ConnectivityManager) mPhone.getContext().getSystemService(
Context.CONNECTIVITY_SERVICE);
mDataEnabledSettings = new DataEnabledSettings(phone);
mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
mAutoAttachOnCreation.set(sp.getBoolean(Phone.DATA_DISABLED_ON_BOOT_KEY, false));
//监听卡信息变化
mSubscriptionManager = SubscriptionManager.from(mPhone.getContext());
mSubscriptionManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
HandlerThread dcHandlerThread = new HandlerThread("DcHandlerThread");
dcHandlerThread.start();
Handler dcHandler = new Handler(dcHandlerThread.getLooper());
mDcc = DcController.makeDcc(mPhone, this, mDataServiceManager, dcHandler);
mDcTesterFailBringUpAll = new DcTesterFailBringUpAll(mPhone, dcHandler);
mDataConnectionTracker = this;
registerForAllEvents();
update();
//监听APN数据库变化
mApnObserver = new ApnChangeObserver();
phone.getContext().getContentResolver().registerContentObserver(
Telephony.Carriers.CONTENT_URI, true, mApnObserver);
//初始化不同APN类型对应的网络能力
initApnContexts();
for (ApnContext apnContext : mApnContexts.values()) {
// Register the reconnect and restart actions.
filter = new IntentFilter();
filter.addAction(INTENT_RECONNECT_ALARM + '.' + apnContext.getApnType());
mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
}
// 默认情况下,将紧急APN添加到APN设置列表,以在不存在情况下支持EPDN
initEmergencyApnSetting();
addEmergencyApnSetting();
mProvisionActionName = "com.android.internal.telephony.PROVISION" + phone.getPhoneId();
mSettingsObserver = new SettingsObserver(mPhone.getContext(), this);
registerSettingsObserver();
}
这一块可能需要看一些注册,监听卡载入(UiccController.getInstance())。还有监听卡的变换, mSubscriptionManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
二,插卡加载
在PhoneFactory.java中初始化UiccController对象,通过ProxyController.getInstance(....) 注册。
当插入卡的情况下会触发UiccController,EVENT_ICC_STATUS_CHANGED。
UiccController.java
@Override
public void handleMessage (Message msg) {
synchronized (mLock) {
//1.首先从Message中取出PhoneId
Integer phoneId = getCiIndex(msg);
}
switch (msg.what) {
case EVENT_ICC_STATUS_CHANGED: //如果拔卡和插卡就会触发到这个位置
Log.v("InitSimCartId","事件注册 : 对ICC状态的任何更改触发 EVENT_ICC_STATUS_CHANGED ");
if (DBG) log("Received EVENT_ICC_STATUS_CHANGED, calling getIccCardStatus");
//2.查询当前SIM卡的状态
mCis[phoneId].getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE,
phoneId));
break;
....
.....
.....
}
}
向RIL查询当前SIM卡的状态,EVENT_GET_ICC_STATUS_DONE
通过RIL交互机制。
UiccController.java
/**
* 实例化UiccCard对象
*当查询SIM卡的状态完毕后,先从result中解析出IccCardStatus,
* 依据IccCardStatus来创建UiccCard对象, 一个UiccCard 对象代表着一张SIM卡;
* 如果UiccCard对象已存在就直接调它的update()方法更新UiccCard的信息。
*/
private synchronized void onGetIccCardStatusDone(AsyncResult ar, Integer index) {
if (ar.exception != null) {
Rlog.e(LOG_TAG,"Error getting ICC status. "
+ "RIL_REQUEST_GET_ICC_STATUS should "
+ "never return an error", ar.exception);
return;
}
if (!isValidPhoneIndex(index)) {
Rlog.e(LOG_TAG,"onGetIccCardStatusDone: invalid index : " + index);
return;
}
IccCardStatus status = (IccCardStatus)ar.result;
sLocalLog.log("onGetIccCardStatusDone: phoneId " + index + " IccCardStatus: " + status);
int slotId = status.physicalSlotIndex;
if (VDBG) log("onGetIccCardStatusDone: phoneId " + index + " physicalSlotIndex " + slotId);
if (slotId == INVALID_SLOT_ID) {
slotId = index;
}
mPhoneIdToSlotId[index] = slotId;
if (VDBG) logPhoneIdToSlotIdMapping();
//创建或更新UiccCard
if (mUiccSlots[slotId] == null) {
if (VDBG) {
log("Creating mUiccSlots[" + slotId + "]; mUiccSlots.length = "
+ mUiccSlots.length);
}
//Create new card 调的是4个参数的构造方法
mUiccSlots[slotId] = new UiccSlot(mContext, true);
}
//最后调用的还是update方法
mUiccSlots[slotId].update(mCis[index], status, index);
if (DBG) log("Notifying IccChangedRegistrants");
//通知监听UiccController的监听者
mIccChangedRegistrants.notifyRegistrants(new AsyncResult(null, index, null));
}
DcTracker.java
@Override
public void handleMessage (Message msg) {
if (VDBG) log("handleMessage msg=" + msg);
....
......
switch (msg.what) {
....
.....
case DctConstants.EVENT_ICC_CHANGED: {
onUpdateIcc();
break;
}
....
}
}
进入onUpdateIcc();其中会注册IccRecord ,观察卡的信息是否载入成功
private void onUpdateIcc() {
if (mUiccController == null ) {
return;
}
IccRecords newIccRecords = mPhone.getIccRecords();
IccRecords r = mIccRecords.get();
if (r != newIccRecords) {
//移除对旧有信息的记录
if (r != null) {
log("Removing stale icc objects.");
r.unregisterForRecordsLoaded(this);
mIccRecords.set(null);
}
if (newIccRecords != null) {
if (mSubscriptionManager.isActiveSubId(mPhone.getSubId())) {
log("New records found.");
mIccRecords.set(newIccRecords);
//向IccRecord注册,观察卡信息是否载入完成
//收到通知后,DcTracker将发送EVENT_RECORDS_LOADED信息给自己处理
newIccRecords.registerForRecordsLoaded(
this, DctConstants.EVENT_RECORDS_LOADED, null);
}
} else {
onSimNotReady();
}
}
}
这里主要处理注册消息。如果卡载入成功会触发DcTracker中的EVENT_RECORDS_LOADED
@Override
public void handleMessage (Message msg) {
if (VDBG) log("handleMessage msg=" + msg);
switch (msg.what) {
case DctConstants.EVENT_RECORDS_LOADED:
mSimRecords = mPhone.getSIMRecords();
if ((mIccRecords.get() instanceof RuimRecords) && (mSimRecords != null)) {
mSimRecords.registerForRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null);
} else {
onRecordsLoaded();
}
break;
}
}
这里会进入onRecordsLoaded()
void onRecordsLoaded() {
// If onRecordsLoadedOrSubIdChanged() is not called here, it should be called on
// onSubscriptionsChanged() when a valid subId is available.
int subId = mPhone.getSubId();
if (mSubscriptionManager.isActiveSubId(subId)) {
onRecordsLoadedOrSubIdChanged();
} else {
log("Ignoring EVENT_RECORDS_LOADED as subId is not valid: " + subId);
}
}
protected void onRecordsLoadedOrSubIdChanged() {
if (DBG) log("onRecordsLoadedOrSubIdChanged: createAllApnList");
mAutoAttachOnCreationConfig = mPhone.getContext().getResources()
.getBoolean(com.android.internal.R.bool.config_auto_attach_data_on_creation);
//
createAllApnList();
//设置初始使用的APN
setInitialAttachApn();
if (mPhone.mCi.getRadioState().isOn()) {
if (DBG) log("onRecordsLoadedOrSubIdChanged: notifying data availability");
notifyOffApnsOfAvailability(Phone.REASON_SIM_LOADED);
}
setupDataOnConnectableApns(Phone.REASON_SIM_LOADED);
}
本文地址:https://blog.csdn.net/qq_35427437/article/details/107239962