本文代码以MTK平台Android 4.4为分析对象,与Google原生AOSP有些许差异,请读者知悉。
本文主要介绍MTK Android开机时,SIM卡的Framework部分初始化过程。
先看一段注释:
/* Once created UiccController registers with RIL for "on" and "unsol_sim_status_changed"
* notifications. When such notification arrives UiccController will call
* getIccCardStatus (GET_SIM_STATUS). Based on the response of GET_SIM_STATUS
* request appropriate tree of uicc objects will be created.
*
* Following is class diagram for uicc classes:
*
* UiccController
* #
* |
* UiccCard
* # #
* | ------------------
* UiccCardApplication CatService
* # #
* | |
* IccRecords IccFileHandler
* ^ ^ ^ ^ ^ ^ ^ ^
* SIMRecords---- | | | | | | ---SIMFileHandler
* RuimRecords----- | | | | ----RuimFileHandler
* IsimUiccRecords--- | | -----UsimFileHandler
* | ------CsimFileHandler
* ----IsimFileHandler
*
* Legend: # stands for Composition
* ^ stands for Generalization
*/
这是UiccController.java文件开头对UiccController的注释,意思很明显UiccController是对Android SIM卡管理的控制器。
下面是SIM卡初始化序列图:
UiccController的初始化是在phone进程启动的时候,PhoneFactory调用makeDefaultPhone()创建默认的Phone,然后走MTK双卡流程中,调用MTKPhoneFactory.makeDefaultPhone()创建的,
{
for (int l2 = 0; l2 < PhoneConstants.GEMINI_SIM_NUM; l2++)
if (j1 == l2)
ai[l2] = j;
else
ai[l2] = 1;
I = new RIL(context, ai[0], l, 0);
J = new RIL(context, ai[1], l, 1);
}
UiccController.make(context, I, 0);
UiccController.make(context, J, 1);
GSMPhone agsmphone[] = new GSMPhone[PhoneConstants.GEMINI_SIM_NUM];
上面是反编译MTK的static_gemini_intermediates库看到的,在RIL创建完成时,使用UiccController.make()初始化:
public static UiccController make(Context c, CommandsInterface ci, int simId) {
synchronized (mLock) {
if (FeatureOption.MTK_GEMINI_SUPPORT) {
if(mInstance[simId] != null) {
throw new RuntimeException("UiccController.make() should only be called once");
}
mInstance[simId] = new UiccController(c, ci, simId);
return mInstance[simId];
} else {
if (mInstance[0] != null) {
throw new RuntimeException("UiccController.make() should only be called once");
}
mInstance[0] = new UiccController(c, ci);
return mInstance[0];
}
}
}
UiccController的创建使用了单例模式,使用时调用getInstance()获取,
public static UiccController getInstance(int simId) {
synchronized (mLock) {
if (FeatureOption.MTK_GEMINI_SUPPORT) {
if(mInstance[simId] == null) {
throw new RuntimeException(
"UiccController.getInstance can't be called before make()");
}
return mInstance[simId];
} else {
if (mInstance[0] == null) {
throw new RuntimeException(
"UiccController.getInstance can't be called before make()");
}
return mInstance[0];
}
}
}
private UiccController(Context c, CommandsInterface ci, int simId) {
if (DBG) log("Creating UiccController simId " + simId);
mContext = c;
mCi = ci;
mSimId = simId;
mCi.registerForIccStatusChanged(this, EVENT_ICC_STATUS_CHANGED, null);
// TODO remove this once modem correctly notifies the unsols
mCi.registerForOn(this, EVENT_ICC_STATUS_CHANGED, null);
mCi.registerForVirtualSimOn