开关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); }