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
原创粉丝点击