Android WifiService的啓動流程分析

最近在學習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

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. try{  
  2.                Slog.i(TAG,"Wi-Fi P2pService");  
  3.                 wifiP2p=newWifiP2pService(context);  
  4.                ServiceManager.addService(Context.WIFI_P2P_SERVICE, wifiP2p);  
  5.            }catch(Throwable e){  
  6.                 reportWtf("starting Wi-Fi P2pService", e);  
  7.            }  
  8.   
  9.            try{  
  10.                Slog.i(TAG,"Wi-Fi Service");  
  11.                 wifi=newWifiService(context);  
  12.                ServiceManager.addService(Context.WIFI_SERVICE, wifi);  
  13.            }catch(Throwable e){  
  14.                 reportWtf("starting Wi-Fi Service", e);  
  15.            }  
  16.   
  17.            try{  
  18.                Slog.i(TAG,"Connectivity Service");  
  19.                 connectivity=newConnectivityService(  
  20.                         context, networkManagement, networkStats, networkPolicy);  
  21.                ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);  
  22.                 networkStats.bindConnectivityManager(connectivity);  
  23.                 networkPolicy.bindConnectivityManager(connectivity);  
  24.                 wifi.checkAndStartWifi();  
  25.                 wifiP2p.connectivityServiceReady();  
  26.            }catch(Throwable e){  
  27.                 reportWtf("starting Connectivity Service", e);  
  28.            }  


這裏我們可以看到在system server中,先構造了WifiP2pService 和WifiService,並將它們註冊在ServiceManager當中,然後調用WifiService的checkAndStartWifi函數。那首先我們進入Wifiservice的構造函數當中,code路徑在:framwork/base/service/java/com/android/server/wifi/WifiService.java,代碼如下:

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1.    WifiService(Context context){  
  2.         mContext= context;  
  3.   
  4.         mInterfaceName=  SystemProperties.get("wifi.interface","wlan0");  
  5.   
  6.         mWifiStateMachine=newWifiStateMachine(mContext, mInterfaceName);  
  7. <span style="white-space:pre">  </span>.......  
  8.   
  9.        HandlerThread wifiThread=newHandlerThread("WifiService");  
  10.         wifiThread.start();  
  11.         mAsyncServiceHandler=newAsyncServiceHandler(wifiThread.getLooper());  
  12.         mWifiStateMachineHandler=newWifiStateMachineHandler(wifiThread.getLooper());  
  13. <span style="white-space:pre">  </span>mWifiController=newWifiController(mContext, this,wifiThread.getLooper());  
  14.   
  15. <span style="white-space:pre">  </span>.......  
  16.    }  



這裏主要創建一個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

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. publicConnectivityService(Context context,INetworkManagementService netManager,  
  2.           INetworkStatsService statsService,INetworkPolicyManager policyManager,  
  3.           NetworkFactory netFactory){  
  4.       if(DBG) log("ConnectivityService starting up");  
  5.   
  6.       HandlerThread handlerThread=newHandlerThread("ConnectivityServiceThread");  
  7.        handlerThread.start();  
  8.        mHandler=newInternalHandler(handlerThread.getLooper());  
  9.        mTrackerHandler=newNetworkStateTrackerHandler(handlerThread.getLooper());  
  10.   
  11.   .......  
  12.   
  13.       // Create and start trackers for hard-coded networks  
  14.       for(int targetNetworkType: mPriorityList){  
  15.           finalNetworkConfig config= mNetConfigs[targetNetworkType];  
  16.           finalNetworkStateTracker tracker;  
  17.           try{  
  18.                tracker= netFactory.createTracker(targetNetworkType, config);  
  19.                mNetTrackers[targetNetworkType]= tracker;  
  20.           }catch(IllegalArgumentException e){  
  21.               Slog.e(TAG,"Problem creating "+ getNetworkTypeName(targetNetworkType)  
  22.                       +" tracker: "+ e);  
  23.               continue;  
  24.            }  
  25.   
  26.            tracker.startMonitoring(context, mTrackerHandler);  
  27.           if(config.isDefault()){  
  28.                tracker.reconnect();  
  29.           }  
  30.       }  



在ConnectivityService中將根據com.android.internal.R.array.networkAttributes中配置的系統network屬性去一一的創建tracker並開始monitor其狀態,tracker.startMonitoring(context, mTrackerHandler)這行code告訴我們這些tracker可以通過mTrackerHandler發送消息給ConnectivityService,我們可以到mTrackerHandler中看看這些消息主要有哪些類型:

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. NetworkStateTracker.EVENT_STATE_CHANGED  
  2. NetworkStateTracker.EVENT_CONFIGURATION_CHANGED  
  3. 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:

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1.     publicNetworkStateTracker createTracker(int targetNetworkType,NetworkConfig config){  
  2.          switch(config.radio){  
  3.             case TYPE_WIFI:  
  4.                 returnnewWifiStateTracker(targetNetworkType, config.name);  
  5.             case TYPE_MOBILE:  
  6.                 returnnewMobileDataStateTracker(targetNetworkType, config.name);  
  7.             case TYPE_DUMMY:  
  8.                 returnnewDummyDataStateTracker(targetNetworkType, config.name);  
  9.             case TYPE_BLUETOOTH:  
  10.                 returnBluetoothTetheringDataTracker.getInstance();  
  11.             case TYPE_WIMAX:  
  12.                 return makeWimaxStateTracker(mContext, mTrackerHandler);  
  13.             case TYPE_ETHERNET:  
  14.                 returnEthernetDataTracker.getInstance();  
  15.             default:  
  16.                 thrownewIllegalArgumentException(  
  17.                         "Trying to create a NetworkStateTracker for an unknown radio type: "  
  18.                         + config.radio);  
  19.         }  
  20.     }  
  21. }  



這裏我們主要關係的是TYPE_WIFI,ConnectivityService將創建一個WiFiStateTracker對象,並調用其startMonitoring方法,進入到WiFiStateTracker代碼中分析:

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. publicWifiStateTracker(int netType,String networkName){  
  2.      mNetworkInfo=newNetworkInfo(netType,0, networkName,"");  
  3.      mLinkProperties=newLinkProperties();  
  4.      mLinkCapabilities=newLinkCapabilities();  
  5.   
  6.      mNetworkInfo.setIsAvailable(false);  
  7.      setTeardownRequested(false);  
  8. }  
  9.   
  10. publicvoid startMonitoring(Context context,Handler target){  
  11.      mCsHandler= target;  
  12.      mContext= context;  
  13.   
  14.      mWifiManager=(WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);  
  15.     IntentFilter filter=newIntentFilter();  
  16.      filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);  
  17.      filter.addAction(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION);  
  18.   
  19.      mWifiStateReceiver=newWifiStateReceiver();  
  20.      mContext.registerReceiver(mWifiStateReceiver, filter);  
  21. }  



WiFiStateTracker的構造函數和startMonitoring方法都比較簡單,主要是註冊一個broadcast receiver用於接收系統的NETWORK_STATE_CHANGED_ACTION和LINK_CONFIGURATION_CHANGED_ACTION消息。
      好,到這裏我們把ConnectivityService的構造函數中與wifi相關的內容介紹完畢了,我們再回到system server當中,在把ConnectivityService加入到Service Manager後,就調用wifi.checkAndStartWifi()來檢查是否可以啓動wifi了

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. publicvoid checkAndStartWifi(){  
  2.      boolean wifiEnabled= mSettingStore.isWifiToggleEnabled();  
  3.     Slog.i(TAG,"WifiService starting up with Wi-Fi "+  
  4.             (wifiEnabled?"enabled":"disabled"));  
  5.   
  6.     // If we are already disabled (could be due to airplane mode), avoid changing persist  
  7.     // state here  
  8.     if(wifiEnabled) setWifiEnabled(wifiEnabled);  
  9.   
  10.      mWifiWatchdogStateMachine=WifiWatchdogStateMachine.  
  11.             makeWifiWatchdogStateMachine(mContext);  
  12.   
  13. }  



  具體的如何啓動wifi和wifi啓動流程將在下一章中分析,這裏來看一下整個Wifiservice啓動的流程圖,圖中的紅色字體部分表示新建一個thread,綠色部分表示在已有的looper當中創建一個handler,黃色部分表示註冊broadcast receiver。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章