1. SIM 卡加载流程(基于 Android O)
1.1 主要流程
-
SIM 框架的中心类为 UiccController,在该类的注释中完整标注了SIM 框架的组成
-
UiccController 会在RILJ中注册监听事件,一旦RILJ收到modem消息,进而 notify 监听,则SIM卡加载流程就开始了
-
UiccController 收到 SIM卡状态变化的消息后会通过 RILJ 主动去获取SIM卡信息, 成功拿到响应后则触发新建 UiccCard 的操作,同时也会在 IccCardProxy 中注册对 UiccCardApplication 状态和 IccRecords 状态的监听。这样在 步骤5 之后,便可以执行上层的更新操作
-
UiccCard 是一张 SIM卡的抽象,其中主要包含了两个部分,一个是UiccCardApplication,另一部分是IccRecords:
- UiccCardApplication 是SIM卡中的应用,一般一张卡里有多个application,比如CSIM,USIM,ISIM等等。SIM对应的IMS业务相关用户信息、鉴权信息等存在ISIM application里, UMTS,LTE等鉴权信息在USIM application里, CDMA的鉴权信息则在CSIM application里。
- IccRecords 是 SIM卡中存储的信息的封装容器,需要借助专门的 IccFileHandler 以 SIM I/O 的方式从SIM卡中读取出来,存储到IccRecords中。
-
SIM 卡中存储的信息都通过 IccFileHandler 加载存储到了IccRecords中,则认为SIM卡已经加载完成了
-
IccCardProxy 监听到了 UiccCardApplication 和 IccRecords 就绪的状态,则发出广播,将相关信息通知到 SubscriptionInfoUpdater,由其完成 siminfo 数据库更新等操作
-
SubscriptionInfoUpdater 主要更新数据库信息,更新call,data,sim等相关偏好设置,同时设置加载的sim卡的网络偏好设置,之后再将 SIM 状态变化的消息广播出去
1.2 需注意的细节
- 在Android P 之后, IccCardProxy已经被移除,也就是说在 P 之后监听 UiccCardApplication 和 IccRecords 加载状态从而确定 SIM卡状态的逻辑已经修改。从代码来看,是移动到了 P 上新增加的 UiccProfile 中
- Android P 之后 SIM卡框架也有很大变化,新增了 UiccSlot 来抽象一个卡槽,UiccSlot 中又有 UiccCard 和 UiccProfile,具体变化可从 UiccController 注释信息中查到
- UiccCardApplication 数量最多为 8 个,但是国内的SIM卡通常不会写入这么多sim卡应用程序,最多会写有 3 个
2. 运营商名称显示流程
2.1 主要流程
- 运营商名称的来源主要有两个,一个是写在 SIM卡中的 SPN,另一个是从网络侧拿到的 PLMN
- SPN 写在SIM卡中,SIM卡加载时期会将其存在 TelephonyManager 的系统属性中,另外如果有相关定制也可以将 SIM 卡中的 SPN 覆盖掉,比如虚拟运营商的 SPN 就需要做这个处理
- 通常在 ServiceStateTracker 中监听到 SIM 卡 READY 的状态后会调用 RILJ 的方法去主动 获取当前驻留网络的PLMN
- 拿到之后将其封装在 ServiceState 对象中,之后根据新旧状态的对比确定运营商名称是否有变化。另外即便有变化也需要根据当前的服务状态来确定显示的字符串,如果服务状态正常则需要读取 SIM卡中运营商名称的显示规则来决定显示的字符串,之后将其广播出去
显示规则主要根据 SIM卡中两个bit位数据来确定,通常在log中会有打印,关键字应该是displaycondition。
1--只显示spn,2--只显示plmn,3--显示spn-plmn
1.名称可以为SPN或PLMN
2、如果没有SPN文件,那么就显示PLMN
3、若有SPN,并且注册的PLMN是HPLMN或者注册的PLMN在SIM卡文件EF_SPDI中,那么:
(1)如果有SPN就要显示SPN
(2)如果SPN的bit1 = 1, 则需要同时显示PLMN,如果SPN的bit1=0,则不需要同时显示PLMN
4、若有SPN,注册的PLMN是Roaming PLMN且注册的PLMN也不在SIM卡文件EF_SPDI中,那么
(1)显示PLMN
(2)如果SPN的bit2=0,则需要同时显示SPN,如果SPN的bit2=1,则不需要同时显示SPN
- SubscriptionController 会接收广播,然后将接收到的字符串写入到 数据库 siminfo 表,并通知监听者运营商名称已经改变了
2.2 需注意的细节
-
通常 SPN 来自sim卡,但是对于虚拟运营商而言需要定制SPN显示,则需要修改 CarrierConfig 文件来达到目的。虚拟运营商的匹配规则也是根据 SIM卡中存储的数据来匹配的,一般分为以下四类
SPN,GID,PNN,ICCID
-
ServiceStateTracker 是服务状态的中心类,其工作机制具有原子性,即只有当所有请求的数据都收到回应后才会 pollState,该机制通过一个计数变量实现
-
Android P 之后该部分变化较多,主要是将 SPN 覆盖的逻辑移动到了 UiccProfile中,另外也有其他的变化,此处不一一列明