关闭

高通平台ModemBindingPolicyHandler和ModemBindingPolicyHandler作用(原)

标签: ModemBindingPolicyHaModemStackControllerandroidsetPreferredNetworkT
1250人阅读 评论(0) 收藏 举报
分类:
        做高通平台双卡项目的时候,高通在Telephony模块中添加了ModemBindingPolicyHandlerModemStackController两个对象,今天我们来看一下他们的作用。由于这两个对象都是高通自己添加的,因此不方便贴出太多的源码,我们简要看一下其作用和原理。
        高通之所以在AP侧添加这两个对象,是和其双卡的协议栈结构相关的。
        我们知道虽然双卡都可能支持3G/4G,但是任意时刻必须有一个卡的网络模式是GSM only,比如SIM1网络模式为GSM only,SIM2为LWG,或者SIM1和SIM2都是GSM only模式,但是一定不能是两张卡同时LWG模式,上层之所以会有这样的限制,是因为Modem虽然有两个协议栈,但是其中只有一个协议栈具备LWG能力,而另一个协议栈仅支持GSM模式。
        但是有个疑问,既然两个协议栈中只有一个支持LWG,那么就应该只有一个卡槽支持LWG,为什么用户可以将任意一张卡设置为LWG呢?

        这是因为底层的协议栈和上层的卡槽是可以交叉绑定的,如下图:


        如图中所示,当按照实线箭头绑定,那么就是SIM1仅支持GSM,SIM2支持LWG,如果按照虚线箭头绑定,那么就是SIM1支持LWG,SIM2仅支持GSM模式。
        也就是说,虽然两个协议栈固定了其中只能有一个工作在LWG模式,但是可以让该协议栈映射到不同的卡槽,从而让用户觉得双卡都支持LWG模式,而做这项映射工作的就是本节中介绍的两个对象。
        当PhoneFactory创建Phone对象的时候,通过ModemBindingPolicyHandler的make()方法创建ModemBindingPolicyHandler对象,该对象是单实例对象,创建成功后可以通过ModemBindingPolicyHandler的getInstance()方法获取其实例。
        当用户点击菜单设置网络模式时,会调用到PhoneBase的setPreferredNetworkType()方法:
        @PhoneBase.java
        public void setPreferredNetworkType(int networkType, Message response) {
            if (TelephonyManager.getDefault().getPhoneCount() > 1) {
                //双卡项目
                ModemBindingPolicyHandler.getInstance().setPreferredNetworkType(networkType, getPhoneId(),response);
            } else {
                //单卡项目,直接修改网络模式即可
                mCi.setPreferredNetworkType(networkType, response);
            }
        }
        在这里我们就看到,双卡项目上,将会利用ModemBindingPolicyHandler的setPreferredNetworkType()方法来设置网络模式,然后ModemBindingPolicyHandler就会在updateStackBindingIfRequired()方法中分情况操作:
        1、如果当前要设置网络模式的卡槽对应的协议栈支持将要设置的网络模式,那么直接修改网络模式即可
        2、如果当前要设置网络模式的卡槽对应的协议栈不支持将要设置的网络模式,那么就去查询另一个协议栈是否支持要设置的网络模式,如果支持,那么就更换两个协议栈与SIM的对应关系
        当发生第二种情况时,就需要经过ModemStackController的updateStackBinding()方法来交换两个协议栈,具体流程如下:
        1、去激活所有的SIM
            subCtrlr.deactivateSubId(subInfo.subId);
        2、解除底层协议栈与上层SIM的绑定关系
            private void unbindStackOnSub(int phoneId) {
                Message msg = Message.obtain(this, EVENT_UNBIND_DONE, new Integer(phoneId));
                //解除当前双卡绑定关系
                mCi[phoneId].updateStackBinding(mCurrentStackId[phoneId], UNBIND_TO_STACK, msg);
            }
        3、将新的绑定关系传递给协议栈,重新绑定
            private void bindStackOnSub(int phoneId) {
                Message msg = Message.obtain(this, EVENT_BIND_DONE, new Integer(phoneId));
                //重新绑定双卡的协议栈
                mCi[phoneId].updateStackBinding(mPreferredStackId[phoneId], BIND_TO_STACK, msg);
            }
        4、重新设置双卡的网络模式
            private void setPrefNwTypeOnAllSubs() {
                resetSubStates();
                for (int i = 0; i < mNumPhones; i++) {
                    Message resp = obtainMessage(EVENT_SET_PREF_MODE_DONE, new Integer(i));
                    //根据最新的用户设置,更新双卡的网络模式
                    mCi[i].setPreferredNetworkType(mPrefNwMode[i], resp);
                }
            }
        经过以上过程,就完成了协议栈的交叉绑定和网络模式的改变。

        此方案在最新的高通平台中被优化,优化为双协议栈都可以支持LWG模式(但任意时刻仍然需要至少一个工作在GSM only模式),因此无需再进行交叉绑定的操作。




2
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:303501次
    • 积分:3627
    • 等级:
    • 排名:第9394名
    • 原创:72篇
    • 转载:0篇
    • 译文:0篇
    • 评论:112条
    最新评论