近来无事,研究下Jelly Bean Wifi的工作流程。
1. 首先是打开wifi流程
packages/apps/Settings/src/com/android/settings/Settings.java里面会持有一个WifiEnabler.java对象, 当用户点击wifi的switch控件时,会调用mWifiEnabler.setSwitch(holder.switch_),然后去WifiEnabler里面看看。
102和104这两行是控制wifi的switch控件UI的。
真正去打开wifi需要看这里:onCheckedChanged(...)
首先判断statte machine event的状态,假如你已经点mStateMachineEvent貌似一直为false。没关系。
然后去检查在Airplane mode 下支不支持打开wifi(114行),Jelly Bean(4.1)源码是支持的哦。
如果wifi ap打开,则关掉(121~125行)
准备工作都做好了。最后干正事:打开wifi(126行)
经WifiManager调用WifiService里的setWifiEnabled方法,其调用的是WifiStateMachine里面的setWifiEnabled方法 { 这里需要继续往下跟,对应到wifi.c里面的int wifi_wait_for_event(char *buf, size_t buflen) }
WifiStateMachine里面的setWifiEnabled方法会去发消息,sendMessage将包含CMD_LOAD_DRIVER 和 WIFI_STATE_ENABLING参数的message放入消息队列。将在handleMessage中接收(知晓StateMachine机制,再看这个就不难了)
具体执行时在,DriverUnloadingState这个内部类里面mWifiNative.loadDriver()。
去看看本地方法吧:
public native static boolean loadDriver();
就这么简单一行。哈哈,接着要看JNI了。frameworks/base/core/jni/android_net_wifi_Wifi.cpp
请看这一行:{ "loadDriver", "()Z", (void *)android_net_wifi_loadDriver }
对应java方法为loadDriver(), JNI里面的方法为android_net_wifi_loadDriver(), 去看看发现对应c里面的方法为wifi_load_driver(), 返回值为bool类型
static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject)
{
return (jboolean)(::wifi_load_driver() == 0);
}
到这里,java层的工作已经做完了,接下来要看底层的处理了。


回到java层,如果driver load成功, 会通知StateMachine去改变状态

把状态改为loaded
loaded成功之后状态机就不需要做什么了, 这里只打了个log
继续往下走!
回顾WifiStateMachine里面setWifiEnabled方法
它将会做一系列操作,我们其中就包括
WifiNative.startSupplicant()
mWifiMonitor.startMonitoring();
第2383,2385行。
先看下2385行mWifiMonitor.startMonitoring()
它将开启一个线程去监听wifi的event,什么都不说了直接贴代码(部分), event来源WifiNative.waitForEvent()。{ 这里需要继续往下跟,对应到wifi.c里面的int wifi_wait_for_event(char *buf, size_t buflen) }