**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中的各個狀態及層級關系:
:-: 
圖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 參考資料說明
- 附錄