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();
}
……
}