闵行区土地规划管理:android Wifi模块分析(一)
来源:百度文库 编辑:中财网 时间:2024/04/27 22:50:58
Wifi模块
(1)
(2)
一,Wifi模块相关文件解析
1)
packages/apps/Settings/src/com/android/settings/wifi wifisettings.java
{
private final IntentFilter mFilter;
//广播接收器,用来接收消息并做响应的处理工作
private final BroadcastReceiver mReceiver;
//这是一个扫描类,会在用户手动扫描
private final Scanner mScanner;
private WifiInfo mLastInfo;
private WifiManager mWifiManager;
//这个类主要实现Wifi的开闭工作
private WifiEnabler mWifiEnabler;
//AP
private AccessPoint mSelected;
private WifiDialog mDialog;
……
}
public WifiSettings() {
mFilter = new IntentFilter();
//intent机制中的intent消息过滤器,下面添加可以处理的动作
//注册了广播接收器,用来处理接收到的消息事件
}
……
mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
mWifiEnabler = new WifiEnabler(this,
……
2)
packages/apps/Settings/src/com/android/settings/wifi/WifiEnabler.java
private final Context mContext;
private final CheckBoxPreference mCheckBox;
//两个重要成员
private final WifiManager mWifiManager;
private final IntentFilter mIntentFilter;
该类中定义了几个重要的函数onPreferenceChange,handleWifiStateChanged和handleStateChanged,onPreferenceChange用来处理按下的Enbler键,它会调用mWifiManager.setWifiEnabled(enable),另外两个用来处理接受的消息事件。
public WifiEnabler(Context context, CheckBoxPreference checkBox) {
}
这里可以总结为:如果上层需要监听或收到下层的消息,那么就要通过定义一个BroadcastReciever,并将它注册,当然在接受到消息后应该有处理消息的函数,然后在onReciever函数中根据消息调用相应的处理函数,这里的消息通知机制是Intent,在BroadcastReciever类的onReciever函数的参数中可以看出。
该类成员函数的也是通过调用mWifimanager的接口来实现的。
//WifiService
IWifiManager mService;
IWifiManager mService和Handler mHandler,这个类拥有了一个WifiService实例,就可以通过它进行一系列的调用;WifiManager中定义了的wifi和ap的状态,这些状态会在其他很多类中有使用;然后定义了大量的函数,这些函数几乎都是对WifiService接口函数的封装,直接调用WifiService的函数。
该类的构造函数很简单:
public WifiManager(IWifiManager service, Handler handler) {
该类中还定义了一个WifiLock类,这个类用来保证在有应用程序使用Wifi无线电传输数据时,wifi radio可用,即当一个应用程序使用wifi的radio进行无线电数据传输时,就要先获得这个锁,如果该锁已被其他程序占有,就要等到该锁被释放后才能获得,只用当所有持有该锁的程序都释放该锁后,才能关闭radio功能。
frameworks/base/services/java/com/android/server/WifiService.java
private final WifiStateTracker mWifiStateTracker;
private Context mContext;
private WifiWatchdogService mWifiWatchdogService = null;
private final
这是WifiService中的几个重要的数据成员。
在接下来的构造函数中初始化了mWifiStateTracker,mContext,然后动态生成mWifiThread子线程并启动,在主线程里用mWifiThread调用getLooper()函数获得线程的looper,来初始化创建一个mWifiHandler对象,这个WifiHandler在WifiService类的后面有定义,并重载了Handler类的handlermessage()函数,这样消息就可以在主线程里被处理了,这是android的handlerthread消息处理机制,可参考相关资料,这里不予详述。在构造函数的最后,注册了两个广播接收器,分别用来ACTION_AIRPLANE_MODE_CHANGED和ACTION_TETHER_STATE_CHANGED这两个动作,这里是android的intent消息通知机制,请参考相关资料,代码如下:
mContext = context;
mWifiStateTracker = tracker;
mWifiStateTracker.enableRssiPolling(true);
……
HandlerThread wifiThread = new HandlerThread("WifiService");
wifiThread.start();
mWifiHandler = new WifiHandler(wifiThread.getLooper());
……
随后定义了一系列的函数,其中有服务器要发送的命令的系列函数,它通过mWifiStateTracker成员类调用自己的的发送命令的接口(其实就是对本地接口的一个封装),最后通过适配层发送命令给wpa_supplicant,而事件处理只到WifiStateTracker层被处理。
要注意的是,在WifiService中,定义了一些函数来创建消息,并通过mWifiHandler将消息发送到消息队列上,然后在mHandlerThread线程体run()分发\处理消息,在主线程中被mWifiHandler的handlerMessage()函数处理,最后调用mWifiStateTracker的对应函数来实现的。这里我也不明白为什么WifiService不直接调用mWifiStateTracker对应的函数,还要通过消息处理机制,绕了一圈在调用,当然Google这么做肯定是有它道理的,忘高手指点。
frameworks/base/wifi/java/android/net/wifi/WifiStateTracker.java
NetworkStateTracker继承了handler类,而WifiStateTracker继承了NetworkStateTracker类,就是说WifiStateTracker间接继承了handler类,属于一个事件处理类。
WifiStateTracker类首先定义了事件日志和事件码(这里包含了所有可能的事件类型),还定义了如下的重要成员数据:
private WifiMonitor mWifiMonitor;
private WifiInfo mWifiInfo;
private WifiManager mWM;
private DhcpHandler mDhcpTarget;
private DhcpInfo mDhcpInfo;
类的构造函数中,初始化了系列成员变量,包括生成了WifiMonitor的实例,在构造函数中,因为WifiStateTracker是一个handler间接子类,所以他会自动调用handler的无参构造函数,获得looper和Queue消息队列。
然后定义了一些设置supplicant和更新网络信息的辅助函数。
这里也定义了很多的WfiNative接口函数,这是JNI的本地接口;类DhcpHandler extends Handler{}也是在该类中定义的,它也是一个handler的子类,用来处理DHCP相关的消息EVENT_DHCP_START,可以想到它和WifiStateTracker不是共用一个looper。
声明了一个重要的成员变量:mWifiStateTracker,并在构造函数中由参数提供初始化,还定义了一系列的可能从wpa_supplicant层接收的事件类型及其名字,这些是消息处理机制的基础。
startMonitoring()函数,这是一个线程启动的封装函数,WifiStateTracker就是通过这个函数启动的WifiThread。
这个重要的类classMonitorThread extends Thread{};它是一个监控进程类,里面有一系列的事件处理函数和一个重要的Run()函数,run函数主要流程:connectToSupplicant()连接精灵进程wpa_supplicant,这里有一个mWifiStateTracker.notifySupplicantXXX()的调用,通知上层是否连接成功,然后就是一个轮询过程,其中调用了WifiNative.waitForEvent()本地轮询函数接口,并从返回的事件字符串类型中提取事件的名称,最后通过事件的名称调用相应的事件处理函数,并将事件转换成mWifiStateTracker能识别的类型上报。
里面定义了一个类WifiNative:其中声明了许多本地接口,可由native的标志看出,这是Java代码和本地库之间的联系接口;
frameworks/base/core/jni/
一类是命令相关的(控制)函数,就是在JNI层android_XXX_Command()函数所调用的::Wifi_Command()函数,调用流程:android_XXX_command()=>docommand()=>wifi_command()=>wifi_send_command()=>wpa_ctrl_require()。
二类是监听函数,即Wifi_wait_for_event()函数,调用流程:android_net_wifi_Waitforevent()=>wifi_wait_for_event()=>wpa_ctrl_recv()。
三类是剩下的函数。
10)wpa_supplicant与上层的接口,wpa_ctrl.c:external/wpa_supplicant
定义了三类套接字,并分别实现了和wpa_supplicant的通信,因此wpa_supplicant适配层和wpa_supplicant层是通过socket通讯的。
要是从wifi.c中真的很难看出它和wpa_supplicant有什么关系,和它联系密切的是wpa_ctrl.h文件,这里面定义了一个类wpa_ctrl,这个类中声明了两个Socket套接口,一个是本地一个是要连接的套接口,wpa_ctrl与wpa_supplicant的通信就需要socket来帮忙了,而wpa_supplicant就是通过调用wpa_ctrl.h中定义的函数和wpa_supplicant进行通讯的,wpa_ctrl类(其实是其中的两个socket)就是他们之间的桥梁。
首先声明了两个主要变量mWifiStateTracker,mWifiManager,需要这两个类对象来完成具体的控制工作,在WifiWatchdogService的构造函数中,创建了这两个类,并通过regesterForWifiBroadcast
frameworks/base/services/java/com/android/server/WifiWatchdogService.java
WifiWatchdogService(Context context, WifiStateTracker wifiStateTracker) {