Android 7.0 UICC 分析(四)
本文讲解SIMRecords
/frameworks/opt/telephony/src/java/com/android/internal/telephony/uicc/SIMRecords.java
构造方法:
public SIMRecords(UiccCardApplication app, Context c, CommandsInterface ci) {
super(app, c, ci);
mAdnCache = new AdnRecordCache(mFh);
mVmConfig = new VoiceMailConstants();
mSpnOverride = new SpnOverride();
mCi.setOnSmsOnSim(this, EVENT_SMS_ON_SIM, null);//消息注册,当Ci接收到EVENT_SMS_ON_SIM消息通知SIMRecords
mCi.registerForIccRefresh(this, EVENT_SIM_REFRESH, null);
// Start off by setting empty state
resetRecords();
mParentApp.registerForReady(this, EVENT_APP_READY, null);//当卡准备好,UiccCardApplication会通过notifyReadyRegistrantsifNeeded()通知SIMRecords
mParentApp.registerForLocked(this, EVENT_APP_LOCKED, null);//EVENT_APP_LOCKED消息同样处理
if (DBG) log("SIMRecords X ctor this=" + this);
IntentFilter intentfilter = new IntentFilter();
intentfilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
c.registerReceiver(mReceiver, intentfilter); //接收ACTION_CARRIER_CONFIG_CHANGED消息的处理
}
接收UiccCardApplication 的通知,消息EVENT_APP_READY、EVENT_APP_LOCKED 的处理:
try { switch (msg.what) {
case EVENT_APP_READY:
onReady();
break;
case EVENT_APP_LOCKED:
onLocked();
break;
}
onReady() 方法,直接调用fetchSimRecords(),到这里开始加载EF文件信息:
具体的读取SIM卡EF文件信息的过程是有IccFileHandler来实现的,根据EF文件的类型,调用不同的方法loadEFTransparent()和loadEFLinearFixed(),最终都会调用RILJ 的iccIOForApp() 方法;
protected void fetchSimRecords() {
if (DBG) log("fetchSimRecords " + mRecordsToLoad);
mCi.getIMSIForApp(mParentApp.getAid(), obtainMessage(EVENT_GET_IMSI_DONE));//获取IMSI信息,返回的数据在该类handleMessage()中处理
mRecordsToLoad++; //没读取一项信息,计数值就加1
mFh.loadEFTransparent(EF_ICCID, obtainMessage(EVENT_GET_ICCID_DONE));//获取ICCID
mRecordsToLoad++;
// Same goes for Call Forward Status indicator: fetch both
// EF[CFIS] and CPHS-EF, with EF[CFIS] preferred.
loadCallForwardingRecords();
getSpnFsm(true, null);
loadEfLiAndEfPl();
if (CRASH_RIL) {
String sms = "0107912160130310f20404d0110041007030208054832b0120"
+ "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ "ffffffffffffffffffffffffffffff";
byte[] ba = IccUtils.hexStringToBytes(sms);
mFh.updateEFLinearFixed(EF_SMS, 1, ba, null,
obtainMessage(EVENT_MARK_SMS_READ_DONE, 1));
}
if (DBG) log("fetchSimRecords " + mRecordsToLoad + " requested: " + mRecordsRequested);
}
loadEFTransparent() 方法:
public void loadEFTransparent(int fileid, Message onLoaded) {
Message response = obtainMessage(EVENT_GET_BINARY_SIZE_DONE,
fileid, , onLoaded);
mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, getEFPath(fileid),
, , GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, response);
}
消息EVENT_GET_IMSI_DONE、EVNET_GET_ICCID_DONE在handleMessage() 中处理,解析出IMSI、ICCID值:
/* IO events */
case EVENT_GET_IMSI_DONE:
isRecordLoadResponse = true; ar = (AsyncResult)msg.obj; mImsi = (String) ar.result;//获取MCC、MNC、MSIN
// IMSI (MCC+MNC+MSIN) is at least 6 digits, but not more
// than 15 (and usually 15).
if (mImsi != null && (mImsi.length() < || mImsi.length() > )) {
loge("invalid IMSI " + mImsi);
mImsi = null;
} log("IMSI: mMncLength=" + mMncLength);
log("IMSI: " + mImsi.substring(, ) + "xxxxxxx");
.........
mImsiReadyRegistrants.notifyRegistrants();
break;
case EVENT_GET_ICCID_DONE:
isRecordLoadResponse = true; ar = (AsyncResult)msg.obj;
data = (byte[])ar.result;
mIccId = IccUtils.bcdToString(data, , data.length);//转换BCD码
mFullIccId = IccUtils.bchToString(data, , data.length); log("iccid: " + SubscriptionInfo.givePrintableIccid(mFullIccId));
break;
handleMessage() 方法解析数据后,调用onRecordLoaded()方法,mRecordsToLoad减1:
protected void onRecordLoaded() {
// One record loaded successfully or failed, In either case
// we need to update the recordsToLoad count
mRecordsToLoad -= 1;//SIM数据读取成功一次,该参数就减1
if (DBG) log("onRecordLoaded " + mRecordsToLoad + " requested: " + mRecordsRequested);
if (mRecordsToLoad == 0 && mRecordsRequested == true) {//mRecordsToLoad值为0,代表fetchSimRecords()中启动加载的数据都已异步读取完成
onAllRecordsLoaded();
} else if (mRecordsToLoad < 0) {
loge("recordsToLoad <0, programmer error suspected");
mRecordsToLoad = 0;
}
}
mRecordsToLoad 值为0,进入onAllRecordsLoaded() 方法,对读取的数据进行处理与存储:
protected void onAllRecordsLoaded() {
if (DBG) log("record load complete");
Resources resource = Resources.getSystem();
if (resource.getBoolean(com.android.internal.R.bool.config_use_sim_language_file)) {
setSimLanguage(mEfLi, mEfPl);
} else {
if (DBG) log ("Not using EF LI/EF PL");
}
setVoiceCallForwardingFlagFromSimRecords();
if (mParentApp.getState() == AppState.APPSTATE_PIN ||
mParentApp.getState() == AppState.APPSTATE_PUK) {
// reset recordsRequested, since sim is not loaded really
mRecordsRequested = false;
// lock state, only update language
return ;
}
// Some fields require more than one SIM record to set
String operator = getOperatorNumeric();
if (!TextUtils.isEmpty(operator)) {
log("onAllRecordsLoaded set 'gsm.sim.operator.numeric' to operator='" +
operator + "'");
log("update icc_operator_numeric=" + operator);
mTelephonyManager.setSimOperatorNumericForPhone(
mParentApp.getPhoneId(), operator);
final SubscriptionController subController = SubscriptionController.getInstance();
subController.setMccMnc(operator, subController.getDefaultSubId());
} else {
log("onAllRecordsLoaded empty 'gsm.sim.operator.numeric' skipping");
}
if (!TextUtils.isEmpty(mImsi)) {
log("onAllRecordsLoaded set mcc imsi" + (VDBG ? ("=" + mImsi) : ""));
mTelephonyManager.setSimCountryIsoForPhone(
mParentApp.getPhoneId(), MccTable.countryCodeForMcc(
Integer.parseInt(mImsi.substring(0,3))));
} else {
log("onAllRecordsLoaded empty imsi skipping setting mcc");
}
setVoiceMailByCountry(operator);
mRecordsLoadedRegistrants.notifyRegistrants(
new AsyncResult(null, null, null));
}
到此sim卡初始化基本流程就结束了。
Android 7.0 UICC 分析(四)的更多相关文章
- Android 7.0 UICC 分析(二)
本文讲解UiccCard类 /frameworks/opt/telephony/src/java/com/android/internal/telephony/uicc/UiccCard.java U ...
- Android 7.0 UICC 分析(三)
本文讲解UICCCardApplication /frameworks/opt/telephony/src/java/com/android/internal/telephony/uicc/UiccC ...
- Android 7.0 UICC 分析(一)
UICC(Universal Intergrated Circuit Card) 框架 * Following is class diagram for uicc classes: * * UiccC ...
- Android 5.0 Uicc框架分析
已同步更新至个人blog: dxjia.cn Uicc框架 UICC框架是Android在4.1引入的,使的对卡的管理控制更加清晰.要了解这个UICC框架,需要从UiccController开始, ...
- Android 8.1 源码_启动篇(二) -- 深入研究 zygote(转 Android 9.0 分析)
前言 在Android中,zygote是整个系统创建新进程的核心进程.zygote进程在内部会先启动Dalvik虚拟机,继而加载一些必要的系统资源和系统类,最后进入一种监听状态.在之后的运作中,当其他 ...
- Android 7.0 启动篇 — init原理(二)(转 Android 9.0 分析)
======================================================== ================================== ...
- Android指纹识别深入浅出分析到实战(6.0以下系统适配方案)
指纹识别这个名词听起来并不陌生,但是实际开发过程中用得并不多.Google从Android6.0(api23)开始才提供标准指纹识别支持,并对外提供指纹识别相关的接口.本文除了能适配6.0及以上系统, ...
- Android 6.0权限全面详细分析和解决方案
原文: http://www.2cto.com/kf/201512/455888.html http://blog.csdn.net/yangqingqo/article/details/483711 ...
- Android深入四大组件(四)Android8.0 根Activity启动过程(前篇)
前言 在几个月前我写了Android深入四大组件(一)应用程序启动过程(前篇)和Android深入四大组件(一)应用程序启动过程(后篇)这两篇文章,它们都是基于Android 7.0,当我开始阅读An ...
随机推荐
- php SimpleXML 例子
$txt = GetRemoteText($url); if(strlen($txt) > 0) { $xml = simplexml_load_string($txt); //获取xml if ...
- Lodop6 以上打印控件使用,详参考自带说明文档,打印样式及文字大小要特殊设置一下
<link href="../css/cssprint.css" rel="stylesheet" /> <script src=" ...
- win7远程桌面恢复全屏状态快捷键
不同的电脑可能有不同的快捷键(有些笔记本电脑甚至没有相应的键值):①台式机:ctrl+alt+break 组合键.②CTRL+ALT+PAGEDOWN 组合键.③有的笔记本没有break键,可以尝试加 ...
- Spring 之注解事务 @Transactional
众所周知的ACID属性: 原子性(atomicity).一致性(consistency).隔离性(isolation)以及持久性(durability).我们无法控制一致性.原子性以及持久性,但可以 ...
- echarts学习网站
echarts : http://echarts.baidu.com/echarts2/doc/example.html 相关脚本学习网站:http://www.jb51.net/html/list/ ...
- js实现表单验证 常用JS表单验证
CSS代码 @charset "gb2312"; /* CSS Document */ body,dl,dt,dd,div,form {padding:;margin:;} #he ...
- Robot Framework:RF中对时间操作的datetime库常用关键字
[转自:http://blog.csdn.net/r455678/article/details/52993765] 1.对固定日期进行操作,增加或减去单位时间或者时间段 2.对两个时间段进行操作 3 ...
- VS有效序列号
VS2005 : KYTYH-TQKW6-VWPBQ-DKC8F-HWC4J VS2008 : PYHYP-WXB3B-B2CCM-V9DX9-VDY8T VS2010 : YCFHQ-9DWCY-D ...
- MongoDB是一个介于关系数据库和非关系数据库之间的产品
MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的.他支持的数据结构非常松散,是类似json的bjson格式,因此可以存储比较复杂的数据类型.M ...
- 40、dom以xml结尾的文件
1.student.xml文件 <?xml version="1.0" encoding="utf-8" ?> <!-- 1.书写根元素(因为 ...