Wifi启动以及Wifi状态机
来源:互联网 发布:万果五笔输入法mac版 编辑:程序博客网 时间:2024/04/28 00:55
第一部分 启动service
</pre><pre name="code" class="java">public class SystemServer {//...//... public static final void init2() { Slog.i(TAG, "Entered the Android system server!"); Thread thr = new ServerThread(); thr.setName("android.server.ServerThread"); thr.start(); }}
init2()创建了一个线程,线程启动后在run中创建一系列的android services,将网络相关的services注册。
class ServerThread extends Thread { private static final String TAG = "SystemServer"; public void run() { //... try { Slog.i(TAG, "Wi-Fi Service"); wifi = new WifiService(context); ServiceManager.addService(Context.WIFI_SERVICE, wifi); } catch (Throwable e) { reportWtf("starting Wi-Fi Service", e); } try { Slog.i(TAG, "Connectivity Service"); connectivity = new ConnectivityService( context, networkManagement, networkStats, networkPolicy); ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity); networkStats.bindConnectivityManager(connectivity); networkPolicy.bindConnectivityManager(connectivity); wifi.checkAndStartWifi(); wifiP2p.connectivityServiceReady(); } catch (Throwable e) { reportWtf("starting Connectivity Service", e); } //... }}第二部分 WifiServiceWifiService的代码位置:frameworks/base/services/java/com/android/server/WifiService.javaWifiService是整个框架的核心。当应用层触发了事件,会调用WifiService里面的方法来处理。包括加载驱动,启动wpa_supplicant,扫描AP等。但是实际上都是调用WifiStateMachine里面的方法发送消息。由WifiStateMachine里面描述wifi的内部类去处理消息。在WifiService.java这个程序中,定义了WifiService这个类,以及它的构造函数(不懂java,不知道是不是叫构造),各种方法的实现。在WifiService这个类的构造函数中,初始化了WifiStateMachine成员mWifiStateMachine,并重新写了广播事件的onReceiver函数。第三部分 WifiStateMachineWifiStateMachine的代码位置:frameworks/base/wifi/java/android/net/wifi/WifiStateMachine.java我们知道WifiService中最终都是调用WifiStateMachine里面的方法来实现的。在WifiStateMachine中,需要传递到wpa_supplicant来实现wifi功能的命令都在这里做了定义。针对每一个wifi状态,都声明了一个内部类去描述。比如:加载驱动,开启wpa_supplicant等。在这个类中可以看到很多状态,在WifiStateMachine这个类中定义了一些私有类成员,他们都是State类的。这些类成员有各自的初始化的函数。比如:private State mDriverLoadingState = new DriverLoadingState();驱动加载时的状态为mDriverLoadingState,它对应的处理类为DriverLoadingState,依次类推。Class WifiStateMachine{ //... //... /* Default parent state */ private State mDefaultState = new DefaultState(); /* Temporary initial state */ private State mInitialState = new InitialState(); /* Unloading the driver */ private State mDriverUnloadingState = new DriverUnloadingState(); /* Loading the driver */ private State mDriverUnloadedState = new DriverUnloadedState(); /* Driver load/unload failed */ private State mDriverFailedState = new DriverFailedState(); /* Driver loading */ private State mDriverLoadingState = new DriverLoadingState(); /* Driver loaded */ private State mDriverLoadedState = new DriverLoadedState(); /* Driver loaded, waiting for supplicant to start */ private State mSupplicantStartingState = new SupplicantStartingState(); /* Driver loaded and supplicant ready */ private State mSupplicantStartedState = new SupplicantStartedState(); /* Waiting for supplicant to stop and monitor to exit */ private State mSupplicantStoppingState = new SupplicantStoppingState(); /* Driver start issued, waiting for completed event */ private State mDriverStartingState = new DriverStartingState(); /* Driver started */ private State mDriverStartedState = new DriverStartedState(); /* Driver stopping */ private State mDriverStoppingState = new DriverStoppingState(); /* Driver stopped */ private State mDriverStoppedState = new DriverStoppedState(); /* Scan for networks, no connection will be established */ private State mScanModeState = new ScanModeState(); /* Connecting to an access point */ private State mConnectModeState = new ConnectModeState(); /* Fetching IP after network connection (assoc+auth complete) */ private State mConnectingState = new ConnectingState(); /* Connected with IP addr */ private State mConnectedState = new ConnectedState(); /* disconnect issued, waiting for network disconnect confirmation */ private State mDisconnectingState = new DisconnectingState(); /* Network is not connected, supplicant assoc+auth is not complete */ private State mDisconnectedState = new DisconnectedState(); /* Waiting for WPS to be completed*/ private State mWaitForWpsCompletionState = new WaitForWpsCompletionState(); /* Soft ap is starting up */ private State mSoftApStartingState = new SoftApStartingState(); /* Soft ap is running */ private State mSoftApStartedState = new SoftApStartedState(); /* Soft ap is running and we are waiting for tether notification */ private State mTetheringState = new TetheringState(); /* Soft ap is running and we are tethered through connectivity service */ private State mTetheredState = new TetheredState(); /* Waiting for untether confirmation to stop soft Ap */ private State mSoftApStoppingState = new SoftApStoppingState(); /* Wait till p2p is disabled */ private State mWaitForP2pDisableState = new WaitForP2pDisableState(); //... //...}//驱动正在加载的状态class DriverLoadingState extends State{ //... //...}//驱动已经加载的状态class DriverLoadedState extends State { //... //...}//驱动正在卸载的状态class DriverUnloadingState extends State { //... //...}//驱动已经卸载的状态class DriverUnloadedState extends State { //... //...}//wpa_supplicant正在开启的状态class SupplicantStartingState extends State { //... //...}//wpa_supplicant已经开启的状态class SupplicantStartedState extends State { //... //...}还有很多类似的状态类,它们的状态不同,但是它们的结构却是相同的,每一个状态类都是由State, enter, processMessage组成。以加载驱动为例:class DriverLoadingState extends State { @Override public void enter() { //... //... } @Override public boolean processMessage(Message message) { //... //... }}WifiStateMachine使用sendMessage()来发送消息,使用transitionTo()来转换状态。状态切换后就根据相应状态里面的processMessage来做一些相应的操作,然后再切换状态。我们以开启wifi并开始扫描AP为例,(略过了通过WifiNative加载驱动那一段,在另一篇博文中有记录),看一下整个状态机的流程。1.在WifiService这个类中,有一个方法 setWifiEnabled,这个就是开启wifi的接口代码位置:frameworks/base/services/java/com/android/server/WifiService.java public synchronized boolean setWifiEnabled(boolean enable) { enforceChangePermission(); if (DBG) { Slog.e(TAG, "Invoking mWifiStateMachine.setWifiEnabled\n"); } if (enable) { reportStartWorkSource(); } mWifiStateMachine.setWifiEnabled(enable); //注意这里,mWifiStateMachine是WifiService这个类中的一个成员。这里调用这个类成员的setWifiEnabled方法去使能wifi. //所以这里我们要去WifiStateMachine去找个方法。 /* * Caller might not have WRITE_SECURE_SETTINGS, * only CHANGE_WIFI_STATE is enforced */ /* Avoids overriding of airplane state when wifi is already in the expected state */ if (enable != mWifiEnabled) { long ident = Binder.clearCallingIdentity(); persistWifiState(enable); Binder.restoreCallingIdentity(ident); } if (enable) { if (!mIsReceiverRegistered) { registerForBroadcasts(); mIsReceiverRegistered = true; } } else if (mIsReceiverRegistered) { mContext.unregisterReceiver(mReceiver); mIsReceiverRegistered = false; } return true; }2.当WifiStateMachine中,状态机初始化的时候为mInitialState,public WifiStateMachine(Context context, String wlanInterface) {//构造函数 //... setInitialState(mInitialState); //...}所以,我们到相应的相应的状态类InitialState中去看看。代码位置:frameworks/base/wifi/java/android/net/wifi/WifiStateMachine.java(1)mInitialStateclass InitialState extends State { @Override //TODO: could move logging into a common class public void enter() { if (DBG) log(getName() + "\n"); // [31-8] Reserved for future use // [7 - 0] HSM state change // 50021 wifi_state_changed (custom|1|5) EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName()); if (WifiNative.isDriverLoaded()) { //注意这里!这里调用WifiNative中的isDriverLoaded来判断驱动是否已经加载了 transitionTo(mDriverLoadedState); //如果已经加载了,我们就切换到mDriverLoadedState状态,即驱动已经加载状态 } else { transitionTo(mDriverUnloadedState); //否则就切换到mDriverUnloadedState,即驱动已经卸载的状态。 } //因为我们这是初始化,驱动肯定没有加载,所以我们会切换到mDriverUnloadedState这个状态。 //...我们只关注一下相关的,其他的我省略了。 //... }}(2)mDriverUnloadedStateclass DriverUnloadedState 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 CMD_LOAD_DRIVER: //看到这条消息了吗,从字面意思我们也能知道,这是要加载驱动的意思,那我们在哪里发送这个消息了呢? mWifiP2pChannel.sendMessage(WIFI_ENABLE_PENDING); transitionTo(mWaitForP2pDisableState); //如果收到了CMD_LOAD_DRIVER,切换到mWaitForP2pDisableState状态 break; case WifiP2pService.P2P_ENABLE_PENDING: mReplyChannel.replyToMessage(message, P2P_ENABLE_PROCEED); break; default: return NOT_HANDLED; } EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what); return HANDLED; }}Q1:我们在哪里发送CMD_LOAD_DRIVER呢?还记得在WifiService类中的一个方法public synchronized boolean setWifiEnabled(boolean enable) { //... mWifiStateMachine.setWifiEnabled(enable);//这里调用了WifiStateMachine中的setWifiEnabled方法 //...}public void setWifiEnabled(boolean enable) { mLastEnableUid.set(Binder.getCallingUid()); if (enable) { /* Argument is the state that is entered prior to load */ sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_STATE_ENABLING, 0)); //发送消息加载驱动 sendMessage(CMD_START_SUPPLICANT); //发送消息,开启wap supplicant } else { sendMessage(CMD_STOP_SUPPLICANT); /* Argument is the state that is entered upon success */ sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_DISABLED, 0)); }}我们在WifiStateMachine这个类中找到setWifiEnabled这个方法的实现。可以看到,它根据参数enable来判断是开启wifi还是关闭wifi。都是通过sendMessage发送消息来实现的。答案找到了,就是在这个时候发送了CMD_LOAD_DRIVER命令。所以我们又切换到了mWaitForP2pDisableState状态。(3)mWaitForP2pDisableStateclass WaitForP2pDisableState extends State { private int mSavedArg; @Override public void enter() { if (DBG) log(getName() + "\n"); EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName()); //Preserve the argument arg1 that has information used in DriverLoadingState mSavedArg = getCurrentMessage().arg1; } @Override public boolean processMessage(Message message) { if (DBG) log(getName() + message.toString() + "\n"); switch(message.what) { case WifiP2pService.WIFI_ENABLE_PROCEED: //上一步发送的CMD_LOAD_DRIVER,就到这里了(还没特别懂) //restore argument from original message (CMD_LOAD_DRIVER) message.arg1 = mSavedArg; //这里是存储CMD_LOAD_DRIVER参数 transitionTo(mDriverLoadingState); //然后切换到mDriverLoadingState状态,已经看到眉目了 break; case CMD_LOAD_DRIVER: case CMD_UNLOAD_DRIVER: case CMD_START_SUPPLICANT: case CMD_STOP_SUPPLICANT: case CMD_START_AP: case CMD_STOP_AP: case CMD_START_DRIVER: case CMD_STOP_DRIVER: case CMD_SET_SCAN_MODE: case CMD_SET_SCAN_TYPE: case CMD_SET_HIGH_PERF_MODE: case CMD_SET_COUNTRY_CODE: case CMD_SET_FREQUENCY_BAND: case CMD_START_PACKET_FILTERING: case CMD_STOP_PACKET_FILTERING: deferMessage(message); break; default: return NOT_HANDLED; } EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what); return HANDLED; }}(4)mDriverLoadingStateclass DriverLoadingState extends State { @Override public void enter() { if (DBG) log(getName() + "\n"); EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName()); final Message message = new Message(); message.copyFrom(getCurrentMessage()); /* TODO: add a timeout to fail when driver load is hung. * Similarly for driver unload. */ new Thread(new Runnable() { public void run() { mWakeLock.acquire(); //enabling state switch(message.arg1) { //我们存储的参数和他不匹配,这里跳过 case WIFI_STATE_ENABLING: setWifiState(WIFI_STATE_ENABLING); break; case WIFI_AP_STATE_ENABLING: setWifiApState(WIFI_AP_STATE_ENABLING); break; } if(WifiNative.loadDriver()) { //重点来了,我们调用了WifiNative.loaderDriver方法加载驱动了,并且会根据返回值判断是否加载成功 if (DBG) log("Driver load successful"); sendMessage(CMD_LOAD_DRIVER_SUCCESS);//如果加载成功,就发送CMD_LOAD_DRIVER_SUCCESS消息,因为我们加载完驱动还是处于mDriverLoadingState //状态,所以CMD_LOAD_DRIVER_SUCCESS这条消息由mDriverLoadingState的processMessage来处理,就在 //我们下面几行代码中实现。 } else { loge("Failed to load driver!"); switch(message.arg1) {//记得我们存储的参数吗,这里使用到了 case WIFI_STATE_ENABLING: setWifiState(WIFI_STATE_UNKNOWN); break; case WIFI_AP_STATE_ENABLING: setWifiApState(WIFI_AP_STATE_FAILED); break; } sendMessage(CMD_LOAD_DRIVER_FAILURE); } mWakeLock.release(); } }).start(); } @Override public boolean processMessage(Message message) { //这里处理消息了 if (DBG) log(getName() + message.toString() + "\n"); switch (message.what) { case CMD_LOAD_DRIVER_SUCCESS: //这条消息眼熟吗,这不就是加载驱动成功后发送的消息吗 transitionTo(mDriverLoadedState); //如果收到了这条消息,我们就要切换到mDriverLoadingState了 break; case CMD_LOAD_DRIVER_FAILURE: transitionTo(mDriverFailedState); break; case CMD_LOAD_DRIVER: case CMD_UNLOAD_DRIVER: case CMD_START_SUPPLICANT: case CMD_STOP_SUPPLICANT: case CMD_START_AP: case CMD_STOP_AP: case CMD_START_DRIVER: case CMD_STOP_DRIVER: case CMD_SET_SCAN_MODE: case CMD_SET_SCAN_TYPE: case CMD_SET_HIGH_PERF_MODE: case CMD_SET_COUNTRY_CODE: case CMD_SET_FREQUENCY_BAND: case CMD_START_PACKET_FILTERING: case CMD_STOP_PACKET_FILTERING: deferMessage(message); break; default: return NOT_HANDLED; } EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what); return HANDLED; }}(5)mDriverLoadingStateclass DriverLoadedState 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 CMD_UNLOAD_DRIVER: transitionTo(mDriverUnloadingState); break; case CMD_START_SUPPLICANT: //到达mDriverLoadingState后,我们会执行这里,因为我们在加载完驱动后又发送了CMD_START_SUPPLICANT,在setWifiEnabled中! //from semco //我们在这里继续执行 //try { // mNwService.wifiFirmwareReload(mInterfaceName, "STA"); //} catch (Exception e) { // loge("Failed to reload STA firmware " + e); // continue //} try { //A runtime crash can leave the interface up and //this affects connectivity when supplicant starts up. //Ensure interface is down before a supplicant start. mNwService.setInterfaceDown(mInterfaceName); //Set privacy extensions mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true); } catch (RemoteException re) { loge("Unable to change interface settings: " + re); } catch (IllegalStateException ie) { loge("Unable to change interface settings: " + ie); } if(WifiNative.startSupplicant()) { //这里调用了WifiNative.startSupplicant来启动wpa supplicant,并通过返回值判断是否开启成功 if (DBG) log("Supplicant start successful"); mWifiMonitor.startMonitoring(); //如果成功了开启WifiMonitor,用来接收来自wpa_supplicant的消息 transitionTo(mSupplicantStartingState);//切换状态到mSupplicantStartingState } else { loge("Failed to start supplicant!"); sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_UNKNOWN, 0)); } break; case CMD_START_AP: transitionTo(mSoftApStartingState); break; default: return NOT_HANDLED; } EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what); return HANDLED; }}(6) mSupplicantStartingStateclass 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: //我们说过,WifiMonitor是为了接受wpa_supplicant消息的,如果启动wpa_supplicant了,那么wpa_supplicant //必定会发消息回来说“我确实已经开启了”,SUP_CONNECTION_EVENT就是类似的消息,所以我们判断是不是这个消息就知道是否 //开启成功。是否真的发送这个消息来呢?在哪发送的?请看Q2 if (DBG) log("Supplicant connection established"); setWifiState(WIFI_STATE_ENABLED); //这个好像挺重要的,设置wifi状态,通知有关进程wifi的状态,下面我们重点看一下这个Q3 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); //广播之后我们转换状态到mDriverStartedState break; case WifiMonitor.SUP_DISCONNECTION_EVENT: if (++mSupplicantRestartCount <= SUPPLICANT_RESTART_TRIES) { loge("Failed to setup control channel, restart supplicant"); WifiNative.killSupplicant(); transitionTo(mDriverLoadedState); sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS); } else { loge("Failed " + mSupplicantRestartCount + " times to start supplicant, unload driver"); mSupplicantRestartCount = 0; transitionTo(mDriverLoadedState); sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_UNKNOWN, 0)); } break; case CMD_LOAD_DRIVER: case CMD_UNLOAD_DRIVER: case CMD_START_SUPPLICANT: case CMD_STOP_SUPPLICANT: case CMD_START_AP: case CMD_STOP_AP: case CMD_START_DRIVER: case CMD_STOP_DRIVER: case CMD_SET_SCAN_MODE: case CMD_SET_SCAN_TYPE: case CMD_SET_HIGH_PERF_MODE: case CMD_SET_COUNTRY_CODE: case CMD_SET_FREQUENCY_BAND: case CMD_START_PACKET_FILTERING: case CMD_STOP_PACKET_FILTERING: deferMessage(message); break; default: return NOT_HANDLED; } EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what); return HANDLED; }} Q2:SUP_CONNECTION_EVENT是谁发送的?什么情况下会发送这个消息?我们知道,WifiMonitor是为了接收wpa_supplicant消息的,代码位置:frameworks/base/wifi/java/android/net/wifi/WifiMonitor.java这里面有一个线程, class MonitorThread extends Thread { public MonitorThread() { super("WifiMonitor"); } public void run() { if (connectToSupplicant()) {//connectToSupplicant,从名字上看我们也知道他是干啥的,同样是根据返回值判断是否执行成功 // Send a message indicating that it is now possible to send commands // to the supplicant mStateMachine.sendMessage(SUP_CONNECTION_EVENT);//如果执行成功,则发送SUP_CONNECTION_EVENT } else { mStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);//不成功则发送SUP_DISCONNECTION_EVENT return; } //... //... //...}Q3:setWifiState();代码位置:frameworks/base/wifi/java/android/net/wifi/WifiStateMachine.javaprivate void setWifiState(int wifiState) { final int previousWifiState = mWifiState.get(); try { if (wifiState == WIFI_STATE_ENABLED) { mBatteryStats.noteWifiOn(); } else if (wifiState == WIFI_STATE_DISABLED) { mBatteryStats.noteWifiOff(); } } catch (RemoteException e) { loge("Failed to note battery stats in wifi"); } mWifiState.set(wifiState); if (DBG) log("setWifiState: " + syncGetWifiStateByName()); final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);//WIFI_STATE_CHANGED_ACTION,准备发送这个消息 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); intent.putExtra(WifiManager.EXTRA_WIFI_STATE, wifiState); //传递的参数 intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_STATE, previousWifiState); mContext.sendStickyBroadcast(intent); //发送}当WifiEnabler收到消息时public class WifiEnabler implements CompoundButton.OnCheckedChangeListener { private final Context mContext; private Switch mSwitch; private AtomicBoolean mConnected = new AtomicBoolean(false); private final WifiManager mWifiManager; private boolean mStateMachineEvent; private final IntentFilter mIntentFilter; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { //mReceiver这个成员 @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) { //如果接受到了消息? handleWifiStateChanged(intent.getIntExtra( //调用handleWifiStateChanged这个方法去处理消息 WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN));//这里面的EXTRA_WIFI_STATE这个参数就是我们传递的wifiState } else if (WifiManager.SUPPLICANT_STATE_CHANGED_ACTION.equals(action)) { if (!mConnected.get()) { handleStateChanged(WifiInfo.getDetailedStateOf((SupplicantState) intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE))); } } else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) { NetworkInfo info = (NetworkInfo) intent.getParcelableExtra( WifiManager.EXTRA_NETWORK_INFO); mConnected.set(info.isConnected()); handleStateChanged(info.getDetailedState()); } } }; //... //... //...}private void handleWifiStateChanged(int state) {//state就是参数wifiState,记得我们传过来的是WIFI_STATE_ENABLED switch (state) { case WifiManager.WIFI_STATE_ENABLING: mSwitch.setEnabled(false); break; case WifiManager.WIFI_STATE_ENABLED: //执行这个分支 setSwitchChecked(true); //看下面的方法 mSwitch.setEnabled(true); break; case WifiManager.WIFI_STATE_DISABLING: mSwitch.setEnabled(false); break; case WifiManager.WIFI_STATE_DISABLED: setSwitchChecked(false); mSwitch.setEnabled(true); break; default: setSwitchChecked(false); mSwitch.setEnabled(true); break; }}private void setSwitchChecked(boolean checked) {//这个应该是设置WifiSetting里面的wifi使能按钮 if (checked != mSwitch.isChecked()) { mStateMachineEvent = true; mSwitch.setChecked(checked); mStateMachineEvent = false; }}当WifiSetting收到消息时public WifiSettings() { mFilter = new IntentFilter(); mFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); //这里应该是设置消息的过滤,即可以接收的消息 mFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); mFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION); mFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); mFilter.addAction(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION); mFilter.addAction(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION); mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); mFilter.addAction(WifiManager.RSSI_CHANGED_ACTION); mFilter.addAction(WifiManager.ERROR_ACTION); mReceiver = new BroadcastReceiver() { //这里设置广播的接收 @Override public void onReceive(Context context, Intent intent) { //如果接受到了消息, handleEvent(context, intent); //使用handleEvent去分析消息 } }; mScanner = new Scanner(); //处理完后我们会返回到这里!!mScanner是一个WifiSetting类中的一个私有成员private final Scanner mScanner;}private void handleEvent(Context context, Intent intent) { String action = intent.getAction(); if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) { //如果是WIFI_STATE_CHANGED_ACTION的话, updateWifiState(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,//使用updateWifiState来更新wifi状态,参数EXTRA_WIFI_STATE还是WIFI_STATE_ENABLED WifiManager.WIFI_STATE_UNKNOWN)); } else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action) || WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION.equals(action) || WifiManager.LINK_CONFIGURATION_CHANGED_ACTION.equals(action)) { updateAccessPoints(); } else if (WifiManager.SUPPLICANT_STATE_CHANGED_ACTION.equals(action)) { //... //... //...} private void updateWifiState(int state) { getActivity().invalidateOptionsMenu(); switch (state) { case WifiManager.WIFI_STATE_ENABLED: //我们设置的wifi的状态为WIFI_STATE_ENABLED mScanner.resume(); //所以执行这个 return; // not break, to avoid the call to pause() below //这里直接返回了,为了避免下面的pause,我们返回直接返回到了WifiSettings()中,里面还有一件事我们要做Q4 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(); }Q4:我们要做的是mScanner = new Scanner(); 这个,看Scanner的构造函数去,private class Scanner extends Handler { private int mRetry = 0; void resume() { if (!hasMessages(0)) { //如果没有消息 sendEmptyMessage(0);//发送一个空消息 } } void forceScan() { removeMessages(0); sendEmptyMessage(0); } void pause() { mRetry = 0; removeMessages(0); } @Override public void handleMessage(Message message) { //发送空消息后来到这个处理函数 if (mWifiManager.startScanActive()) { //调用了mWifiManager的startScanActive方法我们又要到这里看看了 mRetry = 0; } else if (++mRetry >= 3) { mRetry = 0; Toast.makeText(getActivity(), R.string.wifi_fail_to_scan, Toast.LENGTH_LONG).show(); return; } sendEmptyMessageDelayed(0, WIFI_RESCAN_INTERVAL_MS); }}代码位置:frameworks/base/wifi/java/android/net/wifi/WifiManager.javapublic boolean startScanActive() { try { mService.startScan(true); //这里又调用了WifiService里面的startScan return true; } catch (RemoteException e) { return false; }}代码位置:frameworks/base/services/java/com/android/server/WifiService.java/** * see {@link android.net.wifi.WifiManager#startScan()} */public void startScan(boolean forceActive) { enforceChangePermission(); mWifiStateMachine.startScan(forceActive);//唉,调来调去,又回到了WifiStateMachine}代码位置:framworks/base/wifi/java/android/net/wifi/WifiStateMachine.java/** * TODO: doc */public void startScan(boolean forceActive) { sendMessage(obtainMessage(CMD_START_SCAN, forceActive ?//我们调用的时候传递的参数是forceActive,我们调用sendMessage发送了一条消息。 //还记得我们这一切都是由于设置wifi状态引起的,设置完wifi状态我们广播了消息,广播完消息我们切换到了 //mDriverStartedState状态,所以CMD_START_SCAN这个消息由mDriverStartedState的处理函数来处理 SCAN_ACTIVE : SCAN_PASSIVE, 0));}(7)mDriverStartedState切换到这个状态后,驱动就要开始工作了class DriverStartedState extends State { @Override public void enter() { if (DBG) log(getName() + "\n"); EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName()); mIsRunning = true; mInDelayedStop = false; updateBatteryWorkSource(null); /** * Enable bluetooth coexistence scan mode when bluetooth connection is active. * When this mode is on, some of the low-level scan parameters used by the * driver are changed to reduce interference with bluetooth */ WifiNative.setBluetoothCoexistenceScanModeCommand(mBluetoothConnectionActive); /* set country code */ setCountryCode(); /* set frequency band of operation */ setFrequencyBand(); /* initialize network state */ setNetworkDetailedState(DetailedState.DISCONNECTED); /* Remove any filtering on Multicast v6 at start */ WifiNative.stopFilteringMulticastV6Packets(); /* Reset Multicast v4 filtering state */ if (mFilteringMulticastV4Packets.get()) { WifiNative.startFilteringMulticastV4Packets(); } else { WifiNative.stopFilteringMulticastV4Packets(); } if (mIsScanMode) {//这里应该判断扫描状态,如果为1为SCAN_ONLY_MODE,应该只是扫描而不连接,0应该是为CONNECT_MODE,应该是连接 WifiNative.setScanResultHandlingCommand(SCAN_ONLY_MODE); WifiNative.disconnectCommand(); transitionTo(mScanModeState); //这里要转换状态了,根据不同的扫描模式进入不同的状态 } else { WifiNative.setScanResultHandlingCommand(CONNECT_MODE); WifiNative.reconnectCommand(); transitionTo(mDisconnectedState); } } @Override public boolean processMessage(Message message) { if (DBG) log(getName() + message.toString() + "\n"); boolean eventLoggingEnabled = true; switch(message.what) { case CMD_SET_SCAN_TYPE: if (message.arg1 == SCAN_ACTIVE) { WifiNative.setScanModeCommand(true); } else { WifiNative.setScanModeCommand(false); } break; case CMD_START_SCAN: //收到这个消息,我们要开始扫描了 eventLoggingEnabled = false; WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE);//调用WifiNative的scanCommand开始扫描 mScanResultIsPending = true; break; case CMD_SET_HIGH_PERF_MODE: setHighPerfModeEnabledNative(message.arg1 == 1); break; case CMD_SET_COUNTRY_CODE: String country = (String) message.obj; if (DBG) log("set country code " + country); if (!WifiNative.setCountryCodeCommand(country.toUpperCase())) { loge("Failed to set country code " + country); } break; case CMD_SET_FREQUENCY_BAND: int band = message.arg1; if (DBG) log("set frequency band " + band); if (WifiNative.setBandCommand(band)) { mFrequencyBand.set(band); //Fetch the latest scan results when frequency band is set startScan(true); } else { loge("Failed to set frequency band " + band); } break; case CMD_BLUETOOTH_ADAPTER_STATE_CHANGE: mBluetoothConnectionActive = (message.arg1 != BluetoothAdapter.STATE_DISCONNECTED); WifiNative.setBluetoothCoexistenceScanModeCommand(mBluetoothConnectionActive); break; case CMD_STOP_DRIVER: int mode = message.arg1; /* Already doing a delayed stop && not in ecm state */ if (mInDelayedStop && mode != IN_ECM_STATE) { if (DBG) log("Already in delayed stop"); break; } mInDelayedStop = true; mDelayedStopCounter++; if (DBG) log("Delayed stop message " + mDelayedStopCounter); if (mode == IN_ECM_STATE) { /* send a shut down immediately */ sendMessage(obtainMessage(CMD_DELAYED_STOP_DRIVER, mDelayedStopCounter, 0)); } else { /* send regular delayed shut down */ sendMessageDelayed(obtainMessage(CMD_DELAYED_STOP_DRIVER, mDelayedStopCounter, 0), DELAYED_DRIVER_STOP_MS); } break; case CMD_START_DRIVER: if (mInDelayedStop) { mInDelayedStop = false; mDelayedStopCounter++; if (DBG) log("Delayed stop ignored due to start"); } break; case CMD_DELAYED_STOP_DRIVER: if (message.arg1 != mDelayedStopCounter) break; if (getCurrentState() != mDisconnectedState) { WifiNative.disconnectCommand(); handleNetworkDisconnect(); } mWakeLock.acquire(); WifiNative.stopDriverCommand(); transitionTo(mDriverStoppingState); mWakeLock.release(); break; case CMD_START_PACKET_FILTERING: if (message.arg1 == MULTICAST_V6) { WifiNative.startFilteringMulticastV6Packets(); } else if (message.arg1 == MULTICAST_V4) { WifiNative.startFilteringMulticastV4Packets(); } else { loge("Illegal arugments to CMD_START_PACKET_FILTERING"); } break; case CMD_STOP_PACKET_FILTERING: if (message.arg1 == MULTICAST_V6) { WifiNative.stopFilteringMulticastV6Packets(); } else if (message.arg1 == MULTICAST_V4) { WifiNative.stopFilteringMulticastV4Packets(); } else { loge("Illegal arugments to CMD_STOP_PACKET_FILTERING"); } break; default: return NOT_HANDLED; } if (eventLoggingEnabled) { EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what); } return HANDLED; } @Override public void exit() { if (DBG) log(getName() + "\n"); mIsRunning = false; updateBatteryWorkSource(null); mScanResults = null; }}
0 0
- Wifi启动以及Wifi状态机
- Wifi层次结构状态机
- Wifi层次结构状态机
- android wifi状态机原理
- android4.0 WIFI的启动流程和状态机变化
- android4.0 WIFI的启动流程和状态机变化
- android4.0 WIFI的启动流程和状态机变化
- Android系统wifi状态机WifiStateMachine
- 深入分析 ESP32 的 WiFi 状态机
- wifi
- WIFI
- WIFI
- WiFi
- WIFI
- WIFI
- WiFI
- WIFI
- WIFI
- hdoj2089 不要62
- 建造者模式(生成器模式)
- TCP和UDP
- wamp下修改mysql访问密码的解决方法
- Cocos2d-x之 CCCallFunC家族
- Wifi启动以及Wifi状态机
- Jetty开发指导:Jetty Websocket API
- mysql 建表
- github 坑爹的仓库初始化设置
- C# 将基础数据类型转化成字节
- ci smarty 整合
- 2014-08-07处理 can not change the standard mfc resources问题
- python多线程编程(5): 条件变量同步
- 使用反射 访问类实例的所有属性与属性值