Android N SIM 卡信息加载流程

    在 PhoneAPP 启动关系类初始化中,我们提到监听处理SIM卡状态的两个关键类 UiccController 和 IccCardProxy,那么他们与SIM卡信息究竟是如何交互的呢?在UiccController 的 Android 源码中有这样一个 SIM卡相关类关系说明,这里我们先整体上看一下

/**
 * This class is responsible for keeping all knowledge about
 * Universal Integrated Circuit Card (UICC), also know as SIM's,
 * in the system. It is also used as API to get appropriate
 * applications to pass them to phone and service trackers.
 *
 * UiccController is created with the call to make() function.
 * UiccController is a singleton and make() must only be called once
 * and throws an exception if called multiple times.
 *
 * Once created UiccController registers with RIL for "on" and "unsol_sim_status_changed"
 * notifications. When such notification arrives UiccController will call
 * getIccCardStatus (GET_SIM_STATUS). Based on the response of GET_SIM_STATUS
 * request appropriate tree of uicc objects will be created.
 *
 * Following is class diagram for uicc classes:
 *
 *                       UiccController
 *                            #
 *                            |
 *                        UiccCard
 *                          #   #
 *                          |   ------------------
 *                    UiccCardApplication    CatService
 *                      #            #
 *                      |            |
 *                 IccRecords    IccFileHandler
 *                 ^ ^ ^           ^ ^ ^ ^ ^
 *    SIMRecords---- | |           | | | | ---SIMFileHandler
 *    RuimRecords----- |           | | | ----RuimFileHandler
 *    IsimUiccRecords---           | | -----UsimFileHandler
 *                                 | ------CsimFileHandler
 *                                 ----IsimFileHandler
 *
 * Legend: # stands for Composition
 *         ^ stands for Generalization
 *
 * See also {@link com.android.internal.telephony.IccCard}
 * and {@link com.android.internal.telephony.uicc.IccCardProxy}
 */     

UiccController:整个UICC事务处理的入口,负责对外提供IccRecords、IccFileHandler、UiccCardApplication等对象,并完成整个UICC系统的初始化工作。

UiccCard: 本身并不实现具体的功能,只负责UiccCardApplication及CatService对象的创建更新工作,以及当SIM卡被插入或者拔出时弹出提示框是否需要重启设备。

UiccCardApplication:主要任务包括创建并向外提供IccFileHandler、IccRecords对象、提供对SIM卡状态的监听等

IccRecords:提供SIM卡常用信息查询,如IMSI、ICCID、VoiceMail、Contacts等,UiccController根据SIM类型不同,创建不同IccRecords对象

IccFileHandler:负责SIM卡文件系统的读写,会在UiccCardApplication中根据SIM类型不同,创建不同IccFileHandler对象

CatService:负责 STK 相关业务,接收解析 modem 上传的相关数据,并回传给RIL及StkAppService


1、SIM卡信息加载流程图


2、SIM卡状态监听及创建

      在 PhoneAPP 初始化时,PhoneFactory 创建了 UiccController 和 GsmCdmaPhone,前者以RIL为观察对象直接注册监听卡的状态变化,后者构造出 IccCardProxy 间接向UiccController 注册监听卡状态变化,进行相关事件处理。

      在插卡开机或热插拔时,当 Modem 检卡成功后会主动上报 RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGE 消息,通过 RIL 通知上层监听者 UiccController,后者在收到通知后会调用 getIccCardStatus 通过 RIL 向 Modem 主动获取SIM卡相关信息,在得到 RIL_REQUEST_GET_SIM_STATUS 返回后,调用 onGetIccCardStatusDone 进行后续处理。

frameworks/opt/telephony/src/java/com/android/internal/telephony/uicc/UiccController.java

    @Override
    public void handleMessage (Message msg) {
        synchronized (mLock) {
            Integer index = getCiIndex(msg);
            AsyncResult ar = (AsyncResult)msg.obj;
            switch (msg.what) {
                case EVENT_ICC_STATUS_CHANGED:
                    if (DBG) log("Received EVENT_ICC_STATUS_CHANGED, calling getIccCardStatus");
                    mCis[index].getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE, index));
                    break;
                case EVENT_GET_ICC_STATUS_DONE:
                    if (DBG) log("Received EVENT_GET_ICC_STATUS_DONE");
                    onGetIccCardStatusDone(ar, index);
                    break;
                 ......

        在onGetIccCardStatusDone函数中,UiccController将判断是否存在对应的UiccCard,如果没有将根据卡信息创建出对应的UiccCard对象;否则,仅进行UiccCard的更新操作。实际上,从代码逻辑看,即使新建UiccCard对象,最终也会调用到 Update 函数。

    private synchronized void onGetIccCardStatusDone(AsyncResult ar, Integer index) {
        if (ar.exception != null) {
            return;
        }
        if (!isValidCardIndex(index)) {
            Rlog.e(LOG_TAG,"onGetIccCardStatusDone: invalid index : " + index);
            return;
        }

        IccCardStatus status = (IccCardStatus)ar.result;

        if (mUiccCards[index] == null) {
            //Create new card
            mUiccCards[index] = new UiccCard(mContext, mCis[index], status, index);
        } else {
            //Update already existing card
            mUiccCards[index].update(mContext, mCis[index] , status);
        }

        if (DBG) log("Notifying IccChangedRegistrants");
        mIccChangedRegistrants.notifyRegistrants(new AsyncResult(null, index, null));

    }

查看代码,UiccCard.update 最终完成了UiccCardApplication 和 CatService 的创建和更新

frameworks/opt/telephony/src/java/com/android/internal/telephony/uicc/UiccCard.java

    public void update(Context c, CommandsInterface ci, IccCardStatus ics) {
           ......
           //创建/更新UiccCardApplication
            for ( int i = 0; i < mUiccApp
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值