Wifi服務框架介紹

http://blog.csdn.net/u010961631/article/details/48291095


   本文簡要介紹WIFI服務的主要框架以及運作機制

        WIFI框架主要涉及到以下幾個對象:WifiService、WifiManager、WifiServiceImpl、WifiStateMachine等。下面來介紹這四個對象的內在聯繫。


一、WIFI服務的初始化


        WIFI服務的初始化分爲兩個部分,WifiService的初始化和WifiManager的初始化,下面分別介紹。


1.1、WifiService的初始化流程


        WifiService的初始化流程是在SystemService中被啓動的:
[java] view plain copy
  1. @SystemServer.java  
  2. private static final String WIFI_SERVICE_CLASS = "com.android.server.wifi.WifiService";  
  3. private void startOtherServices() {  
  4.     mSystemServiceManager.startService(WIFI_SERVICE_CLASS);  
  5. }  
        在這裏通過SystemServiceManager將WIFI的主服務(WifiService)啓動,然後來看該Service的啓動過程:
[java] view plain copy
  1. @WifiService.java  
  2. public final class WifiService extends SystemService {  
  3.     private static final String TAG = "WifiService";  
  4.     final WifiServiceImpl mImpl;  
  5.     public WifiService(Context context) {  
  6.         super(context);  
  7.         //創建WifiServiceImpl對象  
  8.         mImpl = new WifiServiceImpl(context);  
  9.     }  
  10.     @Override  
  11.     public void onStart() {  
  12.         //將WifiServiceImpl註冊到ServiceManager  
  13.         publishBinderService(Context.WIFI_SERVICE, mImpl);  
  14.     }  
  15.   
  16.   
  17.     @Override  
  18.     public void onBootPhase(int phase) {  
  19.         if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {  
  20.             mImpl.checkAndStartWifi();  
  21.         }  
  22.     }  
  23. }  
        以上是WifiService的全部內容,其實該Service只完成了兩個任務:
        1、在初始化時,也就是構造方法中,創建WifiServiceImpl對象。
        2、在onStart時,將WifiServiceImpl對象註冊到ServiceManager中。

        這裏創建的WifiServiceImpl是整個WIFI服務的管理者,他負責將客戶端對WIFI的請求分類,然後派發給不同的處理中心。
        下面先來看WifiServiceImpl的屬性:
[java] view plain copy
  1. public final class WifiServiceImpl extends IWifiManager.Stub {}  
        這說明該類是一個服務的實現類。
        然後來看該對象的初始化過程,也就是構造方法:
[java] view plain copy
  1. @WifiServiceImpl.java  
  2. public WifiServiceImpl(Context context) {  
  3.     mContext = context;  
  4.     mInterfaceName =  SystemProperties.get("wifi.interface""wlan0");  
  5.     mTrafficPoller = new WifiTrafficPoller(mContext, mInterfaceName);  
  6.     //創建wifi狀態機  
  7.     mWifiStateMachine = new WifiStateMachine(mContext, mInterfaceName, mTrafficPoller);  
  8.     mWifiStateMachine.enableRssiPolling(true);  
  9.     //初始化各種管理者  
  10.     mBatteryStats = BatteryStatsService.getService();  
  11.     mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);  
  12.     mNotificationController = new WifiNotificationController(mContext, mWifiStateMachine);  
  13.     mSettingsStore = new WifiSettingsStore(mContext);  
  14.     HandlerThread wifiThread = new HandlerThread("WifiService");  
  15.     wifiThread.start();  
  16.     mClientHandler = new ClientHandler(wifiThread.getLooper());  
  17.     mWifiStateMachineHandler = new WifiStateMachineHandler(wifiThread.getLooper());  
  18.     mWifiController = new WifiController(mContext, this, wifiThread.getLooper());  
  19.     mBatchedScanSupported = mContext.getResources().getBoolean( R.bool.config_wifi_batched_scan_supported);  
  20. }  
        在這裏初始化各種與WIFI管理有關的輔助類,其中包含最重要的一個就是WIFI的狀態機WifiStateMachine,他是整個WIFI機制的核心。下面來看該狀態機的初始化流程:
[java] view plain copy
  1. @WifiStateMachine.java  
  2. public WifiStateMachine(Context context, String wlanInterface, WifiTrafficPoller trafficPoller){  
  3.     super("WifiStateMachine");  
  4.     mContext = context;  
  5.     mInterfaceName = wlanInterface;  
  6.     //創建NetworkInfo對象  
  7.     mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, NETWORKTYPE, "");  
  8.     mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService( BatteryStats.SERVICE_NAME));  
  9.     //創建各種輔助類  
  10.     IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);  
  11.     mNwService = INetworkManagementService.Stub.asInterface(b);  
  12.     mP2pSupported = mContext.getPackageManager().hasSystemFeature( PackageManager.FEATURE_WIFI_DIRECT);  
  13.     mWifiNative = new WifiNative(mInterfaceName);  
  14.     mWifiConfigStore = new WifiConfigStore(context, mWifiNative);  
  15.     mWifiAutoJoinController = new WifiAutoJoinController(context, this, mWifiConfigStore, mWifiConnectionStatistics, mWifiNative);  
  16.     mWifiMonitor = new WifiMonitor(this, mWifiNative);  
  17.     mWifiInfo = new WifiInfo();  
  18.     ......  
  19.     //初始化狀態機  
  20.     addState(mDefaultState);  
  21.     addState(mInitialState, mDefaultState);  
  22.     addState(mSupplicantStartingState, mDefaultState);  
  23.     addState(mSupplicantStartedState, mDefaultState);  
  24.     addState(mDriverStartingState, mSupplicantStartedState);  
  25.     addState(mDriverStartedState, mSupplicantStartedState);  
  26.     addState(mScanModeState, mDriverStartedState);  
  27.     addState(mConnectModeState, mDriverStartedState);  
  28.     addState(mL2ConnectedState, mConnectModeState);  
  29.     addState(mObtainingIpState, mL2ConnectedState);  
  30.     addState(mVerifyingLinkState, mL2ConnectedState);  
  31.     addState(mConnectedState, mL2ConnectedState);  
  32.     addState(mRoamingState, mL2ConnectedState);  
  33.     addState(mDisconnectingState, mConnectModeState);  
  34.     addState(mDisconnectedState, mConnectModeState);  
  35.     addState(mWpsRunningState, mConnectModeState);  
  36.     addState(mWaitForP2pDisableState, mSupplicantStartedState);  
  37.     addState(mDriverStoppingState, mSupplicantStartedState);  
  38.     addState(mDriverStoppedState, mSupplicantStartedState);  
  39.     addState(mSupplicantStoppingState, mDefaultState);  
  40.     addState(mSoftApStartingState, mDefaultState);  
  41.     addState(mSoftApStartedState, mDefaultState);  
  42.     addState(mTetheringState, mSoftApStartedState);  
  43.     addState(mTetheredState, mSoftApStartedState);  
  44.     addState(mUntetheringState, mSoftApStartedState);  
  45.     //設置狀態機初始模式  
  46.     setInitialState(mInitialState);  
  47.     //啓動狀態機  
  48.     start();  
  49.     ......  
  50. }  
        我們看到,在WifiStateMachine的初始化過程中創建了大量的輔助類,其中就包括NetworkInfo,他的作用就是標記當前網絡的各項屬性,比如當前網絡的類型、是否可用、是否處於漫遊等,然後還創建了許多WIFI的狀態機,標識當前WIFI所處的狀態,最後將狀態機初始狀態設置爲mInitialState,並將狀態機start。
        以上就是WifiService的全部初始化過程,其主要過程分爲以下四個部分:
        1、在SystemServer中啓動WifiService;
        2、在WifiService啓動過程中創建並初始化WifiServiceImpl;
        3、在WifiServiceImpl初始化過程中創建並初始化WifiStateMachine對象;

        4、在WifiStateMachine初始化過程中創建各種狀態機並啓動他們;


1.2、WifiManager的初始化流程


        WIFI框架還有另外一個初始化流程實在ContextImpl中進行的。
        當系統初始化時,會在Context對象的實現類ContextImpl中註冊一些常用的服務,這樣就可以在應用內部通過Context對象的getSystemService()方法來獲取相應的服務。而WIFI在ContextImpl中註冊了WifiManager用於向一般應用提供WIFI的服務:
[java] view plain copy
  1. @ContextImpl.java  
  2. registerService(WIFI_SERVICE, new ServiceFetcher() {  
  3.     public Object createService(ContextImpl ctx) {  
  4.         IBinder b = ServiceManager.getService(WIFI_SERVICE);  
  5.         IWifiManager service = IWifiManager.Stub.asInterface(b);  
  6.         return new WifiManager(ctx.getOuterContext(), service);  
  7.     }});  
        從這裏可以知道兩個信息:
        1、應用可以通過Context對象的getSystemService(Context.WIFI_SERVICE)的方法獲取到一個WifiManager的對象用於控制WIFI;
        2、WifiManager的創建需要使用ServiceManager的WIFI_SERVICE服務,而這個WIFI_SERVICE就是在WifiService中註冊的WifiServiceImpl對象;

        下面來看WifiManager的創建過程:
[java] view plain copy
  1. @WifiManager.java  
  2. public WifiManager(Context context, IWifiManager service) {  
  3.     mContext = context;  
  4.     //這裏的mService就是創建WifiManager時傳遞進來的WifiServiceImpl對象  
  5.     mService = service;  
  6.     init();  
  7. }  
  8. private void init() {  
  9.     synchronized (sThreadRefLock) {  
  10.         if (++sThreadRefCount == 1) {  
  11.             //獲取WifiServiceImpl中的Messenger對象  
  12.             Messenger messenger = getWifiServiceMessenger();  
  13.             if (messenger == null) {  
  14.                 sAsyncChannel = null;  
  15.                 return;  
  16.             }  
  17.             //創建AsyncChannel通道  
  18.             sHandlerThread = new HandlerThread("WifiManager");  
  19.             sAsyncChannel = new AsyncChannel();  
  20.             sConnected = new CountDownLatch(1);  
  21.             sHandlerThread.start();  
  22.             Handler handler = new ServiceHandler(sHandlerThread.getLooper());  
  23.             //與WifiServiceImpl申請建立單向AsyncChannel  
  24.             sAsyncChannel.connect(mContext, handler, messenger);  
  25.             try {  
  26.                 sConnected.await();  
  27.             } catch (InterruptedException e) {  
  28.                 Log.e(TAG, "interrupted wait at init");  
  29.             }  
  30.         }  
  31.     }  
  32. }  
        從上面WifiManager的初始化過程中我們看到,其初始化的過程中完成了以下兩個任務:
        1、用WifiServiceImpl初始化mService對象;
        2、向WifiServiceImpl申請單向的AsyncChannel(想要連接AsyncChannel請點擊這裏);

        至此,WIFI框架就完成了所有需要初始化的動作,我們用一張流程圖來標識該過程:



二、WIFI服務的運作機制


        由於應用操作WIFI是通過WifiManager進行的,那麼我們可以從WifiManager開始來查找消息在WIFI內部的傳遞機制。
        以下是WifiManager提供的幾個比較重要的對外接口:
[java] view plain copy
  1. //獲取所有網絡連接  
  2. public List<WifiConfiguration> getConfiguredNetworks() {}  
  3. //添加網絡連接  
  4. public int addNetwork(WifiConfiguration config) {}  
  5. //更新網絡連接  
  6. public int updateNetwork(WifiConfiguration config) {}  
  7. //是否支持5Ghz  
  8. public boolean is5GHzBandSupported() {}  
  9. //是否支持WIFI熱點  
  10. public boolean isPortableHotspotSupported() {}  
  11. //打開關閉WIFI  
  12. public boolean setWifiEnabled(boolean enabled) {}  
  13. //連接某個WIFI  
  14. public void connect(int networkId, ActionListener listener) {}  
  15. //斷開當前連接  
  16. public boolean disconnect() {}  
  17. //添加黑名單  
  18. public boolean addToBlacklist(String bssid) {}  
  19. //清除黑名單  
  20. public boolean clearBlacklist() {}  
        我們挑選兩個比較典型的方法進行跟蹤,分別是:控制WIFI開關的setWifiEnabled()和連接某個WIFI的connect()方法。

        爲什麼要挑選這兩個方法呢?是因爲這兩個方法分別使用兩種方式與WifiService進行通訊


2.1、setWifiEnabled方式


        在該方式中,WifiManager通過直接調用的方式與WifiServiceImpl進行通訊。
[java] view plain copy
  1. @WifiManager.java  
  2. public boolean setWifiEnabled(boolean enabled) {  
  3.     try {  
  4.         //直接調用mService的setWifiEnabled方法  
  5.         return mService.setWifiEnabled(enabled);  
  6.     } catch (RemoteException e) {  
  7.         return false;  
  8.     }  
  9. }  


2.2、connect方式


        與setWifiEnabled不同,在該方式中,WifiManager利用與WifiServiceImpl之間的AsyncChannel來交換信息
[java] view plain copy
  1. @WifiManager.java  
  2. public void connect(int networkId, ActionListener listener) {  
  3.     if (networkId < 0throw new IllegalArgumentException("Network id cannot be negative");  
  4.     validateChannel();  
  5.     //通過AsyncChannel與WifiServiceImpl傳遞信息  
  6.     sAsyncChannel.sendMessage(CONNECT_NETWORK, networkId, putListener(listener));  
  7. }  


2.3、WifiManager小結


        在上面兩節中分別介紹了兩種WifiManager與WifiServiceImpl通訊的方式,其實不僅是以上兩個方法,WifiManager中所有的對外公開的public方法,最終都是通過這兩種方式與WifiServiceImpl進行溝通

        我們可以這樣理解WifiManager:他是WIFI模塊向外部應用透漏出來的接口,其他所有應用都可以通過WifiManager操作WIFI各項功能,但是WifiManager本身並不具備處理請求的能力,而是把所有請求轉發給WifiServiceImpl對象,而發送請求的方式就是直接調用或者通過AsyncChannel。


2.4、WifiServiceImpl中對請求的處理


        無論採用何種溝通方式,WifiManager最終都會把應用的請求轉交給WifiServiceImpl來處理。那麼接下來的流程是怎樣的呢?WifiServiceImpl將會如何處理WifiManager轉發過來的請求呢?
        我們繼續跟蹤上面兩個方法的調用流程來查看WifiServiceImpl的處理過程。
        先來看setWifiEnabled()方法,該方法是直接由WifiManager調用到WifiServiceImpl中的,其實現如下:
[java] view plain copy
  1. @WifiServiceImpl.java  
  2. public synchronized boolean setWifiEnabled(boolean enable) {  
  3.     //權限檢查  
  4.     enforceChangePermission();  
  5.   
  6.   
  7.     //權限檢查  
  8.     long ident = Binder.clearCallingIdentity();  
  9.     try {  
  10.         if (! mSettingsStore.handleWifiToggled(enable)) {  
  11.             return true;  
  12.         }  
  13.     } finally {  
  14.         Binder.restoreCallingIdentity(ident);  
  15.     }  
  16.     //向WifiController發送請求  
  17.     mWifiController.sendMessage(CMD_WIFI_TOGGLED);  
  18.     return true;  
  19. }  
        在這裏我們看到,WifiServiceImpl將請求轉交給WifiController來處理。
        下面來看WifiManager中connect()方法的處理,當初WifiManager收到該請求後,通過AsyncChannel的方式向WifiServiceImpl發送CONNECT_NETWORK的請求,那麼WifiServiceImpl的接下來就需要在自己的Messenger中處理,而這個Messenger是從getWifiServiceMessenger()中傳遞給WifiManager的,我們來看是哪個Messenger來處理該請求:
[java] view plain copy
  1. @WifiServiceImpl.java  
  2. public Messenger getWifiServiceMessenger() {  
  3.     //權限檢查  
  4.     enforceAccessPermission();  
  5.     enforceChangePermission();  
  6.     //這裏的Messenger的Handler是mClientHandler  
  7.     return new Messenger(mClientHandler);  
  8. }  
        從這裏看到,WifiManager拿到的Messenger中的Handler其實就是mClientHandler,他是在WifiServiceImpl初始化時被創建的:
[java] view plain copy
  1. @WifiServiceImpl.java  
  2. public WifiServiceImpl(Context context) {  
  3.     ......  
  4.     HandlerThread wifiThread = new HandlerThread("WifiService");  
  5.     wifiThread.start();  
  6.     mClientHandler = new ClientHandler(wifiThread.getLooper());  
  7. }  
        也就是說WifiManager通過AsyncChannel發送的消息都會在ClientHandler中接收到:
[java] view plain copy
  1. private class ClientHandler extends Handler {  
  2.     ClientHandler(android.os.Looper looper) {  
  3.         super(looper);  
  4.     }  
  5.     @Override  
  6.     public void handleMessage(Message msg) {  
  7.         switch (msg.what) {  
  8.             case WifiManager.CONNECT_NETWORK:  
  9.             case WifiManager.SAVE_NETWORK: {  
  10.                WifiConfiguration config = (WifiConfiguration) msg.obj;  
  11.                int networkId = msg.arg1;  
  12.                if (msg.what == WifiManager.SAVE_NETWORK) {  
  13.                }  
  14.                if (msg.what == WifiManager.CONNECT_NETWORK) {  
  15.                    if (config != null) {  
  16.                        //配置config  
  17.                        if (config.networkId == WifiConfiguration.INVALID_NETWORK_ID) {  
  18.                            config.creatorUid = Binder.getCallingUid();  
  19.                        } else {  
  20.                            config.lastUpdateUid = Binder.getCallingUid();  
  21.                        }  
  22.                    }  
  23.                }  
  24.                if (config != null && config.isValid()) {  
  25.                    //將請求發送給WifiStateMachine  
  26.                    mWifiStateMachine.sendMessage(Message.obtain(msg));  
  27.                } else if (config == null && networkId != WifiConfiguration.INVALID_NETWORK_ID) {  
  28.                    mWifiStateMachine.sendMessage(Message.obtain(msg));  
  29.                } else {  
  30.                    if (msg.what == WifiManager.CONNECT_NETWORK) {  
  31.                        replyFailed(msg, WifiManager.CONNECT_NETWORK_FAILED, WifiManager.INVALID_ARGS);  
  32.                    } else {  
  33.                        replyFailed(msg, WifiManager.SAVE_NETWORK_FAILED, WifiManager.INVALID_ARGS);  
  34.                    }  
  35.                }  
  36.                break;  
  37.            }  
  38.         }  
  39.     }  
  40. }  
        從上面這個處理來看,WifiServiceImpl將請求轉交給WifiStateMachine來處理。
        其實WifiServiceImpl對請求的處理與WifiManager類似,他本身並不具備處理事物的能力,只是將請求分類後交由不同的處理者去處理
        以上就是整個WIFI框架的初始化以及內部消息處理機制,下面用一張圖來標識WIFI內部的消息流:
        

發佈了4 篇原創文章 · 獲贊 7 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章