Android 4.0 WIFI初始化与启动流程

xiaoxiao2021-02-28  132

这几天闲着没事,我就随便拿起Android源码看看。以下要讲的是在ICS中wifi初始化的一些流程。

涉及的文件有:

SystemServer.Java

WifiSettings.java

WifiEnabler.java

WifiManager.java

WifiService.java

WifiStateMachine.java

android_net_wifi_wifi.cpp

wifi.c

首先从SystemServer.java开始,它做了3个动作:

1.添加注册ConnectivityService连接服务,它跟所有手机的无线通信都有联系,包括wifi,蓝牙,2g网络,3g网络等

connectivity = new ConnectivityService(                         context, networkManagement, networkStats, networkPolicy); ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);

2.管理开机wifi开启与否的问题

wifi.checkAndStartWifi();

    public void checkAndStartWifi() {         mAirplaneModeOn.set(isAirplaneModeOn());         mPersistWifiState.set(getPersistedWifiState());         boolean wifiEnabled = shouldWifiBeEnabled() || testAndClearWifiSavedState();         setWifiEnabled(wifiEnabled);         mWifiWatchdogStateMachine = WifiWatchdogStateMachine.                makeWifiWatchdogStateMachine(mContext);     }

3.添加注册wifi的核心服务wifiservice

 wifi = new WifiService(context);  ServiceManager.addService(Context.WIFI_SERVICE, wifi);

好了,机器启动的时候动作就这些。要开启wifi,还需要人在设置界面进行开启。·

下面将一步步介绍wifi是怎样开启起来的

进入wifi设置界面,相关文件WifiSettings.java

开启Wifi的组件是一个CompoundButton,跟它关联起来的是一个WifiEnabler.java类,它是在WifiSettings里面初始化的

    public void onActivityCreated(Bundle savedInstanceState) {                 mWifiEnabler = new WifiEnabler(activity, actionBarSwitch);

    }

当用户点击wifi的开启按钮时候,会触发WifiEnabler里面的onCheckedChanged函数

    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {         if (mWifiManager.setWifiEnabled(isChecked)) {             mSwitch.setEnabled(false);          } else {                 Toast.makeText(mContext, R.string.wifi_error, Toast.LENGTH_SHORT).show();     } 在onCheckedChanged函数里面,调用了WifiManager的setWifiEnabled方法

    public boolean setWifiEnabled(boolean enabled) {         try {             return mService.setWifiEnabled(enabled);         } catch (RemoteException e) {             return false;         }     }

它返回的是mService.setWifiEnabled(enabled),这里的mService是WifiService的代理,所以它实际调用的是wifiService里面的setWifiEnabled函数

public class WifiService extends IWifiManager.Stub ,我们可以看到WifiService继承一个接口IWifiManager.Stub,凡是继承了像这种形式写法的接口服务,都可以进行远程调用,这就是android内部的aidl通信。接下来进入wifiservice

    public synchronized boolean setWifiEnabled(boolean enable) {         mWifiStateMachine.setWifiEnabled(enable);     }

可以看到,又进入WifiStateMachine的setWifiEnabled方法,mWifiStateMachine是在Wifiservice的构造函数完成初始化 的

    WifiService(Context context) {         mWifiStateMachine = new WifiStateMachine(mContext, mInterfaceName);     }

先介绍一下WifiStateMachine这个类,光看名字就知道wifi状态机,它里面记录了wifi的各种状态,driverUnloadedstate、mDriverUnloadingState、mDriverLoadingState、mDriverLoadedState、mSupplicantStartingState,每种状态都有enter()、exit()、processMessage()3个函数,分别处理进入该状态,退出该状态的动作,以及消息处理。在WifiStateMachine构造函数里面,它把所有状态都添加进状态机去,形成一个状态树,并在结尾出启动这个状态机工作。

    public WifiStateMachine(Context context, String wlanInterface) {         addState(mDefaultState);             addState(mInitialState, mDefaultState);             addState(mDriverUnloadingState, mDefaultState);             addState(mDriverUnloadedState, mDefaultState);                 addState(mDriverFailedState, mDriverUnloadedState);             addState(mDriverLoadingState, mDefaultState);             addState(mDriverLoadedState, mDefaultState);             addState(mSupplicantStartingState, mDefaultState);             addState(mSupplicantStartedState, mDefaultState);                 addState(mDriverStartingState, mSupplicantStartedState);                 addState(mDriverStartedState, mSupplicantStartedState);                     addState(mScanModeState, mDriverStartedState);                     addState(mConnectModeState, mDriverStartedState);                         addState(mConnectingState, mConnectModeState);                         addState(mConnectedState, mConnectModeState);                         addState(mDisconnectingState, mConnectModeState);                         addState(mDisconnectedState, mConnectModeState);                         addState(mWaitForWpsCompletionState, mConnectModeState);                 addState(mDriverStoppingState, mSupplicantStartedState);                 addState(mDriverStoppedState, mSupplicantStartedState);             addState(mSupplicantStoppingState, mDefaultState);             addState(mSoftApStartingState, mDefaultState);             addState(mSoftApStartedState, mDefaultState);                 addState(mTetheringState, mSoftApStartedState);                 addState(mTetheredState, mSoftApStartedState);             addState(mSoftApStoppingState, mDefaultState);             addState(mWaitForP2pDisableState, mDefaultState);     。。。。。。。。。。

         start();

    }

具体状态机是如何工作的,这篇文章有很详细的介绍,我就不累赘了。

http://archive.cnblogs.com/a/2424626/

我们再回到mWifiStateMachine.setWifiEnabled(enable)函数;

    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);         } else {             sendMessage(CMD_STOP_SUPPLICANT);             /* Argument is the state that is entered upon success */             sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_DISABLED, 0));         }     }

它做了两个动作,向状态机发送了2个消息

sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_STATE_ENABLING, 0));加载驱动

sendMessage(CMD_START_SUPPLICANT);开启supplicant

它在哪里处理的呢?

状态机构造函数初始化时候,设置有个一个初始状态

        setInitialState(mInitialState);

我们进入mInitialState状态看看

        public void enter() {             if (WifiNative.isDriverLoaded()) {                 transitionTo(mDriverLoadedState);             }             else {                 transitionTo(mDriverUnloadedState);             } 因为最开始驱动都是没有加载的,所以进入transitionTo(mDriverUnloadedState);

transitionTo函数是状态切换的函数。

继续mDriverUnloadedState

    class DriverUnloadedState extends State {          @Override         public boolean processMessage(Message message) {                switch (message.what) {                 case CMD_LOAD_DRIVER:                     mWifiP2pChannel.sendMessage(WIFI_ENABLE_PENDING);                     transitionTo(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;         }     }

这里会处理刚才的CMD_LOAD_DRIVER这个消息,继续切换到mWaitForP2pDisableState

    class WaitForP2pDisableState extends State {         @Override         public boolean processMessage(Message message) {             if (DBG) log(getName() + message.toString() + "\n");             switch(message.what) {                 case WifiP2pService.WIFI_ENABLE_PROCEED:                     //restore argument from original message (CMD_LOAD_DRIVER)                     message.arg1 = mSavedArg;                     transitionTo(mDriverLoadingState);

                    break;

    }

状态继续切换到mDriverLoadingState

    class DriverLoadingState extends State {         @Override         public void enter() {               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()) {                         if (DBG) log("Driver load successful");                         sendMessage(CMD_LOAD_DRIVER_SUCCESS);                     } 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();         } 这里回调用WifiNative.loadDriver()加载驱动,成功后发送消息CMD_LOAD_DRIVER_SUCCESS,否则CMD_LOAD_DRIVER_FAILURE,进入JNI

static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject) {     return (jboolean)(::wifi_load_driver() == 0); }

会继续到wifi.c处理

int wifi_load_driver() { #ifdef WIFI_DRIVER_MODULE_PATH     char driver_status[PROPERTY_VALUE_MAX];     int count = 100; /* wait at most 20 seconds for completion */     int status = -1;     if (is_wifi_driver_loaded()) {         return 0;     }     /* ensure that wlan driver config file exists (if specified) */     if (ensure_wlan_driver_config_file_exists()) {         return -1;     }     property_set(DRIVER_PROP_NAME, "loading");     if(system(SDIO_POLLING_ON))         LOGW("Couldn't turn on SDIO polling: %s", SDIO_POLLING_ON);     if ('\0' != *DRIVER_SDIO_IF_MODULE_PATH) {        if (insmod(DRIVER_SDIO_IF_MODULE_PATH, DRIVER_SDIO_IF_MODULE_ARG) < 0) {            goto end;        }     }     if (insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG) < 0) {         if ('\0' != *DRIVER_SDIO_IF_MODULE_NAME) {            rmmod(DRIVER_SDIO_IF_MODULE_NAME);         }         goto end;     }     if (strcmp(FIRMWARE_LOADER,"") == 0) {         /* usleep(WIFI_DRIVER_LOADER_DELAY); */         property_set(DRIVER_PROP_NAME, "ok");     }     else {         property_set("ctl.start", FIRMWARE_LOADER);     }     sched_yield();     while (count-- > 0) {         if (property_get(DRIVER_PROP_NAME, driver_status, NULL)) {             if (strcmp(driver_status, "ok") == 0) {                 status = 0;                 goto end;             }             else if (strcmp(driver_status, "failed") == 0) {                 _wifi_unload_driver();                 goto end;             }         }         usleep(200000);     }     property_set(DRIVER_PROP_NAME, "timeout");     wifi_unload_driver(); end:     system(SDIO_POLLING_OFF);     return status; #else     property_set(DRIVER_PROP_NAME, "ok");     return 0; #endif }

这里有几个比较重要的宏

#define WIFI_DRIVER_MODULE_PATH         "/system/lib/modules/wlan.ko"驱动模块地址

static const char SUPP_CONFIG_FILE[]    = "/data/misc/wifi/wpa_supplicant.conf";  supplicant配置文件

在这里wifi.c会跟wpa_supplicant通信,加载驱动

来看另一个消息sendMessage(CMD_START_SUPPLICANT);在DriverLoadedState处理

    class DriverLoadedState extends State {         @Override         public boolean processMessage(Message message) {                          case CMD_START_SUPPLICANT:                     try {                         mNwService.wifiFirmwareReload(mInterfaceName, "STA");                     } catch (Exception e) {                         loge("Failed to reload STA firmware " + e);                         // continue                     }                    try {                          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()) {                         if (DBG) log("Supplicant start successful");                         mWifiMonitor.startMonitoring();                         transitionTo(mSupplicantStartingState);                     } else {                         loge("Failed to start supplicant!");                         sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_UNKNOWN, 0));                     }                     break;

继续调用JNI,WifiNative.startSupplicant(),过程差不多最后在wifi.c处理

int wifi_start_supplicant() {     return wifi_start_supplicant_common(SUPP_CONFIG_FILE); } int wifi_start_supplicant_common(const char *config_file)

。。。。。。。

最后也是在这里跟Wpa_supplicant驱动通信

在wifi状态发生改变的时候,wifistatemachine会通过setwifistate发送WIFI_STATE_CHANGED_ACTION消息通知外面

    private void setWifiState(int wifiState) {

        final Intent intent = new Intent(WifiManager.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); }

例如在驱动加载状态

    class DriverLoadingState extends State {             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;                     }     }

    class SupplicantStartingState extends State {         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);    }

在wifisettings里面也有广播监听器

    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);             }         };         mScanner = new Scanner();     } 当接受到广播会相应处理handleEvent

    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));         }     }

更新wifi状态

    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();     }         比如 case WifiManager.WIFI_STATE_ENABLED:当WIFI可用通知接受到的时候                 mScanner.resume();

Scanner resume函数

        void resume() {             if (!hasMessages(0)) {                 sendEmptyMessage(0);             }         }

再看处理

        @Override         public void handleMessage(Message message) {             if (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);         }     }

会调用mWifiManager.startScanActive()进行ap的扫描

所以当你点击wifi按钮,到驱动加载完成,发出WIFI_STATE_ENABLED消息的时候,

设置里面会进行扫描ap的动作

转载请注明原文地址: https://www.6miu.com/read-18692.html

最新回复(0)