zoukankan      html  css  js  c++  java
  • 开关VoLTE流程分析(二)

    AT指令,暂未发现发送AT请求的frameworks接口,通过打印信息总结AT指令:

    AT+EIMSVOICE: Enable/Disable IMS Voice Capability
    +EIMSVOICE=<config>
    <config>: integer 
    0 disable IMS Voice capability
    1 enable IMS Voice capability
    note:This command should set from AP side while boot-up;
    At runtime, AP side could set the command anytime, and IMS module will apply the setting for next round of IMS registration;


    而后有如下打印信息,发送RIL_REQUEST_SET_IMS_ENABLE请求:

    此发送接口在ImsService.java 类中的onRequestImsSwitch():

            public void onRequestImsSwitch(int simIdx, boolean isImsOn) {
    
                int phoneId = getMainCapabilityPhoneId();
    
                if (DBG) {
                    Rlog.d(LOG_TAG,"onRequestImsSwitch simIdx=" + simIdx +
                            " isImsOn=" + isImsOn + " mainCapability id=" + phoneId);
                }
    
                if (mActivePhoneId != phoneId) {
                    mActivePhoneId = phoneId;
                }
    
                if (isImsOn) {
                    if (mImsState != PhoneConstants.IMS_STATE_ENABLE) { //如果是关闭状态
                        mImsRILAdapter.turnOnIms(mHandler.obtainMessage(EVENT_SET_IMS_ENABLED_DONE));
                        mImsState = PhoneConstants.IMS_STATE_ENABLING;
                    } else {
                        Rlog.d(LOG_TAG, "Ims already enable and ignore to send AT command.");
                    }
             }

    ImsRILAdapter类封装消息请求,通过send()发送RIL接收端;

    ImsIntentReceiver广播接收器,根据log打印信息:

    在PhoneBase类中定义了mImsIntentReceiver广播接收器:

        private BroadcastReceiver mImsIntentReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                Rlog.d(LOG_TAG, "mImsIntentReceiver: action " + intent.getAction());
                if (intent.hasExtra(ImsManager.EXTRA_PHONE_ID)) {
                    int extraPhoneId = intent.getIntExtra(ImsManager.EXTRA_PHONE_ID,
                            SubscriptionManager.INVALID_PHONE_INDEX);
                    Rlog.d(LOG_TAG, "mImsIntentReceiver: extraPhoneId = " + extraPhoneId);
                    if (extraPhoneId == SubscriptionManager.INVALID_PHONE_INDEX ||
                            extraPhoneId != getPhoneId()) {
                        return;
                    }
                }
                
                synchronized (PhoneProxy.lockForRadioTechnologyChange) {
                    //接收广播ACTION_IMS_SERVICE_UP
                    if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_UP)) {
                        ......
                        mImsServiceReady = true;
                        updateImsPhone();
                        ImsManager.updateImsServiceConfig(mContext, mPhoneId, false);
                    //接收广播ACTION_IMS_SERVICE_DOWN
                    } else if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_DOWN)) {
                        mImsServiceReady = false;
                        updateImsPhone();
                    }
                }
            }
        };

    updateImsPhone()方法如下:

        protected void updateImsPhone() {
            Rlog.d(LOG_TAG, "updateImsPhone"
                    + " mImsServiceReady=" + mImsServiceReady);
    
            if (mImsServiceReady && (mImsPhone == null)) {
                         //创建mImsPhone notifyDataRegStateRilRadioTechnologyChanged
                mImsPhone = PhoneFactory.makeImsPhone(mNotifier, this); 
                CallManager.getInstance().registerPhone(mImsPhone); //CallManager里添加Phone对象
                mImsPhone.registerForSilentRedial(
                        this, EVENT_INITIATE_SILENT_REDIAL, null); //注册消息,该消息的处理由该类处理
            } else if (!mImsServiceReady && (mImsPhone != null)) {
                CallManager.getInstance().unregisterPhone(mImsPhone);
                mImsPhone.unregisterForSilentRedial(this);
    
                mImsPhone.dispose();
                // Potential GC issue if someone keeps a reference to ImsPhone.
                // However: this change will make sure that such a reference does
                // not access functions through NULL pointer.
                //mImsPhone.removeReferences();
                mImsPhone = null;
            }
    
    EVENT_INITIATE_SILENT_REDIAL 消息的处理:
                case EVENT_INITIATE_SILENT_REDIAL:
                    Rlog.d(LOG_TAG, "Event EVENT_INITIATE_SILENT_REDIAL Received");
                    ar = (AsyncResult) msg.obj;
                    if ((ar.exception == null) && (ar.result != null)) {
                        String dialString = (String) ar.result;
                        if (TextUtils.isEmpty(dialString)) return;
                        try {
                            dialInternal(dialString, null, VideoProfile.STATE_AUDIO_ONLY, null);
                        } catch (CallStateException e) {
                            Rlog.e(LOG_TAG, "silent redial failed: " + e);
                        }
                    }
                    break;

    ServiceState服务状态,有如下打印信息:

    vendor/mediatek/proprietary/frameworks/opt/tedongle/src/java/android/tedongle/ServiceState.java

        private void setNullState(int state) {
            if (DBG) Rlog.d(LOG_TAG, "[ServiceState] setNullState=" + state);
            mVoiceRegState = state;
            mDataRegState = state;
            mVoiceRoamingType = ROAMING_TYPE_NOT_ROAMING;
            mDataRoamingType = ROAMING_TYPE_NOT_ROAMING;
            .......
        }

    setNullState()该方法传入的参数是3,可判定被该方法调用:

        public void setStateOff() {
            setNullState(STATE_POWER_OFF);
        }

    ServiceState 的定义:

    /**
    * Normal operation condition, the phone is registered
    * with an operator either in home network or in roaming.
    */
    public static final int STATE_IN_SERVICE = 0;

    /**
    * Phone is not registered with any operator, the phone
    * can be currently searching a new operator to register to, or not
    * searching to registration at all, or registration is denied, or radio
    * signal is not available.
    */
    public static final int STATE_OUT_OF_SERVICE = 1;

    /**
    * The phone is registered and locked. Only emergency numbers are allowed. {@more}
    */
    public static final int STATE_EMERGENCY_ONLY = 2;

    /**
    * Radio of telephony is explicitly powered off.
    */
    public static final int STATE_POWER_OFF = 3;

    注册消息:

        private void registerIndicationReceiver() {
            if (DBG) log("registerIndicationReceiver");
            IntentFilter intentfilter = new IntentFilter();
            intentfilter.addAction(ImsManager.ACTION_IMS_INCOMING_CALL_INDICATION);//注册来电通知
            mPhone.getContext().registerReceiver(mIndicationReceiver, intentfilter);
    
        }

    notifyDataRegStateRilRadioTechnologyChanged:

    在GsmServiceStateTracker类的pollStateDone()方法中,调用notifyDataRegStateRilRadioTechnologyChanged():

            if (hasDataRegStateChanged || hasRilDataRadioTechnologyChanged) {
                notifyDataRegStateRilRadioTechnologyChanged();
                          //WLAN 判断
                if (ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN 
                            == mSS.getRilDataRadioTechnology()) {
                    mPhone.notifyDataConnection(Phone.REASON_IWLAN_AVAILABLE);
                } else {
                    mPhone.notifyDataConnection(null);
                }
            }
    
    
        protected void notifyDataRegStateRilRadioTechnologyChanged() {
            int rat = mSS.getRilDataRadioTechnology();
            int drs = mSS.getDataRegState();
            if (DBG) log("notifyDataRegStateRilRadioTechnologyChanged: drs=" + drs + " rat=" + rat);
             //设置TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE属性
            mPhoneBase.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
                    ServiceState.rilRadioTechnologyToString(rat));
            mDataRegStateOrRatChangedRegistrants.notifyResult(new Pair<Integer, Integer>(drs, rat));
        }

    mDataRegStateOrRatChangedRegistrants通知者注册函数:

        public void registerForDataRegStateOrRatChanged(Handler h, int what, Object obj) {
            Registrant r = new Registrant(h, what, obj);
            mDataRegStateOrRatChangedRegistrants.add(r); //添加监听者
            notifyDataRegStateRilRadioTechnologyChanged();
        }

    该注册函数在ImsPhone的构造函数中被调用:

        ImsPhone(Context context, PhoneNotifier notifier, Phone defaultPhone) {
    
            mDefaultPhone = (PhoneBase) defaultPhone;
            /// M: ALPS02759855. ImsPhoneCallTracker may change service state earlier. @{
            // mCT = new ImsPhoneCallTracker(this);
            // mSS.setStateOff();
            mSS.setStateOff();   //此处即在"ServiceState服务状态"中提到的
            mCT = new ImsPhoneCallTracker(this);
            /// @}
    
            mPhoneId = mDefaultPhone.getPhoneId();
    
            // This is needed to handle phone process crashes
            // Same property is used for both CDMA & IMS phone.
            mIsPhoneInEcmState = SystemProperties.getBoolean(
                    TelephonyProperties.PROPERTY_INECM_MODE, false);
    
            PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
            mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);
            mWakeLock.setReferenceCounted(false);
    
            if (mDefaultPhone.getServiceStateTracker() != null) {
                mDefaultPhone.getServiceStateTracker()
                        .registerForDataRegStateOrRatChanged(this,
                        EVENT_DEFAULT_PHONE_DATA_STATE_CHANGED, null); //注册数据状态变化通知消息
            }
            updateDataServiceState();
        }

    EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED消息的处理

    在DataConnection.java中处理:

                    case EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED:
                        ar = (AsyncResult) msg.obj;
                        Pair<Integer, Integer> drsRatPair = (Pair<Integer, Integer>) ar.result;
                        mDataRegState = drsRatPair.first;
                        if (mRilRat != drsRatPair.second) {
                            updateTcpBufferSizes(drsRatPair.second);
                        }
                        mRilRat = drsRatPair.second;
                        if (DBG) {
                            log("DcDefaultState: EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED"
                                    + " drs=" + mDataRegState
                                    + " mRilRat=" + mRilRat);
                        }
    
                        ServiceState ss = mPhone.getServiceState(); //实例化ServiceState
                        // M: [C2K][IRAT] Get network type from IRAT controller
                        // TODO: check if the message is handled before
                        // IratController update its current RAT.
                        if (CdmaFeatureOptionUtils.isCdmaLteDcSupport()) {
                          //can get networkType from svltePhoneProxy to get right network type
                            ServiceState svlteSs = SvlteUtils.getSvltePhoneProxy(mPhone.getPhoneId())
                                    .getSvlteServiceState();
                            if (svlteSs != null) {
                                ss = svlteSs;
                            }
                        }
                        int networkType = ss.getDataNetworkType();
    
                        mNetworkInfo.setSubtype(networkType,
                                TelephonyManager.getNetworkTypeName(networkType));
                        if (mNetworkAgent != null) {
                            updateNetworkInfoSuspendState();
                            mNetworkAgent.sendNetworkCapabilities(makeNetworkCapabilities());
                            mNetworkAgent.sendNetworkInfo(mNetworkInfo);
                            mNetworkAgent.sendLinkProperties(mLinkProperties);
                        }
                        break;

    设置网络参数

        public void setDataRegState(int state) {
            mDataRegState = state;
            if (DBG) Rlog.d(LOG_TAG, "[ServiceState] setDataRegState=" + mDataRegState);
        }
    
        public void setRilDataRadioTechnology(int rt) {
            this.mRilDataRadioTechnology = rt;
            if (DBG) Rlog.d(LOG_TAG, "[ServiceState] setDataRadioTechnology=" + mRilDataRadioTechnology);
        }
  • 相关阅读:
    分布式存储
    存储知识学习
    洛谷 P1003 铺地毯 (C/C++, JAVA)
    多线程面试题系列3_生产者消费者模式的两种实现方法
    多线程面试题系列2_监视线程的简单实现
    多线程面试题系列1_数组多线程分解
    《深度学习》阅读笔记1
    素数在两种常见情况下的标准最优算法
    dfs与dp算法之关系与经典入门例题
    百度之星资格赛2018B题-子串查询
  • 原文地址:https://www.cnblogs.com/kaifyou/p/6283088.html
Copyright © 2011-2022 走看看