一.啓動wifi服務
1.在 SystemServer 啓動的時候,會生成一個 ConnectivityService 的實例
路徑爲:/frameworks/base/services/java/com/android/server/SystemServer.java
try {
Slog.i(TAG, "Connectivity Service");
connectivity = ConnectivityService.getInstance(context);
ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Connectivity Service", e);
}
2.ConnectivityService 類中private ConnectivityService(Context context) 構造函數創建
WifiService和WifiStateTracker對象
/frameworks/base/services/java/com/android/server/ConnectivityService.java
for (int netType : mPriorityList) {
switch (mNetAttributes[netType].mRadio) {
case ConnectivityManager.TYPE_WIFI:
if (DBG) Slog.v(TAG, "Starting Wifi Service.");
WifiStateTracker wst = new WifiStateTracker(context, mHandler);
WifiService wifiService = new WifiService(context, wst);
ServiceManager.addService(Context.WIFI_SERVICE, wifiService);
wifiService.startWifi();
mNetTrackers[ConnectivityManager.TYPE_WIFI] = wst;
wst.startMonitoring();
break;
}
}
3.創建WifiStateTracker和WifiService對象用來啓動wifi管理服務WifiStateTracker 會創建
WifiMonitor 用來接收來自底層的事件,WifiService 和 WifiMonitor 是整個模塊的核心。
4.WifiService 負責啓動關閉 wpa_supplicant、啓動關閉 WifiMonitor 監視線程和把命令下發
給 wpa_supplicant
5. WifiMonitor
開始運行線程,會請求連接wpa_supplicant,通過調用WifiStateTracker函數connectToSupplicant然後通過wifi.c的wifi_connect_to_supplicant,接着向wpa_ctrl的wpa_ctrl_open。然後通過CreateFile函數向wpa_supplicant讀取數據。連接成功後會發送EVENT_SUPPLICANT_CONNECTION消息啓動獲取DHCP地址線程阻塞調用(當連接上AP的時候,該線程會被執行起來獲取IP地址),並記錄自己的MAC地址(因爲MAC地址不會改變
所以請求一次即可) 接着開啓一個死循環處理wpa_supplicant發送的事件。
當用戶點擊Wi-Fi按鈕 的時候WifiEnabler中的onPreferenceChange函數會被調用,再由該函數調用WifiManager的setWifiEnabled函數,它先引用AIDL經由IWifiManager通過Binder機制調用WifiService的setWifiEnabled設置Wifi開啓狀態。同時WifiService會發送MESSAGE_ENABLE_WIFI消息,由WifiService的
setWifiEnabledBlocking函數響應該消息,負責Wifi可用的需要工作。首先他會加載驅動
loadDriver(),然後開啓wpa_supplicant( 配 置 文 件 硬 編 碼 爲
"/data/misc/wifi/wpa_supplicant.conf") 再註冊廣播消息,而後通過 WifiStateTracker 來啓動 WifiMonitor 中的監視線程。以上工作使能成功後,會調用setWifiEnabledState最後廣播WIFI_STATE_CHANGED_ACTION 這個Intent,至此Wifi能動開啓。
接下來是掃描AP。
WifiSettings和WifiEnabler 創 建 的 時 候 就 會 向 Android 注 冊 接 收
WIFI_STATE_CHANGED_ACTION,因此他們都會收到WIFI_STATE_CHANGED_ACTION 這個Intent,WifiEnabler負責使得圖標加亮,WifiSettings負責使得開啓掃描AP。經由
WifiService 的 startScan,再通過JNI由android_net_wifi_scanCommand函數向wpa_supplicant發送掃描命令.當wpa_supplicant 處理完 SCAN 命令後,它會向控制通道發送事件通知掃描完成,從而wifi_wait_for_event 函數會接收到該事件,由此 WifiMonitor 中的 MonitorThread 會被執行來處理接掃描結果事件。此線程通過WifiStateTracker 廣播SCAN_RESULTS_AVAILABLE_ACTION這個Intent。而WifiSettings註冊了接收此Intent,最終由其相應函數updateAccessPoints將AP列表,以GUI的形式列出來。