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 ...
随机推荐
- Arch Linux LibreOffice 中文输入法不能切换
From: http://blog.csdn.net/shallowgrave/article/details/8501629 卸载libreoffice-kde4 # pacman -R libre ...
- window7下使用vagrant打造lamp开发环境(二)
上一节我们基本把软件跟系统环境,以及连接虚拟机给配置好了,下面我们将要进行开发环境的搭建(lamp) 这里安装其实很简单,因为我们用的centos,所以很大一部分安装都是通过yum安装 关于yum的详 ...
- 软件工程—我的IT的新篇章
这学期开了一门软件工程,在开始学习过程中,我对软件工程充满了浓厚的兴趣,我很享受软件工程带给我的快乐与激情,让我对计算机编程更加的了解与享受,我非常的喜欢这门学科,我对老师的教学方式非常的喜欢,我觉得 ...
- backprop示例
http://home.agh.edu.pl/~vlsi/AI/backp_t_en/backprop.html
- 如何存session,取session
存session: Session["codes"] =要存的session字段 用哈希函数存多个: System.Collections.Hashtable hs = new S ...
- 针对APP的测试过程和重点关注内容,做以下梳理和总结
转载自金阳光测试:http://blog.sina.com.cn/s/blog_12df1b9e60102vy57.html 1. 首先是测试资源确认及准备 (1)产品需求文档.产品原型图.接口说 ...
- c#全局鼠标事件以及鼠标事件模拟
最近在编写Max插件时,其主容器FlowLayoutPanel由于隐藏了滚动条,要实现按住鼠标中键上下拖动的功能,因此尝试了全局鼠标事件.以及鼠标勾子,可惜由于Max不争气?都未能实现,于是代码报废, ...
- Appium常见问题(持续更新)
1.Original error: Could not parse activity from dumpsys 命令行:adb shell dumpsys cpuinfo 报:service du ...
- windows7 编译boost1.54
先去下载boost1.54 for windows原码.原来有个安装工具现在已经停止维护了,我试了旧版,已经安装不了. 这是它们的网站:http://www.boostpro.com/download ...
- Delphi控制Excel输出上标示例
直接上代码吧,这个示例在Excel中输出一个M2: unit FfrmMain; interface uses Winapi.Windows, Winapi.Messages, System.SysU ...