**1、WifiWatchdogStateMachine介绍**
WifiWatchdogStateMachine用于监控无线网络的信号质量,它在WifiService的checkAndStartWifi函数中被创建,其创建函数是makeWifiWatchdogStateMachine,代码如下所示:
**WifiWatchdogStateMachine.java::makeWifiWatchdogStateMachine**
~~~
public static WifiWatchdogStateMachine makeWifiWatchdogStateMachine(Context context) {
ContentResolver contentResolver = context.getContentResolver();
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(
Context.CONNECTIVITY_SERVICE);
//判断手机是否只支持Wifi。很显然,对于大部分手机来说,sWifiOnly为false
sWifiOnly = (cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) == false);
//WIFI_WATCHDOG_ON功能默认是打开的
putSettingsGlobalBoolean(contentResolver, Settings.Global.WIFI_WATCHDOG_ON, true);
//创建一个WifiWatchdogStateMachine对象,它也是一个HSM
WifiWatchdogStateMachine wwsm = new WifiWatchdogStateMachine(context);
wwsm.start();//启动HSM
return wwsm;
}
~~~
先来看WifiWatchdogStateMachine的初始化流程。
**①、WifiWatchdogStateMachine构造函数分析**
**WifiWatchdogStateMachine.java::WifiWatchdogStateMachine**
~~~
private WifiWatchdogStateMachine(Context context) {
super(TAG);
mContext = context; mContentResolver = context.getContentResolver();
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
//mWsmChannel用于和WifiStateMachine交互
mWsmChannel.connectSync(mContext, getHandler(),
mWifiManager.getWifiStateMachineMessenger());
//关键函数:setupNetworkReceiver将创建一个广播接收对象,用于接收NETWORK_STATE_CHANGED_ACTION、
// WIFI_STATE_CHANGED_ACTION、RSSI_CHANGED_ACTION、SUPPLICANT_STATE_CHANGED_ACTION等广播
setupNetworkReceiver();
//监控Wifi Watchdog设置的变化情况
registerForSettingsChanges();
registerForWatchdogToggle();
addState(mDefaultState);
......//添加状态,一共有9个状态。如图5-7所示
//Wifi Watchdog默认是开启的,故状态机转入NotConnectedState状态
if (isWatchdogEnabled()) setInitialState(mNotConnectedState);
else setInitialState(mWatchdogDisabledState);
updateSettings();
}
~~~
上面代码中,WifiWatchdogStateMachine的初始状态是NotConnectedState。不过这个状态仅实现了enter函数,而且该函数中仅实现了一句打印输出的代码。所以NotConnectedState是一个象征意义远大于实际作用的类。
图5-7所示为WifiWatchdogStateMachine中的各个状态及层级关系:
:-: ![](http://img.blog.csdn.net/20140309210929406?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvSW5ub3N0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
图5-7 WifiWatchdogStateMachine状态及层级关系
WifiWatchdogStateMachine完全靠广播事件来驱动。相关代码在setupNetworkReceiver函数中。
**WifiWatchdogStateMachine.java::setupNetworkReceiver**
~~~
private void setupNetworkReceiver() {
mBroadcastReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
obtainMessage(EVENT_RSSI_CHANGE,
intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200), 0).sendToTarget();
} else if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) {
sendMessage(EVENT_SUPPLICANT_STATE_CHANGE, intent);
} else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
sendMessage(EVENT_NETWORK_STATE_CHANGE, intent);
} ......
else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION))
sendMessage(EVENT_WIFI_RADIO_STATE_CHANGE,intent.getIntExtra(
WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN));
}
};
mIntentFilter = new IntentFilter();
mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
......//添加感兴趣的广播事件类型
mContext.registerReceiver(mBroadcastReceiver, mIntentFilter);
}
~~~
在前面介绍的WifiService工作流程中,SUPPLICANT_STATE_CHANGED_ACTION和NETWORK_STATE_CHANGED_ACTION广播发送的次数非常频繁。所以,WifiWatchdogStateMachine也不会太清闲。
下面,我们直接从WifiStateMachine在VerifyingLinkState的enter函数中发送的NETWORK_STATE_CHANGED_ACTION广播开始分析WifiWatchdogStateMachine的处理流程。
**②、EVENT_NETWORK_STATE_CHANGE处理流程分析**
该消息被NotConnectedState的父状态WatchdogEnabledState处理,相关代码如下所示:
**WifiWatchdogStateMachine.java::WatchdogEnabledState:processMessage**
~~~
public boolean processMessage(Message msg) {
Intent intent;
switch (msg.what) {
......
case EVENT_NETWORK_STATE_CHANGE:
intent = (Intent) msg.obj;
NetworkInfo networkInfo = (NetworkInfo) intent.getParcelableExtra(
WifiManager.EXTRA_NETWORK_INFO);
mWifiInfo = (WifiInfo) intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO);
//更新bssid信息
updateCurrentBssid(mWifiInfo != null ? mWifiInfo.getBSSID() : null);
switch (networkInfo.getDetailedState()) {
case VERIFYING_POOR_LINK://WifiStateMachine在VerifyingLinkState中设置的状态
mLinkProperties = (LinkProperties) intent.getParcelableExtra(
WifiManager.EXTRA_LINK_PROPERTIES);
//mPoorNetworkDetectionEnabled用于判断是否需要监控AP的信号质量
if (mPoorNetworkDetectionEnabled) {
if (mWifiInfo == null || mCurrentBssid == null) {
//下面这个函数将通过mWsmChannel向WifiStateMachine发送
//GOOD_LINK_DETECTED消息
sendLinkStatusNotification(true);
}
else transitionTo(mVerifyingLinkState);//进入VerifyingLinkState
} else sendLinkStatusNotification(true);
break;
case CONNECTED://WifiStateMachine在ConnectedState中设置的状态,请读者自行分析
//OnlineWatchState的处理流程
transitionTo(mOnlineWatchState);
}
.......
}
return HANDLED;
}
~~~
如果WifiWatchdogStateMachine开启了无线网络信号质量监控的话,它将转入VerifyingLinkState,其enter函数如下所示:
**WifiWatchdogStateMachine.java::VerifyingLinkState:enter**
~~~
public void enter() {
mSampleCount = 0;
mCurrentBssid.newLinkDetected();
//向自己发送CMD_RSSI_FETCH消息
sendMessage(obtainMessage(CMD_RSSI_FETCH, ++mRssiFetchToken, 0));
}
~~~
来看CMD_RSSI_FETCH消息的处理。
**③、CMD_RSSI_FETCH处理流程分析**
**WifiWatchdogStateMachine.java::VerifyingLinkState:processMessage**
~~~
public boolean processMessage(Message msg) {
switch (msg.what) {
......
case CMD_RSSI_FETCH:
if (msg.arg1 == mRssiFetchToken) {
/*
向WifiStateMachine发送RSSI_PKTCNT_FETCH消息,WifiStateMachine的处理过程
就是调用WifiNative的signalPoll和pktcntPoll以获取RSSI、LinkSpeed、发送
Packet的总个数、发送失败的Packet总个数。注意,4.2中的WPAS才支持pktcntPoll。
WifiStateMachine处理完RSSI_PKTCNT_FETCH后将回复RSSI_PKTCNT_FETCH_SUCCEEDED
消息给WifiWatchdogStateMachine
*/
mWsmChannel.sendMessage(WifiManager.RSSI_PKTCNT_FETCH);
//LINK_SAMPLING_INTERVAL_MS值为1000ms
sendMessageDelayed(obtainMessage(CMD_RSSI_FETCH, ++mRssiFetchToken, 0),
LINK_SAMPLING_INTERVAL_MS);
}
break;
case WifiManager.RSSI_PKTCNT_FETCH_SUCCEEDED:
//WifiStateMachine回复的消息中携带一个RssiPacketCountInfo对象
RssiPacketCountInfo info = (RssiPacketCountInfo) msg.obj;
int rssi = info.rssi;
/*
WifiWatchdog用了一个名为指数加权移动平均算法(Volume-weighted Exponential
Moving Average)的方法来辨别网络信号质量的好坏。本书不拟对它进行讨论,感兴趣的读者不妨
自行研究
*/
long time = mCurrentBssid.mBssidAvoidTimeMax - SystemClock.elapsedRealtime();
//假设网络质量很好,则调用sendLinkStateNotification以发送GOOD_LINK_DETECT消息给
//WifiStateMachine
if (time <= 0) sendLinkStatusNotification(true);
else {
//此时的rssi好于某个阈值。mGoodLinkTargetRssi由算法计算得来
if (rssi >= mCurrentBssid.mGoodLinkTargetRssi) {
//当采样次数大于一定值时,才认为网络状态变好。mGoodLinkTargetCount也是通过
//相关方法计算得来
if (++mSampleCount >= mCurrentBssid.mGoodLinkTargetCount) {
mCurrentBssid.mBssidAvoidTimeMax = 0;
sendLinkStatusNotification(true);
}
} else mSampleCount = 0;
}
break;
......
}
return HANDLED;
}
~~~
当WifiWatchdogStateMachine检测到Pool link时,它将发送POOL_LINK_DETECT消息给WifiStateMachine去处理。相关流程请感兴趣的读者自行研究。
WifiWatchdogStateMachine是一个比较有趣的模块。其目的很简单,就是监测无线网络的信号质量,然后做相应动作。另外,WifiWatchdogStateMachine还使用了一些比较高级的算法来判断网络信号质量的好坏,感兴趣的读者不妨进行一番深入研究。
- 前言
- 第1章 准备工作
- 1.1 Android系统架构
- 1.2 工具使用
- 1.2.1 Source Insight的使用
- 1.2.2 Eclipse的使用
- 1.2.3 BusyBox的使用
- 1.3 本书资源下载说明
- 第2章 深入理解Netd
- 2.1 概述
- 2.2 Netd工作流程
- 2.2.1 main函数分析
- 2.2.2 NetlinkManager分析
- 2.2.3 CommandListener分析
- 2.2.4 DnsProxyListener分析
- 2.2.5 MDnsSdListener分析
- 2.3 CommandListener中的命令
- 2.3.1 iptables、tc和ip命令
- 2.3.2 CommandListener构造函数和测试工具ndc
- 2.3.3 InterfaceCmd命令
- 2.3.4 IpFwd和FirewallCmd命令
- 2.3.5 ListTtysCmd和PppdCmd命令
- 2.3.6 BandwidthControlCmd和IdletimerControlCmd命令
- 2.3.7 NatCmd命令
- 2.3.8 TetherCmd和SoftapCmd命令
- 2.3.9 ResolverCmd命令
- 2.4 NetworkManagementService介绍
- 2.4.1 create函数详解
- 2.4.2 systemReady函数详解
- 2.5 本章总结和参考资料说明
- 2.5.1 本章总结
- 2.5.2 参考资料说明
- 第3章 Wi-Fi基础知识
- 3.1 概述
- 3.2 无线电频谱和802.11协议的发展历程
- 3.2.1 无线电频谱知识
- 3.2.2 IEEE 802.11发展历程
- 3.3 802.11无线网络技术
- 3.3.1 OSI基本参考模型及相关基本概念
- 3.3.2 802.11知识点导读
- 3.3.3 802.11组件
- 3.3.4 802.11 Service介绍
- 3.3.5 802.11 MAC服务和帧
- 3.3.6 802.11 MAC管理实体
- 3.3.7 无线网络安全技术知识点
- 3.4 Linux Wi-Fi编程API介绍
- 3.4.1 Linux Wireless Extensions介绍
- 3.4.2 nl80211介绍
- 3.5 本章总结和参考资料说明
- 3.5.1 本章总结
- 3.5.2 参考资料说明
- 第4章 深入理解wpa_supplicant
- 4.1 概述
- 4.2 初识wpa_supplicant
- 4.2.1 wpa_supplicant架构
- 4.2.2 wpa_supplicant编译配置
- 4.2.3 wpa_supplicant命令和控制API
- 4.2.4 git的使用
- 4.3 wpa_supplicant初始化流程
- 4.3.1 main函数分析
- 4.3.2 wpa_supplicant_init函数分析
- 4.3.3 wpa_supplicant_add_iface函数分析
- 4.3.4 wpa_supplicant_init_iface函数分析
- 4.4 EAP和EAPOL模块
- 4.4.1 EAP模块分析
- 4.4.2 EAPOL模块分析
- 4.5 wpa_supplicant连接无线网络分析
- 4.5.1 ADD_NETWORK命令处理
- 4.5.2 SET_NETWORK命令处理
- 4.5.3 ENABLE_NETWORK命令处理
- 4.6 本章总结和参考资料说明
- 4.6.1 本章总结
- 4.6.2 参考资料说明
- 第5章 深入理解WifiService
- 5.1 概述
- 5.2 WifiService的创建及初始化
- 5.2.1 HSM和AsyncChannel介绍
- 5.2.2 WifiService构造函数分析
- 5.2.3 WifiStateMachine介绍
- 5.3 加入无线网络分析
- 5.3.1 Settings操作Wi-Fi分析
- 5.3.2 WifiService操作Wi-Fi分析
- 5.4 WifiWatchdogStateMachine介绍
- 5.5 Captive Portal Check介绍
- 5.6 本章总结和参考资料说明
- 5.6.1 本章总结
- 5.6.2 参考资料说明
- 第6章 深入理解Wi-Fi Simple Configuration
- 6.1 概述
- 6.2 WSC基础知识
- 6.2.1 WSC应用场景
- 6.2.2 WSC核心组件及接口
- 6.3 Registration Protocol详解
- 6.3.1 WSC IE和Attribute介绍
- 6.3.2 802.11管理帧WSC IE设置
- 6.3.3 EAP-WSC介绍
- 6.4 WSC代码分析
- 6.4.1 Settings中的WSC处理
- 6.4.2 WifiStateMachine的处理
- 6.4.3 wpa_supplicant中的WSC处理
- 6.4.4 EAP-WSC处理流程分析
- 6.5 本章总结和参考资料说明
- 6.5.1 本章总结
- 6.5.2 参考资料说明
- 第7章 深入理解Wi-Fi P2P
- 7.1 概述
- 7.2 P2P基础知识
- 7.2.1 P2P架构
- 7.2.2 P2P Discovery技术
- 7.2.3 P2P工作流程
- 7.3 WifiP2pSettings和WifiP2pService介绍
- 7.3.1 WifiP2pSettings工作流程
- 7.3.2 WifiP2pService工作流程
- 7.4 wpa_supplicant中的P2P
- 7.4.1 P2P模块初始化
- 7.4.2 P2P Device Discovery流程分析
- 7.4.3 Provision Discovery流程分析
- 7.4.4 GO Negotiation流程分析
- 7.5 本章总结和参考资料说明
- 7.5.1 本章总结
- 7.5.2 参考资料说明
- 第8章 深入理解NFC
- 8.1 概述
- 8.2 NFC基础知识
- 8.2.1 NFC概述
- 8.2.2 NFC R/W运行模式
- 8.2.3 NFC P2P运行模式
- 8.2.4 NFC CE运行模式
- 8.2.5 NCI原理
- 8.2.6 NFC相关规范
- 8.3 Android中的NFC
- 8.3.1 NFC应用示例
- 8.3.2 NFC系统模块
- 8.4 NFC HAL层讨论
- 8.5 本章总结和参考资料说明
- 8.5.1 本章总结
- 8.5.2 参考资料说明
- 第9章 深入理解GPS
- 9.1 概述
- 9.2 GPS基础知识
- 9.2.1 卫星导航基本原理
- 9.2.2 GPS系统组成及原理
- 9.2.3 OMA-SUPL协议
- 9.3 Android中的位置管理
- 9.3.1 LocationManager架构
- 9.3.2 LocationManager应用示例
- 9.3.3 LocationManager系统模块
- 9.4 本章总结和参考资料说明
- 9.4.1 本章总结
- 9.4.2 参考资料说明
- 附录