开关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);
    }
原文地址:https://www.cnblogs.com/kaifyou/p/6283088.html