kaifyou Android 7.0 UICC 分析
来源:互联网 发布:淘宝 笑涵阁 猫腻 编辑:程序博客网 时间:2024/05/22 17:38
Android 7.0 UICC 分析(一)
Android 7.0 UICC 分析(一)
UICC(Universal Intergrated Circuit Card) 框架
* Following is class diagram for uicc classes: * * UiccController * # * | * UiccCard * # # * | ------------------ * UiccCardApplication CatService * # # * | | * IccRecords IccFileHandler * ^ ^ ^ ^ ^ ^ ^ ^ * SIMRecords---- | | | | | | ---SIMFileHandler * RuimRecords----- | | | | ----RuimFileHandler * IsimUiccRecords--- | | -----UsimFileHandler * | ------CsimFileHandler * ----IsimFileHandler
UiccController 类与RILJ 交互,实质是一个Handler,当SIM卡状态发生变化UICCController就会更新。
其构造函数注册监听事件:
private UiccController(Context c, CommandsInterface []ci) { if (DBG) log("Creating UiccController"); mContext = c; mCis = ci; for (int i = 0; i < mCis.length; i++) { Integer index = new Integer(i); 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); } mCis[i].registerForNotAvailable(this, EVENT_RADIO_UNAVAILABLE, index); mCis[i].registerForIccRefresh(this, EVENT_SIM_REFRESH, index); } }
CommandsInterface[] 数组对象的 i 对应的就是PhoneID;
EVENT_ICC_STATUS_CHANGED 监听SIM卡的状态变化;
当SIM卡状态变化,就有EVENT_ICC_STATUS_CHANGED 消息发出,此消息的处理如下:
public void handleMessage (Message msg) { synchronized (mLock) { Integer index = getCiIndex(msg); if (index < 0 || index >= mCis.length) { Rlog.e(LOG_TAG, "Invalid index : " + index + " received with event " + msg.what); return; } AsyncResult ar = (AsyncResult)msg.obj; switch (msg.what) { case EVENT_ICC_STATUS_CHANGED: if (DBG) log("Received EVENT_ICC_STATUS_CHANGED, calling getIccCardStatus"); mCis[index].getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE, index)); break; ............. default: Rlog.e(LOG_TAG, " Unknown Event " + msg.what); } } }
调用RILJ 的getIccCardStatus() 方法,参数是自定义的EVENT_GET_ICC_STATUS_DONE 消息Message对象,用于返回SIM卡状态信息;
生成RIL_REQUEST_GET_SIM_STATUS RILRequest 请求下发RILC 层,获取SIM 卡状态信息:
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); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); }
SIM 卡状态的信息通过 RILReceiver 类接收 RILC 层的返回,由ProcessSolicited() 方法处理;
case RIL_REQUEST_GET_SIM_STATUS: ret = responseIccCardStatus(p); break;
responseIccCardStatus() 方法返回IccCardStatus 对象,保存着SIM卡的状态信息,上报UiccController EVENT_GET_ICC_STATUS_DONE 消息:
case EVENT_GET_ICC_STATUS_DONE: if (DBG) log("Received EVENT_GET_ICC_STATUS_DONE"); onGetIccCardStatusDone(ar, index); break;
onGetIccCardStatusDone() 方法解析出IccCardStatue,如果没有SIM卡,则创建一个UiccCard,否则更新UiccCard 信息,一个UiccCard对象代表着一张SIM:
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); } if (DBG) log("Notifying IccChangedRegistrants"); mIccChangedRegistrants.notifyRegistrants(new AsyncResult(null, index, null)); }
mIccChangedRigistrants 向监听者发出消息通知,监听者通过如下方法注册mIccChangedRigistrants :
//Notifies when card status changes public void registerForIccChanged(Handler h, int what, Object obj) { synchronized (mLock) { Registrant r = new Registrant (h, what, obj); mIccChangedRegistrants.add(r); //Notify registrant right after registering, so that it will get the latest ICC status, //otherwise which may not happen until there is an actual change in ICC status. r.notifyRegistrant(); } }
监听者有如下:
IccCardProxy、GsmSMSDispactcher、CatService、Phone、ServiceStateTracker、DcTracker
Android 7.0 UICC 分析(二)
本文讲解UiccCard类
/frameworks/opt/telephony/src/java/com/android/internal/telephony/uicc/UiccCard.java
UICCController 类的onGetIccCardStatusDone() 方法,根据获取的SIM状态信息IccCardStatus 创建或更新UiccCard 对象;
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); } ....... }
UiccCard 类的构造方法,同样会调用update() 方法更新SIM 卡状态信息;
public UiccCard(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId) { mCardState = ics.mCardState; mPhoneId = phoneId; update(c, ci, ics); }
UiccCard 类的 update() 方法:
1、根据IccCardStatus 参数在mUiccApplication 列表中匹配UiccCardApplication 对象,通过UiccCardApplication 类的update() 方法更新,否则创建一个UiccCardApplication 对象;
2、调用createAndUpdateCatService() 方法创建或更新CatService 对象;
3、获取RadioState状态,更新CardState,发出SIM卡插拔消息;
public void update(Context c, CommandsInterface ci, IccCardStatus ics) { ........ //update applications if (DBG) log(ics.mApplications.length + " 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 mUiccApplications[i].update(ics.mApplications[i], mContext, mCi); //调用UiccCardApplication.java } } createAndUpdateCatService(); //CatService .......... 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; } }
createAndUpdateCatService() 方法,创建或更新CatService:
protected void createAndUpdateCatService() { if (mUiccApplications.length > 0 && mUiccApplications[0] != null) { // Initialize or Reinitialize CatService if (mCatService == null) { mCatService = CatService.getInstance(mCi, mContext, this, mPhoneId); } else { ((CatService)mCatService).update(mCi, mContext, this); } } else { if (mCatService != null) { mCatService.dispose(); } mCatService = null; } }
消息EVENT_CARD_REMOVED、 EVENT_CARD_ADDED 在UiccCard 类的handleMessage()方法中处理:
protected Handler mHandler = new Handler() { @Override public void handleMessage(Message msg){ switch (msg.what) { case EVENT_CARD_REMOVED: onIccSwap(false); break; case EVENT_CARD_ADDED: onIccSwap(true); break; ......... } } };
onIccSwap() 方法,判断是否共卡座,如果是直接返回,否则调用promptForRestart():
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); }
promptForRestart() 方法,切换sim卡,弹出提示框:
private void promptForRestart(boolean isAdded) { synchronized (mLock) { final Resources res = mContext.getResources(); final String dialogComponent = res.getString( R.string.config_iccHotswapPromptForRestartDialogComponent); if (dialogComponent != null) { Intent intent = new Intent().setComponent(ComponentName.unflattenFromString( dialogComponent)).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) .putExtra(EXTRA_ICC_CARD_ADDED, isAdded); try { mContext.startActivity(intent); return; } catch (ActivityNotFoundException e) { loge("Unable to find ICC hotswap prompt for restart activity: " + e); } } // TODO: Here we assume the device can't handle SIM hot-swap // and has to reboot. We may want to add a property, // e.g. REBOOT_ON_SIM_SWAP, to indicate if modem support // hot-swap. DialogInterface.OnClickListener listener = null; // TODO: SimRecords is not reset while SIM ABSENT (only reset while // Radio_off_or_not_available). Have to reset in both both // added or removed situation. listener = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { synchronized (mLock) { if (which == DialogInterface.BUTTON_POSITIVE) { if (DBG) log("Reboot due to SIM swap"); PowerManager pm = (PowerManager) mContext .getSystemService(Context.POWER_SERVICE); pm.reboot("SIM is added."); //SIM卡上电重启 } } } }; Resources r = Resources.getSystem(); String title = (isAdded) ? r.getString(R.string.sim_added_title) : r.getString(R.string.sim_removed_title); String message = (isAdded) ? r.getString(R.string.sim_added_message) : r.getString(R.string.sim_removed_message); String buttonTxt = r.getString(R.string.sim_restart_button); AlertDialog dialog = new AlertDialog.Builder(mContext) .setTitle(title) .setMessage(message) .setPositiveButton(buttonTxt, listener) .create(); dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); dialog.show(); //SIM卡弹出提示框 } }
- kaifyou Android 7.0 UICC 分析
- android telephony uicc
- Android之Uicc框架
- UICC
- UICC
- UICC
- android telephony 之 UICC 卡数据读写及 UICC 框架结构
- android telephony 之 UICC 卡数据读写及 UICC 框架结构
- Android中的Uicc框架(原)
- Android中的Uicc框架(转)
- Android UICC 好文关键字备忘
- Android UICC 实现框架和数据读写
- UICC之UICC框架
- android telephony 工作流程(二)--UICC上层实现框架
- android telephony 工作流程(三)--UICC CARD & APP 更新
- Uicc card
- Android6.0的phone应用源码分析(9)——UICC卡管理
- Android6.0的phone应用源码分析(9)——UICC卡管理
- Android数据加密之异或加密算法
- C与指针
- K-Means++
- 关于"UnityEditor" namespace not found的问题的个人解决方案
- Photon Server环境搭建
- kaifyou Android 7.0 UICC 分析
- 通过GitHub Pages创建个人主页
- [编程题] 构造队列
- 【每周牧函】我的异性交往界限(王怡牧师)
- Charles抓包(Android手机)
- IK Expression 简单用
- Spring HtmlUtils用法
- java.lang.SecurityException: Permission Denial: starting Intent
- 备忘录