一直在做WiFi蓝牙底层的东西,但是不可避免的也要跟Android的Framework和Apps打交道,这几天有点空,顺便整理一下。
先写一篇分析关于Android WiFi framework的吧.文档格式借鉴了邓凡平<<深入理解Android>>系列。关于HSM,Handler和AsyncChannel的介绍详见邓凡平<<深入理解Android WiFi, NFC和GPS卷>>
WifiP2p,WifiDisplay和SoftAP将另行分析
-
源文件名及位置
./frameworks/base/services/java/com/android/server/SystemServer.java
./framework/base/core/java/android/app/ContextImpl.java
./out/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/wifi/java/android/net/wifi/IWifiManager.java
./framework/base/wifi/java/android/net/wifi/WifiManager.java
./framework/base/services/java/com/android/server/wifi/WifiService.java
./framework/base/wifi/java/android/net/wifi/WifiStateMachine.java
./packages/apps/Settings/src/com/android/settings/wifi/WifiEnabler.java
-
应用程序如何访问WiFi API:
[-->WifiEnabler.java:: WifiEnabler]
应用程序得到的WiFi_SERVICE是什么东西呢?其实为IWifiManager.Stub.Proxy对象,下面将详细分析。
publicWifiEnabler(Context context, Switch switch_) {
mWifiManager= (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
}
[-->SystermServer.java:: initAndLoop]
public void initAndLoop() {
wifiP2p = new WifiP2pService(context);
ServiceManager.addService(Context.WIFI_P2P_SERVICE,wifiP2p);
wifi = new WifiService(context);//IWifiManager.Stub
/*注意这个WIFI_SERVICE不是应用程序用到的那个哦!*/
ServiceManager.addService(Context.WIFI_SERVICE,wifi);
}
[-->ContextImpl.java::ContextImpl]
class ContextImpl extends Context {
/*static代码块,比构造器里面的语句执行的还要早。和static变量同时被初始化,
然后再去执行构造器里的语句*/
static {
/*注册WifiManager, WifiManager通过binder调用WifiService*/
registerService(WIFI_SERVICE, newServiceFetcher() {
publicObject createService(ContextImpl ctx) {
/*得到WifiService实例*/
IBinderb = ServiceManager.getService(WIFI_SERVICE);
/*实际为IWifiManager.Stub.Proxy对象*/
IWifiManagerservice = IWifiManager.Stub.asInterface(b);
return new WifiManager(ctx.getOuterContext(),service);
}});
registerService(WIFI_P2P_SERVICE, newServiceFetcher() {
publicObject createService(ContextImpl ctx) {
IBinderb = ServiceManager.getService(WIFI_P2P_SERVICE);
IWifiP2pManagerservice = IWifiP2pManager.Stub.asInterface(b);
return new WifiP2pManager(service);
}});
}
}
[-->IwifiManager.java::IWifiManager.Stub.asInterface]
/*通过IWifiManager.Stub.asInterface()从IBinder转换到IWifiManager*/
public static android.net.wifi.IWifiManagerasInterface(android.os.IBinder obj)
{
/*通过比较descriptor判断是不是在当前进程中,如果在当前进程中是不需要binder IPC的*/
android.os.IInterface iin =obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceofandroid.net.wifi.IWifiManager))) {
return ((android.net.wifi.IWifiManager)iin);
}
return new android.net.wifi.IWifiManager.Stub.Proxy(obj);
}
-
Wifi framework类图
图中加了enableNetwork这个功能的调用,调用过程还是很清晰的,所以就不画sequence图了
-
从WifiManager(应用程序API)到WifiNative(调用WiFiJNI的入口)的调用过程,关键代码分析。
[-->WifiManager.java:: WifiManager]
public class WifiManager {
IWifiManager mService;
private static AsyncChannel sAsyncChannel;
public WifiManager(Context context, IWifiManagerservice) {
mContext = context;
mService = service; //IWifiManager.Stub.Proxy实例
/*建立WifiManager和WifiService之间的Handler的连接,
见下面对init()的分析*/
init();
}
/* 得到WifiService的handler,以便WifiManager sAsyncChannel
和WifiService通讯*/
public Messenger getWifiServiceMessenger() {
returnmService.getWifiServiceMessenger();
}
private void init() {
Messengermessenger = getWifiServiceMessenger();
sHandlerThread = new HandlerThread("WifiManager");
sAsyncChannel = new AsyncChannel();
sHandlerThread.start();
Handler handler = new ServiceHandler(sHandlerThread.getLooper());
/*在handler(WifiManager Handler)和messenger(WifiService Handler)
之间建立连接,sAsyncChannel可以理解一个连接的实例,
WifiManager将通过它给WifiService发消息*/
sAsyncChannel.connect(mContext,handler,messenger);
}
}
/*下面两个函数作为WifiManager向应用程序提供API的例子: 1.直接调用 IWifiManager API 或者 2. 给WifiService发消息(WifiService需要给WifiStateMachine发消息来实际处理来自WifiManager的消息)
[-->WifiManager.java::getConfiguredNetworks]
//API for applications
public List<WifiConfiguration> getConfiguredNetworks(){
returnmService.getConfiguredNetworks(); //直接调用Proxy接口
}
[-->WifiManager.java:: connect]
public void connect(int networkId,ActionListener listener) {
/*通过给WifiService发消息,开始Wifi连接*/
sAsyncChannel.sendMessage(CONNECT_NETWORK, networkId, putListener(listener));
}
}
WifiService的处理流程:
[-->WifiService.java::WifiService]
public final class WifiService extendsIWifiManager.Stub {
final WifiStateMachine mWifiStateMachine;
/*负责和WifiStateMachine handler通讯的Channel*/
private AsyncChannelmWifiStateMachineChannel;
private class WifiStateMachineHandler extendsHandler {
private AsyncChannel mWsmChannel;
WifiStateMachineHandler(android.os.Looperlooper) {
super(looper);
mWsmChannel = new AsyncChannel();
/*mWifiStateMachine.getHandler()调用的为WifiStateMachine
基类StateMachine的getHandler() */
mWsmChannel.connect(mContext, this,mWifiStateMachine.getHandler());
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
caseAsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
/*mWifiStateMachineChannel作为WifiService向WifiStateMachine
发消息的连接实例*/
mWifiStateMachineChannel= mWsmChannel;
break;
}
caseAsyncChannel.CMD_CHANNEL_DISCONNECTED: {
//Re-establish connectionto state machine
mWsmChannel.connect(mContext, this, mWifiStateMachine.getHandler());
break;
}
default: {
Slog.d(TAG,"WifiStateMachineHandler.handleMessage ignoring msg=" + msg);
break;
}
}
}
}
}
WifiStateMachineHandlermWifiStateMachineHandler;
private class ClientHandler extends Handler{
@Override
public void handleMessage(Message msg) {
switch(msg.what) {
/*Client commands are forwarded to state machine */
case WifiManager.CONNECT_NETWORK:
case WifiManager.SAVE_NETWORK: {
WifiConfigurationconfig = (WifiConfiguration) msg.obj;
intnetworkId = msg.arg1;
if(config != null && config.isValid()) {
if (config.proxySettings != ProxySettings.PAC) {
/*WifiService将CONNECT_NETWORK发送给WifiStateMachine
处理:调用WifiStateMachine基类的sendMessage()将消息发
给WifiStateMachine自己的消息队列*/
mWifiStateMachine.sendMessage(Message.obtain(msg));
}
}
break;
}
}
}
/*在getWifiServiceMessenger()中实例化messenger和WifiManager的Handler通讯*/
private ClientHandlermClientHandler;
}// class WifiService
[-->WifiService.java::enableNetwork]
在WifiService ClientHandler:: handleMessage里会直接调用mWifiStateMachine.sendMessage()。
再举一个更典型WifiService调用WifiStateMachine的例子,这个例子里会调用WifiStateMachine封装好的函数而不是直接调用sendMessage()
public boolean enableNetwork(int netId,boolean disableOthers) {
return mWifiStateMachine.syncEnableNetwork(
mWifiStateMachineChannel,
netId,
disableOthers);
}
[-->WifiStateMachine.java::syncEnableNetwork]
public boolean syncEnableNetwork(AsyncChannel channel, int netId,boolean disableOthers) {
Message resultMsg = channel.sendMessageSynchronously(CMD_ENABLE_NETWORK,netId,disableOthers ? 1 : 0);
}
[-->WifiStateMachine.java::WifiStateMachine::ConnectModeState]
/*最终在ConnectModeState里面处理 CMD_ENABLE_NETWORK和
WifiManager.CONNECT_NETWORK命令*/
class ConnectModeState extends State {
@Override
public boolean processMessage(Message message) {
WifiConfigurationconfig;
boolean ok;
switch(message.what){
case CMD_ENABLE_NETWORK:
/*mWifiConfigStore.enableNetwork will
callWifiNative::enableNetwork()*/
ok =mWifiConfigStore.enableNetwork(message.arg1,
message.arg2 == 1);
replyToMessage(message,message.what, ok ? SUCCESS : FAILURE);
break;
caseWifiManager.CONNECT_NETWORK:
/*The connect message can contain a network id passed as
*arg1 on message or
*or a config passed as obj on message.
*For a new network, a config is passed to create and connect.
*For an existing network, a network id is passed
*/
intnetId = message.arg1;
config= (WifiConfiguration) message.obj;
if(mWifiConfigStore.selectNetwork(netId)&&
mWifiNative.reconnect()) {
/* The state tracker handles enablingnetworks upon completion/failure */ mSupplicantStateTracker.sendMessage(WifiManager.CONNECT_NETWORK);
replyToMessage(message, WifiManager.CONNECT_NETWORK_SUCCEEDED);
/* Expect a disconnection from the old connection */
transitionTo(mDisconnectingState);
}
break;
}
-
WifiStateMachine中的重要成员功能介绍
[-->WifiStateMachine.java::WifiStateMachine]
public class WifiStateMachine extendsStateMachine {
/*接受来自wpa_supplicant的事件*/
private WifiMonitor mWifiMonitor;
/*提供给WiFiFramework层的API*/
private WifiNative mWifiNative;
/*save,forget,remove,select,enableanddisable network*/
private WifiConfigStore mWifiConfigStore;
/*NETWORKMANAGEMENT_SERVICE,处理/监听网络接口相关,e.g ifconfig wlan0 down*/
private INetworkManagementService mNwService;
/*CONNECTIVITY_SERVICE,处理Tethering相关*/
private ConnectivityManager mCm;
}
今天先写到这里,很多细节如WifiMonitor的工作流程等先不写了