1. 程式人生 > >Android WifiService的啟動流程分析

Android WifiService的啟動流程分析

轉於: 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
  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.            try
    {  
  9.                Slog.i(TAG,"Wi-Fi Service");  
  10.                 wifi=newWifiService(context);  
  11.                ServiceManager.addService(Context.WIFI_SERVICE, wifi);  
  12.            }catch(Throwable e){  
  13.                 reportWtf("starting Wi-Fi Service", e);  
  14.            }  
  15.            try{  
  16.                Slog.i(TAG,"Connectivity Service"
    );  
  17.                 connectivity=newConnectivityService(  
  18.                         context, networkManagement, networkStats, networkPolicy);  
  19.                ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);  
  20.                 networkStats.bindConnectivityManager(connectivity);  
  21.                 networkPolicy.bindConnectivityManager(connectivity);  
  22.                 wifi.checkAndStartWifi();  
  23.                 wifiP2p.connectivityServiceReady();  
  24.            }catch(Throwable e){  
  25.                 reportWtf("starting Connectivity Service", e);  
  26.            }  

這裡我們可以看到在system server中,先構造了WifiP2pService 和WifiService,並將它們註冊在ServiceManager當中,然後呼叫WifiService的checkAndStartWifi函式。那首先我們進入Wifiservice的建構函式當中,code路徑在:framwork/base/service/java/com/android/server/wifi/WifiService.java,程式碼如下:
  1.    WifiService(Context context){  
  2.         mContext= context;  
  3.         mInterfaceName=  SystemProperties.get("wifi.interface","wlan0");  
  4.         mWifiStateMachine=newWifiStateMachine(mContext, mInterfaceName);  
  5. <span style="white-space:pre">  </span>.......  
  6.        HandlerThread wifiThread=newHandlerThread("WifiService");  
  7.         wifiThread.start();  
  8.         mAsyncServiceHandler=newAsyncServiceHandler(wifiThread.getLooper());  
  9.         mWifiStateMachineHandler=newWifiStateMachineHandler(wifiThread.getLooper());  
  10. <span style="white-space:pre">  </span>mWifiController=newWifiController(mContext, this,wifiThread.getLooper());  
  11. <span style="white-space:pre">  </span>.......  
  12.    }  


這裡主要建立一個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
  1. publicConnectivityService(Context context,INetworkManagementService netManager,  
  2.           INetworkStatsService statsService,INetworkPolicyManager policyManager,  
  3.           NetworkFactory netFactory){  
  4.       if(DBG) log("ConnectivityService starting up");  
  5.       HandlerThread handlerThread=newHandlerThread("ConnectivityServiceThread");  
  6.        handlerThread.start();  
  7.        mHandler=newInternalHandler(handlerThread.getLooper());  
  8.        mTrackerHandler=newNetworkStateTrackerHandler(handlerThread.getLooper());  
  9.   .......  
  10.       // Create and start trackers for hard-coded networks
  11.       for(int targetNetworkType: mPriorityList){  
  12.           finalNetworkConfig config= mNetConfigs[targetNetworkType];  
  13.           finalNetworkStateTracker tracker;  
  14.           try{  
  15.                tracker= netFactory.createTracker(targetNetworkType, config);  
  16.                mNetTrackers[targetNetworkType]= tracker;  
  17.           }catch(IllegalArgumentException e){  
  18.               Slog.e(TAG,"Problem creating "+ getNetworkTypeName(targetNetworkType)  
  19.                       +" tracker: "+ e);  
  20.               continue;  
  21.            }  
  22.            tracker.startMonitoring(context, mTrackerHandler);  
  23.           if(config.isDefault()){  
  24.                tracker.reconnect();  
  25.           }  
  26.       }  



在ConnectivityService中將根據com.android.internal.R.array.networkAttributes中配置的系統network屬性去一一的建立tracker並開始monitor其狀態,tracker.startMonitoring(context, mTrackerHandler)這行code告訴我們這些tracker可以通過mTrackerHandler傳送訊息給ConnectivityService,我們可以到mTrackerHandler中看看這些訊息主要有哪些型別:
  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:
  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程式碼中分析:
  1. publicWifiStateTracker(int netType,String networkName){  
  2.      mNetworkInfo=newNetworkInfo(netType,0, networkName,"");  
  3.      mLinkProperties=newLinkProperties();  
  4.      mLinkCapabilities=newLinkCapabilities();  
  5.      mNetworkInfo.setIsAvailable(false);  
  6.      setTeardownRequested(false);  
  7. }  
  8. publicvoid startMonitoring(Context context,Handler target){  
  9.      mCsHandler= target;  
  10.      mContext= context;  
  11.      mWifiManager=(WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);  
  12.     IntentFilter filter=newIntentFilter();  
  13.      filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);  
  14.      filter.addAction(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION);  
  15.      mWifiStateReceiver=newWifiStateReceiver();  
  16.      mContext.registerReceiver(mWifiStateReceiver, filter);  
  17. }  


WiFiStateTracker的建構函式和startMonitoring方法都比較簡單,主要是註冊一個broadcast receiver用於接收系統的NETWORK_STATE_CHANGED_ACTION和LINK_CONFIGURATION_CHANGED_ACTION訊息。
      好,到這裡我們把ConnectivityService的建構函式中與wifi相關的內容介紹完畢了,我們再回到system server當中,在把ConnectivityService加入到Service Manager後,就呼叫wifi.checkAndStartWifi()來檢查是否可以啟動wifi了
  1. publicvoid checkAndStartWifi(){  
  2.      boolean wifiEnabled= mSettingStore.isWifiToggleEnabled();  
  3.     Slog.i(TAG,"WifiService starting up with Wi-Fi "+  
  4.             (wifiEnabled?"enabled":"disabled"));  
  5.     // If we are already disabled (could be due to airplane mode), avoid changing persist
  6.     // state here
  7.     if(wifiEnabled) setWifiEnabled(wifiEnabled);  
  8.      mWifiWatchdogStateMachine=WifiWatchdogStateMachine.  
  9.             makeWifiWatchdogStateMachine(mContext);  
  10. }  


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