第3章 SubscriptionInfo的更新调用流程
3.1 UiccController
Sim卡状态发生改变,发送EVENT_GET_ICC_STATUS_DONE消息到UiccController的handleMessage。
图3.1UiccController的handleMessage消息处理
UiccController调RIL的getIccCardStatus()传EVENT_GET_ICC_STATUS_DONE消息作为参数到modem,方法处理完ril会上报该消息回来引起回调。
3.2 IccCardProxy
补充:当PhoneFactory创建出GsmCdmaPhone后,GsmCdmaPhone在其初始化函数中将创建出IccCardProxy对象。IccCardProxy对象将作为UiccController的观察者,同样监听卡状态变化。
图3.2在其初始化函数中将创建出IccCardProxy对象
a. IccCardProxy的构造函数中向UicccController注册了监听卡的变化的事件。
图3.3注册了监听卡的变化的事件
看一下UiccController的registerForIccChanged方法,这个方法中主要是做了两件事
1. 先新建了一个Registrant对象,将其加入mIccChangedRegistrants中;
2. 调用了该对象的notifyRegistrant方法。
图3.4 UiccController的registerForIccChanged方法调用notifyRegistrant
接着看一下Registrant.java 的notifyRegistrant方法
图3.5 notifyRegistrant方法调internalNotifyRegistrant
接着看一下Registrant.java 的notifyRegistrant方法调用的internalNotifyRegistrant()方法;
图3.6 internalNotifyRegistrant()方法发消息给自己
从这两个方法中,我们知道,其获取了Handler对象,并发送消息给自己。所以此处调用了IccCardProxy的handleMessage方法,且传入的消息的switch(msg.what)为EVENT_ICC_CHANGED。
b. 收到消息后调用IccCardProxy类中的handleMessage进行消息处理。
图3.7 调用updateIccAvailability()
c. handleMessage处理过程中调用updateIccAvailability(),updateIccAvailability()在某些情况下调用registerUiccCardEvents()。
图3.8在某些情况下调用registerUiccCardEvents()
d. registerUiccCardEvents()中注册了EVENT_RECORDS_LOADED消息。
图3.9
3.3 SimRecords解析EVENT_RECORDS_LOADED上报流程:
- SimRecords中的public SimRecords(…),注册了EVENT_APP_READY。
图3.10 SimRecords中注册了EVENT_APP_READY
- UiccCardApplication发送EVENT_APP_READY消息,SimRecords就会响应,然后去handleMessage()方法进行下一步处理。
图3.11handleMessage()方法调用onReady()
- 可以看到会执行onReady(),进入onReady,会调用fetchSimRecords()
图3.12 onReady()会调用fetchSimRecords()
- fetchSimRecords()中获取EVENT_GET_ICCID_DONE ,进行相应的处理,同样也会去handleMessage中进行消息处理。
图3.13获取EVENT_GET_ICCID_DONE
- 同样也会去handleMessage中进行消息处理。
图3.14 isRecordLoadResponse设为true
- isRecordLoadResponse为true,handleMessage最后会执行onRecordLoaded。
图3.15 handleMessage调用onRecordLoaded()
- onRecordLoaded()会调用onAllRecordsLoaded()方法。
图3.16调用onAllRecordsLoaded()方法
- onAllRecordsLoaded()方法会通知所有注册的handler这样EVENT_RECORDS_LOADED消息就会发送到IccCardProxy的消息处理函数中。当SIMRecords加载完毕后,发送EVENT_RECORDS_LOADED
图3.17 onAllRecordsLoaded()通知所有注册的handler
mRecordsLoadedRegistrants是ICCRecords中定义的变量。
3.4 IccCardProxy的消息处理。
a. 收到EVENT_RECORDS_LOADED消息后调用IccCardProxy类中的handleMessage(),最后会执行onRecordsLoaded()。
图3.18执行onRecordsLoaded()
- onRecordsLoaded()方法调broadcastInternalIccStateChangedIntent()。
图3.19onRecordsLoaded()中会执行broadcastInternalIccStateChangedIntent()
- broadcastInternalIccStateChangedIntent()最后会发送一个ACTION_INTERNAL_SIM_STATE_CHANGED广播
图3.20 最后发送广播
3.5 SubscriptionInfoUpdater
a. 上一节讲到发送了个ACTION_INTERNAL_SIM_STATE_CHANGED广播。 SubscriptionInfoUpdater构造函数中注册了广播接受器接收这个广播。SubscriptionInfoUpdater收到通知的链条就搭起来了。
图3.21
收到广播之后就该处理广播了,接下来看一下处理过程:
b. 接着看SubscriptionInfoUpdater的onReceiver()收广播,收到后会进入handleMessage()处理消息,但是在处理的过程之中onReceiver()又会发送EVENT_SIM_LOADED。
………
图3.22在handleMessage处理广播的过程中 onReceiver()发送EVENT_SIM_LOADED
- SubscriptionInfoUpdater的handleMessage中处理,执行 handleSimLoaded(msg.arg1)
图3.23执行 handleSimLoaded(msg.arg1)
- handleSimLoaded()执行过程,针对插卡或者拔卡不同分支处理,现只看插卡:
图3.24 调用updateSubscriptionInfoByIccId
e. 在handleSimLoaded函数中,主要工作将由updateSubscriptionInfoByIccId函数来承担。
updateSubscriptionInfoByIccId依次调用clearSubInfo和addSubscriptionInfoRecord函数完成实际的工作。
图3.25 调用clearSubInfo
图3.26 addSubscriptionInfoRecord()在SubscriptionController中定义
clearSubInfo主要用于清除slot Id和sub Id之间的关系。毕竟在卡槽中重新插入一张卡后,sub Id可能发生了变化,因此需要先清理过去的缓存信息。
addSubscriptionInfoRecord实际上是通过SubscriptioManager间接地调用SubscriptionController的接口进行实际工作。
SubscriptionController首先将更新一些数据库字段,设置一些卡界面显示所需要信息,如SIM卡在设置界面中的名称、颜色等。然后,SubscriptionController重新建立起Slot Id和Sub Id之间的映射关系。最后,SubscriptionController判断终端中只有一张卡时,开始设置数据、语音和短信使用的Sub Id等。数据卡设置完毕后,SubscriptionController将发送相应的广播信息。