信号强度上报流程


SignalStrenth的获取可分为2中方式:
1.BP侧上报状态变化,从而触发AP侧查询
2.AP侧主动查询

默认情况下,这两种查询方式都是有效的,但是,一旦modem主动上报信号状态后,就会disable掉AP侧的主动查询。

1.BP侧上报状态变化,从而触发AP侧查询
还是先从初始化流程来分析。
首先来看ServiceStateTracker的构造函数,会注册监听SignalStrengthUpdate的事件。

public ServiceStateTracker(GsmCdmaPhone phone, CommandsInterface ci) {
......
mCi.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
......
}

当RIL收到RIL_UNSOL_SIGNAL_STRENGTH通知后,就会触发ServiceStateTracker的EVENT_SIGNAL_STRENGTH_UPDATE事件。
这里会把mDontPollSignalStrength设为true,即禁止AP主动查询SignalStrenth。
然后就是调用onSignalStrengthResult方法处理收到的信息。
public void handleMessage(Message msg) {
......
case EVENT_SIGNAL_STRENGTH_UPDATE:
......
// The radio is telling us about signal strength changes
// we don't have to ask it
mDontPollSignalStrength = true;

onSignalStrengthResult(ar);
break;
......
}

在queueNextSignalStrengthPoll方法中,如果mDontPollSignalStrength为true,就会停掉AP侧周期性的查询操作。
private void queueNextSignalStrengthPoll() {
if (mDontPollSignalStrength) {
// The radio is telling us about signal strength changes
// we don't have to ask it
return;
}
......
msg.what = EVENT_POLL_SIGNAL_STRENGTH;
......
sendMessageDelayed(msg, POLL_PERIOD_MILLIS);
}

onSignalStrengthResult方法中会对modem上报的内容进行解析并保存,然后再通知其它模块SignalStrength发生改变。

protected boolean onSignalStrengthResult(AsyncResult ar) {
......
if ((ar.exception == null) && (ar.result != null)) {
mSignalStrength = (SignalStrength) ar.result;
mSignalStrength.validateInput(); // 将无效的信号值设置为有效值
mSignalStrength.setGsm(isGsm);
mSignalStrength.setLteRsrpBoost(mSS.getLteEarfcnRsrpBoost());
......
boolean ssChanged = notifySignalStrength();
}

通知信号发生改变。
protected boolean notifySignalStrength() {
boolean notified = false;
if (!mSignalStrength.equals(mLastSignalStrength)) {
try {
mPhone.notifySignalStrength();
notified = true;
......
}

通知流程最终会走到TelephonyRegistry.notifySignalStrengthForPhoneId()方法。
所有通过TelephonyRegistry注册监听了PhoneStateListener.LISTEN_SIGNAL_STRENGTHS事件的对象都会以回调的形式进行通知。
同时还会发送广播TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED进行通知。
public void notifySignalStrengthForPhoneId(int phoneId, int subId,
SignalStrength signalStrength) {
......
if (r.matchPhoneStateListenerEvent(
PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) &&
idMatch(r.subId, subId, phoneId)) {
try {
......
r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength));
......
broadcastSignalStrengthChanged(signalStrength, phoneId, subId);
}

在发送广播前,我们发现SignalStrength还会被传递给BatteryStats用于统计网络信号强度的历史信息。
在这里曾经还遇到一个bug,就是对于双卡手机,当只插入一张卡时,无卡的Phone会周期性的查询信号强度,
然后BatteryStats也会将其记录下来,结果就导致网络的历史记录中出现了很多无服务的状态。
而正常的流程应该是无卡的Phone不会发起周期性的查询信号强度的操作。

private void broadcastSignalStrengthChanged(SignalStrength signalStrength, int phoneId,
int subId) {
......
mBatteryStats.notePhoneSignalStrength(signalStrength);
......
Intent intent = new Intent(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED);
......
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
}


2.AP侧主动查询
在很多种情况下,AP都会发起查询SignalStrength的操作,我们以下面3种事件为例来进行说明:
EVENT_SIM_READY (Only for gsm phone)
EVENT_RADIO_STATE_CHANGED/EVENT_PHONE_TYPE_SWITCHED

先来看看EVENT_SIM_READY事件,这是gsm phone专属的(cdma phone为EVENT_RUIM_READY),
当收到此事件后,首先会调用pollState方法查询网络状态,如运营商名称、voice/data注册状态、选网模式。
然后就是调用queueNextSignalStrengthPoll方法启动查询SignalStrength的任务。

public void handleMessage(Message msg) {
......
// GSM
case EVENT_SIM_READY:
......
pollState();
// Signal strength polling stops when radio is off
queueNextSignalStrengthPoll();
break;

case EVENT_RADIO_STATE_CHANGED:
case EVENT_PHONE_TYPE_SWITCHED:
if(!mPhone.isPhoneTypeGsm() &&
mCi.getRadioState() == CommandsInterface.RadioState.RADIO_ON) {
......
// Signal strength polling stops when radio is off.
queueNextSignalStrengthPoll();
......
}

再来看EVENT_RADIO_STATE_CHANGED/EVENT_PHONE_TYPE_SWITCHED事件,对于cdma phone当Radio_On时也会
调用queueNextSignalStrengthPoll方法启动查询SignalStrength的任务。
queueNextSignalStrengthPoll中并不会立即去查询SignalStrength,而是在20s后触发EVENT_POLL_SIGNAL_STRENGTH事件去执行查询操作。
private void queueNextSignalStrengthPoll() {
......
msg.what = EVENT_POLL_SIGNAL_STRENGTH;
......
sendMessageDelayed(msg, POLL_PERIOD_MILLIS);
}

查询完成后会触发EVENT_GET_SIGNAL_STRENGTH事件。
在这里我们可以看到,如果radio未开启,就不会触发下一次查询操作,而需要等到radio再次开启时才会再去查询;
而如果radio开启的话,就会再次调用queueNextSignalStrengthPoll方法触发20s继续查询,
这样就实现了每隔20s进行一次的循环查询操作。
而处理查询结果的流程跟modem主动上报SignalStrength时相同,都是调用onSignalStrengthResult方法处理。
public void handleMessage(Message msg) {
......
case EVENT_GET_SIGNAL_STRENGTH:
if (!(mCi.getRadioState().isOn())) {
// Polling will continue when radio turns back on
return;
}
ar = (AsyncResult) msg.obj;
onSignalStrengthResult(ar);
queueNextSignalStrengthPoll();

break;
......
case EVENT_POLL_SIGNAL_STRENGTH:
mCi.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
break;
......
}

分析完了SignalStrength的查询流程,接下来我们在来看看它是怎么传给状态栏显示的。
我们前面提到过,所有通过TelephonyRegistry注册监听了PhoneStateListener.LISTEN_SIGNAL_STRENGTHS事件的对象都会以回调的形式进行通知。
而MobileSignalController通过其registerListener方法注册监听了PhoneStateListener.LISTEN_SIGNAL_STRENGTHS事件。

public void registerListener() {
mPhone.listen(mPhoneStateListener,
PhoneStateListener.LISTEN_SERVICE_STATE
| PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
| PhoneStateListener.LISTEN_CALL_STATE
| PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
| PhoneStateListener.LISTEN_DATA_ACTIVITY
| PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE);
......
}

所以,当查询到SignalStrength变化后,就会回调mPhoneStateListener.onSignalStrengthsChanged()方法。

class MobilePhoneStateListener extends PhoneStateListener {
......
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
......
mSignalStrength = signalStrength;
updateTelephony();
}
......
}

在updateTelephony方法中就会去获取信号格数。
在往后就是根据信号格数进行显示了,这里就不再继续分析了。
private final void updateTelephony() {
......
if (!mSignalStrength.isGsm() && mConfig.alwaysShowCdmaRssi) {
mCurrentState.level = mSignalStrength.getCdmaLevel();
} else {
mCurrentState.level = mSignalStrength.getLevel();
if (mConfig.showRsrpSignalLevelforLTE) {
int dataType = mServiceState.getDataNetworkType();
if (dataType == TelephonyManager.NETWORK_TYPE_LTE ||
dataType == TelephonyManager.NETWORK_TYPE_LTE_CA) {
mCurrentState.level = getAlternateLteLevel(mSignalStrength);
}
}
}
......
}





 

转载于:https://my.oschina.net/igiantpanda/blog/2222415

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值