(M)SIM卡开机流程分析之UiccController类分析
2017-03-02 15:02
405 查看
看看这个方法,定义一个UiccController对象
UiccController.make(context, sCommandsInterfaces);
进入RIL.java文件中看看:
RIL.java
在EVENT_ICC_STATUS_CHANGED消息被接收到后,在UiccController中处理:
读取数据完成后,发送EVENT_GET_ICC_STATUS_DONE消息,在UiccController.java中接收,如上述UiccController代码,然后直接调用onGetIccCardStatusDone(ar, index);方法:
进入UiccCards.java文件:
先新建UiccCardApplications对象:
再看UiccCard.java的update方法中的createAndUpdateCatService();这个方法,从名字看,是创建/更新CatService,进入其中查看:
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]; } }后续,还有很多流程,等以后有时间研究
相关文章推荐
- (M)SIM卡开机流程分析之TelephonyManager类分析
- (M)SIM卡开机流程分析之显示名称加载
- Android 4.4Telephony流程分析SIM卡开机时的初始化
- (M)SIM卡开机流程分析之RIL类分析
- Android4.4 Telephony流程分析——SIM卡开机时的数据加载
- Android4.4 Telephony流程分析——SIM卡开机时的初始化
- Android 4.4Telephony流程分析SIM卡开机时的数据加载
- (M)SIM卡开机流程分析之SubscriptionController类分析
- (M)SIM卡开机流程分析之主线分析
- (M)SIM卡开机流程分析之默认APN设置
- Android4.4 Telephony流程分析——SIM卡开机时的初始化
- (M)SIM卡开机流程分析之TelephonyDevController类分析
- (M)SIM卡开机流程分析之DefaultPhoneNotifier类分析
- Android源码分析---系统开机流程
- Linux之RHEL6的开机流程分析
- Android开机流程分析 -- 概述
- STM32 开机流程分析
- 浅析android锁屏开机绘制流程(基于android4.0源码分析) .
- Android开机流程分析 -- Zygote
- QualComm 8x50 上MMC host controller 驱动的初始化流程分析