趁做Android WIFI驱动移植,对Android WIFI框架做了深刻的分析,并做此文档共同学习。
对上层WIFI的应用,基本流程为:(1)WIFI初始化 (2)Wifi启动 (3)开始扫描AP (4)显示扫描的AP (5)配置AP (6)连接AP (7)获取IP地址 (8)上网
一、AndroidWIFI模块初始化
上文Android系统启动分析 讲到在SystemServer中实例化了ConnectivityService,接着的便是WIFI初始化:
frameworks/base/services/java/com/android/server/ConnectivityService.java
ConnectivityService 的构造函数会创建WifiService,
if (DBG) Log.v(TAG, "Starting Wifi Service.");
WifiStateTracker wst = new WifiStateTracker(context,mHandler);
WifiService wifiService = new WifiService(context,wst);
ServiceManager.addService(Context.WIFI_SERVICE, wifiService);
WifiStateTracker 会创建WifiMonitor 接收来自底层的事件,WifiService 和WifiMonitor是整个模块的核心。WifiService 负责启动关闭wpa_supplicant、启动关闭WifiMonitor监视线程和把命令下发给wpa_supplicant,而WifiMonitor 则负责从wpa_supplicant接收事件通知。
具体流程图如下:
二、WIFI模块启动
WirelessSettings 在初始化的时候配置了由WifiEnabler 来处理Wifi 按钮 WirelessSettings在初始化的时候配置了由WifiEnabler 来处理Wifi按钮
Packages\apps\settings\src\com\android\settings\WirelessSettings.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.wireless_settings);
initToggles();
mAirplaneModePreference = (CheckBoxPreference)findPreference(KEY_TOGGLE_AIRPLANE);
}
private void initToggles(){
…………
mWifiEnabler= new WifiEnabler(
this, (WifiManager) getSystemService(WIFI_SERVICE),
(CheckBoxPreference) wifiPreference);
…………
}
当用户按下Wifi 按钮后,Android 会调用WifiEnabler的onPreferenceChange,再由WifiEnabler调用WifiManager 的setWifiEnabled接口函数,通过AIDL,实际调用的是WifiService 的setWifiEnabled 函数,WifiService接着向自身发送一条MESSAGE_ENABLE_WIFI 消息,在处理该消息的代码中做真正的使能工作:
首先装载WIFI 内核模块(该模块的位置硬编码为"/system/lib/modules/libertas_sdio.ko"),
然后启动wpa_supplicant (配置文件硬编码为"/data/misc/wifi/wpa_supplicant.conf"),再通过WifiStateTracker来启动WifiMonitor 中的监视线程。
WifiEnabler.java
publicboolean onPreferenceChange(Preferencepreference, Object value) {
// Turn on/off Wi-Fi
setWifiEnabled((Boolean)value);
}
private void setWifiEnabled(finalboolean enable) {
if (!mWifiManager.setWifiEnabled(enable)){
}
}
WifiManager.java
public boolean setWifiEnabled(boolean enabled){
return mService.setWifiEnabled(enabled);
}
IWifiManager mService;
interface IWifiManager{
…………
boolean startScan(booleanforceActive);
boolean setWifiEnabled(booleanenable);
…………
}
IWifiManger.aidl编译后生成了IWifiManger.java,并生成IWifiManger.Stub(服务器端抽象类)和IWifiManger.Stub.Proxy(客户端代理实现类)。WifiService通过继承IWifiManger.Stub实现,而客户端通过getService()函数获取IWifiManger.Stub.Proxy(即Service的代理类),将其作为参数传递给WifiManger,供其与WifiService通信时使用。
WifiService.java
publicboolean setWifiEnabled(booleanenable) {
…………
sendEnableMessage(enable, true,Binder.getCallingUid());
…………
}
private void sendEnableMessage(boolean enable, boolean persist, intuid) {
Message msg = Message.obtain(mWifiHandler,
(enable ? MESSAGE_ENABLE_WIFI : MESSAGE_DISABLE_WIFI),
(persist ? 1 : 0), uid);
msg.sendToTarget();
}
public void handleMessage(Messagemsg) {
switch (msg.what) {
case MESSAGE_ENABLE_WIFI:
setWifiEnabledBlocking(true,msg.arg1 == 1, msg.arg2);
caseMESSAGE_START_WIFI:
mWifiStateTracker.restart();
caseMESSAGE_DISABLE_WIFI:
setWifiEnabledBlocking(false, msg.arg1 == 1,msg.arg2);