Android Q Wifi开启流程

最近在处理一些wifi问题,所以梳理wifi的启动流程有助于快速定位wifi问题的根源。此篇是根据Android 10的源码来分析的,Android 11及以上略微有点不同,但大差不差。

wifi打开方式有两种,一是从Settings里面打开,二是从通知栏的快捷方式快速开启,两者的入口分别位于

  • packages\apps\Settings\src\com\android\settings\wifi\WifiEnabler.java
 	@Override
    public boolean onSwitchToggled(boolean isChecked) {
    
    
        //Do nothing if called as a result of a state machine event
        if (mStateMachineEvent) {
    
    
            return true;
        }
        // Show toast message if Wi-Fi is not allowed in airplane mode
        if (isChecked && !WirelessUtils.isRadioAllowed(mContext, Settings.Global.RADIO_WIFI)) {
    
    
            Toast.makeText(mContext, R.string.wifi_in_airplane_mode, Toast.LENGTH_SHORT).show();
            // Reset switch to off. No infinite check/listener loop.
            mSwitchWidget.setChecked(false);
            return false;
        }

        if (isChecked) {
    
    
            mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_WIFI_ON);
        } else {
    
    
            // Log if user was connected at the time of switching off.
            mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_WIFI_OFF,
                    mConnected.get());
        }
        //通过WifiManager.setWifiEnabled()开启/关闭wifi
        if (!mWifiManager.setWifiEnabled(isChecked)) {
    
    
            // Error
            mSwitchWidget.setEnabled(true);
            Toast.makeText(mContext, R.string.wifi_error, Toast.LENGTH_SHORT).show();
        }
        return true;
    }
  • frameworks\base\packages\SystemUI\src\com\android\systemui\qs\tiles\WifiTile.java
    @Override
    protected void handleClick() {
    
    
        // Secondary clicks are header clicks, just toggle.
        mState.copyTo(mStateBeforeClick);
        boolean wifiEnabled = mState.value;
        // Immediately enter transient state when turning on wifi.
        refreshState(wifiEnabled ? null : ARG_SHOW_TRANSIENT_ENABLING);
        //通过NetworkController.setWifiEnabled()开启wifi
        mController.setWifiEnabled(!wifiEnabled);
        mExpectDisabled = wifiEnabled;
        if (mExpectDisabled) {
    
    
            mHandler.postDelayed(() -> {
    
    
                if (mExpectDisabled) {
    
    
                    mExpectDisabled = false;
                    refreshState();
                }
            }, QSIconViewImpl.QS_ANIM_LENGTH);
        }
    }

NetworkController是一个接口,其实现类为NetworkControllerImpl,查看该类setWifiEnabled()的实现方式

	@Override
    public void setWifiEnabled(final boolean enabled) {
    
    
        new AsyncTask<Void, Void, Void>() {
    
    
            @Override
            protected Void doInBackground(Void... args) {
    
    
                //最终也是通过WifiManager.setWifiEnabled()控制wifi的开启
                mWifiManager.setWifiEnabled(enabled);
                return null;
            }
        }.execute();
    }

查看WifiManager.setWifiEnabled()的代码

 	@Deprecated
    public boolean setWifiEnabled(boolean enabled) {
    
    
        try {
    
    
            return mService.setWifiEnabled(mContext.getOpPackageName(), enabled);
        } catch (RemoteException e) {
    
    
            throw e.rethrowFromSystemServer();
        }
    }

这里的mService是WifiServiceImpl的代理对象IWifiManager,通过aidl方式调用了WifiServiceImpl的setWifiEnabled()方法,而WifiServiceImpl在WifiService启动时被创建,WifiService是一个SystemService,在系统启动的时候被启动

public final class WifiService extends SystemService {
    
    

    private static final String TAG = "WifiService";
    final WifiServiceImpl mImpl;

    public WifiService(Context context) {
    
    
        super(context);
        //创建WifiServiceImpl对象,wifi相关的处理都有此对象来完成
        mImpl = new WifiServiceImpl(context, new WifiInjector(context), new WifiAsyncChannel(TAG));
    }

    @Override
    public void onStart() {
    
    
        Log.i(TAG, "Registering " + Context.WIFI_SERVICE);
        publishBinderService(Context.WIFI_SERVICE, mImpl);
    }

    @Override
    public void onBootPhase(int phase) {
    
    
        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
    
    
            mImpl.checkAndStartWifi();
        } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
    
    
            mImpl.handleBootCompleted();
        }
    }

    @Override
    public void onSwitchUser(int userId) {
    
    
        mImpl.handleUserSwitch(userId);
    }

    @Override
    public void onUnlockUser(int userId) {
    
    
        mImpl.handleUserUnlock(userId);
    }

    @Override
    public void onStopUser(int userId) {
    
    
        mImpl.handleUserStop(userId);
    }
}

关于Android系统启动流程,后续会单独用一篇文章去分析,这里只需要知道WifiServiceImpl是什么时候被创建的,查看WifiServiceImpl.setWifiEnabled()

	@Override
    public synchronized boolean setWifiEnabled(String packageName, boolean enable) {
    
    
        return setWifiEnabled2(packageName, STA_PRIMARY, enable);
    }

    @Override
    public synchronized boolean setWifiEnabled2(String packageName, int staId, boolean enable) {
    
    
        if (enforceChangePermission(packageName) != MODE_ALLOWED) {
    
    
            return false;
        }
        boolean isPrivileged = isPrivileged(Binder.getCallingPid(), Binder.getCallingUid());
        if (!isPrivileged && !isDeviceOrProfileOwner(Binder.getCallingUid())
                && !mWifiPermissionsUtil.isTargetSdkLessThan(packageName, Build.VERSION_CODES.Q,
                  Binder.getCallingUid())
                && !isSystem(packageName, Binder.getCallingUid())) {
    
    
            mLog.info("setWifiEnabled not allowed for uid=%")
                    .c(Binder.getCallingUid()).flush();
            return false;
        }
        // If Airplane mode is enabled, only privileged apps are allowed to toggle Wifi
        if (mSettingsStore.isAirplaneModeOn() && !isPrivileged) {
    
    
            mLog.err("setWifiEnabled in Airplane mode: only Settings can toggle wifi").flush();
            return false;
        }

        // If SoftAp is enabled, only privileged apps are allowed to toggle wifi
        boolean apEnabled = mWifiApState == WifiManager.WIFI_AP_STATE_ENABLED;
        if (apEnabled && !isPrivileged) {
    
    
            mLog.err("setWifiEnabled SoftAp enabled: only Settings can toggle wifi").flush();
            return false;
        }

        // If we're in crypt debounce, ignore any wifi state change APIs.
        if (mFrameworkFacade.inStorageManagerCryptKeeperBounce()) {
    
    
            return false;
        }

        mLog.info("setWifiEnabled package=% uid=% enable=%").c(packageName)
                .c(Binder.getCallingUid()).c(enable).flush();
        long ident = Binder.clearCallingIdentity();
        try {
    
    
            if (staId == STA_PRIMARY && !mSettingsStore.handleWifiToggled(enable)) {
    
    
                // Nothing to do if wifi cannot be toggled
                return true;
            }
        } finally {
    
    
            Binder.restoreCallingIdentity(ident);
        }

        if (!mIsControllerStarted) {
    
    
            Slog.e(TAG,"WifiController is not yet started, abort setWifiEnabled");
            return false;
        }

        mWifiMetrics.incrementNumWifiToggles(isPrivileged, enable);

        if (staId == STA_PRIMARY) {
    
    
            //这里通过Handler发送了一个消息,通知系统wifi状态发生了改变
            mWifiController.sendMessage(CMD_WIFI_TOGGLED);
        } else if ((getNumConcurrentStaSupported() > 1)
                   && (getWifiEnabledState() == WifiManager.WIFI_STATE_ENABLED)
                   && staId > STA_PRIMARY) {
    
    
            mWifiController.sendMessage(CMD_ADD_WIFI_SET, staId, enable ? 1 : 0);
        } else {
    
    
           Slog.e(TAG,"setWifiEnabled not allowed for id:"+staId);
           return false;
        }

        return true;
    }

mWififContoller中定义了一个SmHandler,通过SmHandler发送了一个wifi状态改变的消息,然后在其handleMessage()方法中处理消息

		@Override
        public final void handleMessage(Message msg) {
    
    
            if (!mHasQuit) {
    
    
                if (mSm != null && msg.what != SM_INIT_CMD && msg.what != SM_QUIT_CMD) {
    
    
                    mSm.onPreHandleMessage(msg);
                }

                if (mDbg) mSm.log("handleMessage: E msg.what=" + msg.what);

                /** Save the current message */
                mMsg = msg;

                /** State that processed the message */
                State msgProcessedState = null;
                if (mIsConstructionCompleted || (mMsg.what == SM_QUIT_CMD)) {
    
    
                    /** Normal path */
                    //执行processMsg方法处理消息
                    msgProcessedState = processMsg(msg);
                } else if (!mIsConstructionCompleted && (mMsg.what == SM_INIT_CMD)
                        && (mMsg.obj == mSmHandlerObj)) {
    
    
                    /** Initial one time path. */
                    mIsConstructionCompleted = true;
                    invokeEnterMethods(0);
                } else {
    
    
                    throw new RuntimeException("StateMachine.handleMessage: "
                            + "The start method not called, received msg: " + msg);
                }
                //执行transitions方法,该方法是为了执行下一状态的enter()方法
                performTransitions(msgProcessedState, msg);

                // We need to check if mSm == null here as we could be quitting.
                if (mDbg && mSm != null) mSm.log("handleMessage: X");

                if (mSm != null && msg.what != SM_INIT_CMD && msg.what != SM_QUIT_CMD) {
    
    
                    mSm.onPostHandleMessage(msg);
                }
            }
        }
		private final State processMsg(Message msg) {
    
    
            //获取当前状态机
            StateInfo curStateInfo = mStateStack[mStateStackTopIndex];
            if (mDbg) {
    
    
                mSm.log("processMsg: " + curStateInfo.state.getName());
            }

            if (isQuit(msg)) {
    
    
                transitionTo(mQuittingState);
            } else {
    
    
                //执行状态机的processMessage()方法
                while (!curStateInfo.state.processMessage(msg)) {
    
    
                    /**
                     * Not processed
                     */
                    curStateInfo = curStateInfo.parentStateInfo;
                    if (curStateInfo == null) {
    
    
                        /**
                         * No parents left so it's not handled
                         */
                        mSm.unhandledMessage(msg);
                        break;
                    }
                    if (mDbg) {
    
    
                        mSm.log("processMsg: " + curStateInfo.state.getName());
                    }
                }
            }
            return (curStateInfo != null) ? curStateInfo.state : null;
        }

首先获取当前wifi状态,wifi状态是通过StateMachine状态机来管理的,状态机划分如下

  • ModeStateMachine:非客户端模式下的状态机
    • StaDisabledState:wifi不可用状态
    • StaEnabledState:wifi可用状态
  • ClientModeStateMachine:客户端模式下的状态机
    • WifiDisabledState:wifi不可用状态
    • ClientModeActiveState:wifi激活状态
      • IdleState:空闲状态
      • StartedState:已启动状态
    • ScanOnlyModeActiveState:扫描状态

获取到State之后执行对应的processMessage()方法,这里研究开启流程,默认从ModeStateMachine到ClientModeStateMachine的顺序执行,所以先执行的是StaDisabledState的processMessage()方法

		@Override
        public boolean processMessage(Message msg) {
    
    
            switch (msg.what) {
    
    
                case CMD_WIFI_TOGGLED:
                    if (mSettingsStore.isWifiToggleEnabled()) {
    
    
                        if (doDeferEnable(msg)) {
    
    
                            if (mHaveDeferredEnable) {
    
    
                                //  have 2 toggles now, inc serial number and ignore both
                                mDeferredEnableSerialNumber++;
                            }
                            mHaveDeferredEnable = !mHaveDeferredEnable;
                            break;
                        }
                        //将状态切换到StaEnabledState,执行该状态的enter()方法
                        transitionTo(mStaEnabledState);
                    } else if (checkScanOnlyModeAvailable()) {
    
    
                        // only go to scan mode if we aren't in airplane mode
                        if (mSettingsStore.isAirplaneModeOn()) {
    
    
                            transitionTo(mStaDisabledWithScanState);
                        }
                    }
                    break;
                case CMD_SCAN_ALWAYS_MODE_CHANGED:
                    if (checkScanOnlyModeAvailable()) {
    
    
                        transitionTo(mStaDisabledWithScanState);
                        break;
                    }
                    break;
                case CMD_SET_AP:
                    if (msg.arg1 == 1) {
    
    
                        // remember that we were disabled, but pass the command up to start softap
                        mSettingsStore.setWifiSavedState(WifiSettingsStore.WIFI_DISABLED);
                    }
                    return NOT_HANDLED;
                case CMD_DEFERRED_TOGGLE:
                    if (msg.arg1 != mDeferredEnableSerialNumber) {
    
    
                        log("DEFERRED_TOGGLE ignored due to serial mismatch");
                        break;
                    }
                    log("DEFERRED_TOGGLE handled");
                    sendMessage((Message)(msg.obj));
                    break;
                case CMD_DEFERRED_RECOVERY_RESTART_WIFI:
                    // wait mRecoveryDelayMillis for letting driver clean reset.
                    sendMessageDelayed(CMD_RECOVERY_RESTART_WIFI_CONTINUE, mRecoveryDelayMillis);
                    break;
                case CMD_RECOVERY_RESTART_WIFI_CONTINUE:
                    if (mSettingsStore.isWifiToggleEnabled()) {
    
    
                        // wifi is currently disabled but the toggle is on, must have had an
                        // interface down before the recovery triggered
                        transitionTo(mStaEnabledState);
                        break;
                    } else if (checkScanOnlyModeAvailable()) {
    
    
                        transitionTo(mStaDisabledWithScanState);
                        break;
                    }
                    break;
                default:
                    return NOT_HANDLED;
            }
            return HANDLED;
        }

StaDisabledState在处理CMD_WIFI_TOGGLED消息时,直接通过transitionTo()将状态切换至StaEnabledState,在SmHandler的handleMessage()中,执行完msgProcessedState = processMsg(msg)后会执行performTransitions(msgProcessedState, msg),此方法里面执行了invokeEnterMethods(stateStackEnteringIndex),该方法就是调用State的enter()方法,也就是说状态切换后会立即执行当前状态的enter()方法,查看StaEnabledState的enter()方法

		@Override
        public void enter() {
    
    
            log("StaEnabledState.enter()");
            mActiveModeWarden.enterClientMode();
        }

执行了ActiveModeWarden.enterClientMode(),进入客户端模式,查看该方法

	public void enterClientMode() {
    
    
        changeMode(ModeStateMachine.CMD_START_CLIENT_MODE);
    }
	private void changeMode(int newMode) {
    
    
        mModeStateMachine.sendMessage(newMode);
    }

这里通过mModeStateMachine里面的SmHandler对象发送了CMD_START_CLIENT_MODE消息,对应的由客户端模式下的WifiDisabledState来处理此消息,因为ModeStateMachine创建时设置WifiDisabledState为初始化的状态,如下:

		ModeStateMachine() {
    
    
            super(TAG, mLooper);

            addState(mClientModeActiveState);
            addState(mScanOnlyModeActiveState);
            addState(mWifiDisabledState);

            Log.d(TAG, "Starting Wifi in WifiDisabledState");
            //设置WifiDisabledState为初始化状态
            setInitialState(mWifiDisabledState);
            start();
        }

查看WifiDisabledState,注意WifiDisabledState是ModeStateMachine的内部类,而ModeStateMachine又是ActiveModeWarden的内部类

		class WifiDisabledState extends ModeActiveState {
    
    
            @Override
            public void enter() {
    
    
                Log.d(TAG, "Entering WifiDisabledState");
            }

            @Override
            public boolean processMessage(Message message) {
    
    
                Log.d(TAG, "received a message in WifiDisabledState: " + message);
                //处理CMD_START_CLIENT_MODE消息
                if (checkForAndHandleModeChange(message)) {
    
    
                    return HANDLED;
                }
                return NOT_HANDLED;
            }

            @Override
            public void exit() {
    
    
                // do not have an active mode manager...  nothing to clean up
            }

        }

又执行checkForAndHandleModeChange()处理消息

		private boolean checkForAndHandleModeChange(Message message) {
    
    
            switch(message.what) {
    
    
                case ModeStateMachine.CMD_START_CLIENT_MODE:
                    Log.d(TAG, "Switching from " + getCurrentMode() + " to ClientMode");
                    if (getCurrentMode().equals(mClientModeActiveState.getName()))
                        return NOT_HANDLED;
                    //将状态切换至ClientModeActiveState
                    mModeStateMachine.transitionTo(mClientModeActiveState);
                    break;
                case ModeStateMachine.CMD_START_SCAN_ONLY_MODE:
                    Log.d(TAG, "Switching from " + getCurrentMode() + " to ScanOnlyMode");
                    if (getCurrentMode().equals(mScanOnlyModeActiveState.getName()))
                        return NOT_HANDLED;
                    mModeStateMachine.transitionTo(mScanOnlyModeActiveState);
                    break;
                case ModeStateMachine.CMD_DISABLE_WIFI:
                    Log.d(TAG, "Switching from " + getCurrentMode() + " to WifiDisabled");
                    if (getCurrentMode().equals(mWifiDisabledState.getName()))
                        return NOT_HANDLED;
                    mModeStateMachine.transitionTo(mWifiDisabledState);
                    break;
                default:
                    return NOT_HANDLED;
            }
            return HANDLED;
        }

这里状态机直接将状态切换至ClientModeActiveState,此时会执行ClientModeActiveState的enter()方法

			@Override
            public void enter() {
    
    
                Log.d(TAG, "Entering ClientModeActiveState");

                mListener = new ClientListener();
                //创建wifi客户端管理者ClientModeManager
                mManager = mWifiInjector.makeClientModeManager(mListener);
                //启动客户端模式
                mManager.start();
                mActiveModeManagers.add(mManager);

                updateBatteryStatsWifiState(true);
            }

查看start()

	/**
     * Start client mode.
     */
    public void start() {
    
    
        mStateMachine.sendMessage(ClientModeStateMachine.CMD_START);
    }

这里又通过ClientModeStateMachine发送了一个CMD_START消息,使状态机由激活状态下的空闲状态变为已开启状态,而ClientModeStateMachine初始化时也是设置的IdleState为默认状态

		ClientModeStateMachine(Looper looper) {
    
    
            super(TAG, looper);

            addState(mIdleState);
            addState(mStartedState);
			//设置IdleState为默认状态
            setInitialState(mIdleState);
            start();
        }

所以这里先由IdleState处理此消息

		private class IdleState extends State {
    
    

            @Override
            public void enter() {
    
    
                Log.d(TAG, "entering IdleState");
                mClientInterfaceName = null;
                mIfaceIsUp = false;
            }

            @Override
            public boolean processMessage(Message message) {
    
    
                switch (message.what) {
    
    
                    case CMD_START:
                    	//将wifi状态由不可用变为连接中状态
                        updateWifiState(WifiManager.WIFI_STATE_ENABLING,
                                        WifiManager.WIFI_STATE_DISABLED);
						//为连接状态下的客户端设置一个接口,此接口用于上层客户端与hal层通信
                        mClientInterfaceName =
                                mWifiNative.setupInterfaceForClientInConnectivityMode(
                                mWifiNativeInterfaceCallback);
                        if (TextUtils.isEmpty(mClientInterfaceName)) {
    
    
                            Log.e(TAG, "Failed to create ClientInterface. Sit in Idle");
                            updateWifiState(WifiManager.WIFI_STATE_UNKNOWN,
                                            WifiManager.WIFI_STATE_ENABLING);
                            updateWifiState(WifiManager.WIFI_STATE_DISABLED,
                                            WifiManager.WIFI_STATE_UNKNOWN);
                            break;
                        }
                        //将状态切换至已启动状态
                        transitionTo(mStartedState);
                        break;
                    default:
                        Log.d(TAG, "received an invalid message: " + message);
                        return NOT_HANDLED;
                }
                return HANDLED;
            }
        }

updateWifiState()方法会更新wifi的状态,此更新会发送一个全局的粘性广播,随后通过mWifiNative.setupInterfaceForClientInConnectivityMode(mWifiNativeInterfaceCallback)为连接状态下的客户端设置一个接口,此接口用于上层客户端与hal层通信,看一下该方法的实现

    /**
     * Setup an interface for client mode (for connectivity) operations.
     *
     * This method configures an interface in STA mode in all the native daemons
     * (wificond, wpa_supplicant & vendor HAL).
     *
     * @param interfaceCallback Associated callback for notifying status changes for the iface.
     * @return Returns the name of the allocated interface, will be null on failure.
     */
    public String setupInterfaceForClientInConnectivityMode(
            @NonNull InterfaceCallback interfaceCallback) {
    
    
        return setupInterfaceForClientInConnectivityMode(interfaceCallback, false);
    }
    /**
     * Setup an interface for client mode (for connectivity) operations.
     *
     * This method configures an interface in STA mode in all the native daemons
     * (wificond, wpa_supplicant & vendor HAL).
     *
     * @param interfaceCallback Associated callback for notifying status changes for the iface.
     * @param lowPriority the iface is of low priority.
     * @return Returns the name of the allocated interface, will be null on failure.
     */
    public String setupInterfaceForClientInConnectivityMode(
            @NonNull InterfaceCallback interfaceCallback, boolean lowPriority) {
    
    
        synchronized (mLock) {
    
    
            //加载wifi驱动
            if (!startHal()) {
    
    
                Log.e(TAG, "Failed to start Hal");
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
                return null;
            }
			//启动FST管理器,并开启与FST组的通信
            boolean res = startFst();
            if (!res)
                return null;
			//建立与spplicant的连接
            if (!startSupplicant()) {
    
    
                Log.e(TAG, "Failed to start supplicant");
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
                return null;
            }
            //分配Iface,全名Internet Interface,就是我们说的网卡
            Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_STA_FOR_CONNECTIVITY);
            if (iface == null) {
    
    
                Log.e(TAG, "Failed to allocate new STA iface");
                return null;
            }
            //绑定Iface的回调对象
            iface.externalListener = interfaceCallback;
            //设置Iface的名称
            iface.name = createStaIface(iface, lowPriority);
            if (TextUtils.isEmpty(iface.name)) {
    
    
                Log.e(TAG, "Failed to create STA iface in vendor HAL");
                mIfaceMgr.removeIface(iface.id);
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
                return null;
            }
            //为mWificondControl绑定Iface
            if (mWificondControl.setupInterfaceForClientMode(iface.name) == null) {
    
    
                Log.e(TAG, "Failed to setup iface in wificond on " + iface);
                teardownInterface(iface.name);
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToWificond();
                return null;
            }
            //为mSupplicantStaIfaceHal绑定Iface
            if (!mSupplicantStaIfaceHal.setupIface(iface.name)) {
    
    
                Log.e(TAG, "Failed to setup iface in supplicant on " + iface);
                teardownInterface(iface.name);
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
                return null;
            }
            if (mIsFstAvailable) {
    
    
                if (!mSupplicantStaIfaceHal.setupIface(getFstSlaveIface())) {
    
    
                    Log.e(TAG, "Failed to setup iface " + getFstSlaveIface() + " in supplicant on");
                    teardownInterface(iface.name);
                    return null;
                }
            }
            //创建网络观察者
            iface.networkObserver = new NetworkObserverInternal(iface.id);
            if (!registerNetworkObserver(iface.networkObserver)) {
    
    
                Log.e(TAG, "Failed to register network observer on " + iface);
                teardownInterface(iface.name);
                return null;
            }
            //启动wifi监视器
            mWifiMonitor.startMonitoring(iface.name);
            // Just to avoid any race conditions with interface state change callbacks,
            // update the interface state before we exit.
            //激活Iface,up-激活,down-禁用
            onInterfaceStateChanged(iface, isInterfaceUp(iface.name));
            //初始化Iface信息
            initializeNwParamsForClientInterface(iface.name);
            Log.i(TAG, "Successfully setup " + iface);

            iface.featureSet = getSupportedFeatureSetInternal(iface.name);
            return iface.name;
        }
    }

此方法基本上涵盖了wifi开启的全过程,从加载驱动,建立通信到分配网卡,基本都是在hal层完成的,上层设置好回调接口后直接执行结果回调即可。关于hal层的启动流程后续会再梳理。

hal层启动之后再通过transitionTo(mStartedState)将状态切换至StartedState,此时执行StartedState的enter()方法

		private class StartedState extends State {
    
    

            private void onUpChanged(boolean isUp) {
    
    
                if (isUp == mIfaceIsUp) {
    
    
                    return;  // no change
                }
                mIfaceIsUp = isUp;
                if (isUp) {
    
    
                    Log.d(TAG, "Wifi is ready to use for client mode");
                    //将wifi状态由连接中更改为已连接
                    mClientModeImpl.setOperationalMode(ClientModeImpl.CONNECT_MODE,
                                                       mClientInterfaceName);
                    updateWifiState(WifiManager.WIFI_STATE_ENABLED,
                                    WifiManager.WIFI_STATE_ENABLING);
                } else {
    
    
                    if (mClientModeImpl.isConnectedMacRandomizationEnabled()) {
    
    
                        // Handle the error case where our underlying interface went down if we
                        // do not have mac randomization enabled (b/72459123).
                        return;
                    }
                    // if the interface goes down we should exit and go back to idle state.
                    Log.d(TAG, "interface down!");
                    updateWifiState(WifiManager.WIFI_STATE_UNKNOWN,
                                    WifiManager.WIFI_STATE_ENABLED);
                    mStateMachine.sendMessage(CMD_INTERFACE_DOWN);
                }
            }

            @Override
            public void enter() {
    
    
                Log.d(TAG, "entering StartedState");
                mIfaceIsUp = false;
                //执行状态更改逻辑
                onUpChanged(mWifiNative.isInterfaceUp(mClientInterfaceName));
            }

            @Override
            public boolean processMessage(Message message) {
    
    
                switch(message.what) {
    
    
                    case CMD_START:
                        // Already started, ignore this command.
                        break;
                    case CMD_INTERFACE_DOWN:
                        Log.e(TAG, "Detected an interface down, reporting failure to SelfRecovery");
                        mClientModeImpl.failureDetected(SelfRecovery.REASON_STA_IFACE_DOWN);

                        updateWifiState(WifiManager.WIFI_STATE_DISABLING,
                                        WifiManager.WIFI_STATE_UNKNOWN);
                        transitionTo(mIdleState);
                        break;
                    case CMD_INTERFACE_STATUS_CHANGED:
                        boolean isUp = message.arg1 == 1;
                        onUpChanged(isUp);
                        break;
                    case CMD_INTERFACE_DESTROYED:
                        Log.d(TAG, "interface destroyed - client mode stopping");

                        updateWifiState(WifiManager.WIFI_STATE_DISABLING,
                                        WifiManager.WIFI_STATE_ENABLED);
                        mClientInterfaceName = null;
                        transitionTo(mIdleState);
                        break;
                    default:
                        return NOT_HANDLED;
                }
                return HANDLED;
            }

            /**
             * Clean up state, unregister listeners and update wifi state.
             */
            @Override
            public void exit() {
    
    
                mClientModeImpl.setOperationalMode(ClientModeImpl.DISABLED_MODE, null);

                if (mClientInterfaceName != null) {
    
    
                    mWifiNative.teardownInterface(mClientInterfaceName);
                    mClientInterfaceName = null;
                    mIfaceIsUp = false;
                }

                updateWifiState(WifiManager.WIFI_STATE_DISABLED,
                                WifiManager.WIFI_STATE_DISABLING);

                // once we leave started, nothing else to do...  stop the state machine
                mStateMachine.quitNow();
            }
        }

enter()方法中执行了onUpChanged(mWifiNative.isInterfaceUp(mClientInterfaceName)),此方法中通过updateWifiState()更新wifi状态,将连接中更改为已连接,至此,wifi才得以真正的启动。同时在updateWifiState()中,会触发ClientModeManager.Listener的回调

	/**
     * Update Wifi state and send the broadcast.
     * @param newState new Wifi state
     * @param currentState current wifi state
     */
    private void updateWifiState(int newState, int currentState) {
    
    
        if (!mExpectedStop) {
    
    
            //触发回调
            mListener.onStateChanged(newState);
        } else {
    
    
            Log.d(TAG, "expected stop, not triggering callbacks: newState = " + newState);
        }

        // Once we report the mode has stopped/failed any other stop signals are redundant
        // note: this can happen in failure modes where we get multiple callbacks as underlying
        // components/interface stops or the underlying interface is destroyed in cleanup
        if (newState == WifiManager.WIFI_STATE_UNKNOWN
                || newState == WifiManager.WIFI_STATE_DISABLED) {
    
    
            mExpectedStop = true;
        }

        if (newState == WifiManager.WIFI_STATE_UNKNOWN) {
    
    
            // do not need to broadcast failure to system
            return;
        }

        mClientModeImpl.setWifiStateForApiCalls(newState);

        //发送粘性广播
        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, newState);
        intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_STATE, currentState);
        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
    }

mListener是在ClientModeActiveState里面被实现了

		class ClientModeActiveState extends ModeActiveState {
    
    
            ClientListener mListener;
            //此处实现了ClientModeManager.Listener回调
            private class ClientListener implements ClientModeManager.Listener {
    
    
                @Override
                public void onStateChanged(int state) {
    
    
                    // make sure this listener is still active
                    if (this != mListener) {
    
    
                        Log.d(TAG, "Client mode state change from previous manager");
                        return;
                    }

                    Log.d(TAG, "State changed from client mode. state = " + state);

                    if (state == WifiManager.WIFI_STATE_UNKNOWN) {
    
    
                        // error while setting up client mode or an unexpected failure.
                        mModeStateMachine.sendMessage(CMD_CLIENT_MODE_FAILED, this);
                    } else if (state == WifiManager.WIFI_STATE_DISABLED) {
    
    
                        // client mode stopped
                        mModeStateMachine.sendMessage(CMD_CLIENT_MODE_STOPPED, this);
                    } else if (state == WifiManager.WIFI_STATE_ENABLED) {
    
    
                        // client mode is ready to go
                        Log.d(TAG, "client mode active");
                        //wifi开启后执行此方法
                        onModeActivationComplete();
                    } else {
    
    
                        // only care if client mode stopped or started, dropping
                    }
                }
            }

            @Override
            public void enter() {
    
    
                Log.d(TAG, "Entering ClientModeActiveState");

                mListener = new ClientListener();
                mManager = mWifiInjector.makeClientModeManager(mListener);
                mManager.start();
                mActiveModeManagers.add(mManager);

                updateBatteryStatsWifiState(true);
            }

            @Override
            public void exit() {
    
    
                super.exit();
                mListener = null;
            }

            @Override
            public boolean processMessage(Message message) {
    
    
                if (checkForAndHandleModeChange(message)) {
    
    
                    return HANDLED;
                }

                switch(message.what) {
    
    
                    case CMD_START_CLIENT_MODE:
                        Log.d(TAG, "Received CMD_START_CLIENT_MODE when active - drop");
                        break;
                    case CMD_CLIENT_MODE_FAILED:
                        if (mListener != message.obj) {
    
    
                            Log.d(TAG, "Client mode state change from previous manager");
                            return HANDLED;
                        }
                        Log.d(TAG, "ClientMode failed, return to WifiDisabledState.");
                        // notify WifiController that ClientMode failed
                        mClientModeCallback.onStateChanged(WifiManager.WIFI_STATE_UNKNOWN);
                        mModeStateMachine.transitionTo(mWifiDisabledState);
                        break;
                    case CMD_CLIENT_MODE_STOPPED:
                        if (mListener != message.obj) {
    
    
                            Log.d(TAG, "Client mode state change from previous manager");
                            return HANDLED;
                        }

                        Log.d(TAG, "ClientMode stopped, return to WifiDisabledState.");
                        // notify WifiController that ClientMode stopped
                        mClientModeCallback.onStateChanged(WifiManager.WIFI_STATE_DISABLED);
                        mModeStateMachine.transitionTo(mWifiDisabledState);
                        break;
                    default:
                        return NOT_HANDLED;
                }
                return NOT_HANDLED;
            }
        }

wifi开启之后会执行ClientListener的onStateChange()方法,此时状态机的状态为WIFI_STATE_ENABLED,所以会执行onModeActivationComplete()

			// Hook to be used by sub-classes of ModeActiveState to indicate the completion of
            // bringup of the corresponding mode.
            public void onModeActivationComplete() {
    
    
                updateScanMode();
            }
			// Update the scan state based on all active mode managers.
            // Note: This is an overkill currently because there is only 1 of scan-only or client
            // mode present today.
            private void updateScanMode() {
    
    
                boolean scanEnabled = false;
                boolean scanningForHiddenNetworksEnabled = false;
                for (ActiveModeManager modeManager : mActiveModeManagers) {
    
    
                    @ActiveModeManager.ScanMode int scanState = modeManager.getScanMode();
                    switch (scanState) {
    
    
                        case ActiveModeManager.SCAN_NONE:
                            break;
                        case ActiveModeManager.SCAN_WITHOUT_HIDDEN_NETWORKS:
                            scanEnabled = true;
                            break;
                        case ActiveModeManager.SCAN_WITH_HIDDEN_NETWORKS:
                            scanEnabled = true;
                            scanningForHiddenNetworksEnabled = true;
                            break;
                    }
                }
                mScanRequestProxy.enableScanning(scanEnabled, scanningForHiddenNetworksEnabled);
            }

此时状态机切换到ScanOnlyModeActiveState,开始扫描周围wifi,至此,wifi启动流程分析完毕。

猜你喜欢

转载自blog.csdn.net/u013936727/article/details/128021497