Android 4.4Telephony流程分析SIM卡开机时的数据加载

来源:互联网 发布:手机淘宝口令怎么设置 编辑:程序博客网 时间:2024/04/24 22:15

本文代码以MTK平台Android 4.4为分析对象,与Google原生AOSP有些许差异,请读者知悉。

本文主要介绍sim卡数据的读取过程,当射频状态处于准备状态时,此时UiccCardApplication应处于AppState.APPSTATE_READY状态,我们沿着这个信号跟踪下去。阅读本文时可先阅读Android4.4 Telephony流程分析——SIM卡开机时的初始化一文,了解Radio和sim卡状态更新过程。

先来看一下数据加载的序列图:

\

step1~step3,走的是更新过程,创建过程参考Android4.4 Telephony流程分析——SIM卡开机时的初始化一文step21之后的步骤。

step4,通过Modem查询sim卡的FDN(固定拨号)数据。

step5,通过Modem查询sim卡的pin1状态。

step6~step7,将pin1状态通知出去,IccCardProxy会注册mPinLockedRegistrants。

step8~step9,将sim卡ready状态发出去。

 

view sourceprint?
01.private void notifyReadyRegistrantsIfNeeded(Registrant r) {
02.if (mDestroyed) {
03.return;
04.}
05.if (mAppState == AppState.APPSTATE_READY) {
06.if (mPin1State == PinState.PINSTATE_ENABLED_NOT_VERIFIED ||
07.mPin1State == PinState.PINSTATE_ENABLED_BLOCKED ||
08.mPin1State == PinState.PINSTATE_ENABLED_PERM_BLOCKED) {
09.loge("Sanity check failed! APPSTATE is ready while PIN1 is not verified!!!");
10.// Don't notify if application is in insane state
11.return;
12.}
13.if (r == null) {
14.if (DBG) log("Notifying registrants: READY");
15.mReadyRegistrants.notifyRegistrants();
16.else {
17.if (DBG) log("Notifying 1 registrant: READY");
18.r.notifyRegistrant(new AsyncResult(nullnullnull));
19.}
20.}
21.}

如果此时pin1是被激活的,也就是sim卡开启了pin1锁,sim卡ready状态就不会发出去。

 

监听mReadyRegistrants状态变化的对象很多,主要有:SIMRecords(同类的还有RuimRecords、IsimUiccRecords),IccCardProxy(会将SIM卡状态广播出去),GsmServiceStateTracker(会根据SIM状态去注册网络),这里主要说一下SIMRecords,读取SIM的数据。

step12,fetchSimRecords()方法:

 

view sourceprint?
001.//MTK-END [mtk80601][111215][ALPS00093395]
002.protected void fetchSimRecords() {
003.mRecordsRequested = true;
004. 
005.if (DBG) log("fetchSimRecords " + mRecordsToLoad);
006. 
007.mCi.getIMSIForApp(mParentApp.getAid(), obtainMessage(EVENT_GET_IMSI_DONE));//读IMSI
008.mRecordsToLoad++;
009. 
010.//iccFh.loadEFTransparent(EF_ICCID, obtainMessage(EVENT_GET_ICCID_DONE));
011.//mRecordsToLoad++;
012. 
013.// FIXME should examine EF[MSISDN]'s capability configuration
014.// to determine which is the voice/data/fax line
015.//new AdnRecordLoader(phone).loadFromEF(EF_MSISDN, EF_EXT1, 1,
016.//obtainMessage(EVENT_GET_MSISDN_DONE));
017.//recordsToLoad++;
018. 
019.// Record number is subscriber profile
020.mFh.loadEFLinearFixed(EF_MBI, 1, obtainMessage(EVENT_GET_MBI_DONE));
021.mRecordsToLoad++;
022. 
023.mFh.loadEFTransparent(EF_AD, obtainMessage(EVENT_GET_AD_DONE));
024.mRecordsToLoad++;
025. 
026.// Record number is subscriber profile
027.mFh.loadEFLinearFixed(EF_MWIS, 1, obtainMessage(EVENT_GET_MWIS_DONE));
028.mRecordsToLoad++;
029. 
030. 
031.// Also load CPHS-style voice mail indicator, which stores
032.// the same info as EF[MWIS]. If both exist, both are updated
033.// but the EF[MWIS] data is preferred
034.// Please note this must be loaded after EF[MWIS]
035.mFh.loadEFTransparent(
036.EF_VOICE_MAIL_INDICATOR_CPHS,
037.obtainMessage(EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE));
038.mRecordsToLoad++;
039. 
040.// Same goes for Call Forward Status indicator: fetch both
041.// EF[CFIS] and CPHS-EF, with EF[CFIS] preferred.
042.mFh.loadEFLinearFixed(EF_CFIS, 1, obtainMessage(EVENT_GET_CFIS_DONE));
043.mRecordsToLoad++;
044.mFh.loadEFTransparent(EF_CFF_CPHS, obtainMessage(EVENT_GET_CFF_DONE));
045.mRecordsToLoad++;
046. 
047. 
048.//getSpnFsm(true, null);
049. 
050.mFh.loadEFTransparent(EF_SPDI, obtainMessage(EVENT_GET_SPDI_DONE));
051.mRecordsToLoad++;
052. 
053.//mFh.loadEFLinearFixed(EF_PNN, 1, obtainMessage(EVENT_GET_PNN_DONE));
054.//recordsToLoad++;
055. 
056.mFh.loadEFTransparent(EF_SST, obtainMessage(EVENT_GET_SST_DONE));
057.mRecordsToLoad++;
058. 
059.mFh.loadEFTransparent(EF_INFO_CPHS, obtainMessage(EVENT_GET_INFO_CPHS_DONE));
060.mRecordsToLoad++;
061. 
062.mFh.loadEFTransparent(EF_CSP_CPHS,obtainMessage(EVENT_GET_CSP_CPHS_DONE));
063.mRecordsToLoad++;
064. 
065.mFh.loadEFTransparent(EF_GID1, obtainMessage(EVENT_GET_GID1_DONE));
066.mRecordsToLoad++;
067. 
068./*
069.Detail description:
070.This feature provides a interface to get menu title string from EF_SUME
071.*/
072.if (mTelephonyExt != null) {
073.if (mTelephonyExt.isSetLanguageBySIM()) {
074.mFh.loadEFTransparent(EF_SUME, obtainMessage(EVENT_QUERY_MENU_TITLE_DONE));
075.mRecordsToLoad++;
076.}
077.else {
078.loge("fetchSimRecords(): mTelephonyExt is null!!!");
079.}
080. 
081.fetchCPHSOns();
082. 
083.// XXX should seek instead of examining them all
084.if (false) { // XXX
085.mFh.loadEFLinearFixedAll(EF_SMS, obtainMessage(EVENT_GET_ALL_SMS_DONE));
086.mRecordsToLoad++;
087.}
088. 
089.if (CRASH_RIL) {
090.String sms = "0107912160130310f20404d0110041007030208054832b0120"
091."fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
092."fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
093."fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
094."fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
095."ffffffffffffffffffffffffffffff";
096.byte[] ba = IccUtils.hexStringToBytes(sms);
097. 
098.mFh.updateEFLinearFixed(EF_SMS, 1, ba, null,
099.obtainMessage(EVENT_MARK_SMS_READ_DONE, 1));
100.}
101.if (DBG) log("fetchSimRecords " + mRecordsToLoad + " requested: " + mRecordsRequested);
102./*
103.* Here, we assume that PHB is ready and try to read the entries.
104.* If it is not, we will receive the event EVENT_PHB_READY later.
105.* Then, we will ready the PHB entries again.
106.*/
107.fetchPhbRecords();//读adn联系人
108. 
109.fetchRatBalancing();
110.}

读SIM卡是要通过Modem的,上层读Modem就得通过RIL,我们以读ADN联系人fetchPhbRecords()为例,来看看读取过程step13~step22,主要是通过IccFileHandler实现,先请求adn的长度(step16~step19),然后再请求具体的adn联系人数据step20~step22,这个过程就是与Modem交互的过程,读者可以先了解一下SIM卡的文件结构,才能更好的理解为什么这样读,我也不甚熟悉。

 

step23,获取SIM卡内置的紧急号码,这个是由运营商定制的。

step24~step26,当需要load的数据都load完成,才会执行,再在onAllRecordsLoaded中发布mRecordsLoadedRegistrants通知。

 

view sourceprint?
01.protected void onRecordLoaded() {
02.// One record loaded successfully or failed, In either case
03.// we need to update the recordsToLoad count
04.mRecordsToLoad -= 1;
05.if (DBG) log("onRecordLoaded " + mRecordsToLoad + " requested: " + mRecordsRequested);
06. 
07.if (mRecordsToLoad == 0 && mRecordsRequested == true) {
08.onAllRecordsLoaded();
09.else if (mRecordsToLoad < 0) {
10.loge("recordsToLoad <0, programmer error suspected");
11.mRecordsToLoad = 0;
12.}
13.}

step27之后的步骤,都是对mRecordsLoadedRegistrants侦听的响应,IccCardProxy侦听到后,会发广播给外界:

 

 

view sourceprint?
01.private void broadcastIccStateChangedIntent(String value, String reason) {
02.synchronized (mLock) {
03.if (mQuietMode) {
04.log("QuietMode: NOT Broadcasting intent ACTION_SIM_STATE_CHANGED " +  value
05." reason " + reason);
06.return;
07.}
08. 
09.Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
10.//intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
11.intent.putExtra(PhoneConstants.PHONE_NAME_KEY, "Phone");
12.intent.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE, value);
13.intent.putExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON, reason);
14.intent.putExtra(PhoneConstants.GEMINI_SIM_ID_KEY, mSimId);
15.if (DBG) log("Broadcasting intent ACTION_SIM_STATE_CHANGED " +  value
16." reason " + reason + " sim id " + mSimId);
17.ActivityManagerNative.broadcastStickyIntent(intent, READ_PHONE_STATE,
18.UserHandle.USER_ALL);
19.}
20.}
21. 
22.public void broadcastIccStateChangedExtendIntent(String value, String reason) {
23.synchronized (mLock) {
24.if (mQuietMode) {
25.log("QuietMode: NOT Broadcasting extend intent ACTION_SIM_STATE_CHANGED " +  value
26." reason " + reason);
27.return;
28.}
29. 
30.Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED_EXTEND);
31.//intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
32.intent.putExtra(PhoneConstants.PHONE_NAME_KEY, "Phone");
33.intent.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE, value);
34.intent.putExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON, reason);
35.intent.putExtra(PhoneConstants.GEMINI_SIM_ID_KEY, mSimId);
36.if (DBG) log("Broadcasting intent ACTION_SIM_STATE_CHANGED_EXTEND " +  value
37." reason " + reason + " sim id " + mSimId);
38.ActivityManagerNative.broadcastStickyIntent(intent, READ_PHONE_STATE,
39.UserHandle.USER_ALL);
40.}
41.}

0 0
原创粉丝点击