当前位置: 代码迷 >> Android >> Android4.4(MT8685)源码WIFI-初始化二
  详细解决方案

Android4.4(MT8685)源码WIFI-初始化二

热度:585   发布时间:2016-04-28 02:56:44.0
Android4.4(MT8685)源码WIFI--初始化2

上一章我们讲到在SystemServer中会初始化一个WifiService对象,那么我们来看看这个WifiService的构造方法,路径:./frameworks/base/services/java/com/android/server/wifi/WifiService.java

<span style="font-size:14px;"><span style="font-size:12px;"><span style="font-size:10px;"> public WifiService(Context context) {        mContext = context;        mInterfaceName =  SystemProperties.get("wifi.interface", "wlan0");        mWifiStateMachine = new WifiStateMachine(mContext, mInterfaceName);        mWifiStateMachine.enableRssiPolling(true);        mBatteryStats = BatteryStatsService.getService();        mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);        mNotificationController = new WifiNotificationController(mContext, mWifiStateMachine);        mTrafficPoller = new WifiTrafficPoller(mContext, mInterfaceName);        mSettingsStore = new WifiSettingsStore(mContext);        HandlerThread wifiThread = new HandlerThread("WifiService");        wifiThread.start();        mClientHandler = new ClientHandler(wifiThread.getLooper());        mWifiStateMachineHandler = new WifiStateMachineHandler(wifiThread.getLooper());        mWifiController = new WifiController(mContext, this, wifiThread.getLooper());        mWifiController.start();        mBatchedScanSupported = mContext.getResources().getBoolean(                R.bool.config_wifi_batched_scan_supported);        registerForScanModeChange();        mContext.registerReceiver(                new BroadcastReceiver() {                    @Override                    public void onReceive(Context context, Intent intent) {                        ///M: modify for timing issue to access Settings.Global.AIRPLANE_MODE_ON                        boolean isAirplaneModeOn = intent.getBooleanExtra("state", false);                        SXlog.i(TAG, "ACTION_AIRPLANE_MODE_CHANGED isAirplaneModeOn="+isAirplaneModeOn);                                                if (mSettingsStore.handleAirplaneModeToggled(isAirplaneModeOn)) {                            mWifiController.sendMessage(CMD_AIRPLANE_TOGGLED);                        }                    }                },                new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));        // Adding optimizations of only receiving broadcasts when wifi is enabled        // can result in race conditions when apps toggle wifi in the background        // without active user involvement. Always receive broadcasts.        registerForBroadcasts();        ///M:        initializeExtra();    }</span></span></span>

这里主要创建一个WifiStateMachine,然后新建一个HandlerThread来处理消息,还创建了一个WifiController。接下来我们先分析WifiStateMachine。

WifiStateMachine用于控制整个Wifi的开启、关闭、连接、断开的状态切换,它继承了StateMachine,来看看构造方法的关键代码,路径为:./frameworks/base/wifi/java/android/net/wifi/WifiStateMachine.java

<span style="font-size:14px;"><span style="font-size:12px;"><span style="font-size:10px;">public WifiStateMachine(Context context, String wlanInterface) {        super("WifiStateMachine");        addState(mDefaultState);            addState(mInitialState, mDefaultState);            addState(mSupplicantStartingState, mDefaultState);            addState(mSupplicantStartedState, mDefaultState);                addState(mDriverStartingState, mSupplicantStartedState);                addState(mDriverStartedState, mSupplicantStartedState);                    addState(mScanModeState, mDriverStartedState);                    addState(mConnectModeState, mDriverStartedState);                        addState(mL2ConnectedState, mConnectModeState);                            addState(mObtainingIpState, mL2ConnectedState);                            addState(mVerifyingLinkState, mL2ConnectedState);                            addState(mCaptivePortalCheckState, mL2ConnectedState);                            addState(mConnectedState, mL2ConnectedState);                        addState(mDisconnectingState, mConnectModeState);                        addState(mDisconnectedState, mConnectModeState);                        addState(mWpsRunningState, mConnectModeState);                addState(mWaitForP2pDisableState, mSupplicantStartedState);                addState(mDriverStoppingState, mSupplicantStartedState);                addState(mDriverStoppedState, mSupplicantStartedState);            addState(mSupplicantStoppingState, mDefaultState);            addState(mSoftApStartingState, mDefaultState);            addState(mSoftApStartedState, mDefaultState);                addState(mTetheringState, mSoftApStartedState);                addState(mTetheredState, mSoftApStartedState);                addState(mUntetheringState, mSoftApStartedState);        setInitialState(mInitialState);        //start the state machine        start();    }</span></span></span>

这里添加了各种状态,并且调用了父类的start方法,说明此时,WifiStateMachine的状态为其初始状态,也就是mInitialState状态。


回到WifiService的构造方法中,还有一个WifiController对象被创建,WifiController类也是StateMachine的子类,看看其构造方法,路径:./frameworks/base/services/java/com/android/server/wifi/WifiController.java

<span style="font-size:14px;"><span style="font-size:12px;"><span style="font-size:10px;">WifiController(Context context, WifiService service, Looper looper) {        super(TAG, looper);        mContext = context;        mWifiStateMachine = service.mWifiStateMachine;        mSettingsStore = service.mSettingsStore;        mLocks = service.mLocks;        mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);        Intent idleIntent = new Intent(ACTION_DEVICE_IDLE, null);        mIdleIntent = PendingIntent.getBroadcast(mContext, IDLE_REQUEST, idleIntent, 0);        ///M: add plugin         mWifiFwkExt = MediatekClassFactory.createInstance(IWifiFwkExt.class, mContext);        addState(mDefaultState);            addState(mApStaDisabledState, mDefaultState);            addState(mStaEnabledState, mDefaultState);                addState(mDeviceActiveState, mStaEnabledState);                addState(mDeviceInactiveState, mStaEnabledState);                    addState(mScanOnlyLockHeldState, mDeviceInactiveState);                    addState(mFullLockHeldState, mDeviceInactiveState);                    addState(mFullHighPerfLockHeldState, mDeviceInactiveState);                    addState(mNoLockHeldState, mDeviceInactiveState);            addState(mStaDisabledWithScanState, mDefaultState);            addState(mApEnabledState, mDefaultState);            addState(mEcmState, mDefaultState);        if (mSettingsStore.isScanAlwaysAvailable()) {            setInitialState(mStaDisabledWithScanState);        } else {            setInitialState(mApStaDisabledState);        }        setLogRecSize(100);        setLogOnlyTransitions(false);        IntentFilter filter = new IntentFilter();        filter.addAction(ACTION_DEVICE_IDLE);        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);        mContext.registerReceiver(                new BroadcastReceiver() {                    @Override                    public void onReceive(Context context, Intent intent) {                        String action = intent.getAction();                        if (action.equals(ACTION_DEVICE_IDLE)) {                            sendMessage(CMD_DEVICE_IDLE);                        } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {                            mNetworkInfo = (NetworkInfo) intent.getParcelableExtra(                                    WifiManager.EXTRA_NETWORK_INFO);                        }                    }                },                new IntentFilter(filter));        initializeAndRegisterForSettingsChange(looper);    }</span></span></span>

这里把WifiService中的WifiStateMachine对象传递进来了,并且添加了各种状态,并且设置了初始状态。

在WifiService构造方法中创建了WifiController对象了就立即调用了它的start方法,所以此时WifiController所在状态为它的初始状态,那么它的初始状态为什么呢?我们可以看到当系统在Wifi关闭的状态下仍然可以扫描时,那么初始状态为mStaDisabledWithScanState,否则为mApStaDisabledState,目前我们的系统的初始状态应该属于后者,也就是mApStaDisabledState,那我们进入到其enter方法中

<span style="font-size:14px;"><span style="font-size:12px;"><span style="font-size:10px;">@Override        public void enter() {            if (DBG) log(getName() + "\n");        	            mWifiStateMachine.setSupplicantRunning(false);            // Supplicant can't restart right away, so not the time we switched off            mDisabledTimestamp = SystemClock.elapsedRealtime();            mDeferredEnableSerialNumber++;            mHaveDeferredEnable = false;        }</span></span></span>

其实这里没做什么特别的操作。此时WifiService的初始化分析完成。

在之前的SystemServer中,在WifiService对象创建之后,我们还调用了它的checkAndStartWifi方法,这个方法就是用来检测是否可以启动Wifi了

<span style="font-size:14px;"><span style="font-size:12px;"><span style="font-size:10px;"> /**     * Check if Wi-Fi needs to be enabled and start     * if needed     *     * This function is used only at boot time     */    public void checkAndStartWifi() {        ///M:         mWifiStateMachine.autoConnectInit();                /* Check if wi-fi needs to be enabled */        boolean wifiEnabled = mSettingsStore.isWifiToggleEnabled();        ///M: @{        if (mWifiStateMachine.hasCustomizedAutoConnect() && mSettingsStore.isAirplaneModeOn()) {            SXlog.i(TAG, "Don't enable wifi when airplane mode is on for customization.");        } else {        ///@}            Slog.i(TAG, "WifiService starting up with Wi-Fi " +                        (wifiEnabled ? "enabled" : "disabled"));            // If we are already disabled (could be due to airplane mode), avoid changing persist            // state here            if (wifiEnabled) setWifiEnabled(wifiEnabled);        }        mWifiWatchdogStateMachine = WifiWatchdogStateMachine.               makeWifiWatchdogStateMachine(mContext);    }</span></span></span>

这里获取到上一次系统的Wifi状态,根据状态来决定是否开启Wifi,我们看看setWifiEnabled这个方法

<span style="font-size:14px;"><span style="font-size:12px;"><span style="font-size:10px;"> /**     * see [email protected] android.net.wifi.WifiManager#setWifiEnabled(boolean)}     * @param enable [email protected] true} to enable, [email protected] false} to disable.     * @return [email protected] true} if the enable/disable operation was     *         started or is already in the queue.     */    public synchronized boolean setWifiEnabled(boolean enable) {        Slog.d(TAG, "setWifiEnabled: " + enable + " pid=" + Binder.getCallingPid()                    + ", uid=" + Binder.getCallingUid());        enforceChangePermission();        ///M: @{        if (mWifiStateMachine.hasCustomizedAutoConnect() && enable &&  mSettingsStore.isAirplaneModeOn()) {            SXlog.i(TAG, "Can't enable wifi when airplane mode is on for customization.");            return false;        }        ///@}        if (DBG) {            Slog.e(TAG, "Invoking mWifiStateMachine.setWifiEnabled\n");        }        if (FeatureOption.MTK_MOBILE_MANAGEMENT) {            if (enable == true) {                if (mMobileManagerService == null) {                    mMobileManagerService = IMobileManagerService.Stub.asInterface(                            ServiceManager.getService(Context.MOBILE_SERVICE));                }                try {                    mMobileManagerService.checkPermissionAsync(SubPermissions.CHANGE_WIFI_STATE_ON,                            Binder.getCallingUid(), new wifiOnPermissionCheckCallback());                } catch (RemoteException e) {                    Slog.e(TAG, "checkPermissionAsync() failed", e);                }                return true;            }        }        /*        * Caller might not have WRITE_SECURE_SETTINGS,        * only CHANGE_WIFI_STATE is enforced        */        long ident = Binder.clearCallingIdentity();        try {            if (! mSettingsStore.handleWifiToggled(enable)) {                // Nothing to do if wifi cannot be toggled                return true;            }        } finally {            Binder.restoreCallingIdentity(ident);        }        ///M: put extra mWifiIpoOff        Log.e("dd","mWifiIpoOff1="+String.valueOf(mWifiIpoOff));        mWifiController.obtainMessage(CMD_WIFI_TOGGLED, mWifiIpoOff ? 1 : 0 ).sendToTarget();        return true;    }</span></span></span>

这里主要就是想WifiController发送一个CMD_WIFI_TOGGLED消息,我们看看接收消息的地方,找到ApStaDisabledState类的processMessage方法

<span style="font-size:14px;"><span style="font-size:12px;"><span style="font-size:10px;"> @Override        public boolean processMessage(Message msg) {            SXlog.d(TAG, getName() + msg.toString() + "\n");            switch (msg.what) {                case CMD_WIFI_TOGGLED:                case CMD_AIRPLANE_TOGGLED:                    ///M: add WifiIpoOff@{                    boolean wifiIpoOff = (msg.arg1==1) ? true: false;                    boolean ipoStateChange= false;                    if(mWifiIpoOff!=wifiIpoOff) ipoStateChange=true;                    mWifiIpoOff = wifiIpoOff;                    if(wifiIpoOff ==true){                        SXlog.d(TAG,"ipooff  don't enable wifi\n");                        break;                    }                    if (mSettingsStore.isWifiToggleEnabled()) {                    //@}                        if (doDeferEnable(msg)) {                            if (mHaveDeferredEnable) {                                //  have 2 toggles now, inc serial number an ignore both                                mDeferredEnableSerialNumber++;                            }                            mHaveDeferredEnable = !mHaveDeferredEnable;                            break;                        }                        if (mDeviceIdle == false) {							Log.e("dd","ApStaDisabledState to mDeviceActiveState");                            transitionTo(mDeviceActiveState);                        } else {                            checkLocksAndTransitionWhenDeviceIdle();                        }                    ///M: check scan always avaliable only when ipo change from ipo on to off                    }else if (ipoStateChange ==true && mSettingsStore.isScanAlwaysAvailable() && mSettingsStore.isAirplaneModeOn()==false ) {                        SXlog.d(TAG,"ipoStateChange = "+ipoStateChange + "isAirplaneModeOn= "+mSettingsStore.isAirplaneModeOn());                        transitionTo(mStaDisabledWithScanState);                    }                    break;default:                    return NOT_HANDLED;            }            return HANDLED;        }</span></span></span>

这里只是简单的跳转状态到mDeviceActiveState,mDeviceActiveState状态的父状态是mStaEnabledState,所以分别会进入它们的enter方法:

<span style="font-size:14px;"><span style="font-size:12px;"><span style="font-size:10px;">    class StaEnabledState extends State {        @Override        public void enter() {            mWifiStateMachine.setSupplicantRunning(true);        }    class DeviceActiveState extends State {        @Override        public void enter() {            mWifiStateMachine.setOperationalMode(WifiStateMachine.CONNECT_MODE);            mWifiStateMachine.setDriverStart(true);            mWifiStateMachine.setHighPerfModeEnabled(false);        }</span></span></span>

这里都是向WifiStateMachine发送消息CMD_START_SUPPLICANT、SET_OPERATIONAL_MODE、CMD_START_DRIVER和SET_HTGH_PERF_MODE

先来看看处理CMD_START_SUPPLICANT消息的地方

<span style="font-size:14px;"><span style="font-size:12px;"><span style="font-size:10px;">@Override        public boolean processMessage(Message message) {            if (DBG) log(getName() + message.toString() + "\n");            switch (message.what) {                case CMD_START_SUPPLICANT:                    setWifiState(WIFI_STATE_ENABLING);                    if (mWifiNative.loadDriver()) {                        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);                           // IPv6 is enabled only as long as access point is connected since:                           // - IPv6 addresses and routes stick around after disconnection                           // - kernel is unaware when connected and fails to start IPv6 negotiation                           // - kernel can start autoconfiguration when 802.1x is not complete                            mNwService.disableIpv6(mInterfaceName);                        } catch (RemoteException re) {                            loge("Unable to change interface settings: " + re);                        } catch (IllegalStateException ie) {                            loge("Unable to change interface settings: " + ie);                        }                       /* Stop a running supplicant after a runtime restart                        * Avoids issues with drivers that do not handle interface down                        * on a running supplicant properly.                        */                        mWifiMonitor.killSupplicant(mP2pSupported);                        if(mWifiNative.startSupplicant(mP2pSupported)) {                            if (DBG) log("Supplicant start successful");                            mWifiMonitor.startMonitoring();                            transitionTo(mSupplicantStartingState);                        } else {                            loge("Failed to start supplicant!");                        }                    } else {                        loge("Failed to load driver");                    }                    break;                              default:                    return NOT_HANDLED;            }            return HANDLED;        }    }</span></span></span>

这里主要调用WifiNative的loadDriver和startSupplicant两个函数去加载wifi driver和启动wpa_supplicant,当启动成功wpa_supplicant后,就会调用WifiMonitor的startMonitoring去和wpa_supplicant建立socket连接,并不断的从wpa_supplicant收event。wpa_supplicant是一个独立的运行程序,它和应用程序之间通过socket来通信,主要存在两个socket连接,一个用来向wpa_supplicant发送命令,另一个是wpa_supplicant用来向应用程序通知event,应用程序在收到event后可以知道当前的连接状态来进行下一步动作。我们进入到WifiMonitor.startMonitoring这个函数看看:

<span style="font-size:14px;"><span style="font-size:12px;"><span style="font-size:10px;"> public synchronized void startMonitoring(String iface) {            WifiMonitor m = mIfaceMap.get(iface);            if (m == null) {                Log.e(TAG, "startMonitor called with unknown iface=" + iface);                return;            }            Log.d(TAG, "startMonitoring(" + iface + ") with mConnected = " + mConnected);            if (mConnected) {                m.mMonitoring = true;                m.mWifiStateMachine.sendMessage(SUP_CONNECTION_EVENT);            } else {                if (DBG) Log.d(TAG, "connecting to supplicant");                int connectTries = 0;                while (true) {                    if (mWifiNative.connectToSupplicant()) {                        m.mMonitoring = true;                        m.mWifiStateMachine.sendMessage(SUP_CONNECTION_EVENT);                        new MonitorThread(mWifiNative, this).start();                        mConnected = true;                        break;                    }                    if (connectTries++ < 5) {                        try {                            Thread.sleep(1000);                        } catch (InterruptedException ignore) {                        }                    } else {                    Log.d(TAG, "rmIfaceMap remove " + iface);                        mIfaceMap.remove(iface);                        ///M:@{                        if (!m.mInterfaceName.equals("ap0")) {                            m.mWifiStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);                        }                        ///@}                        Log.e(TAG, "startMonitoring(" + iface + ") failed! " );                        break;                    }                }            }        </span></span></span>


这个方法里面主要调用WifiNative的connenctToSupplicant去和wpa_supplicant建立socket连接,然后给WifiStateMachine发送一个SUP_CONNECTION_EVENT消息,最后新建一个MonitorThread运行,MonitorThread就是一个循环,不断的从wpa_supplicant收event,然后进行解析,并dispatch到不同的函数去处理,后面我们再来分析MonitorThread的流程。回到WifiStateMachine的InitialState中去看看如何处理CMD_START_SUPPLICANT的流程中来,当startMonitoring结束后,WifiStateMachine就跳转到SupplicantStartingState。

接着来看当WifiStateMachine处理完SUP_CONNECTION_EVENT消息后,马上会收到SET_OPERATIONAL_MODE和CMD_START_DRIVER消息,这两个消息都会被SupplicantStartingState延迟处理,SET_HTGH_PERF_MODE会被DefaultState处理。接着SupplicantStartingState会收到SUP_CONNECTION_EVENT,处理代码如下:

<span style="font-size:14px;"><span style="font-size:12px;"><span style="font-size:10px;"> @Override        public boolean processMessage(Message message) {            if (DBG) log(getName() + message.toString() + "\n");            switch(message.what) {                case WifiMonitor.SUP_CONNECTION_EVENT:                    if (DBG) log("Supplicant connection established");                    setWifiState(WIFI_STATE_ENABLED);                    mSupplicantRestartCount = 0;                    /* Reset the supplicant state to indicate the supplicant                     * state is not known at this time */                    mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);                    /* Initialize data structures */                    mLastBssid = null;                    mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;                    mLastSignalLevel = -1;                    mWifiInfo.setMacAddress(mWifiNative.getMacAddress());                    mWifiConfigStore.loadAndEnableAllNetworks();                    initializeWpsDetails();                    mStopSupplicantScan = false;                    mConnectNetwork = false;                    mLastExplicitNetworkId = INVALID_NETWORK_ID;                    mOnlineStartTime = 0;                    mUsingPppoe = false;                    if (mWifiFwkExt.hasCustomizedAutoConnect()) {                        mWifiNative.setBssExpireAge(IWifiFwkExt.BSS_EXPIRE_AGE);                        mWifiNative.setBssExpireCount(IWifiFwkExt.BSS_EXPIRE_COUNT);                        mDisconnectOperation = false;                        mScanForWeakSignal = false;                        mShowReselectDialog = false;                        if (!mWifiFwkExt.shouldAutoConnect()) {                            disableAllNetworks(false);                        }                    }                    if (FeatureOption.MTK_EAP_SIM_AKA) {                        if (isAirplaneModeOn()) {                            List<WifiConfiguration> networks = mWifiConfigStore.getConfiguredNetworks();                            if (null != networks) {                               for (WifiConfiguration network : networks) {                                    int value = network.enterpriseConfig.getEapMethod();                                    Xlog.d(TAG, "EAP value:" + value);                                    if (value == WifiEnterpriseConfig.Eap.SIM || value == WifiEnterpriseConfig.Eap.AKA) {                                        mWifiConfigStore.disableNetwork(network.networkId,                                            WifiConfiguration.DISABLED_UNKNOWN_REASON);                                    }                                }                            } else {                                Xlog.d(TAG, "Check for EAP_SIM_AKA, networks is null!");                            }                        }                    }                    sendSupplicantConnectionChangedBroadcast(true);                    transitionTo(mDriverStartedState);                    break;                case WifiMonitor.SUP_DISCONNECTION_EVENT:                    if (++mSupplicantRestartCount <= SUPPLICANT_RESTART_TRIES) {                        loge("Failed to setup control channel, restart supplicant");                        mWifiMonitor.killSupplicant(mP2pSupported);                        transitionTo(mInitialState);                        sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS);                    } else {                        loge("Failed " + mSupplicantRestartCount +                                " times to start supplicant, unload driver");                        mSupplicantRestartCount = 0;                        setWifiState(WIFI_STATE_UNKNOWN);                        transitionTo(mInitialState);                    }                    break;                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_OPERATIONAL_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;            }            return HANDLED;        }</span></span></span>


在SUP_CONNECTION_EVENT的处理流程中,主要是调用WifiConfigStore的loadAndEnableAllNetworks函数来加载并enable用户之前连接过并保存的AP,然后会初始化一些Wps相关的信息,最后transition到DriverStartedState上。再来看DriverStartedState的enter函数,这里面有一些重要的流程:

<span style="font-size:14px;"><span style="font-size:12px;"><span style="font-size:10px;">    class DriverStartedState extends State {        @Override        public void enter() {            /* set country code */            setCountryCode();            /* set frequency band of operation */            setFrequencyBand();            /* initialize network state */            setNetworkDetailedState(DetailedState.DISCONNECTED);            mDhcpActive = false;            startBatchedScan();            if (mOperationalMode != CONNECT_MODE) {                mWifiNative.disconnect();                mWifiConfigStore.disableAllNetworks();                if (mOperationalMode == SCAN_ONLY_WITH_WIFI_OFF_MODE) {                    setWifiState(WIFI_STATE_DISABLED);                }                transitionTo(mScanModeState);            } else {                /* Driver stop may have disabled networks, enable right after start */                mWifiConfigStore.enableAllNetworks();                if (DBG) log("Attempting to reconnect to wifi network ..");                mWifiNative.reconnect();                // Status pulls in the current supplicant state and network connection state                // events over the monitor connection. This helps framework sync up with                // current supplicant state                mWifiNative.status();                transitionTo(mDisconnectedState);            }</span></span></span>

enter函数的代码比较多,上面是精简后的代码,上面主要分为两条分支,一是OperationalMode != CONNECT_MODE,一种是OperationalMode = CONNECT_MODE,根据官方的解释,OperationalMode一共有三种,分别如下:

1.CONNECT_MODE,这种模式下,STA可以scan并连接热点

2.SCAN_ONLY_MODE,这种模式下,STA只能扫描热点

3.SCAN_ONLY_WIFI_OFF_MODE,在这种模式下,当wifi是toggle off的情况下,也可以进行scan

这三种模式默认的是CONNECT_MODE,后面两种模式现在用到的不多,但按照Google的设计,后面可能会有很多的app会用到,比如利用热点来进行点位,这个应用其实这需要能够scan,并不需要链接热点。那我们接看这OperationalMode = CONNECT_MODE的流程,它直接transition 到DisconnectedState,如上图中的Figure 4,在transition到DisconnectedState之前,还会向WifiNative下reconnect的命令,用于重新连接上次连接但没有forget的AP,即开机后自动连上AP。


接着会进入mDisconnectedState状态,由于mDisconnectedState的父状态为mConnectedState状态,所以会先进入mConnectedState状态再进入mDisconnectedState状态,在这两个状态的enter方法中都没有什么特别的操作。


分析到这里,系统启动Wifi的初始化分析已经完成。





  相关解决方案