您的位置:首页 > 产品设计 > UI/UE

(M)SIM卡开机流程分析之UiccController类分析

2017-03-02 15:02 405 查看
看看这个方法,定义一个UiccController对象

UiccController.make(context, sCommandsInterfaces);
// 单例模式
public static UiccController make(Context c, CommandsInterface[] ci) {
synchronized (mLock) {
if (mInstance != null) {
throw new RuntimeException("MSimUiccController.make() should only be called once");
}
mInstance = new UiccController(c, ci);
return (UiccController)mInstance;
}
}
private UiccController(Context c, CommandsInterface []ci) {
if (DBG) log("Creating UiccController");
mContext = c;
// 这个是RIL,CommandsInterface
mCis = ci;
for (int i = 0; i < mCis.length; i++) {
Integer index = new Integer(i);
// 注册EVENT_ICC_STATUS_CHANGED
mCis[i].registerForIccStatusChanged(this, EVENT_ICC_STATUS_CHANGED, index);
// TODO remove this once modem correctly notifies the unsols
if (DECRYPT_STATE.equals(SystemProperties.get("vold.decrypt"))) {
mCis[i].registerForAvailable(this, EVENT_ICC_STATUS_CHANGED, index);
} else {
mCis[i].registerForOn(this, EVENT_ICC_STATUS_CHANGED, index);
}
// 注册EVENT_RADIO_UNAVAILABLE
mCis[i].registerForNotAvailable(this, EVENT_RADIO_UNAVAILABLE, index);
// 注册EVENT_SIM_REFRESH
mCis[i].registerForIccRefresh(this, EVENT_SIM_REFRESH, index);
}
}
此处的mCis为CommandsInterface对象,从前文知道,这个是RIL对象。

进入RIL.java文件中看看:
public final class RIL extends BaseCommands implements CommandsInterface {
……
}
BaseCommands.java文件:
@Override
public void registerForIccStatusChanged(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
mIccStatusChangedRegistrants.add(r);
}
而mIccStatusChangedRegistrants在RIL.java文件中使用的。

RIL.java
switch (rr.mRequest) {
case RIL_REQUEST_ENTER_SIM_PUK:
case RIL_REQUEST_ENTER_SIM_PUK2:
if (mIccStatusChangedRegistrants != null) {
if (RILJ_LOGD) {
riljLog("ON enter sim puk fakeSimStatusChanged: reg count=" + mIccStatusChangedRegistrants.size());
}
mIccStatusChangedRegistrants.notifyRegistrants();
}
break;
}
case RIL_REQUEST_ENTER_SIM_PIN:
case RIL_REQUEST_ENTER_SIM_PIN2:
case RIL_REQUEST_CHANGE_SIM_PIN:
case RIL_REQUEST_CHANGE_SIM_PIN2:
case RIL_REQUEST_SET_FACILITY_LOCK:
if (mIccStatusChangedRegistrants != null) {
if (RILJ_LOGD) {
riljLog("ON some errors fakeSimStatusChanged: reg count=" + mIccStatusChangedRegistrants.size());
}
mIccStatusChangedRegistrants.notifyRegistrants();
}
break;
case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:
if (RILJ_LOGD) unsljLog(response);
if (mIccStatusChangedRegistrants != null) {
mIccStatusChangedRegistrants.notifyRegistrants();
}
break;
也就是说,在UiccController.java的函数中,注册了一个EVENT_ICC_STATUS_CHANGED的消息,而它是在接收到RIL_REQUEST_ENTER_SIM_PUK、RIL_REQUEST_ENTER_SIM_PUK2、或者RIL_REQUEST_ENTER_SIM_PIN、RIL_REQUEST_ENTER_SIM_PIN2、RIL_REQUEST_CHANGE_SIM_PIN、RIL_REQUEST_CHANGE_SIM_PIN2、RIL_REQUEST_SET_FACILITY_LOCK和RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED消息后就会直接调用,那么这几个消息会从什么地方发出来呢?其实这些都就是底层Rild中会发出了,这个不做研究。

在EVENT_ICC_STATUS_CHANGED消息被接收到后,在UiccController中处理:
@Override
public void handleMessage (Message msg) {
AsyncResult ar = (AsyncResult)msg.obj;
switch (msg.what) {
case EVENT_ICC_STATUS_CHANGED:
……
// mCis为CommandsInterface,为RIL对象
mCis[index].getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE, index));
break;
case EVENT_GET_ICC_STATUS_DONE:
……
onGetIccCardStatusDone(ar, index);
break;
……
}
}
进入RIL.java中,getIccCardStatus方法:
@Override
public void getIccCardStatus(Message result) {
//Note: This RIL request has not been renamed to ICC,
//       but this request is also valid for SIM and RUIM
RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_SIM_STATUS, result);
……
send(rr);
}
case RIL_REQUEST_GET_SIM_STATUS: ret =  responseIccCardStatus(p); break;
private Object responseIccCardStatus(Parcel p) {
IccCardApplicationStatus appStatus;
IccCardStatus cardStatus = new IccCardStatus();
cardStatus.setCardState(p.readInt());
cardStatus.setUniversalPinState(p.readInt());
cardStatus.mGsmUmtsSubscriptionAppIndex = p.readInt();
cardStatus.mCdmaSubscriptionAppIndex = p.readInt();
cardStatus.mImsSubscriptionAppIndex = p.readInt();
int numApplications = p.readInt();
// limit to maximum allowed applications
if (numApplications > IccCardStatus.CARD_MAX_APPS) {
numApplications = IccCardStatus.CARD_MAX_APPS;
}
cardStatus.mApplications = new IccCardApplicationStatus[numApplications];
for (int i = 0 ; i < numApplications ; i++) {
appStatus = new IccCardApplicationStatus();
appStatus.app_type = appStatus.AppTypeFromRILInt(p.readInt());
appStatus.app_state = appStatus.AppStateFromRILInt(p.readInt());
appStatus.perso_substate = appStatus.PersoSubstateFromRILInt(p.readInt());
appStatus.aid = p.readString();
appStatus.app_label = p.readString();
appStatus.pin1_replaced = p.readInt();
appStatus.pin1 = appStatus.PinStateFromRILInt(p.readInt());
appStatus.pin2 = appStatus.PinStateFromRILInt(p.readInt());
cardStatus.mApplications[i] = appStatus;
}
return cardStatus;
}
这个是读取SIM卡中的信息了,这个不做研究,若有需要,可以在这个位置打一些LOG,来确认SIM卡中读取到的数据值。

读取数据完成后,发送EVENT_GET_ICC_STATUS_DONE消息,在UiccController.java中接收,如上述UiccController代码,然后直接调用onGetIccCardStatusDone(ar, index);方法:
private synchronized void onGetIccCardStatusDone(AsyncResult ar, Integer index) {
……
IccCardStatus status = (IccCardStatus)ar.result;
if (mUiccCards[index] == null) {
//Create new card
mUiccCards[index] = new UiccCard(mContext, mCis[index], status, index);
} else {
//Update already existing card
mUiccCards[index].update(mContext, mCis[index] , status);
}
……
mIccChangedRegistrants.notifyRegistrants(new AsyncResult(null, index, null));
}
新建一个UiccCards对象,注意这个地方UiccCards对象,先判断存在与否,若存在,则直接update数据,若不存在,在新建一个UiccCards对象。新建对象时,传入的参数为,第一个是上下文对象,第二个是mCis[index],CommandsInterface,即RIL对象,第三个为status,即在RIL.java文件中读取到的IccCardStatus对象,第四个为index,为第几张SIM卡。

进入UiccCards.java文件:
public UiccCard(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId) {
mCardState = ics.mCardState;
mPhoneId = phoneId;
// 第一个参数是上下文对象,第二个为RIL对象,第三个为IccCardStatus对象,从RIL.java文件中读取到的
update(c, ci, ics);
}
public void update(Context c, CommandsInterface ci, IccCardStatus ics) {
synchronized (mLock) {
……
mContext = c;
mCi = ci;

//update applications
for ( int i = 0; i < mUiccApplications.length; i++) {
if (mUiccApplications[i] == null) {
//Create newly added Applications
if (i < ics.mApplications.length) {
mUiccApplications[i] = new UiccCardApplication(this,
ics.mApplications[i], mContext, mCi);
}
} else if (i >= ics.mApplications.length) {
//Delete removed applications
mUiccApplications[i].dispose();
mUiccApplications[i] = null;
} else {
//Update the rest
mUiccApplica
4000
tions[i].update(ics.mApplications[i], mContext, mCi);
}
}
createAndUpdateCatService();
……
}
}
新建UiccCardApplications对象,若已经存在,则直接update,若不存在,新建,和之前UiccCards一样。mUiccApplications新建函数中的第二个参数ics.mApplications[i],是从RIL.java文件中读取到的,见前面的RIL.java文件讲解。

先新建UiccCardApplications对象:
UiccCardApplication(UiccCard uiccCard,
IccCardApplicationStatus as,
Context c,
CommandsInterface ci) {
// 这些值全部是在RIL.java文件中,从SIM卡中读出来的
mUiccCard = uiccCard;
mAppState = as.app_state;
mAppType = as.app_type;
mAuthContext = getAuthContext(mAppType);
mPersoSubState = as.perso_substate;
mAid = as.aid;
mAppLabel = as.app_label;
mPin1Replaced = (as.pin1_replaced != 0);
mPin1State = as.pin1;
mPin2State = as.pin2;

mContext = c;
mCi = ci;

mIccFh = createIccFileHandler(as.app_type);
mIccRecords = createIccRecords(as.app_type, mContext, mCi);
if (mAppState == AppState.APPSTATE_READY) {
queryFdn();
queryPin1State();
}
mCi.registerForNotAvailable(mHandler, EVENT_RADIO_UNAVAILABLE, null);
}
private IccFileHandler createIccFileHandler(AppType type) {
switch (type) {
case APPTYPE_SIM:
return new SIMFileHandler(this, mAid, mCi);
case APPTYPE_RUIM:
return new RuimFileHandler(this, mAid, mCi);
case APPTYPE_USIM:
return new UsimFileHandler(this, mAid, mCi);
case APPTYPE_CSIM:
return new CsimFileHandler(this, mAid, mCi);
case APPTYPE_ISIM:
return new IsimFileHandler(this, mAid, mCi);
default:
return null;
}
}
private IccRecords createIccRecords(AppType type, Context c, CommandsInterface ci) {
if (type == AppType.APPTYPE_USIM || type == AppType.APPTYPE_SIM) {
return new SIMRecords(this, c, ci);
} else if (type == AppType.APPTYPE_RUIM || type == AppType.APPTYPE_CSIM){
return new RuimRecords(this, c, ci);
} else if (type == AppType.APPTYPE_ISIM) {
return new IsimUiccRecords(this, c, ci);
} else {
// Unknown app type (maybe detection is still in progress)
return null;
}
}
根据从SIM卡中读取出来的字段,新建IccFileHandler和IccRecords对象。

再看UiccCard.java的update方法中的createAndUpdateCatService();这个方法,从名字看,是创建/更新CatService,进入其中查看:
protected void createAndUpdateCatService() {
if (mUiccApplications.length > 0 && mUiccApplications[0] != null) {
// Initialize or Reinitialize CatService
if (mCatService == null) {
// mCi为ConmandsInterface,RIL对象
mCatService = CatService.getInstance(mCi, mContext, this, mPhoneId);
} else {
((CatService)mCatService).update(mCi, mContext, this);
}
}
……
}
单例模式,和之前一样,若无,则新建,若已有,则update。
public static CatService getInstance(CommandsInterface ci,
Context context, UiccCard ic, int slotId) {
UiccCardApplication ca = null;
IccFileHandler fh = null;
IccRecords ir = null;
if (ic != null) {
/* Since Cat is not tied to any application, but rather is Uicc application
* in itself - just get first FileHandler and IccRecords object
*/
ca = ic.getApplicationIndex(0);
if (ca != null) {
//IccFileHandler对象,在上面新建的,ca是UiccCardApplication
fh = ca.getIccFileHandler();
//新建IccRecords对象,在上面新建的
ir = ca.getIccRecords();
}
}

synchronized (sInstanceLock) {
……
if (sInstance[slotId] == null) {
……
sInstance[slotId] = new CatService(ci, ca, ir, context, fh, ic, slotId);
} else if ((ir != null) && (mIccRecords != ir)) {
if (mIccRecords != null) {
mIccRecords.unregisterForRecordsLoaded(sInstance[slotId]);
}
mIccRecords = ir;
mUiccApplication = ca;
mIccRecords.registerForRecordsLoaded(sInstance[slotId],
MSG_ID_ICC_RECORDS_LOADED, null);
CatLog.d(sInstance[slotId], "registerForRecordsLoaded slotid=" + slotId + " instance:" + sInstance[slotId]);
}
return sInstance[slotId];
}
}
后续,还有很多流程,等以后有时间研究

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: