Android4.0 wifi 启动流程二
在Android4.0 wifi 启动流程一中,就分析到启动wifimonitor线程来接收wpa_supplicant发送的消息,之后切换到SupplicantStartingState状态。
在wifiMonitor.java中wifiMonitor线程的开始就是连接supplicant,程序如下:
public void run() {
if (connectToSupplicant()) {
// Send a message indicating that it is now possible to send commands
// to the supplicant
mStateMachine.sendMessage(SUP_CONNECTION_EVENT);
} else {
mStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
return;
}
connectToSupplicant()调用JNI函数WifiNative.connectToSupplicant(),如果连接成功则向wifiStatemachine发送SUP_CONNECTION_EVENT消息。
在wifistateMachine.java中,wifi状态机当前状态是SupplicantStartingState,处理SUP_CONNECTION_EVENT消息,如下:
class SupplicantStartingState extends State {
@Override
public void enter() {
if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
}
@Override
public boolean processMessage(Message message) {
if (DBG) log(getName() + message.toString() + "\n");
switch(message.what) {
case WifiMonitor.SUP_CONNECTION_EVENT:
if (DBG) log("Supplicant connection established");
setWifiState(WIFI_STATE_ENABLED);
mSupplicantRestartCount = 0;
/* Reset the supplicant state to indicate the supplicant
* state is not known at this time */
mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
mWpsStateMachine.sendMessage(CMD_RESET_WPS_STATE);
/* Initialize data structures */
mLastBssid = null;
mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
mLastSignalLevel = -1;
mWifiInfo.setMacAddress(WifiNative.getMacAddressCommand());
WifiConfigStore.initialize(mContext);
sendSupplicantConnectionChangedBroadcast(true);
transitionTo(mDriverStartedState);
break;
1, setWifiState(WIFI_STATE_ENABLED):设置wifi状态,通知有关进程wifi的状态。
WifiEnabler接收到该消息时会调用handleWifiStateChanged,如下:
if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
handleWifiStateChanged(intent.getIntExtra(
WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN));
handleWifiStateChanged定义如下:
private void handleWifiStateChanged(int state) {
switch (state) {
case WifiManager.WIFI_STATE_ENABLING:
mSwitch.setEnabled(false);
break;
case WifiManager.WIFI_STATE_ENABLED:
setSwitchChecked(true);
mSwitch.setEnabled(true);
break;
根据此消息WIFI_STATE_ENABLED会把settings里的Switch控件设置成enable状态。
WifiSettings接收到WIFI_STATE_CHANGED_ACTION会调用updateWifiState函数,如下:
private void handleEvent(Context context, Intent intent) {
String action = intent.getAction();
if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
updateWifiState(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
WifiManager.WIFI_STATE_UNKNOWN));
updateWifiState函数定义如下:
private void updateWifiState(int state) {
getActivity().invalidateOptionsMenu();
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:
addMessagePreference(R.string.wifi_empty_list_wifi_off);
break;
}
mLastInfo = null;
mLastState = null;
mScanner.pause();
}
根据WIFI_STATE_ENABLED消息会调用mScanner.resume()函数,该函数会发送一个空消息,如下:
void resume() {
if (!hasMessages(0)) {
sendEmptyMessage(0);
}
}
之后handleMessage会调用mWifiManager.startScanActive函数进行ap扫描。
public void handleMessage(Message message) {
if (mWifiManager.startScanActive()) {
在WifiManager.java中:
public boolean startScanActive() {
try {
return true;
} catch (RemoteException e) {
return false;
}
}
这里调用了mService.startScan(true)函数,在wifiService.java中:
public void startScan(boolean forceActive) {
enforceChangePermission();
mWifiStateMachine.startScan(forceActive);
}
这里调用了mWifiStateMachine.startScan(forceActive),在WifiStateMachine.java中:
public void startScan(boolean forceActive) {
sendMessage(obtainMessage(CMD_START_SCAN, forceActive ?
SCAN_ACTIVE : SCAN_PASSIVE, 0));
}
由于forceActive为true,则有发送了一个消息。
2, mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE):resetsupplicant。
3, mWifiInfo.setMacAddress(WifiNative.getMacAddressCommand()):回去mac地址赋给wifiinfo类。
4, transitionTo(mDriverStartedState):切换到DriverStartedState状态。
在DriverStartedState状态接收到CMD_START_SCAN命令进行处理:
case CMD_START_SCAN:
eventLoggingEnabled = false;
WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE);
mScanResultIsPending = true;
break;
调用JNI函数WifiNative.scanCommand进行ap扫描。
当扫描完成时,wifiMonitor线程会接收到SCAN_RESULTS事件,然后发送消息:
case SCAN_RESULTS:
mStateMachine.sendMessage(SCAN_RESULTS_EVENT);
break;