• Telephony状态维护—ServiceStateTracker


    一 ServiceStateTracker

      作为Phone重要的Tracker:CallTracker,DataConnectionTracker,ServiceStateTracker

    ServiceStateTracker:处理和维护手机各种状态

                       小区位置CellLocation,网络状态ServiceState,信号强度SignalStrength,

                       业务限制状态RestrictedState,用户识别卡信息IccRecords……

    看一下ServiceStateTracker类结构图:

                

    对于CDMA和GSM两种网络通信技术,存在着一些差异,下面看看CDMAServiceStateTracker工作流程。

             CDMAServiceStateTracker是一个Handler,用来处理很多Message,从其处理的Message上就可以了解CDMAServiceStateTracker流程和作用。

    二 CDMAServiceStateTracker构造

    1 CDMAServiceStateTracker构造

    public CdmaServiceStateTracker(CDMAPhone phone) {
            //相关对象初始化
            this.phone = phone;
            ss = new ServiceState();
            newSS = new ServiceState();
            cellLoc = new CdmaCellLocation();
            mSignalStrength = new SignalStrength();
            
            //CDMA Subscription Source 管理 机卡分离 Or 机卡一体
            mCdmaSSM = CdmaSubscriptionSourceManager.getInstance(phone.getContext(), cm, this,
                    EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null);
    
            //向RIL注册相关的事件
            //注册Radio 状态变化监听事件
            cm.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
    //语音业务状态变化 cm.registerForVoiceNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED_CDMA, null);
    //时间更新 cm.setOnNITZTime(this, EVENT_NITZ_TIME, null);
    //信号强度更新 cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
    //漫游列表相关 cm.registerForCdmaPrlChanged(this, EVENT_CDMA_PRL_VERSION_CHANGED, null);
    //OTA相关 cm.registerForCdmaOtaProvision(this,EVENT_OTA_PROVISION_STATUS_CHANGE, null);
    //获取CDMA制式 cm.getCDMASubscription(obtainMessage(EVENT_POLL_STATE_CDMA_SUBSCRIPTION)); // System setting property AIRPLANE_MODE_ON is set in Settings. int airplaneMode = Settings.System.getInt(cr, Settings.System.AIRPLANE_MODE_ON, 0); mDesiredPowerState = ! (airplaneMode > 0); }

    2 事件处理

    RIL接收到此类事件就会notify到注册的Handler中处理;

                       

    public void handleMessage (Message msg) {
            switch (msg.what) {
                    ……
                case EVENT_RUIM_READY:
                    //解析漫游相关的ERI数据
                    phone.prepareEri();
                    break;
                case EVENT_NV_READY:
                    //机卡一体subscription information存储在手机上NV中
                    getSubscriptionInfoAndStartPollingThreads();
                    break;
                case EVENT_RADIO_STATE_CHANGED:
                    //Radio打开状态 获取信号强度
                    if(cm.getRadioState() == RadioState.RADIO_ON) {
                        handleCdmaSubscriptionSource(mCdmaSSM.getCdmaSubscriptionSource());
                        // Signal strength polling stops when radio is off.
                        queueNextSignalStrengthPoll();
                    }
                    //start Radio
                    setPowerStateToDesired();
                    //网络状态变化更新
                    pollState();
                    break;
                case EVENT_NETWORK_STATE_CHANGED_CDMA:
                    //网络状态变化更新
                    pollState();
                    break;
                case EVENT_GET_SIGNAL_STRENGTH:
                    //获取射频信号强度
                    onSignalStrengthResult(ar, phone, false);
                    queueNextSignalStrengthPoll();
                    break;
                case EVENT_POLL_SIGNAL_STRENGTH:
                    cm.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
                    break;
    
                case EVENT_NITZ_TIME:
                    //更新时间
                    setTimeFromNITZString(nitzString, nitzReceiveTime);
                    break;
                case EVENT_SIGNAL_STRENGTH_UPDATE:
                    //更新信号强度
                    onSignalStrengthResult(ar, phone, false);
                    break;
                case EVENT_RUIM_RECORDS_LOADED:
                    //更新手机Spn显示
                    updateSpnDisplay();
                    break;
                ……
            }
        }

     

    3 事件处理流程

                       开机构造Phone时,创建CdmaServiceStateTracker对象并注册监听事件.

    开机几个事件处理:

              

      rild进程中建立RIL CPP与QCRIL的连接之后,要保证建立Framework层RIL与Native RIL socket连接

    当建立socket连接之后,RIL_CPP会想 RIL_JAVA发送RIL_UNSOL_RIL_CONNECTED消息,告诉RIL_JAVA已经建立连接;

      否则RIL_JAVA不断尝试建立连接,RIL_CPP会继续监听连接.

    根据这个序列图过程:

      1)  RIL_CPP向RIL_JAVA发送建立连接消息RIL_UNSOL_RIL_CONNECTED

      2) RIL_JAVA收到建立连接的RIL_UNSOL_RIL_CONNECTED后,向RILD发送RIL_REQUEST_RADIO_POWER消息,将RADIO置为 OFF状态

      3)  MODEM发送RADIO状态改变的事件,RIL_JAVA收到后,切换状态并通知RADIO状态变化

      4)  CdmaServiceStateTracker接收到EVENT_RADIO_STATE_CHANGED通知,会启动RADIO设置为On状态

      5)  RIL_JAVA会向RILD发送RIL_REQUEST_RADIO_POWER消息,去启动RADIO

      6)  RADIO状态变化,发送EVENT_RADIO_STATE_CHANGED通知,CdmaServiceStateTracker更新状态,获取信号强度……

     

    4  状态设置

             在代码里看到状态的变化处理都是在pollState中处理的

      case EVENT_RADIO_STATE_CHANGED:
                setPowerStateToDesired();
                pollState();
                break;
       case EVENT_NETWORK_STATE_CHANGED_CDMA:
                pollState();
                break;

    最终状态的都是通过调用函数pollStateDone完成:

      protected void pollStateDone() {
                //维护两个ServiceState状态,判断状态的变化状况
            if (DBG) log("pollStateDone: oldSS=[" + ss + "] newSS=[" + newSS + "]");
            
               //移动网络状况
            boolean hasRegistered =
                ss.getState() != ServiceState.STATE_IN_SERVICE
                && newSS.getState() == ServiceState.STATE_IN_SERVICE;
    
            boolean hasDeregistered =
                ss.getState() == ServiceState.STATE_IN_SERVICE
                && newSS.getState() != ServiceState.STATE_IN_SERVICE;
            
               //数据网络状况
            boolean hasCdmaDataConnectionAttached =
                mDataConnectionState != ServiceState.STATE_IN_SERVICE
                && mNewDataConnectionState == ServiceState.STATE_IN_SERVICE;
            boolean hasCdmaDataConnectionDetached =
                mDataConnectionState == ServiceState.STATE_IN_SERVICE
                && mNewDataConnectionState != ServiceState.STATE_IN_SERVICE;
            
               //各种数据连接状态变化判断
            boolean hasCdmaDataConnectionChanged =
                           mDataConnectionState != mNewDataConnectionState;
    
            boolean hasRadioTechnologyChanged = mRilRadioTechnology != mNewRilRadioTechnology;
    
            boolean hasChanged = !newSS.equals(ss);
    
            boolean hasRoamingOn = !ss.getRoaming() && newSS.getRoaming();
    
            boolean hasRoamingOff = ss.getRoaming() && !newSS.getRoaming();
    
            boolean hasLocationChanged = !newCellLoc.equals(cellLoc);
    
            
                //更新状态
            ServiceState tss;
            tss = ss;
            ss = newSS;
            newSS = tss;
            // clean slate for next time
            newSS.setStateOutOfService();
    
            CdmaCellLocation tcl = cellLoc;
            cellLoc = newCellLoc;
            newCellLoc = tcl;
    
            mDataConnectionState = mNewDataConnectionState;
            mRilRadioTechnology = mNewRilRadioTechnology;
            // this new state has been applied - forget it until we get a new new state
            mNewRilRadioTechnology = 0;
            newSS.setStateOutOfService(); // clean slate for next time
            
            
                //网络注册状态通知
            if (hasRegistered) {
                mNetworkAttachedRegistrants.notifyRegistrants();
            }
    
            //数据连接通知
            if (hasCdmaDataConnectionAttached) {
                mAttachedRegistrants.notifyRegistrants();
            }
                //数据断开通知
            if (hasCdmaDataConnectionDetached) {
                mDetachedRegistrants.notifyRegistrants();
            }
    
                //开启漫游通知
            if (hasRoamingOn) {
                mRoamingOnRegistrants.notifyRegistrants();
            }
            
                ……
        }
  • 相关阅读:
    Prim算法的3个版本
    [转]"undefined reference to" 问题解决方法
    C/C++ 读写 Excel
    Poj 3468
    关于PS中矩形工具的学习
    PS初学习
    java第二天学习。
    Java学习第一天
    二叉树的线索化
    struct files_struct
  • 原文地址:https://www.cnblogs.com/bastard/p/3031964.html
Copyright © 2020-2023  润新知