Uicc card
来源:互联网 发布:英国海淘鞋子 知乎 编辑:程序博客网 时间:2024/06/10 12:01
Uicc card
关于这部分的流程,UiccController.java中的注释写的很清楚,先把这部分注释拿出来,如下:
* 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---- | | | | | | ---SIMFileHandle RuimRecords---- | | | | ----RuimFileHandler IsimUiccRecords--- | | -----UsimFileHandler | -------CsimFileHandler -----IsimFileHandler
上面的注释是简单明了,按照代码流程看几遍,记住每个类的主要作用, 这部分也就算是掌握了。
UiccController
UiccController是在PhoneApp启动的过程中创建的,算是这部分知识的一个起点;UiccController构造函数里面便注册了RIL监听, 后续根据这些监听反馈便逐层创建了各个对象。
比较重要的两个点:
1.调用Ril的getIccCardStatus方法向modem查询card的状态。
2.用onGetIccCardStatusDone方法处理modem的反馈结果,UiccCard对象就是在这个方法里面创建的。
UiccCard
UiccCard—每个对象对应一张卡。
1.创建UiccCardApplication—每张卡最多有8个应用。
2.创建Catservice。
3.通过这个对象提供的API可以获取Card state,application等信息。
UiccCard的update方法用来更新对象的内部信息,方法如下:
public void update(Context c, CommandsInterface ci, IccCardStatus ics) { synchronized (mLock) { CardState oldState = mCardState; mCardState = ics.mCardState;//更新card state mUniversalPinState = ics.mUniversalPinState;//更新pin state mGsmUmtsSubscriptionAppIndex = ics.mGsmUmtsSubscriptionAppIndex;//更新application的index,下面两句也是这个作用. mCdmaSubscriptionAppIndex = ics.mCdmaSubscriptionAppIndex; mImsSubscriptionAppIndex = ics.mImsSubscriptionAppIndex; mContext = c; mCi = ci; //update applications if (DBG) log(ics.mApplications.length + " applications"); for ( int i = 0; i < mUiccApplications.length; i++) { //下面这段代码用来创建/删除UiccCardApplication对象。 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 mUiccApplications[i].update(ics.mApplications[i], mContext, mCi); } } createAndUpdateCatService();//catservice相关的操作。 // Reload the carrier privilege rules if necessary. log("Before privilege rules: " + mCarrierPrivilegeRules + " : " + mCardState); if (mCarrierPrivilegeRules == null && mCardState == CardState.CARDSTATE_PRESENT) { mCarrierPrivilegeRules = new UiccCarrierPrivilegeRules(this, mHandler.obtainMessage(EVENT_CARRIER_PRIVILIGES_LOADED)); } else if (mCarrierPrivilegeRules != null && mCardState != CardState.CARDSTATE_PRESENT) { mCarrierPrivilegeRules = null; } sanitizeApplicationIndexes();//通过判断Application是否有效来确定application index有效性. RadioState radioState = mCi.getRadioState(); if (DBG) log("update: radioState=" + radioState + " mLastRadioState=" + mLastRadioState); // No notifications while radio is off or we just powering up if (radioState == RadioState.RADIO_ON && mLastRadioState == RadioState.RADIO_ON) { //下面这段代码用于提示用户卡插入或者拔出,重启手机。 if (oldState != CardState.CARDSTATE_ABSENT && mCardState == CardState.CARDSTATE_ABSENT) { if (DBG) log("update: notify card removed"); mAbsentRegistrants.notifyRegistrants(); mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_REMOVED, null)); } else if (oldState == CardState.CARDSTATE_ABSENT && mCardState != CardState.CARDSTATE_ABSENT) { if (DBG) log("update: notify card added"); mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_ADDED, null)); } } mLastRadioState = radioState; } }
上面update方法根据卡的状态变化发出EVENT_CARD_REMOVED/EVENT_CARD_ADDED 消息,handler处理这两个消息时会调用onIccSwap(boolean isAdded) 方法。
private void onIccSwap(boolean isAdded) { boolean isHotSwapSupported = mContext.getResources().getBoolean(//判断是否支持热插拔。 R.bool.config_hotswapCapable); if (isHotSwapSupported) {//如果支持热插拔就不需要重启手机。 log("onIccSwap: isHotSwapSupported is true, don't prompt for rebooting"); return; } log("onIccSwap: isHotSwapSupported is false, prompt for rebooting"); promptForRestart(isAdded);//用于不支持热插拔时,提示用户重启手机,并调用PowerManager }
UiccCardApplication
1.内部存储了Pin1,Pin2, FDN等信息; 所以可以通过这个对象提供的API来查询这些信息。
2.内部有IccFileHandler,SIMRecords对象; 可以通过这个对象提供的API来获取这两个对象。
SIMRecords
IccRecords有三个子类,分别对应了一种卡,主要看看SIMRecords。
1.fetchSimRecords是重要的一个方法, 这个方法获取了卡里的很多数据,像IMSI, Spn,PLMN,PNN, CPHS等;SIM refresh,ready时会调用该方法。
2.SIMRecords对象在RIL里注册了SIM refresh监听,在UiccCardAoolication里面注册了app ready/lock事件,还注册了ACTION_CARRIER_CONFIG_CHANGED的广播(用于spn的override)。
IccCardProxy
另外IccCardProxy也要说下,根据这个名字也能猜到这个类的大致作用; 这个类实现了IccCard接口,根据注释,
这个接口是为了外部应用(主要是PhoneApp)可以方便的操作icc card相关的功能,这当然也是IccCardProxy的作用了。
这个类的对象是在phone对象初始化的过程中创建的,我们通过phone.getIccCard()获取的也是这个类的对象。
由于这个类的作用是方便外部应用操作icc card相关的功能, 所以这个类的方法很多, 而具体方法里的实现自然要用到UiccController,Uicard, UiccCardApplication, IccRecords和IccFileHandler。IccCardProxy 会通过ACTION_SIM_STATE_CHANGED 将SIM state发出去。当IccCardProxy收到IccCardConstants.INTENT_VALUE_ICC_LOCKED的状态,SIMRecords的records loaded以及UiccCard 的EVENT_CARRIER_PRIVILIGES_LOADED的通知后,还会发送ACTION_INTERNAL_SIM_STATE_CHANGED广播。
ICC Card状态(IccCardStatus.CardState)
CARDSTATE_ABSENT,
CARDSTATE_PRESENT,
CARDSTATE_ERROR,
CARDSTATE_RESTRICTED;
SIM状态(IccCardConstants.State)
UNKNOWN, /* ordinal(0) == {@See TelephonyManager#SIM_STATE_UNKNOWN} /
ABSENT, /* ordinal(1) == {@See TelephonyManager#SIM_STATE_ABSENT} /
PIN_REQUIRED, /* ordinal(2) == {@See TelephonyManager#SIM_STATE_PIN_REQUIRED} /
PUK_REQUIRED, /* ordinal(3) == {@See TelephonyManager#SIM_STATE_PUK_REQUIRED} /
NETWORK_LOCKED, /* ordinal(4) == {@See TelephonyManager#SIM_STATE_NETWORK_LOCKED} /
READY, /* ordinal(5) == {@See TelephonyManager#SIM_STATE_READY} /
NOT_READY, /* ordinal(6) == {@See TelephonyManager#SIM_STATE_NOT_READY} /
PERM_DISABLED, /* ordinal(7) == {@See TelephonyManager#SIM_STATE_PERM_DISABLED} /
CARD_IO_ERROR, /* ordinal(8) == {@See TelephonyManager#SIM_STATE_CARD_IO_ERROR} /
CARD_RESTRICTED;/* ordinal(9) == {@See TelephonyManager#SIM_STATE_CARD_RESTRICTED} /
icc card的状态比较好理解,通过UiccCard的getCardState方法可以获取。
我们比较常用的是SIM状态,可以通过TelephonyManger提供的getSimState(int slotIndex)/getSimState() 这两个API可以获取。getSimState(int slotIndex)/getSimState()内部进一步调用了SubscriptionController里面的方法getSimStateForSlotIndex(int index),而getSimStateForSlotIndex(int index)进一步调用了IccCardProxy的getState()方法,所以如果可以获取PhoneApp对象,可以通过getIccCard()方法获取IccCardProxy对象,进而调用getState()方法获取SIM状态。getState()方法只是返回了一个成员变量mExternalState,而这个变量
值的更新是通过IccCardProxy在UiccController,UiccCard以及UiccApplication里面注册的监听驱动的(registerUiccCardEvents方法), 而这个成员变量的赋值操作是通过setExternalState方法,下面几个情况会调用这个方法:
1.构造函数State.NOT_READY
2.updateQuietMode
- EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED
- EVENT_RADIO_ON
- setVoiceRadioTech
3.handleMessage
- EVENT_RADIO_OFF_OR_UNAVAILABLE
- EVENT_ICC_ABSENT
- EVENT_APP_READY
- EVENT_NETWORK_LOCKED
4.updateExternalState
- updateIccAvailability<–EVENT_ICC_CHANGED
- onSubscriptionActivated<–EVENT_SUBSCRIPTION_ACTIVATED
- onSubscriptionDeactivated<–EVENT_SUBSCRIPTION_DEACTIVATED
5.processLockedState
- handleMessage:EVENT_ICC_LOCKED
SIM state的定义是综合了IccCardStatus.CardState,IccCardStatus.PinState以及IccCardApplicationStatus.AppState。
下面的表格根据IccCardProxy里面的代码逻辑,总结了SIM state各个状态所依赖的条件。
开机SIM状态更新
命令GET_SIM_STATUS, 首先返回CARDSTATE_ABSENT, 然后是CARDSTATE_PRESENT, 这些RIL消息里面会带有PIN lock等信息。
onRecordLoaded
对于SIMRecords中的onRecordLoaded方法, 从定义和调用角度考虑,分成两部分:
- 在IccRecords中定义的onRecordLoaded方法,子类SIMRecords复写了该方法。
IccRecords的handleMessage(EVENT_GET_ICC_RECORD_DONE)中调用该方法,
SIMRecords重写了IccRecords的handleMessage方法(在default中调用IccRecords的handleMessage方法),
对onRecordLoaded的调用也做了调整,将调用放在了handleMessage的末尾,通过变量isRecordLoadResponse做调用控制,所有需要调用该方法的EVENT可以将isRecordLoadResponse赋值为true。该方法会调用onAllRecordsLoaded(所有records都加载完成时),onAllRecordsLoaded除了保存一些数据之外还会通知监听了records loaded的观察者,比如IccCardProxy。 在IccRecords中的接口IccRecordLoaded中定义的onRecordLoaded方法,SIMRecords中的私有类EfPlLoaded和EfUsimLiLoaded都实现了IccRecordLoaded接口,
也实现了onRecordLoaded方法。 接口IccRecordLoaded是用来作为call
back的,根据code,是作为EVENT_GET_ICC_RECORD_DONE的call
back用来获取EF_LI和EF_PL这两个文件的值(SIMRecords.loadEfLiAndEfPl)。
- Uicc card
- android telephony 工作流程(三)--UICC CARD & APP 更新
- UICC
- UICC
- UICC
- UICC之UICC框架
- card
- Card
- 1012 card card card
- HDU6205 card card card
- HDU6205-card card card
- card card card
- HDU6205 card card card
- android telephony uicc
- Uicc之UiccCardApplication(转)
- Android之Uicc框架
- Uicc之UiccController
- Uicc之UiccCard
- 三星Galaxy Note7爆炸,苹果成最大赢家
- 聚焦4G、双沃突破——vivo与中国联通聚焦139城市专项工作启动
- python应用系列教程——python使用smtp上传邮件,使用pop3下载邮件
- iOS瘦身之路(上)
- CAN为什么会发送失败
- Uicc card
- cenos7.0 LNMP搭建
- 苹果赚了多少,iPhone 7的硬件成本不到售价的40%
- 苹果发布 OS X 继任者 macOS Sierra,到底更新了什么?
- 坚果投影仪亮相广州办公行业年会 获创新之星大奖
- 土豪公司一口气买下24000台HoloLens,微软黑科技成为效率工具了?
- 福建省和腾讯达成战略合作 全面拥抱互联网+ | 2016 TGPC
- 排序查询
- JDBC 连接数据库开发步骤