【google M】android 网络服务状态运行机制(语音、数据注册状态;运营商信息PLMN,SPN;radio技术;信号强度)

涉及的framework telephony类有:

frameworks/base/telephony/.../ServiceState.java
frameworks/opt/telephony/.../ServiceStateTracker.java
frameworks/opt/telephony/.../gsm/GsmServiceStateTracker.java
frameworks/opt/telephony/.../gsm/GSMPhone.java

frameworks/opt/telephony/.../RIL.java

一. ServiceState

在Telephony Framework层中,使用ServiceState实体类来保存SIM卡注册成功后电信运营商网络的一些基本服务信息,其中的关键信息包括:

1.  mVoiceRegState   // 语音通话服务的注册状态,可能的状态包括,STATE_IN_SERVICE, STATE_OUT_OF_SERVICE,                     STATE_EMERGENCY_ONLY, STATE_POWER_OFF

2. mDataRegState   // 数据服务的注册状态,可能的状态同上

3. mVoiceOperatorAlphaLong, mVoiceOperatorAlphaShort, mVoiceOperatorNumeric,mDataOperatorAlphaLong, mDataOperatorAlphaShort, mDataOperatorNumeric   // 电信运营商的名字(完整),电信运营商的名字(简写),电信运营商编号

4. mRilVoiceRadioTechnology, mRilDataRadioTechnology   // 注册上的radio技术。例如2G, 3G, 4G

二.ServiceStateTracker的运行机制

ServiceStateTracker按字面意思可以理解为网络服务状态管理的跟踪者。Phone对象将网络服务状态交给它来管理和维护,即管理,维护上面讲的ServiceState。

对于GSMPhone来说,使用ServiceStateTracker的子类GsmServiceStateTracker,下面具体讲解GsmServiceStateTracker

GsmServiceStateTracker的关键属性如下:

1. mSS   // 当前ServiceState对象,调用new ServiceState()创建对象,此构造函数为空,所有的ServiceState的关键属性都是通过调用类似mSS.setState()函数设置的。

2. mNewSS   // 最新ServiceState对象,构造方法同上。

3. mSignalStrength   // 手机信号强度

GsmServiceStateTracker的关键方法如下:

1. pollState()   // 连续向RIL对象发起4个查询请求, 分别是getOperator()获取电信运营商信息,getDataRegistrationState()获取数据服务注册状态,getVoiceRegistrationState()获取语音通话服务注册状态,getNetworkSelectionMode()选择接入电信网络的类型。

2. handlePollStateResult()   // 处理RIL返回的查询结果,根据查询结果更新mSS, mNewSS等

3. pollStateDone()   // 根据pollState()查询的结果,完成ServiceState对象mSS的更新以及发出服务信息变化对应的通知。

4. updateSpnDisplay()   // 更新PLMN,SPN等运营商信息并发出广播

5. queueNextSignalStrengthPoll() // 定时查询手机信号强度,并发出消息通知

GsmServiceStateTracker   pollState 流程图如下:


需要注意的是,在handlePollStateResult()中,只有4个查询都返回的时候才会去调用pollStateDone()。

下面具体解析一下pollStateDone(),抽取部分代码如下

private void pollStateDone() {
        
        boolean hasChanged = !mNewSS.equals(mSS);

        // swap mSS and mNewSS to put new state in mSS
        ServiceState tss = mSS;
        mSS = mNewSS;
        mNewSS = tss;
        // clean slate for next time
        mNewSS.setStateOutOfService();

        
        // radio technology changed, such as cdmaphone --> gsmphone
        if (hasRilVoiceRadioTechnologyChanged) {
            updatePhoneObject();
        }

        if (hasRilDataRadioTechnologyChanged) {
            tm.setDataNetworkTypeForPhone(mPhone.getPhoneId(), mSS.getRilVoiceRadioTechnology());

            if (ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN
                        == mSS.getRilDataRadioTechnology()) {
                log("pollStateDone: IWLAN enabled");
            }
        }

        

        if (hasChanged) {
            String operatorNumeric;
            // 后面有详细介绍
            updateSpnDisplay();

            tm.setNetworkRoamingForPhone(mPhone.getPhoneId(), mSS.getVoiceRoaming());

            setRoamingType(mSS);
            log("Broadcasting ServiceState : " + mSS);
            // 通知service state发生变化
            mPhone.notifyServiceStateChanged(mSS);
        }
        
    }
下面看一下updateSpnDisplay()的关键代码

@Override
    protected void updateSpnDisplay() {
        // The values of plmn/showPlmn change in different scenarios.
        // 1) No service but emergency call allowed -> expected
        //    to show "Emergency call only"
        //    EXTRA_SHOW_PLMN = true
        //    EXTRA_PLMN = "Emergency call only"

        // 2) No service at all --> expected to show "No service"
        //    EXTRA_SHOW_PLMN = true
        //    EXTRA_PLMN = "No service"

        // 3) Normal operation in either home or roaming service
        //    EXTRA_SHOW_PLMN = depending on IccRecords rule
        //    EXTRA_PLMN = plmn

        // 4) No service due to power off, aka airplane mode
        //    EXTRA_SHOW_PLMN = false
        //    EXTRA_PLMN = null

        
        Intent intent = new Intent(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION);
        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
        intent.putExtra(TelephonyIntents.EXTRA_SHOW_SPN, showSpn);
        intent.putExtra(TelephonyIntents.EXTRA_SPN, spn);
        intent.putExtra(TelephonyIntents.EXTRA_DATA_SPN, dataSpn);
        intent.putExtra(TelephonyIntents.EXTRA_SHOW_PLMN, showPlmn);
        intent.putExtra(TelephonyIntents.EXTRA_PLMN, plmn);
        SubscriptionManager.putPhoneIdAndSubIdExtra(intent, mPhone.getPhoneId());
        mPhone.getContext().sendStickyBroadcastAsUser(intent, UserHandle.ALL);

    }

从上面代码可知,这个函数的主要作用就是把RIL返上来的运营商信息plmn, spn构造广播发出去,

广播类型是SPN_STRINGS_UPDATED_ACTION。锁屏界面会接受这个广播,然后更新锁屏界面的运营商信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值