android之wifi體系架構源碼流程分析

1、SystemServer類(frameworks\base\services\java\com\android\Server)
    --> 在frameworks\base\cmds\system_server\Library\System_init.cpp中有:
         runtime->callStatic("com/android/server/SystemServer", "init2");
        /**
            * This method is called from Zygote to initialize the system. This will cause the native
            * services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back
            * up into init2() to start the Android services.
          */
          說明開機以後就自動執行SystemServer類中的init2方法: public static final void init2() {
                                                                    Log.i(TAG, "Entered the Android system server!");
                                                                    Thread thr = new ServerThread();
                                                                    thr.setName("android.server.ServerThread");
                                                                    thr.start();
                                                                }
          從中可看出啓動了ServerThread線程,其中的run方法建立了不少的服務。咱們分析的wifi服務(Connectivity連接服務)中也在run方法中加載:
                                       try {
                                            Log.i(TAG, "Connectivity Service");
                                            connectivity = ConnectivityService.getInstance(context);
                                            ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
                                        } catch (Throwable e) {
                                            Log.e(TAG, "Failure starting Connectivity Service", e);
                                        }
2、Connectivity類(frameworks\base\core\java\android\Net  : extends IConnectivityManager.Stub )
             猜想connectivity = ConnectivityService.getInstance(context)是爲了獲得connectivity這個類。看看:
                                          public static ConnectivityService getInstance(Context context) {
                                                 return ConnectivityThread.getServiceInstance(context); 
                                          }
             爲何它不直接建立 ?   
             在看看:private static class ConnectivityThread extends Thread 說明這個類文內部靜態類, 並且裏面有個run方法。
                                          public static ConnectivityService getServiceInstance(Context context) {                                                     
                                                 ConnectivityThread thread = new ConnectivityThread(context);
                                                 thread.start();
                                                 ...
                                          }
             在run中:
                      public void run() {                                                 
                                 Looper.prepare();                                                                         
                                 synchronized (this) {                                   
                                     sServiceInstance = new ConnectivityService(mContext);
                                     notifyAll();                                        
                                 }                                                       
                                 Looper.loop();                                          
                             }
                            
           好!如今已經建立ConnectivityService一個類,並把這個類的對象傳到ServerThread線程中的添加服務。
           我發如今SystemServer 和Connectivity都啓動了一個線程,難道爲了建立一個類而啓動新線程?確定不是
           ,可是卻發現run的最後都有Looper.loop();猜想其它不少線程中的最後也有Looper.loop。去搜索Looper.loop,果真,發現looper.loop
           都在run方法的最後。由此我猜想:
           由於我在使用Handler時,裏面有個構造方法Handler(Looper looper) ,因此在線程專遞Message時確定與它有關。
           我記得,好像HandlerThread線程會去時不時的處理Message(handlerMessage)隊列。而後到handlerThread概看了下,它繼承了Thread
           類,中的run的方法就有looper.loop。看來最關鍵的就是這個loop。
           那如今到Looper.loop去看下,發現有個MessageQueue queue = me.mQueue;還有個大循環,裏面有句 msg.target.dispatchMessage(msg);
           跟進去裏面實際上最後是調用HandlerMessage方法。
           ...
          
          
          
           接下來在回來在看看Connectivity的構造函數作了什麼:
                  其中有:
                            if (DBG) Log.v(TAG, "Starting Wifi Service.");                        
                            WifiStateTracker wst = new WifiStateTracker(context, mHandler);
                            WifiService wifiService = new WifiService(context, wst);             
                            ServiceManager.addService(Context.WIFI_SERVICE, wifiService); 
                            mNetTrackers[ConnectivityManager.TYPE_WIFI] = wst;
                           
                            還有其它的服務,如:mNetTrackers[ConnectivityManager.TYPE_MOBILE] =
                                               mNetTrackers[ConnectivityManager.TYPE_MOBILE_MMS]=
                                               mNetTrackers[ConnectivityManager.TYPE_MOBILE_SUPL] =
                                               ...
                                                           
                                                           
                                                           
                  咱們的wifi服務模塊就在其中。如今就有了WifiStateTracker和WifiService。這兩個到底起什麼用呢?
                  我去查開發文檔,並無這兩個,看來對於應用開發者不可用;開發文檔中關於wifi的類就這些:
                            WifiConfiguration                     A class representing a configured Wi-Fi network, including the security configuration. 
                            WifiConfiguration.AuthAlgorithm       Recognized IEEE 802.11 authentication algorithms. 
                            WifiConfiguration.GroupCipher         Recognized group ciphers. 
                            WifiConfiguration.KeyMgmt             Recognized key management schemes. 
                            WifiConfiguration.PairwiseCipher      Recognized pairwise ciphers for WPA. 
                            WifiConfiguration.Protocol            Recognized security protocols. 
                            WifiConfiguration.Status              Possible status of a network configuration. 
                            WifiInfo                              Describes the state of any Wifi connection that is active or is in the process of being set up. 
                            WifiManager                           This class provides the primary API for managing all aspects of Wi-Fi connectivity. 
                            WifiManager.MulticastLock             Allows an application to receive Wifi Multicast packets. 
                            WifiManager.WifiLock                  Allows an application to keep the Wi-Fi radio awake. 
                           
         只能到這兩個類大概瀏覽一下了
      
           1)WifiStateTracker類
                  先看WifiStateTracker構造:我看得眼有點熟的有 mWifiInfo = new WifiInfo();                
                                                                       mWifiMonitor = new WifiMonitor(this);
                                                                       ...
                                                                       ...還不少都不認識。
                                                                       看方法列表中也只認識:notifyStateChange
                                                                                   notifyXXX
                                                                             也無心看到handleMessage
                                                                             我想應該有looper,本文件搜索looper,果真有:
                                                                                    public DhcpHandler(Looper looper, Handler target) {
                                                                                                     super(looper);
                                                                                                                           
                         
                   2) WifiService類
                          再看一下WifiService(Context context, WifiStateTracker tracker) 構造: mWifiStateTracker = tracker;
                                                                                                HandlerThread wifiThread = new HandlerThread("WifiService"); 
                                                                                                wifiThread.start();
                                                                                                mWifiHandler = new WifiHandler(wifiThread.getLooper());
                                                                                                這熟悉這幾個,其它的幾乎不認識;
                                 既然有HandlerThread和 mWifiHandler,那麼應該mWifiHandler重寫了Handler的某些方法:
                                       再去找一下:  private class WifiHandler extends Handler {                              
                                                           public WifiHandler(Looper looper) {                                                                                                   
                                                               super(looper);                                                 
                                                           }                                                                  
                                                                 
                                                           @Override                                                          
                                                           public void handleMessage(Message msg) {                           
                                                               switch (msg.what) {                                            
                                                                 
                                                                   case MESSAGE_ENABLE_WIFI:                                  
                                                                       setWifiEnabledBlocking(true, msg.arg1 == 1, msg.arg2); 
                                                                       sWakeLock.release();                                   
                                                                       break;                                                 
                                                                 
                                                                   case MESSAGE_START_WIFI:                                   
                                                                       mWifiStateTracker.setScanOnlyMode(msg.arg1 != 0);      
                                                                       mWifiStateTracker.restart();                           
                                                                       sWakeLock.release();                                   
                                                                       break;                                                 
                                                                 
                                                                   case MESSAGE_DISABLE_WIFI:                                 
                                                                       // a non-zero msg.arg1 value means the "enabled" setting
                                                                       // should be persisted                                 
                                                                       setWifiEnabledBlocking(false, msg.arg1 == 1, msg.arg2);
                                                                       sWakeLock.release();                                   
                                                                       break;                                                 
                                                                 
                                                                   case MESSAGE_STOP_WIFI:                                    
                                                                       mWifiStateTracker.disconnectAndStop();                 
                                                                       // don't release wakelock                              
                                                                       break;                                                 
                                                                 
                                                                   case MESSAGE_RELEASE_WAKELOCK:                             
                                                                       synchronized (sDriverStopWakeLock) {                   
                                                                           if (sDriverStopWakeLock.isHeld()) {                
                                                                               sDriverStopWakeLock.release();                 
                                                                           }                                                  
                                                                       }                                                      
                                                                       break;                                                 
                                                               }                                                              
                                                           }                                                                  
                                                       }   
                                                      
                          從中可發現WifiService建立新的線程,那麼只誰往這個線程的MessageQueue中放Message的話,這個線程的looper就取出來
                         而後執行handleMessage。那麼誰會往這個線程放Message? 我如今也還不清楚,可是,不是從wifi網卡上來的,就是應用編程吧!  
                        
                       再大概瀏覽一下方法列表:
                               public boolean startScan(boolean forceActive)
                               public boolean setWifiEnabled(boolean enable)
                               private boolean setWifiEnabledBlocking(boolean enable, boolean persist, int uid)
                               private void setWifiEnabledState(int wifiState, int uid)
                               public boolean enableNetwork(int netId, boolean disableOthers)
                               private ScanResult parseScanResult(String line)
                               private void updateWifiState()
                               ...
                               ...
                           從名字中可看出WifiService類這些方法是用來使能wifi,搜尋ap等等。
                          
                          
      跟了那麼多代碼,應用什麼使能wifi呢?確定要用涉及到 WifiService,而後又什麼調到底層?                 
                          
                          
 3、 1)WifiSettings類(packages\apps\settings\src\com\android\settings\Wifi :
         extends PreferenceActivity implements WifiLayer.Callback,DialogInterface.OnDismissListener )
         從包(app)和父類能夠知道這個是一個Activity,也是一個應用程序。
         因此看構造和oncreat:
          public WifiSettings() {
             mAps = new WeakHashMap<AccessPointState, AccessPointPreference>();
             mWifiLayer = new WifiLayer(this, this);
         }
         又出現了個與wifi相關的WifiLayer,不過它與應用相關,先無論它,
           protected void onCreate(Bundle savedInstanceState) {
               super.onCreate(savedInstanceState);
       
               onCreatePreferences(); ------------------------->中包含:if (!getIntent().getBooleanExtra(KEY_ONLY_ACCESS_POINTS, false)) {
                                                                          mWifiEnabled = (CheckBoxPreference) preferenceScreen.findPreference(KEY_WIFI_ENABLED);
                                                                          mWifiEnabler = new WifiEnabler(this, (WifiManager) getSystemService(WIFI_SERVICE),
                                                                                  mWifiEnabled);
                                                                      傳了一個wifiManager到wifiEnabler,我覺的很重要,由於wifiManager是frameworks\base\wifi \java\android\net\Wifi
                                                                      這個包的,在看名字Manager,確定是用它來管理的。並且在開發文檔中也有它。等下看看wifiEnabler它什麼使用wifiManager。


               mWifiLayer.onCreate();      上面創了WifiEnabler,這裏就調用它的oncreat函 數。                                                           
       
               onCreatedWifi();空的
               mWifiLayer.onCreatedCallback();
           } java

       其它的方法調用到了再看吧,下面看看WifiEnabler,以前知道它從系統服務中獲得了wifiManager  ;  
      
       2)WifiEnabler類 packages\apps\settings\src\com\android\settings\Wifi
                                implements Preference.OnPreferenceChangeListener
                               
          其構造函數: public WifiEnabler(Context context, WifiManager wifiManager,
                           CheckBoxPreference wifiCheckBoxPreference) {
                           mContext = context;
                           mWifiCheckBoxPref = wifiCheckBoxPreference;
                           mWifiManager = wifiManager;
                          
                           mOriginalSummary = wifiCheckBoxPreference.getSummary();
                           wifiCheckBoxPreference.setPersistent(false);
                          
                           mWifiStateFilter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION);
                           mWifiStateFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
                       }
               mWifiStateFilter就是一個IntentFiler,  看到WifiManager.WIFI_STATE_CHANGED_ACTION,猜裏面應該有不少宏吧!
              
              
              大概瀏覽下發現有個成員類,並建立好了的,說明這個類一建立,也就建立了該類:
                    private final BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() {                  
                                                                                                              
                            @Override                                                                               
                            public void onReceive(Context context, Intent intent) {                                 
                                if (intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {             
                                    handleWifiStateChanged(                                                         
                                            intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WIFI_STATE_UNKNOWN),   
                                            intent.getIntExtra(WifiManager.EXTRA_PREVIOUS_WIFI_STATE,               
                                                    WIFI_STATE_UNKNOWN));                                           
                                } else if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {   
                                    handleNetworkStateChanged(                                                      
                                            (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO));
                                }                                                                                   
                            }                                                                                       
                        };
                       
                     而後調用handleWifiStateChanged,來處理不一樣的action!
                                                                                                               
                  咱們發現這是個廣播接收類,重寫了onReceive方法:由此上面的IntentFiler 也就不奇怪了,可是還不知道誰發了
                  廣播?                                                                                           
       
               其它方法看了一下,有個
                    private void setWifiEnabled(final boolean enable) {                                               
                            // Disable button                                                                           
                            mWifiCheckBoxPref.setEnabled(false);                                                        
                                                                                                                        
                            if (!mWifiManager.setWifiEnabled(enable)) {                                                 
                                mWifiCheckBoxPref.setSummary(enable ? R.string.error_starting : R.string.error_stopping);
                            }                                                                                           
                        }
                    正如它的類名同樣,使能wifi,而用到的使能類wifiManager,就是wifiManager.setWifiEnabled(enable) ;                                                                                             
             
               又有這個方法private static String getHumanReadableWifiState(int wifiState),看裏面是用來
               獲取wifi當前狀態的的方法,在結合廣播接收器,可大概知道知道這個類的做用,就是能接收wifi狀態的
               改變,咱們也就能經過該類獲取wifi當前的狀態,並能使能wifi,也就是經過wifiManager來使能的。
              
              
       
       3)上面的分析還有兩個類不知道它們什麼意思,就是WifiLayer和wifiManager?
         咱們先看app中的這個wifiLayer,看它用不用到wifiManager,再猜想這個wifiManager,而後再分析這個wifiManager就應該
         比較清楚了。
         經過上面跟的代碼,知道wifiLayer是在wifiSetting類的構造方法建立的:mWifiLayer = new WifiLayer(this, this);
          而在wifisetting的oncreat中調用了wifiEnable中的oncreat,
          那麼咱們在先看wifiLayer的構造再看wifiEnable.oncreat:
           public WifiLayer(Context context, Callback callback) {
                  mContext = context;                            
                  mCallback = callback;                                                                              
              } 
                callback是wifiLayer中的一個接口,在看傳進來的是this也就是wifiSetting,那麼在wifiSetting中確定實現了這個接口,
                看看wifiSetting類, 果然有implements WifiLayer.Callback  。
                瀏覽一下這個接口每一個方法的描述:
                       void onAccessPointSetChanged(AccessPointState ap, boolean added);-->Called when an AP is added or removed.
                       void onScanningStatusChanged(boolean started);                   -->Called when the scanning status changes.
                       void onAccessPointsStateChanged(boolean enabled);                -->Called when the access points should be enabled or disabled. This is                                                        
                                                                                                  called from both wpa_supplicant being connected/disconnected and Wi-Fi
                                                                                                  being enabled/disabled.
                       void onRetryPassword(AccessPointState ap);                       -->Called when there is trouble authenticating and the retry-password                                            
                                                                                                  dialog should be shown. 
                                                                                                 
             onCreate中:public void onCreate() {                                                                                                                                                
                                 mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);              
                                                                                                                   
                                 mIntentFilter = new IntentFilter();                                               
                                 mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);                
                                 mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);               
                                 mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);         
                                 mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);             
                                 mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);                   
                                 mIntentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION);                         
                                 mIntentFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION);                  
                                                                                                                   
                                 WIFI_NUM_OPEN_NETWORKS_KEPT = Settings.Secure.getInt(mContext.getContentResolver(),
                                     Settings.Secure.WIFI_NUM_OPEN_NETWORKS_KEPT, 10);                             
                             }
             這裏它也從系統服務中獲得了一個WifiManager,在動態的建立過濾器, 那麼也必定有 BroadcastReceiver,來處理
             不一樣的action。
             果真:private BroadcastReceiver mReceiver = new BroadcastReceiver() {                                                                                                                     
                                                                                                
                           @Override                                                                               
                           public void onReceive(Context context, Intent intent) {                                 
                               final String action = intent.getAction();                                           
                               if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {                      
                                   handleNetworkStateChanged(                                                      
                                           (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO),
                                           intent.getStringExtra(WifiManager.EXTRA_BSSID));                        
                               } else if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {              
                                   handleScanResultsAvailable();                                                   
                               } else if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {        
                                   handleSupplicantConnectionChanged(                                              
                                           intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false)); 
                               } else if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) {            
                                   handleSupplicantStateChanged(                                                   
                                           (SupplicantState) intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE),
                                           intent.hasExtra(WifiManager.EXTRA_SUPPLICANT_ERROR),                    
                                           intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, 0));             
                               } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {                  
                                   handleWifiStateChanged(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,         
                                           WifiManager.WIFI_STATE_UNKNOWN));                                       
                               } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {                        
                                   handleSignalChanged(intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, 0));         
                               } else if (action.equals(WifiManager.NETWORK_IDS_CHANGED_ACTION)) {                 
                                   handleNetworkIdsChanged();                                                      
                               }                                                                                   
                           }                                                                                       
                       };  
            這裏有不少handleXXX,說明這個處理更多的狀態了。
            到這裏回頭看一下以前的wifiEnabler中的onReceive
                它處理的Intent中action的有 :* WifiManager.WIFI_STATE_CHANGED_ACTION
                                 WifiManager.NETWORK_STATE_CHANGED_ACTION
               
                而這wifiLayer處理的action有:WifiManager.NETWORK_STATE_CHANGED_ACTION
                               WifiManager.SCAN_RESULTS_AVAILABLE_ACTION
                               WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION
                               WifiManager.SUPPLICANT_STATE_CHANGED_ACTION
                             *  WifiManager.WIFI_STATE_CHANGED_ACTION (上面也有這個)
                               WifiManager.RSSI_CHANGED_ACTION
                               WifiManager.NETWORK_IDS_CHANGED_ACTION  
          
           不用管它什麼處理先。
          
          
           瞄一眼其它的,還發如今有個Handler,
                                                private class MyHandler extends Handler {                                                                                
                                               
                                                      @Override                              
                                                      public void handleMessage(Message msg) {
                                                          switch (msg.what) {                
                                                              case MESSAGE_ATTEMPT_SCAN:     
                                                                  attemptScan();             
                                                                  break;                     
                                                          }                                  
                                                      }                                      
                                                  }
            看來是用來處理本線程的Messagequeue。
           
     4) 接下來能夠去看看wifiManager了。 如今我還不是很清楚,他能作什麼,有什麼用。
        可是得先思考一下:第1、wifiManager何時建立?我猜應該是在addservice時(也就是上面Connectivity中的構造)
                                WifiStateTracker wst = new WifiStateTracker(context, mHandler);                                              
                                WifiService wifiService = new WifiService(context, wst);          
                                ServiceManager.addService(Context.WIFI_SERVICE, wifiService);     
                                mNetTrackers[ConnectivityManager.TYPE_WIFI] = wst;
                          第2、wifiManager向誰提供服務?誰來管理它?整理一下思路,咱們的wifiLayer和wifiEnabler都用到了wifiManager,
                                因此我猜應該是,系統給咱們用來控制wifi使能,查看狀態,搜尋ap的類。
                               
                          第一的猜測是不對的,我從 ServiceManager 類往下找,並無找到。只發現個 getIServiceManager().addService(name, service); 
                           IServiceManager這只是個接口 ,而後有句:sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
                           不得在往下了,看不懂了,接口太多。仍是去搜WifiManager吧!而後發現以下:
                                private WifiManager getWifiManager()                                             
                                    {                                                                            
                                        synchronized (sSync) {                                                   
                                            if (sWifiManager == null) {                                          
                                                IBinder b = ServiceManager.getService(WIFI_SERVICE);             
                                                IWifiManager service = IWifiManager.Stub.asInterface(b);             
                                                sWifiManager = new WifiManager(service, mMainThread.getHandler());
                                            }                                                                    
                                        }                                                                        
                                        return sWifiManager;                                                     
                                    }
                           看來應該是,wifiManager = this.(WifiManager) getSystemService(WIFI_SERVICE)時建立的。
                           看看是否是呢,這個方法在Context類中。
                              public abstract Object getSystemService(String name); 
                            不過是抽象的方法,在哪裏實現呢?
                            咱們去看一下android的開發文檔:public abstract Object getSystemService (String name)                                                                                                                                     
                                                           Since: API Level 1 Return the handle to a system-level service by name.
                                                                  The class of the returned object varies by the requested name.
                                                                  Currently available names are:
                                                                                                                                                                     
                                                           WINDOW_SERVICE ("window")                                                                                                                                            
                                                           The top-level window manager in which you can place custom windows. The returned object is a WindowManager.                                                          
                                                           LAYOUT_INFLATER_SERVICE ("layout_inflater")                                                                                                                          
                                                           A LayoutInflater for inflating layout resources in this context.                                                                                                     
                                                           ...
                                                           WIFI_SERVICE ("wifi")                                                                                                                                             
                                                           A WifiManager for management of Wi-Fi connectivity.
                             沒看到啊!這個開發文檔只說返回什麼而已,沒說在哪裏產生。
                             回到上面咱們搜索的private WifiManager getWifiManager() ;看看是什麼類:
                             class ReceiverRestrictedContext extends ContextWrapper  。public class ContextWrapper extends android.content.Context
                             這回有聯繫了,我猜這裏確定有抽象方法 getSystemService的實現。
                             果真。  } else if (WIFI_SERVICE.equals(name)) {                                                                              
                                               return getWifiManager();                                                                                                                                                 
                             終於找到了。
                            
                            
                      如今就分析這個WifiManager 類
                               sWifiManager = new WifiManager(service, mMainThread.getHandler())  
                              
                        public WifiManager(IWifiManager service, Handler handler) {       
                               mService = service;                                                                                                                                                                              
                               mHandler = handler;                                
                           }
                          
                      這個類比想象的簡單啊!
                      首先他確實有不少宏。 我前面分析的是,應用程序這個wifiManager來控制wifi網卡狀態,好比:使能,搜尋ap等等,
                      可是卻發現,return mService.startScan(false);
                                  return mService.enableNetwork(netId, disableOthers);
                                  return mService.disconnect();
                                  ...
                                  mService是個接口,public interface IWifiManager extends android.os.IInterface
                                  public class WifiService extends IWifiManager.Stub
                                  public static abstract class Stub extends android.os.Binder implements android.net.wifi.IWifiManager
                       這個mService是從哪裏來的?
                       在ApplicationContext:
                       IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
                       越往下看越複雜,反正知道mService就是上面分析的WifiService 。
                      
                這個wifiManager將大部分的操做都轉交給WifiService了。
               
               
               
               
                在作個小總結,咱們能夠經過wifiManager來間接調用wifiService的服務,應用調用的wifiManager的方法來控制wifi網卡狀態,
                接下來咱們看,從wifiService什麼往下調用的:以Scan爲例
                wifiManager.Scan
                    -->return mService.startScan(false);
                         -->  return WifiNative.scanCommand(forceActive);
                           
                    咱們到wifiNative去,發現全部函數都只聲明,沒有實現體。但發現每一個函數都有個關鍵字native。其實就是
                經過jni來調用c++下面的代碼,想了解深刻的在去找jni的資料。
                    經過搜索咱們找到:
                    在android_net_wifi_Wifi.cpp frameworks\base\core\Jni 有
                         { "scanCommand", "(Z)Z", (void*) android_net_wifi_scanCommand }, 
                    這個在一個結構體裏,確定是經過註冊,與java層中的WifiNative 的方法聯繫起來。
                如今這兩個函數經過jni有關聯了,調用 WifiNative.ScanCommand 就至關於調用  android_net_wifi_ScanCommand
                咱們發現這函數名也有規則,實際上是能夠隨便取的。
                    無論它,往下看:
                                                  android_net_wifi_ScanCommand
                                                |     --> result = doBooleanCommand("SCAN", "OK");
                 android_net_wifi_Wifi.cpp <--  |         -->if (doCommand(cmd, reply, sizeof(reply)) != 0)
                                                      |      -->if (::wifi_command(cmd, replybuf, &reply_len) != 0)
                                          wifi.c   <--|        --> return wifi_send_command(ctrl_conn, command, reply, reply_len);
                                                      |            -->wifi_send_command
                                                                 |    -->ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), reply, reply_len, NULL);
                                          wpa_supplicant  <--    |      -->if (send(ctrl->s, _cmd, _cmd_len, 0) < 0)
                                                                 |        --> return (ssize_t) sendto(socket, buf, buflen, flags, NULL, 0);
                                                                 |          --> return __socketcall( SYS_SENDTO, t );
                                                                      在往下就是驅動了。
                那麼以前那個疑問又來了?誰給wifiService發Message呢?
                     咱們在跟一下wifi網卡使能。
                        從wifiManager開始
                         -->public boolean setWifiEnabled(boolean enabled) {
                             -->  return mService.setWifiEnabled(enabled);
                                --> sendEnableMessage(enable, true, Binder.getCallingUid());
                                   -->Message msg = Message.obtain(mWifiHandler,
                                     (enable ? MESSAGE_ENABLE_WIFI : MESSAGE_DISABLE_WIFI),
                                     (persist ? 1 : 0), uid);
                                      msg.sendToTarget();
         
                                    看到沒有,給本身發了Message。因此到這隻能到handleMessage去找了。
                                     setWifiEnabledBlocking(true, msg.arg1 == 1, msg.arg2);
                                        |-->  if (!WifiNative.loadDriver())
                                        |  -->public native static boolean loadDriver();
                                        |              |jni|
                                        |           -->  { "loadDriver", "()Z",  (void *)android_net_wifi_loadDriver },
                                        |               --> return (jboolean)(::wifi_load_driver() == 0);
                                        |     wifi.c         -->if (insmod( "/system/lib/modules/wlan.ko", "") < 0)這裏我把宏替換掉了;
                                        |                     這裏就加載完了驅動。
                                        |可是這樣wifi網卡還不得用,還要個 wpa_supplicant.  在setWifiEnabledBlocking中還發現:
                                        |    
                                        | --> if (!WifiNative.startSupplicant())
                                            --> public native static boolean startSupplicant();
                                               --> { "startSupplicant", "()Z",  (void *)android_net_wifi_startSupplicant },
                                                  -->  return (jboolean)(::wifi_start_supplicant() == 0);
                                                    --> /*Check whether already running  */
                                                        ...
                                                       /* Before starting the daemon, make sure its config file exists */
                                                        ...
                                                       /* Clear out any stale socket files that might be left over. */  
                                                       要用到的確實挺多的。                   
                                                        static const char IFACE_DIR[]           = "/data/system/wpa_supplicant";
                                                        static const char DRIVER_PROP_NAME[]    = "wlan.driver.status";                 
                                                        static const char SUPPLICANT_NAME[]     = "wpa_supplicant";                     
                                                        static const char SUPP_PROP_NAME[]      = "init.svc.wpa_supplicant";            
                                                        static const char SUPP_CONFIG_TEMPLATE[]= "/system/etc/wifi/wpa_supplicant.conf";
                                                        static const char SUPP_CONFIG_FILE[]    = "/data/misc/wifi/wpa_supplicant.conf";     
                                                       
                                                                
    4、咱們是從上層往底層是通了,那麼從底層到上層呢,就是當咱們啓動wifi網卡成功後,要得通知應用層
    使能wifi是否成功啊!
    網上搜一下,有:
    當wpa_supplicant 處理完SCAN 命令後,它會向控制通道發送事件通知掃描完成,從wifi_wait_for_event 函數會接收到該事件,由 此                                                                
    WifiMonitor 中的MonitorThread 會被執行來出來這個事件。
    知道這樣了咱們再跟一下源碼,看看是否是?
       先搜源碼   wifi_wait_for_event  看誰調用
             { "waitForEvent", "()Ljava/lang/String;", (void*) android_net_wifi_waitForEvent },
               -->wifi_wait_for_event
                 -->result = wpa_ctrl_recv(monitor_conn, buf, &nread);        (wifi.c)
                     -->res = recv(ctrl->s, reply, *reply_len, 0); 
                       -->return recvfrom(socket, buf, buflen, flags, NULL, 0);                                               
                 在wifiNative裏有
                   /**
                   * Wait for the supplicant to send an event, returning the event string.
                   * @return the event string sent by the supplicant.                    */                   public native static String waitForEvent();                    如今知道了這函數就是在等待事件上報。                   經過搜索發現:                   在wifiMonitor類中  for (;;) {                                        String eventStr = WifiNative.waitForEvent();                                        ...                                      }                   咱們在上面略微看了WifiStateTracker構造時發現(不記得的話就搜索,看誰建立它):                                             mWifiMonitor = new WifiMonitor(this);                   1)分析wifiMonitor, 先看構造:                            public WifiMonitor(WifiStateTracker tracker) {                                         mWifiStateTracker = tracker;                                               }                      傳的是WifiStateTracker,說明還得用到這個類。                      明顯的發現有個線程類class MonitorThread extends Thread {                                                                                                                         public MonitorThread() {                                                         super("WifiMonitor");                                                    }                      有如今就在本文件搜start,因而有:                                                   public void startMonitoring() {                                                                                        new MonitorThread().start();                                                      }                      看來是讓人家調用的,咱們搜一下,看誰調用:                             在WifiStateTracker裏面有兩個方法:                                                       public void startMonitoring() {                                                                                                                                 /*                                                                                                                            * Get a handle on the WifiManager. This cannot be done in our                                                                * constructor, because the Wifi service is not yet registered.                                                               */                                                                                                                          mWM = (WifiManager)mContext.getSystemService(Context.WIFI_SERVICE);                                                       }                                                                                                                                                                                                       public void startEventLoop() {                                                                                                   mWifiMonitor.startMonitoring();                                                                                          }                      看註釋應該是startEventLoop,誰又調用它?再搜:                         發現了,在wifiService中的private boolean setWifiEnabledBlocking(boolean enable, boolean persist, int uid)                                    mWifiStateTracker.startEventLoop();                           細心點的話,會發現這個函數就是咱們上面wifi使能的時候。從handleMessage中調用的,因此咱們                      只有咱們使能後,纔會去啓動wifiMonitor的線程,而後去監聽wpa_supplicant返回的事件。                                       這個線程是起來了, 這線程最重要的任務是String eventStr = WifiNative.waitForEvent(); 去查詢監聽                      上報的事件。那事件來個呢,我猜應該也在這個run中作相應的處理吧!                                       確實:                                        handlePasswordKeyMayBeIncorrect();                                        handleSupplicantStateChange(eventData);                                        handleDriverEvent(eventData);                                        mWifiStateTracker.notifySupplicantLost();                                        handleEvent(event, eventData);                             跟進去一些的話,這些handleXXX最終都是調用到 WifiStateTracker.notifyXXX,也就知道了                          爲什建立wifiMonitor時構造方法要用到  WifiStateTracker作參數。                                                         源碼大抵流程也跟得差很少了。      
相關文章
相關標籤/搜索