Uicc之CatService(原)

        CatService主要负责STK菜单的相关事宜,本节我们就来分析该对象。


一、CatService的创建过程


        在前面第二节中我们分析过,在UiccCard的更新过程中,会初始化CatService对象:
        @UiccCard.java
        public void update(Context c, CommandsInterface ci, IccCardStatus ics) {
            synchronized (mLock) {
                if (mUiccApplications.length > 0 && mUiccApplications[0] != null) {
                    //创建CatService
                    mCatService = CatService.getInstance(mCi, mContext, this);
                } else {
                    if (mCatService != null) {
                        mCatService.dispose();
                    }
                    mCatService = null;
                }
            }
        }
        然后看具体的初始化流程:
        @CatService.java
        public static CatService getInstance(CommandsInterface ci, Context context, UiccCard ic) {
            UiccCardApplication ca = null;
            IccFileHandler fh = null;
            IccRecords ir = null;
            if (ic != null) {
                //获取UiccCardApplication、IccFileHandler、IccRecords等对象
                ca = ic.getApplicationIndex(0);
                if (ca != null) {
                    fh = ca.getIccFileHandler();
                    ir = ca.getIccRecords();
                }
            }
            synchronized (sInstanceLock) {
                if (sInstance == null) {
                    if (ci == null || ca == null || ir == null || context == null || fh == null || ic == null) {
                        return null;
                    }
                    //创建CatService的消息处理线程
                    HandlerThread thread = new HandlerThread("Cat Telephony service");
                    thread.start();
                    //创建CatService实例对象
                    sInstance = new CatService(ci, ca, ir, context, fh, ic);
                } else if ((ir != null) && (mIccRecords != ir)) {
                    //CatService已经被创建过,只需要更新其监听器
                    if (mIccRecords != null) {
                        mIccRecords.unregisterForRecordsLoaded(sInstance);
                    }
                    if (mUiccApplication != null) {
                        mUiccApplication.unregisterForReady(sInstance);
                    }
                    mIccRecords = ir;
                    mUiccApplication = ca;
                    mIccRecords.registerForRecordsLoaded(sInstance, MSG_ID_ICC_RECORDS_LOADED, null);
                    mUiccApplication.registerForReady(sInstance, MSG_ID_SIM_READY, null);
                } else {
                    CatLog.d(sInstance, "Return current sInstance");
                }
                return sInstance;
            }
        }
        看他的构造函数:
        private CatService(CommandsInterface ci, UiccCardApplication ca, IccRecords ir, Context context, IccFileHandler fh, UiccCard ic) {
            if (ci == null || ca == null || ir == null || context == null || fh == null || ic == null) {
                throw new NullPointerException( "Service: Input parameters must not be null");
            }
            mCmdIf = ci;
            mContext = context;

            //获取RilMessageDecoder对象
            mMsgDecoder = RilMessageDecoder.getInstance(this, fh);
            //向RIL注册监听器
            mCmdIf.setOnCatSessionEnd(this, MSG_ID_SESSION_END, null);
            mCmdIf.setOnCatProactiveCmd(this, MSG_ID_PROACTIVE_COMMAND, null);
            mCmdIf.setOnCatEvent(this, MSG_ID_EVENT_NOTIFY, null);
            mCmdIf.setOnCatCallSetUp(this, MSG_ID_CALL_SETUP, null);

            mIccRecords = ir;
            mUiccApplication = ca;
            //向UiccCardApplication对象注册SIM Ready的监听器
            //向IccRecords对象注册Icc Record Loaded的监听器
            mUiccApplication.registerForReady(this, MSG_ID_SIM_READY, null);
            mIccRecords.registerForRecordsLoaded(this, MSG_ID_ICC_RECORDS_LOADED, null);

            mStkAppInstalled = isStkAppInstalled();
        }
        我们看到在CatService的初始化过程中主要完成了一下三个任务:
        1、获取RilMessageDecoder对象mMsgDecoder;
        2、向RIL注册相关的通知监听;

        3、向UiccCardApplication、IccRecords注册SIM卡和Record的监听;


二、CatService的消息机制


        在上面的CatService构造函数中我们看到,CatService注册了六个主要的监听器:
        1、MSG_ID_SESSION_END
        2、MSG_ID_PROACTIVE_COMMAND
        3、MSG_ID_RIL_MSG_DECODED
        4、MSG_ID_EVENT_NOTIFY
        5、MSG_ID_CALL_SETUP
        6、MSG_ID_SIM_READY
        7、MSG_ID_ICC_RECORDS_LOADED

        而这六个消息事件中,有四个是比较重要的,按照接收的先后顺序分别是:
        MSG_ID_SIM_READY            ----通知CatService,SIM卡已经就绪,需要CatService反馈是否就绪
        MSG_ID_PROACTIVE_COMMAND    ----CatService拿到SIM卡中的STK信息
        MSG_ID_RIL_MSG_DECODED      ----RilMessageDecoder解析完STK数据后给CatService发送通知
        MSG_ID_SESSION_END          ----RIL上传当前消息已经传输完毕

        下面我们主要介绍以上四个消息的处理流程。


2.1、MSG_ID_SIM_READY


        这是CatService接收到的第一个消息,接收到该消息就说明SIM卡已经处于Ready状态,此时CatService向RIL报告说明CatService已经运行,准备接受消息。下面来看详细流程:
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_ID_SIM_READY:
                    //向RIL发送消息
                    mCmdIf.reportStkServiceIsRunning(null);
                    break;
                default:
                    throw new AssertionError("Unrecognized CAT command: " + msg.what);
            }
        }

        此时的RIL将会向Modem发送RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING的消息,从而告诉Modem,CatService已经准备好接受STK的数据了。


2.2、MSG_ID_PROACTIVE_COMMAND


        Modem接收到CatService已经启动的消息后,就会上报MSG_ID_PROACTIVE_COMMAND的消息,该消息中包含了SIM卡中存储的STK信息,此时 CatService需要将这些信息解析并保存,用于构建STK菜单
        请注意, 如果SIM卡不支持STK业务,将接收不到该消息
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_ID_SESSION_END:
                case MSG_ID_PROACTIVE_COMMAND:
                case MSG_ID_EVENT_NOTIFY:
                case MSG_ID_REFRESH:
                    String data = null;
                    if (msg.obj != null) {
                        AsyncResult ar = (AsyncResult) msg.obj;
                        if (ar != null && ar.result != null) {
                            try {
                                data = (String) ar.result;
                            } catch (ClassCastException e) {
                                break;
                            }
                        }
                    }
                    //通过RilMessageDecoder去解析数据
                    mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, data));
                    break;
                default:
                    throw new AssertionError("Unrecognized CAT command: " + msg.what);
            }
        }
        我们看到,对于拿到的数据时通过mMsgDecoder去解析的,也就是RilMessageDecoder的对象,这个对象是在CatService的构造函数中被创建的。我们来看具体的解析数据的过程:
        @RilMessageDecoder.java
        public void sendStartDecodingMessageParams(RilMessage rilMsg) {
            Message msg = obtainMessage(CMD_START);
            msg.obj = rilMsg;
            sendMessage(msg);
        }
        在RilMessageDecoder中又将消息封装后发送给自己,并在StateStart中被处理:
        private class StateStart extends State {
            @Override
            public boolean processMessage(Message msg) {
                if (msg.what == CMD_START) {
                    if (decodeMessageParams((RilMessage)msg.obj)) {
                        transitionTo(mStateCmdParamsReady);
                    }
                } else {
                    CatLog.d(this, "StateStart unexpecte
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值