本文简要介绍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内部的消息流: