Wifi服务框架介绍

来源:互联网 发布:旅游网站cms 编辑:程序博客网 时间:2024/04/28 06:47

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内部的消息流:
        

0 0
原创粉丝点击