软件平台:android4.4.2 硬件平台:leadcore1860
1.自动扫描流程
当Load wifi驱动ko,启动supplicant,并且connect to supplicant成功后,在WifiStateMachine中,调用setWifiState(WIFI_STATE_ENABLED);它会发intent,当wifisettings接收到这个intent,就进行处理,代码如下:
private void handleEvent(Context context, Intent intent) {
String action = intent.getAction();
WifiUtils.log(TAG, "receive intent " + action);
if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
updateAccessPoints();
updateWifiState(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
WifiManager.WIFI_STATE_UNKNOWN));
其中updateWifiState(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
WifiManager.WIFI_STATE_UNKNOWN));的实现如下:
private void updateWifiState(int state) {
WifiUtils.log(TAG, "updateWifiState state is " + state);
Activity activity = getActivity();
if (activity != null) {
activity.invalidateOptionsMenu();
}
WifiUtils.log(TAG, "updateWifiState state22 is " + state);
switch (state) {
case WifiManager.WIFI_STATE_ENABLED:
mScanner.resume();
return; // not break, to avoid the call to pause() below
case WifiManager.WIFI_STATE_ENABLING:
addMessagePreference(R.string.wifi_starting);
break;
case WifiManager.WIFI_STATE_DISABLED:
setOffMessage();
break;
}
mLastInfo = null;
mLastState = null;
mScanner.pause();
}
其中,mScanner.resume()的实现如下
private class Scanner extends Handler {
private int mRetry = 0;
void resume() {
if (!hasMessages(0)) {
WifiUtils.log(TAG, "Scanner resume sendEmptyMessage");
sendEmptyMessage(0);
}
}
它是发送一条空消息,到消息处理的地方看,如下:
public void handleMessage(Message message) {
WifiUtils.log(TAG, "Scanner message is [" + message + "]");
if (mWifiManager.startScan()) {
mRetry = 0;
} else if (++mRetry >= 3) {
mRetry = 0;
Activity activity = getActivity();
if (activity != null) {
Toast.makeText(activity, R.string.wifi_fail_to_scan,
Toast.LENGTH_LONG).show();
}
return;
}
sendEmptyMessageDelayed(0, WIFI_RESCAN_INTERVAL_MS);
}
上面代码中的黄色部份,就一层一层往下调,去驱动硬件做扫描动作,而红色部分,则是重新扫描的延时,默认是10s,若用户没做任何操作,那么10s钟后,又发送一条空消息,再回到handleMessage方法来处理,这样一直循环下去。因此,从logcat的log来看,在打开wifi之后,成功connect to supplicant后,只要用户不做任何操作,每10s钟,应用层发送一条扫描请求,从而通过wifinative,jni,hal到supplicant发送了scan命令,然后通过supplicant给kernel层发scan命令,去驱动硬件做扫描的动作
2.当用户点击扫描按钮
当用户点击扫描按钮,在wifisettings的public boolean onOptionsItemSelected(MenuItem item) 中,对应的处理如下:
case MENU_ID_SCAN:
WifiUtils.log(TAG, "user click scan");
if (mWifiManager.isWifiEnabled()) {
mScanner.forceScan();
}
return true;
显而易见,调用了mScanner.forceScan(),它的实现如下:
void forceScan() {
removeMessages(0);
sendEmptyMessage(0);
}
就是删除队列中的空消息,然后又发一条空消息