一:打开wifi。

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

当用户点击android 设置按钮时,会创建wifisettings类,创建wifisettings类的条件应该在布局文件中指定,这个还不是太明白,有待研究。

由于wifisettings类是一个PreferenceFragment,当初始化wifisettings之后会调用onActivityCreated函数,

    public void onActivityCreated(Bundle savedInstanceState) {
                mWifiEnabler = new WifiEnabler(activity, actionBarSwitch);  //创建wifienabler类

    }

 

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

   

 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        //Do nothing if called as a result of a state machine event
        if (mStateMachineEvent) {
            return;
        }
        // Show toast message if Wi-Fi is not allowed in airplane mode
        if (isChecked && !WirelessSettings.isRadioAllowed(mContext, Settings.System.RADIO_WIFI)) {
            Toast.makeText(mContext, R.string.wifi_in_airplane_mode, Toast.LENGTH_SHORT).show();
            // Reset switch to off. No infinite check/listenenr loop.
            buttonView.setChecked(false);
        }

        // Disable tethering if enabling Wifi
        int wifiApState = mWifiManager.getWifiApState();
        if (isChecked && ((wifiApState == WifiManager.WIFI_AP_STATE_ENABLING) ||
                (wifiApState == WifiManager.WIFI_AP_STATE_ENABLED))) {
            mWifiManager.setWifiApEnabled(null, false);
        }

        if (mWifiManager.setWifiEnabled(isChecked)) {
            // Intent has been taken into account, disable until new state is active
            mSwitch.setEnabled(false);
        } else {
            // Error
            Toast.makeText(mContext, R.string.wifi_error, Toast.LENGTH_SHORT).show();
        }
    }

 

 

在onCheckedChanged函数里调用mWifiManager.setWifiEnabled函数,

在wifimanager.java中:

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

调用了mService.setWifiEnabled。

 

这里的mService是WifiService的代理,所以它实际调用的是wifiService里面的setWifiEnabled函数
mService的定义是 IWifiManager mService;

Iwifimanager的定义是public interface IWifiManager extends android.os.IInterface

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

public synchronized boolean setWifiEnabled(boolean enable) {
        enforceChangePermission();
        if (DBG) {
            Slog.e(TAG, "Invoking mWifiStateMachine.setWifiEnabled\n");
        }

        if (enable) {
            reportStartWorkSource();
        }
        mWifiStateMachine.setWifiEnabled(enable);

        /*
         * 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;
    }

以上函数又调用了mWifiStateMachine.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();

    }

再回到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。

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这个消息,发送WIFI_ENABLE_PENDING到wifip2pservice,如果不支持p2p的话,

wifiservice会回复一个WIFI_ENABLE_PROCEED消息:

class P2pNotSupportedState extends State {
        @Override
        public boolean processMessage(Message message) {
            switch (message.what) {
                // Allow Wi-Fi to proceed
                case WifiStateMachine.WIFI_ENABLE_PENDING:
                    replyToMessage(message, WIFI_ENABLE_PROCEED);
                    break;

然后继续切换到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通信,加载驱动成功后会发送消息CMD_LOAD_DRIVER_SUCCESS,

DriverLoadingState状态接收到CMD_LOAD_DRIVER_SUCCESS消息,然后处理:

public boolean processMessage(Message message) {
            if (DBG) log(getName() + message.toString() + "\n");
            switch (message.what) {
                case CMD_LOAD_DRIVER_SUCCESS:
                    transitionTo(mDriverLoadedState);
                    break;

 

然后切换到DriverLoadedState状态。

来看另一个消息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驱动通信.

当startSupplicant返回真时,会启动wifiMonitor线程来接收从wpa_supplicant发送的消息,之后切换到SupplicantStartingState状态。

 

 

 

更多相关文章

  1. android输入法状态控制
  2. Android控件笔记——多状态按钮ToggleButton
  3. Android消息提示:AlertDialog、Toast、Notification的使用
  4. Android 沉浸式状态栏,别搞那么麻烦
  5. Android消息处理机制-Handler&Message概述与使用(含源码解析)
  6. Android 沉浸式状态栏实现, 在Activity和Fragment中
  7. Android消息机制学习
  8. 重磅消息!Android与IOS的合体!高仿IOS动态高斯模糊背景!

随机推荐

  1. THINKPHP 中关联查询(多表查询)
  2. 使用phpstorm进行PHP断点调试
  3. centos上安装php运行环境
  4. 招聘php开发工程师3-5人
  5. HPH+Mysql注入点利用 读取文件内容和导出
  6. 如何只从$_SERVER['HTTP_REFERER']中选择
  7. 选择* to table,其中datetime是24小时前
  8. 如何调整图像覆盖滑块
  9. PHP的文本到HTML转换器
  10. PHP接收到的$_POST数据里的邮箱符号@变成