Android WifiService的啟動流程分析
阿新 • • 發佈:2019-01-04
轉於: http://blog.csdn.net/lilian0118/article/details/21964423
最近在學習Android WiFi framework的相關知識,這裡總結以下。WiFi framework的內容大致可以分為以下幾個模組:
1. WiFi相關內容
2.WiFi P2P相關內容
3.Hotspot相關內容
4.WiFi Display相關內容
後面就將從這四個方面一一介紹。
WiFi service的啟動流程
Wifiservice的啟動地方在system server中,code路徑在:framwork/base/service/java/com/android/server/SystemServer.java-
try
- Slog.i(TAG,"Wi-Fi P2pService");
- wifiP2p=newWifiP2pService(context);
- ServiceManager.addService(Context.WIFI_P2P_SERVICE, wifiP2p);
- }catch(Throwable e){
- reportWtf("starting Wi-Fi P2pService", e);
- }
-
try
- Slog.i(TAG,"Wi-Fi Service");
- wifi=newWifiService(context);
- ServiceManager.addService(Context.WIFI_SERVICE, wifi);
- }catch(Throwable e){
- reportWtf("starting Wi-Fi Service", e);
- }
- try{
-
Slog.i(TAG,"Connectivity Service"
- connectivity=newConnectivityService(
- context, networkManagement, networkStats, networkPolicy);
- ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
- networkStats.bindConnectivityManager(connectivity);
- networkPolicy.bindConnectivityManager(connectivity);
- wifi.checkAndStartWifi();
- wifiP2p.connectivityServiceReady();
- }catch(Throwable e){
- reportWtf("starting Connectivity Service", e);
- }
這裡我們可以看到在system server中,先構造了WifiP2pService 和WifiService,並將它們註冊在ServiceManager當中,然後呼叫WifiService的checkAndStartWifi函式。那首先我們進入Wifiservice的建構函式當中,code路徑在:framwork/base/service/java/com/android/server/wifi/WifiService.java,程式碼如下:
- WifiService(Context context){
- mContext= context;
- mInterfaceName= SystemProperties.get("wifi.interface","wlan0");
- mWifiStateMachine=newWifiStateMachine(mContext, mInterfaceName);
- <span style="white-space:pre"> </span>.......
- HandlerThread wifiThread=newHandlerThread("WifiService");
- wifiThread.start();
- mAsyncServiceHandler=newAsyncServiceHandler(wifiThread.getLooper());
- mWifiStateMachineHandler=newWifiStateMachineHandler(wifiThread.getLooper());
- <span style="white-space:pre"> </span>mWifiController=newWifiController(mContext, this,wifiThread.getLooper());
- <span style="white-space:pre"> </span>.......
- }
這裡主要建立一個WifiStateMachine的例項,然後新建一個HandlerThread來處理所有的message,並註冊一些broadcast的receive,例如WIFI_STATE_CHANGED_ACTION、NETWORK_STATE_CHANGED_ACTION等。WifiStateMachine用於控制整個wifi的開啟、關閉、連線、斷開等各個狀態切換,我們將在後面具體來介紹StateMachine。 接著回到system server中,ConnectivityService用於管控機器中所有的資料連線服務,WiFi當然也屬於其監控的物件,那我們進入到ConnectivityService建構函式中一看。code路徑在:framwork/base/service/java/com/android/server/ConnectivityService.java
- publicConnectivityService(Context context,INetworkManagementService netManager,
- INetworkStatsService statsService,INetworkPolicyManager policyManager,
- NetworkFactory netFactory){
- if(DBG) log("ConnectivityService starting up");
- HandlerThread handlerThread=newHandlerThread("ConnectivityServiceThread");
- handlerThread.start();
- mHandler=newInternalHandler(handlerThread.getLooper());
- mTrackerHandler=newNetworkStateTrackerHandler(handlerThread.getLooper());
- .......
- // Create and start trackers for hard-coded networks
- for(int targetNetworkType: mPriorityList){
- finalNetworkConfig config= mNetConfigs[targetNetworkType];
- finalNetworkStateTracker tracker;
- try{
- tracker= netFactory.createTracker(targetNetworkType, config);
- mNetTrackers[targetNetworkType]= tracker;
- }catch(IllegalArgumentException e){
- Slog.e(TAG,"Problem creating "+ getNetworkTypeName(targetNetworkType)
- +" tracker: "+ e);
- continue;
- }
- tracker.startMonitoring(context, mTrackerHandler);
- if(config.isDefault()){
- tracker.reconnect();
- }
- }
在ConnectivityService中將根據com.android.internal.R.array.networkAttributes中配置的系統network屬性去一一的建立tracker並開始monitor其狀態,tracker.startMonitoring(context, mTrackerHandler)這行code告訴我們這些tracker可以通過mTrackerHandler傳送訊息給ConnectivityService,我們可以到mTrackerHandler中看看這些訊息主要有哪些型別:
- NetworkStateTracker.EVENT_STATE_CHANGED
- NetworkStateTracker.EVENT_CONFIGURATION_CHANGED
- NetworkStateTracker.EVENT_NETWORK_SUBTYPE_CHANGED
其中NetworkStateTracker.EVENT_STATE_CHANGED極為重要,我們將在後面的內容中看到當wifi連線AP成功後,會發送這個訊息給ConnectivityService來做一些其它的檢測。 回到ConnectivityService的建構函式中,剛剛說到ConnectivityService中將根據com.android.internal.R.array.networkAttributes中配置的系統network屬性去一一的建立tracker,那我們進入到netFactory.createTracker(targetNetworkType, config)去看看究竟會建立哪些tracker:
- publicNetworkStateTracker createTracker(int targetNetworkType,NetworkConfig config){
- switch(config.radio){
- case TYPE_WIFI:
- returnnewWifiStateTracker(targetNetworkType, config.name);
- case TYPE_MOBILE:
- returnnewMobileDataStateTracker(targetNetworkType, config.name);
- case TYPE_DUMMY:
- returnnewDummyDataStateTracker(targetNetworkType, config.name);
- case TYPE_BLUETOOTH:
- returnBluetoothTetheringDataTracker.getInstance();
- case TYPE_WIMAX:
- return makeWimaxStateTracker(mContext, mTrackerHandler);
- case TYPE_ETHERNET:
- returnEthernetDataTracker.getInstance();
- default:
- thrownewIllegalArgumentException(
- "Trying to create a NetworkStateTracker for an unknown radio type: "
- + config.radio);
- }
- }
- }
這裡我們主要關係的是TYPE_WIFI,ConnectivityService將建立一個WiFiStateTracker物件,並呼叫其startMonitoring方法,進入到WiFiStateTracker程式碼中分析:
- publicWifiStateTracker(int netType,String networkName){
- mNetworkInfo=newNetworkInfo(netType,0, networkName,"");
- mLinkProperties=newLinkProperties();
- mLinkCapabilities=newLinkCapabilities();
- mNetworkInfo.setIsAvailable(false);
- setTeardownRequested(false);
- }
- publicvoid startMonitoring(Context context,Handler target){
- mCsHandler= target;
- mContext= context;
- mWifiManager=(WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
- IntentFilter filter=newIntentFilter();
- filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
- filter.addAction(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION);
- mWifiStateReceiver=newWifiStateReceiver();
- mContext.registerReceiver(mWifiStateReceiver, filter);
- }
WiFiStateTracker的建構函式和startMonitoring方法都比較簡單,主要是註冊一個broadcast receiver用於接收系統的NETWORK_STATE_CHANGED_ACTION和LINK_CONFIGURATION_CHANGED_ACTION訊息。
好,到這裡我們把ConnectivityService的建構函式中與wifi相關的內容介紹完畢了,我們再回到system server當中,在把ConnectivityService加入到Service Manager後,就呼叫wifi.checkAndStartWifi()來檢查是否可以啟動wifi了
- publicvoid checkAndStartWifi(){
- boolean wifiEnabled= mSettingStore.isWifiToggleEnabled();
- Slog.i(TAG,"WifiService starting up with Wi-Fi "+
- (wifiEnabled?"enabled":"disabled"));
- // If we are already disabled (could be due to airplane mode), avoid changing persist
- // state here
- if(wifiEnabled) setWifiEnabled(wifiEnabled);
- mWifiWatchdogStateMachine=WifiWatchdogStateMachine.
- makeWifiWatchdogStateMachine(mContext);
- }
具體的如何啟動wifi和wifi啟動流程將在下一章中分析,這裡來看一下整個Wifiservice啟動的流程圖,圖中的紅色字型部分表示新建一個thread,綠色部分表示在已有的looper當中建立一個handler,黃色部分表示註冊broadcast receiver。