Wifi服务框架介绍(原)

原创 2015年09月08日 15:09:45
        本文简要介绍WIFI服务的主要框架以及运作机制

        WIFI框架主要涉及到以下几个对象:WifiService、WifiManager、WifiServiceImpl、WifiStateMachine等。下面来介绍这四个对象的内在联系。


一、WIFI服务的初始化


        WIFI服务的初始化分为两个部分,WifiService的初始化和WifiManager的初始化,下面分别介绍。


1.1、WifiService的初始化流程


        WifiService的初始化流程是在SystemService中被启动的:
        @SystemServer.java
        private static final String WIFI_SERVICE_CLASS = "com.android.server.wifi.WifiService";
        private void startOtherServices() {
            mSystemServiceManager.startService(WIFI_SERVICE_CLASS);
        }
        在这里通过SystemServiceManager将WIFI的主服务(WifiService)启动,然后来看该Service的启动过程:
        @WifiService.java
        public final class WifiService extends SystemService {
            private static final String TAG = "WifiService";
            final WifiServiceImpl mImpl;
            public WifiService(Context context) {
                super(context);
                //创建WifiServiceImpl对象
                mImpl = new WifiServiceImpl(context);
            }
            @Override
            public void onStart() {
                //将WifiServiceImpl注册到ServiceManager
                publishBinderService(Context.WIFI_SERVICE, mImpl);
            }


            @Override
            public void onBootPhase(int phase) {
                if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
                    mImpl.checkAndStartWifi();
                }
            }
        }
        以上是WifiService的全部内容,其实该Service只完成了两个任务:
        1、在初始化时,也就是构造方法中,创建WifiServiceImpl对象。
        2、在onStart时,将WifiServiceImpl对象注册到ServiceManager中。

        这里创建的WifiServiceImpl是整个WIFI服务的管理者,他负责将客户端对WIFI的请求分类,然后派发给不同的处理中心。
        下面先来看WifiServiceImpl的属性:
        public final class WifiServiceImpl extends IWifiManager.Stub {}
        这说明该类是一个服务的实现类。
        然后来看该对象的初始化过程,也就是构造方法:
        @WifiServiceImpl.java
        public WifiServiceImpl(Context context) {
            mContext = context;
            mInterfaceName =  SystemProperties.get("wifi.interface", "wlan0");
            mTrafficPoller = new WifiTrafficPoller(mContext, mInterfaceName);
            //创建wifi状态机
            mWifiStateMachine = new WifiStateMachine(mContext, mInterfaceName, mTrafficPoller);
            mWifiStateMachine.enableRssiPolling(true);
            //初始化各种管理者
            mBatteryStats = BatteryStatsService.getService();
            mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
            mNotificationController = new WifiNotificationController(mContext, mWifiStateMachine);
            mSettingsStore = new WifiSettingsStore(mContext);
            HandlerThread wifiThread = new HandlerThread("WifiService");
            wifiThread.start();
            mClientHandler = new ClientHandler(wifiThread.getLooper());
            mWifiStateMachineHandler = new WifiStateMachineHandler(wifiThread.getLooper());
            mWifiController = new WifiController(mContext, this, wifiThread.getLooper());
            mBatchedScanSupported = mContext.getResources().getBoolean( R.bool.config_wifi_batched_scan_supported);
        }
        在这里初始化各种与WIFI管理有关的辅助类,其中包含最重要的一个就是WIFI的状态机WifiStateMachine,他是整个WIFI机制的核心。下面来看该状态机的初始化流程:
        @WifiStateMachine.java
        public WifiStateMachine(Context context, String wlanInterface, WifiTrafficPoller trafficPoller){
            super("WifiStateMachine");
            mContext = context;
            mInterfaceName = wlanInterface;
            //创建NetworkInfo对象
            mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, NETWORKTYPE, "");
            mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService( BatteryStats.SERVICE_NAME));
            //创建各种辅助类
            IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
            mNwService = INetworkManagementService.Stub.asInterface(b);
            mP2pSupported = mContext.getPackageManager().hasSystemFeature( PackageManager.FEATURE_WIFI_DIRECT);
            mWifiNative = new WifiNative(mInterfaceName);
            mWifiConfigStore = new WifiConfigStore(context, mWifiNative);
            mWifiAutoJoinController = new WifiAutoJoinController(context, this, mWifiConfigStore, mWifiConnectionStatistics, mWifiNative);
            mWifiMonitor = new WifiMonitor(this, mWifiNative);
            mWifiInfo = new WifiInfo();
            ......
            //初始化状态机
            addState(mDefaultState);
            addState(mInitialState, mDefaultState);
            addState(mSupplicantStartingState, mDefaultState);
            addState(mSupplicantStartedState, mDefaultState);
            addState(mDriverStartingState, mSupplicantStartedState);
            addState(mDriverStartedState, mSupplicantStartedState);
            addState(mScanModeState, mDriverStartedState);
            addState(mConnectModeState, mDriverStartedState);
            addState(mL2ConnectedState, mConnectModeState);
            addState(mObtainingIpState, mL2ConnectedState);
            addState(mVerifyingLinkState, mL2ConnectedState);
            addState(mConnectedState, mL2ConnectedState);
            addState(mRoamingState, mL2ConnectedState);
            addState(mDisconnectingState, mConnectModeState);
            addState(mDisconnectedState, mConnectModeState);
            addState(mWpsRunningState, mConnectModeState);
            addState(mWaitForP2pDisableState, mSupplicantStartedState);
            addState(mDriverStoppingState, mSupplicantStartedState);
            addState(mDriverStoppedState, mSupplicantStartedState);
            addState(mSupplicantStoppingState, mDefaultState);
            addState(mSoftApStartingState, mDefaultState);
            addState(mSoftApStartedState, mDefaultState);
            addState(mTetheringState, mSoftApStartedState);
            addState(mTetheredState, mSoftApStartedState);
            addState(mUntetheringState, mSoftApStartedState);
            //设置状态机初始模式
            setInitialState(mInitialState);
            //启动状态机
            start();
            ......
        }
        我们看到,在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的服务:
        @ContextImpl.java
        registerService(WIFI_SERVICE, new ServiceFetcher() {
            public Object createService(ContextImpl ctx) {
                IBinder b = ServiceManager.getService(WIFI_SERVICE);
                IWifiManager service = IWifiManager.Stub.asInterface(b);
                return new WifiManager(ctx.getOuterContext(), service);
            }});
        从这里可以知道两个信息:
        1、应用可以通过Context对象的getSystemService(Context.WIFI_SERVICE)的方法获取到一个WifiManager的对象用于控制WIFI;
        2、WifiManager的创建需要使用ServiceManager的WIFI_SERVICE服务,而这个WIFI_SERVICE就是在WifiService中注册的WifiServiceImpl对象;

        下面来看WifiManager的创建过程:
        @WifiManager.java
        public WifiManager(Context context, IWifiManager service) {
            mContext = context;
            //这里的mService就是创建WifiManager时传递进来的WifiServiceImpl对象
            mService = service;
            init();
        }
        private void init() {
            synchronized (sThreadRefLock) {
                if (++sThreadRefCount == 1) {
                    //获取WifiServiceImpl中的Messenger对象
                    Messenger messenger = getWifiServiceMessenger();
                    if (messenger == null) {
                        sAsyncChannel = null;
                        return;
                    }
                    //创建AsyncChannel通道
                    sHandlerThread = new HandlerThread("WifiManager");
                    sAsyncChannel = new AsyncChannel();
                    sConnected = new CountDownLatch(1);
                    sHandlerThread.start();
                    Handler handler = new ServiceHandler(sHandlerThread.getLooper());
                    //与WifiServiceImpl申请建立单向AsyncChannel
                    sAsyncChannel.connect(mContext, handler, messenger);
                    try {
                        sConnected.await();
                    } catch (InterruptedException e) {
                        Log.e(TAG, "interrupted wait at init");
                    }
                }
            }
        }
        从上面WifiManager的初始化过程中我们看到,其初始化的过程中完成了以下两个任务:
        1、用WifiServiceImpl初始化mService对象;
        2、向WifiServiceImpl申请单向的AsyncChannel(想要连接AsyncChannel请点击这里);

        至此,WIFI框架就完成了所有需要初始化的动作,我们用一张流程图来标识该过程:



二、WIFI服务的运作机制


        由于应用操作WIFI是通过WifiManager进行的,那么我们可以从WifiManager开始来查找消息在WIFI内部的传递机制。
        以下是WifiManager提供的几个比较重要的对外接口:
        //获取所有网络连接
        public List<WifiConfiguration> getConfiguredNetworks() {}
        //添加网络连接
        public int addNetwork(WifiConfiguration config) {}
        //更新网络连接
        public int updateNetwork(WifiConfiguration config) {}
        //是否支持5Ghz
        public boolean is5GHzBandSupported() {}
        //是否支持WIFI热点
        public boolean isPortableHotspotSupported() {}
        //打开关闭WIFI
        public boolean setWifiEnabled(boolean enabled) {}
        //连接某个WIFI
        public void connect(int networkId, ActionListener listener) {}
        //断开当前连接
        public boolean disconnect() {}
        //添加黑名单
        public boolean addToBlacklist(String bssid) {}
        //清除黑名单
        public boolean clearBlacklist() {}
        我们挑选两个比较典型的方法进行跟踪,分别是:控制WIFI开关的setWifiEnabled()和连接某个WIFI的connect()方法。

        为什么要挑选这两个方法呢?是因为这两个方法分别使用两种方式与WifiService进行通讯


2.1、setWifiEnabled方式


        在该方式中,WifiManager通过直接调用的方式与WifiServiceImpl进行通讯。
        @WifiManager.java
        public boolean setWifiEnabled(boolean enabled) {
            try {
                //直接调用mService的setWifiEnabled方法
                return mService.setWifiEnabled(enabled);
            } catch (RemoteException e) {
                return false;
            }
        }


2.2、connect方式


        与setWifiEnabled不同,在该方式中,WifiManager利用与WifiServiceImpl之间的AsyncChannel来交换信息
        @WifiManager.java
        public void connect(int networkId, ActionListener listener) {
            if (networkId < 0) throw new IllegalArgumentException("Network id cannot be negative");
            validateChannel();
            //通过AsyncChannel与WifiServiceImpl传递信息
            sAsyncChannel.sendMessage(CONNECT_NETWORK, networkId, putListener(listener));
        }


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中的,其实现如下:
        @WifiServiceImpl.java
        public synchronized boolean setWifiEnabled(boolean enable) {
            //权限检查
            enforceChangePermission();


            //权限检查
            long ident = Binder.clearCallingIdentity();
            try {
                if (! mSettingsStore.handleWifiToggled(enable)) {
                    return true;
                }
            } finally {
                Binder.restoreCallingIdentity(ident);
            }
            //向WifiController发送请求
            mWifiController.sendMessage(CMD_WIFI_TOGGLED);
            return true;
        }
        在这里我们看到,WifiServiceImpl将请求转交给WifiController来处理。
        下面来看WifiManager中connect()方法的处理,当初WifiManager收到该请求后,通过AsyncChannel的方式向WifiServiceImpl发送CONNECT_NETWORK的请求,那么WifiServiceImpl的接下来就需要在自己的Messenger中处理,而这个Messenger是从getWifiServiceMessenger()中传递给WifiManager的,我们来看是哪个Messenger来处理该请求:
        @WifiServiceImpl.java
        public Messenger getWifiServiceMessenger() {
            //权限检查
            enforceAccessPermission();
            enforceChangePermission();
            //这里的Messenger的Handler是mClientHandler
            return new Messenger(mClientHandler);
        }
        从这里看到,WifiManager拿到的Messenger中的Handler其实就是mClientHandler,他是在WifiServiceImpl初始化时被创建的:
        @WifiServiceImpl.java
        public WifiServiceImpl(Context context) {
            ......
            HandlerThread wifiThread = new HandlerThread("WifiService");
            wifiThread.start();
            mClientHandler = new ClientHandler(wifiThread.getLooper());
        }
        也就是说WifiManager通过AsyncChannel发送的消息都会在ClientHandler中接收到:
        private class ClientHandler extends Handler {
            ClientHandler(android.os.Looper looper) {
                super(looper);
            }
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case WifiManager.CONNECT_NETWORK:
                    case WifiManager.SAVE_NETWORK: {
                       WifiConfiguration config = (WifiConfiguration) msg.obj;
                       int networkId = msg.arg1;
                       if (msg.what == WifiManager.SAVE_NETWORK) {
                       }
                       if (msg.what == WifiManager.CONNECT_NETWORK) {
                           if (config != null) {
                               //配置config
                               if (config.networkId == WifiConfiguration.INVALID_NETWORK_ID) {
                                   config.creatorUid = Binder.getCallingUid();
                               } else {
                                   config.lastUpdateUid = Binder.getCallingUid();
                               }
                           }
                       }
                       if (config != null && config.isValid()) {
                           //将请求发送给WifiStateMachine
                           mWifiStateMachine.sendMessage(Message.obtain(msg));
                       } else if (config == null && networkId != WifiConfiguration.INVALID_NETWORK_ID) {
                           mWifiStateMachine.sendMessage(Message.obtain(msg));
                       } else {
                           if (msg.what == WifiManager.CONNECT_NETWORK) {
                               replyFailed(msg, WifiManager.CONNECT_NETWORK_FAILED, WifiManager.INVALID_ARGS);
                           } else {
                               replyFailed(msg, WifiManager.SAVE_NETWORK_FAILED, WifiManager.INVALID_ARGS);
                           }
                       }
                       break;
                   }
                }
            }
        }
        从上面这个处理来看,WifiServiceImpl将请求转交给WifiStateMachine来处理。
        其实WifiServiceImpl对请求的处理与WifiManager类似,他本身并不具备处理事物的能力,只是将请求分类后交由不同的处理者去处理
        以上就是整个WIFI框架的初始化以及内部消息处理机制,下面用一张图来标识WIFI内部的消息流:
        
版权声明:本文为博主原创文章,未经博主允许不得转载。

WifiManager详解

最近项目中用到了wifi模块,今天做一个简单的总结。 1.怎样获取wifi对象并进行操作 要操作WIFI设备,需要先获取Context.getSystemService(Context.W...

使用WifiManager服务进行wifi相关设置实现

安卓API中提供了wifi的使用接口,在android.net.wifi包中。 既然使用了安卓系统接口,相关权限肯定少不了: 主要使用WifiManager类中提供的接口,因为Wif...

WifiManager详解-wifi连接状态的监听

1.XML中声明                                                                              ...

WifiManager类详解

Calculates the level of the signal. This should be used any time a signal is being shown. 参数 rssi T...

连接到指定wifi——WIFIManager

定义工具类: public class WifiAdmin {      // 定义WifiManager对象      private WifiManager mWifiManager; ...

Android WiFi开发 (一)扫描、连接、信息

在平常开发中经常会涉及到wifi相关的内容,在此将之前所用到的整理一下,以免忘记。 操作wifi的相关类,主要放在android.net.wifi包下面。使用wifi相关方法需要申请一些权限:   A...

Android WiFi功能实现,知其然必知其所以然! (二)

终于吧WiFi功能搞定了,前后历时半个多月的时间。进度有些慢。但还是很充实的,搞定一个自己面临的难题时,那种豁然开朗的感觉,让人神清气爽。要不是在公司上班时间,真想大吼一声!“咱老百姓啊,今儿个真高兴...

wifiManager的使用

/** *  */package com.FengWo.activity;  import android.app.Activity;import android.content.Context;im...

《深入理解Android:Wi-Fi,NFC和GPS》章节连载[节选]--第五章 深入理解WifiService

首先感谢各位兄弟姐妹们的耐心等待。本书预计在3月中旬上市发售。从今天开始,我将在博客中连载此书的一些内容。注意,此处连载的是未经出版社编辑的原始稿件,所以样子会有些非专业。注意,如下是本章目录,本文节...
  • Innost
  • Innost
  • 2014年03月16日 15:59
  • 17538

Android WIFI框架分析(1)

趁做Android WIFI驱动移植,对Android WIFI框架做了深刻的分析,并做此文档共同学习。        对上层WIFI的应用,基本流程为:(1)WIFI初始化  (2)Wifi启动 ...
  • yicao821
  • yicao821
  • 2011年10月21日 20:51
  • 14986
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Wifi服务框架介绍(原)
举报原因:
原因补充:

(最多只允许输入30个字)