Bootstrap

Android P WIFI启动流程梳理

另有一篇类似的 Wifi模块—源码分析Wifi启动1(Android P)_wifi ap_started csdn-CSDN博客

1.回顾
android O wifi启动流程主要包括驱动的加载,supplicant的启动,以及supplicant的连接(hidl),之前也看过Android 4.4的WiFi启动流程,前面提及的几个主要部分功能实现还是差不多的,Android O主要引入了Wificond和hidl。

2.流程梳理

下面这个图来自于 Wifi模块—源码分析Wifi启动1(Android P)_wifi ap_started csdn-CSDN博客


2.1 WifiManager
    /**
     * Enable or disable Wi-Fi.
     * <p>
     * Applications must have the {@link android.Manifest.permission#CHANGE_WIFI_STATE}
     * permission to toggle wifi.
     *
     * @param enabled {@code true} to enable, {@code false} to disable.
     * @return {@code false} if the request cannot be satisfied; {@code true} indicates that wifi is
     *         either already in the requested state, or in progress toward the requested state.
     * @throws  {@link java.lang.SecurityException} if the caller is missing required permissions.
     */
    public boolean setWifiEnabled(boolean enabled) {
        try {
            return mService.setWifiEnabled(mContext.getOpPackageName(), enabled);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
2.2 WifiSerivceImpl
   /**
     * see {@link android.net.wifi.WifiManager#setWifiEnabled(boolean)}
     * @param enable {@code true} to enable, {@code false} to disable.
     * @return {@code true} if the enable/disable operation was
     *         started or is already in the queue.
     */
    @Override
    public synchronized boolean setWifiEnabled(String packageName, boolean enable)
            throws RemoteException {
        if (enforceChangePermission(packageName) != MODE_ALLOWED) {
            return false;
        }
 
        Slog.d(TAG, "setWifiEnabled: " + enable + " pid=" + Binder.getCallingPid()
                    + ", uid=" + Binder.getCallingUid() + ", package=" + packageName);
        mLog.info("setWifiEnabled package=% uid=% enable=%").c(packageName)
                .c(Binder.getCallingUid()).c(enable).flush();
 
        boolean isFromSettings = checkNetworkSettingsPermission(
                Binder.getCallingPid(), Binder.getCallingUid());
 
        // If Airplane mode is enabled, only Settings is allowed to toggle Wifi
        if (mSettingsStore.isAirplaneModeOn() && !isFromSettings) {
            mLog.info("setWifiEnabled in Airplane mode: only Settings can enable wifi").flush();
            return false;
        }
 
        // If SoftAp is enabled, only Settings is allowed to toggle wifi
        boolean apEnabled = mWifiApState == WifiManager.WIFI_AP_STATE_ENABLED;
 
        if (apEnabled && !isFromSettings) {
            mLog.info("setWifiEnabled SoftAp not disabled: only Settings can enable wifi").flush();
            return false;
        }
 
        /*
        * 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);
        }
 
 
        if (mPermissionReviewRequired) {
            final int wiFiEnabledState = getWifiEnabledState();
            if (enable) {
                if (wiFiEnabledState == WifiManager.WIFI_STATE_DISABLING
                        || wiFiEnabledState == WifiManager.WIFI_STATE_DISABLED) {
                    if (startConsentUi(packageName, Binder.getCallingUid(),
                            WifiManager.ACTION_REQUEST_ENABLE)) {
                        return true;
                    }
                }
            } else if (wiFiEnabledState == WifiManager.WIFI_STATE_ENABLING
                    || wiFiEnabledState == WifiManager.WIFI_STATE_ENABLED) {
                if (startConsentUi(packageName, Binder.getCallingUid(),
                        WifiManager.ACTION_REQUEST_DISABLE)) {
                    return true;
                }
            }
        }
 
        mWifiController.sendMessage(CMD_WIFI_TOGGLED);
        return true;
    }
2.3 WifiController
先看下状态机

        // CHECKSTYLE:OFF IndentationCheck
        addState(mDefaultState);
            addState(mStaDisabledState, mDefaultState);
            addState(mStaEnabledState, mDefaultState);
                addState(mDeviceActiveState, mStaEnabledState);
            addState(mStaDisabledWithScanState, mDefaultState);
            addState(mEcmState, mDefaultState);
        // CHECKSTYLE:ON IndentationCheck


对比Android O的

简略了很多,ap相关(softap)剥离了,StaEnabledState和DeviceActiveState其实是一个了,可以合成一个。

初始状态

        if (checkScanOnlyModeAvailable()) {
            setInitialState(mStaDisabledWithScanState);
        } else {
            setInitialState(mStaDisabledState);
        }
先暂时略过ScanOnly,先看StaDisabledState

    class StaDisabledState extends State {
        private int mDeferredEnableSerialNumber = 0;
        private boolean mHaveDeferredEnable = false;
        private long mDisabledTimestamp;
 
        @Override
        public void enter() {
            mWifiStateMachinePrime.disableWifi();
            // Supplicant can't restart right away, so note the time we switched off
            mDisabledTimestamp = SystemClock.elapsedRealtime();
            mDeferredEnableSerialNumber++;
            mHaveDeferredEnable = false;
            mWifiStateMachine.clearANQPCache();
        }
        @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;
                        }
                        transitionTo(mDeviceActiveState);
                    } else if (checkScanOnlyModeAvailable()) {
                        // only go to scan mode if we aren't in airplane mode
                        if (mSettingsStore.isAirplaneModeOn()) {
                            transitionTo(mStaDisabledWithScanState);
                        }
                    }
                    break;
打开WiFi后WifiController状态机切换(这边先梳理主动打开WiFi逻辑,always scan后续梳理)

    /**
     * Parent: StaEnabledState
     *
     * TODO (b/79209870): merge DeviceActiveState and StaEnabledState into a single state
     */
    class DeviceActiveState extends State {
        @Override
        public void enter() {
            mWifiStateMachinePrime.enterClientMode();
            mWifiStateMachine.setHighPerfModeEnabled(false);
        }
 
        @Override
        public boolean processMessage(Message msg) {
            if (msg.what == CMD_USER_PRESENT) {
                // TLS networks can't connect until user unlocks keystore. KeyStore
                // unlocks when the user punches PIN after the reboot. So use this
                // trigger to get those networks connected.
                if (mFirstUserSignOnSeen == false) {
                    mWifiStateMachine.reloadTlsNetworksAndReconnect();
                }
                mFirstUserSignOnSeen = true;
                return HANDLED;
            } else if (msg.what == CMD_RECOVERY_RESTART_WIFI) {
                final String bugTitle;
                final String bugDetail;
                if (msg.arg1 < SelfRecovery.REASON_STRINGS.length && msg.arg1 >= 0) {
                    bugDetail = SelfRecovery.REASON_STRINGS[msg.arg1];
                    bugTitle = "Wi-Fi BugReport: " + bugDetail;
                } else {
                    bugDetail = "";
                    bugTitle = "Wi-Fi BugReport";
                }
                if (msg.arg1 != SelfRecovery.REASON_LAST_RESORT_WATCHDOG) {
                    (new Handler(mWifiStateMachineLooper)).post(() -> {
                        mWifiStateMachine.takeBugReport(bugTitle, bugDetail);
                    });
                }
                return NOT_HANDLED;
            }
            return NOT_HANDLED;
        }
    }
这边不一样了,出现了个WifiStateMachinePrime

            mWifiStateMachinePrime.enterClientMode();
            mWifiStateMachine.setHighPerfModeEnabled(false);
2.4 WifiStateMachinePrime
先瞄一眼这个新类的初始化

WifiInjector

        mWifiStateMachinePrime = new WifiStateMachinePrime(this, mContext, wifiStateMachineLooper,
                mWifiNative, new DefaultModeManager(mContext, wifiStateMachineLooper),
                mBatteryStats);
...
        mWifiController = new WifiController(mContext, mWifiStateMachine, wifiStateMachineLooper,
                mSettingsStore, mWifiServiceHandlerThread.getLooper(), mFrameworkFacade,
                mWifiStateMachinePrime);
看下enterClientMode

    /**
     * Method to switch wifi into client mode where connections to configured networks will be
     * attempted.
     */
    public void enterClientMode() {
        changeMode(ModeStateMachine.CMD_START_CLIENT_MODE);
    }
看下ModeStateMachine的模式

        // Commands for the state machine  - these will be removed,
        // along with the StateMachine itself
        public static final int CMD_START_CLIENT_MODE    = 0;
        public static final int CMD_START_SCAN_ONLY_MODE = 1;
        public static final int CMD_DISABLE_WIFI         = 3;
有3个模式,ClientMode模式,应该就是WiFi普通打开模式,Scan_ONLY应该就是不打开WiFi只打开WiFi扫描的模式,Disable_WIFI应该是上面两个都没打开的情况。(具体情况待更新)

    private void changeMode(int newMode) {
        mModeStateMachine.sendMessage(newMode);
    }
看下ModeStateMachine状态机

    private class ModeStateMachine extends StateMachine {
        // Commands for the state machine  - these will be removed,
        // along with the StateMachine itself
        public static final int CMD_START_CLIENT_MODE    = 0;
        public static final int CMD_START_SCAN_ONLY_MODE = 1;
        public static final int CMD_DISABLE_WIFI         = 3;
 
        private final State mWifiDisabledState = new WifiDisabledState();
        private final State mClientModeActiveState = new ClientModeActiveState();
        private final State mScanOnlyModeActiveState = new ScanOnlyModeActiveState();
 
        ModeStateMachine() {
            super(TAG, mLooper);
 
            addState(mClientModeActiveState);
            addState(mScanOnlyModeActiveState);
            addState(mWifiDisabledState);
 
            Log.d(TAG, "Starting Wifi in WifiDisabledState");
            setInitialState(mWifiDisabledState);
            start();
        }
初始WifiDiabledState处理刚发来的切换状态消息

        class WifiDisabledState extends ModeActiveState {
            @Override
            public void enter() {
                Log.d(TAG, "Entering WifiDisabledState");
                mDefaultModeManager.sendScanAvailableBroadcast(mContext, false);
                mScanRequestProxy.enableScanningForHiddenNetworks(false);
                mScanRequestProxy.clearScanResults();
            }
 
            @Override
            public boolean processMessage(Message message) {
                Log.d(TAG, "received a message in WifiDisabledState: " + message);
                if (checkForAndHandleModeChange(message)) {
                    return HANDLED;
                }
                return NOT_HANDLED;
            }
 
            @Override
            public void exit() {
                // do not have an active mode manager...  nothing to clean up
            }
 
        }
 
        private boolean checkForAndHandleModeChange(Message message) {
            switch(message.what) {
                case ModeStateMachine.CMD_START_CLIENT_MODE:
                    Log.d(TAG, "Switching from " + getCurrentMode() + " to ClientMode");
                    mModeStateMachine.transitionTo(mClientModeActiveState);
                    break;
                case ModeStateMachine.CMD_START_SCAN_ONLY_MODE:
                    Log.d(TAG, "Switching from " + getCurrentMode() + " to ScanOnlyMode");
                    mModeStateMachine.transitionTo(mScanOnlyModeActiveState);
                    break;
                case ModeStateMachine.CMD_DISABLE_WIFI:
                    Log.d(TAG, "Switching from " + getCurrentMode() + " to WifiDisabled");
                    mModeStateMachine.transitionTo(mWifiDisabledState);
                    break;
                default:
                    return NOT_HANDLED;
            }
            return HANDLED;
        }
状态切换到ClientModeActiveState

        class ClientModeActiveState extends ModeActiveState {
            ClientListener mListener;
            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");
                    } 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;
            }
        }
enter方法里主要干了两件事

                Log.d(TAG, "Entering ClientModeActiveState");
 
                mListener = new ClientListener();
                mManager = mWifiInjector.makeClientModeManager(mListener);
                mManager.start();
                mActiveModeManagers.add(mManager);
 
                updateBatteryStatsWifiState(true);
 
 
    /**
     * Create a ClientModeManager
     *
     * @param listener listener for ClientModeManager state changes
     * @return a new instance of ClientModeManager
     */
    public ClientModeManager makeClientModeManager(ClientModeManager.Listener listener) {
        return new ClientModeManager(mContext, mWifiStateMachineHandlerThread.getLooper(),
                mWifiNative, listener, mWifiMetrics, mScanRequestProxy, mWifiStateMachine);
    }
 
 
    /**
     *  Helper method to report wifi state as on/off (doesn't matter which mode).
     *
     *  @param enabled boolean indicating that some mode has been turned on or off
     */
    private void updateBatteryStatsWifiState(boolean enabled) {
        try {
            if (enabled) {
                if (mActiveModeManagers.size() == 1) {
                    // only report wifi on if we haven't already
                    mBatteryStats.noteWifiOn();
                }
            } else {
                if (mActiveModeManagers.size() == 0) {
                    // only report if we don't have any active modes
                    mBatteryStats.noteWifiOff();
                }
            }
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to note battery stats in wifi");
        }
    }
ClientModeManager.start
updateBatteryStatsWifiState
主要看下ClientModeManager.start

/**
 * Manager WiFi in Client Mode where we connect to configured networks.
 */
public class ClientModeManager implements ActiveModeManager {
 
/**
 * Base class for available WiFi operating modes.
 *
 * Currently supported modes include Client, ScanOnly and SoftAp.
 */
public interface ActiveModeManager {
    String TAG = "ActiveModeManager";
 
    /**
     * Method used to start the Manager for a given Wifi operational mode.
     */
    void start();
 
    /**
     * Method used to stop the Manager for a give Wifi operational mode.
     */
    void stop();
 
    /**
     * Method to dump for logging state.
     */
    void dump(FileDescriptor fd, PrintWriter pw, String[] args);
 
    /**
     * Method that allows Mode Managers to update WifiScanner about the current state.
     *
     * @param context Context to use for the notification
     * @param available boolean indicating if scanning is available
     */
    default void sendScanAvailableBroadcast(Context context, boolean available) {
        Log.d(TAG, "sending scan available broadcast: " + available);
        final Intent intent = new Intent(WifiManager.WIFI_SCAN_AVAILABLE);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
        if (available) {
            intent.putExtra(WifiManager.EXTRA_SCAN_AVAILABLE, WifiManager.WIFI_STATE_ENABLED);
        } else {
            intent.putExtra(WifiManager.EXTRA_SCAN_AVAILABLE, WifiManager.WIFI_STATE_DISABLED);
        }
        context.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
    }
}
这里从api注释来看解耦出来了一个接口,用于Client, ScanOnly and SoftAp的实现。

看下start()方法

    ClientModeManager(Context context, @NonNull Looper looper, WifiNative wifiNative,
            Listener listener, WifiMetrics wifiMetrics, ScanRequestProxy scanRequestProxy,
            WifiStateMachine wifiStateMachine) {
        mContext = context;
        mWifiNative = wifiNative;
        mListener = listener;
        mWifiMetrics = wifiMetrics;
        mScanRequestProxy = scanRequestProxy;
        mWifiStateMachine = wifiStateMachine;
        mStateMachine = new ClientModeStateMachine(looper);
    }
 
    /**
     * Start client mode.
     */
    public void start() {
        mStateMachine.sendMessage(ClientModeStateMachine.CMD_START);
    }
初始化了一个状态机,start是发出了一个消息给状态机来处理

        ClientModeStateMachine(Looper looper) {
            super(TAG, looper);
 
            addState(mIdleState);
            addState(mStartedState);
 
            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:
                        updateWifiState(WifiManager.WIFI_STATE_ENABLING,
                                        WifiManager.WIFI_STATE_DISABLED);
 
                        mClientInterfaceName = mWifiNative.setupInterfaceForClientMode(
                                false /* not low priority */, 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;
                        }
                        sendScanAvailableBroadcast(false);
                        mScanRequestProxy.enableScanningForHiddenNetworks(false);
                        mScanRequestProxy.clearScanResults();
                        transitionTo(mStartedState);
                        break;
                    default:
                        Log.d(TAG, "received an invalid message: " + message);
                        return NOT_HANDLED;
                }
                return HANDLED;
            }
        }
这边逻辑和Android O的WiFi启动逻辑很像了,应该是初始化驱动和启动supplicant,具体看下。

        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");
                    sendScanAvailableBroadcast(true);
                    mWifiStateMachine.setOperationalMode(WifiStateMachine.CONNECT_MODE,
                                                         mClientInterfaceName);
                    updateWifiState(WifiManager.WIFI_STATE_ENABLED,
                                    WifiManager.WIFI_STATE_ENABLING);
                } else {
                    if (mWifiStateMachine.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));
                mScanRequestProxy.enableScanningForHiddenNetworks(true);
            }
进入到StartedState可以看到wifi状态就更新为enabled了。

2.5 WifiNative
    /**
     * Setup an interface for Client mode operations.
     *
     * This method configures an interface in STA mode in all the native daemons
     * (wificond, wpa_supplicant & vendor HAL).
     *
     * @param lowPrioritySta The requested STA has a low request priority (lower probability of
     *                       getting created, higher probability of getting destroyed).
     * @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 setupInterfaceForClientMode(boolean lowPrioritySta,
            @NonNull InterfaceCallback interfaceCallback) {
        synchronized (mLock) {
            if (!startHal()) {
                Log.e(TAG, "Failed to start Hal");
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
                return null;
            }
            if (!startSupplicant()) {
                Log.e(TAG, "Failed to start supplicant");
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
                return null;
            }
            Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_STA);
            if (iface == null) {
                Log.e(TAG, "Failed to allocate new STA iface");
                return null;
            }
            iface.externalListener = interfaceCallback;
            iface.name = createStaIface(iface, lowPrioritySta);
            if (TextUtils.isEmpty(iface.name)) {
                Log.e(TAG, "Failed to create STA iface in vendor HAL");
                mIfaceMgr.removeIface(iface.id);
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
                return null;
            }
            if (mWificondControl.setupInterfaceForClientMode(iface.name) == null) {
                Log.e(TAG, "Failed to setup iface in wificond on " + iface);
                teardownInterface(iface.name);
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToWificond();
                return null;
            }
            if (!mSupplicantStaIfaceHal.setupIface(iface.name)) {
                Log.e(TAG, "Failed to setup iface in supplicant on " + iface);
                teardownInterface(iface.name);
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
                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;
            }
            mWifiMonitor.startMonitoring(iface.name);
            // Just to avoid any race conditions with interface state change callbacks,
            // update the interface state before we exit.
            onInterfaceStateChanged(iface, isInterfaceUp(iface.name));
            initializeNwParamsForClientInterface(iface.name);
            Log.i(TAG, "Successfully setup " + iface);
            return iface.name;
        }
    }
这边逻辑不大一样,framework基本梳理完了到hal了,先梳理下面3步

startHal
startSupplicant
createStaIface
    /** Helper method invoked to start supplicant if there were no ifaces */
    private boolean startHal() {
        synchronized (mLock) {
            if (!mIfaceMgr.hasAnyIface()) {
                if (mWifiVendorHal.isVendorHalSupported()) {
                    if (!mWifiVendorHal.startVendorHal()) {
                        Log.e(TAG, "Failed to start vendor HAL");
                        return false;
                    }
                } else {
                    Log.i(TAG, "Vendor Hal not supported, ignoring start.");
                }
            }
            return true;
        }
    }
2.6 WifiVendorHal
    /**
     * Bring up the HIDL Vendor HAL.
     * @return true on success, false otherwise.
     */
    public boolean startVendorHal() {
        synchronized (sLock) {
            if (!mHalDeviceManager.start()) {
                mLog.err("Failed to start vendor HAL").flush();
                return false;
            }
            mLog.info("Vendor Hal started successfully").flush();
            return true;
        }
    }
2.7 HalDeviceManager
    /**
     * Attempts to start Wi-Fi (using HIDL). Returns the success (true) or failure (false) or
     * the start operation. Will also dispatch any registered ManagerStatusCallback.onStart() on
     * success.
     *
     * Note: direct call to HIDL.
     */
    public boolean start() {
        return startWifi();
    }
 
    private boolean startWifi() {
        if (VDBG) Log.d(TAG, "startWifi");
 
        synchronized (mLock) {
            try {
                if (mWifi == null) {
                    Log.w(TAG, "startWifi called but mWifi is null!?");
                    return false;
                } else {
                    int triedCount = 0;
                    while (triedCount <= START_HAL_RETRY_TIMES) {
                        WifiStatus status = mWifi.start();
                        if (status.code == WifiStatusCode.SUCCESS) {
                            initIWifiChipDebugListeners();
                            managerStatusListenerDispatch();
                            if (triedCount != 0) {
                                Log.d(TAG, "start IWifi succeeded after trying "
                                         + triedCount + " times");
                            }
                            return true;
                        } else if (status.code == WifiStatusCode.ERROR_NOT_AVAILABLE) {
                            // Should retry. Hal might still be stopping.
                            Log.e(TAG, "Cannot start IWifi: " + statusString(status)
                                    + ", Retrying...");
                            try {
                                Thread.sleep(START_HAL_RETRY_INTERVAL_MS);
                            } catch (InterruptedException ignore) {
                                // no-op
                            }
                            triedCount++;
                        } else {
                            // Should not retry on other failures.
                            Log.e(TAG, "Cannot start IWifi: " + statusString(status));
                            return false;
                        }
                    }
                    Log.e(TAG, "Cannot start IWifi after trying " + triedCount + " times");
                    return false;
                }
            } catch (RemoteException e) {
                Log.e(TAG, "startWifi exception: " + e);
                return false;
            }
        }
    }
先看下mWifi是什么

    /**
     * Initialize IWifi and register death listener and event callback.
     *
     * - It is possible that IWifi is not ready - we have a listener on IServiceManager for it.
     * - It is not expected that any of the registrations will fail. Possible indication that
     *   service died after we obtained a handle to it.
     *
     * Here and elsewhere we assume that death listener will do the right thing!
    */
    private void initIWifiIfNecessary() {
        if (mDbg) Log.d(TAG, "initIWifiIfNecessary");
 
        synchronized (mLock) {
            if (mWifi != null) {
                return;
            }
 
            try {
                mWifi = getWifiServiceMockable();
                if (mWifi == null) {
                    Log.e(TAG, "IWifi not (yet) available - but have a listener for it ...");
                    return;
                }
 
                if (!mWifi.linkToDeath(mIWifiDeathRecipient, /* don't care */ 0)) {
                    Log.e(TAG, "Error on linkToDeath on IWifi - will retry later");
                    return;
                }
 
                WifiStatus status = mWifi.registerEventCallback(mWifiEventCallback);
                if (status.code != WifiStatusCode.SUCCESS) {
                    Log.e(TAG, "IWifi.registerEventCallback failed: " + statusString(status));
                    mWifi = null;
                    return;
                }
                // Stopping wifi just in case. This would also trigger the status callback.
                stopWifi();
            } catch (RemoteException e) {
                Log.e(TAG, "Exception while operating on IWifi: " + e);
            }
        }
    }
 
    /**
     * Wrapper function to access the HIDL services. Created to be mockable in unit-tests.
     */
    protected IWifi getWifiServiceMockable() {
        try {
            return IWifi.getService();
        } catch (RemoteException e) {
            Log.e(TAG, "Exception getting IWifi service: " + e);
            return null;
        }
    }
这和之前Android O一样的

2.8 wifi.cpp
hardware/interfaces/wifi/1.0/default/wifi.cpp

Return<void> Wifi::start(start_cb hidl_status_cb) {
    return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN,
                           &Wifi::startInternal, hidl_status_cb);
}
 
WifiStatus Wifi::startInternal() {
    if (run_state_ == RunState::STARTED) {
        return createWifiStatus(WifiStatusCode::SUCCESS);
    } else if (run_state_ == RunState::STOPPING) {
        return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE,
                                "HAL is stopping");
    }
    WifiStatus wifi_status = initializeModeControllerAndLegacyHal();
    if (wifi_status.code == WifiStatusCode::SUCCESS) {
        // Create the chip instance once the HAL is started.
        chip_ = new WifiChip(kChipId, legacy_hal_, mode_controller_,
                             feature_flags_);
        run_state_ = RunState::STARTED;
        for (const auto& callback : event_cb_handler_.getCallbacks()) {
            if (!callback->onStart().isOk()) {
                LOG(ERROR) << "Failed to invoke onStart callback";
            };
        }
        LOG(INFO) << "Wifi HAL started";
    } else {
        for (const auto& callback : event_cb_handler_.getCallbacks()) {
            if (!callback->onFailure(wifi_status).isOk()) {
                LOG(ERROR) << "Failed to invoke onFailure callback";
            }
        }
        LOG(ERROR) << "Wifi HAL start failed";
    }
    return wifi_status;
}
看下initializeModeControllerAndLegacyHal

WifiStatus Wifi::initializeModeControllerAndLegacyHal() {
    if (!mode_controller_->initialize()) {
        LOG(ERROR) << "Failed to initialize firmware mode controller";
        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
    }
    legacy_hal::wifi_error legacy_status = legacy_hal_->initialize();
    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
        LOG(ERROR) << "Failed to initialize legacy HAL: "
                   << legacyErrorToString(legacy_status);
        return createWifiStatusFromLegacyError(legacy_status);
    }
    return createWifiStatus(WifiStatusCode::SUCCESS);
}
这边也有两步,第二步应该和Android O一样

mode_controller_->initialize()
legacy_hal_->initialize()
2.9 wifi_mode_controller.cpp
/hardware/interfaces/wifi/1.2/default/wifi_mode_controller.cpp

bool WifiModeController::initialize() {
    if (!driver_tool_->LoadDriver()) {
        LOG(ERROR) << "Failed to load WiFi driver";
        return false;
    }
    return true;
}
加载WiFi驱动

2.10 wifi_legacy_hal.cpp
/hardware/interfaces/wifi/1.2/default/wifi_legacy_hal.cpp

wifi_error WifiLegacyHal::initialize() {
    LOG(DEBUG) << "Initialize legacy HAL";
    // TODO: Add back the HAL Tool if we need to. All we need from the HAL tool
    // for now is this function call which we can directly call.
    if (!initHalFuncTableWithStubs(&global_func_table_)) {
        LOG(ERROR)
            << "Failed to initialize legacy hal function table with stubs";
        return WIFI_ERROR_UNKNOWN;
    }
    wifi_error status = init_wifi_vendor_hal_func_table(&global_func_table_);
    if (status != WIFI_SUCCESS) {
        LOG(ERROR) << "Failed to initialize legacy hal function table";
    }
    return status;
}
这边初始化legacy hal和Android O一模一样,不重复梳理了。

到这边startHal就梳理完了,下面接着梳理startSupplicant

2.11 WificondControl
回头看下WifiNative的startSupplicant

    /** Helper method invoked to start supplicant if there were no STA ifaces */
    private boolean startSupplicant() {
        synchronized (mLock) {
            if (!mIfaceMgr.hasAnyStaIface()) {
                if (!mWificondControl.enableSupplicant()) {
                    Log.e(TAG, "Failed to enable supplicant");
                    return false;
                }
                if (!waitForSupplicantConnection()) {
                    Log.e(TAG, "Failed to connect to supplicant");
                    return false;
                }
                if (!mSupplicantStaIfaceHal.registerDeathHandler(
                        new SupplicantDeathHandlerInternal())) {
                    Log.e(TAG, "Failed to register supplicant death handler");
                    return false;
                }
            }
            return true;
        }
    }
 
    /**
     * This method is called to wait for establishing connection to wpa_supplicant.
     *
     * @return true if connection is established, false otherwise.
     */
    private boolean waitForSupplicantConnection() {
        // Start initialization if not already started.
        if (!mSupplicantStaIfaceHal.isInitializationStarted()
                && !mSupplicantStaIfaceHal.initialize()) {
            return false;
        }
        boolean connected = false;
        int connectTries = 0;
        while (!connected && connectTries++ < CONNECT_TO_SUPPLICANT_RETRY_TIMES) {
            // Check if the initialization is complete.
            connected = mSupplicantStaIfaceHal.isInitializationComplete();
            if (connected) {
                break;
            }
            try {
                Thread.sleep(CONNECT_TO_SUPPLICANT_RETRY_INTERVAL_MS);
            } catch (InterruptedException ignore) {
            }
        }
        return connected;
    }
可以看到先启动supplicant,然后等待supplicant连接上方便后续通信,连接逻辑也和Android O一样的。

WificondControl

    /**
    * Enable wpa_supplicant via wificond.
    * @return Returns true on success.
    */
    public boolean enableSupplicant() {
        if (!retrieveWificondAndRegisterForDeath()) {
            return false;
        }
        try {
            return mWificond.enableSupplicant();
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to enable supplicant due to remote exception");
        }
        return false;
    }
2.12 server.cpp
/system/connectivity/wificond/server.cpp

Status Server::enableSupplicant(bool* success) {
  *success = supplicant_manager_->StartSupplicant();
  return Status::ok();
}
2.13 supplicant_manager.cpp
/frameworks/opt/net/wifi/libwifi_system/supplicant_manager.cpp

bool SupplicantManager::StartSupplicant() {
  char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
  int count = 200; /* wait at most 20 seconds for completion */
  const prop_info* pi;
  unsigned serial = 0;
 
  /* Check whether already running */
  if (property_get(kSupplicantInitProperty, supp_status, NULL) &&
      strcmp(supp_status, "running") == 0) {
    return true;
  }
 
  /*
   * Get a reference to the status property, so we can distinguish
   * the case where it goes stopped => running => stopped (i.e.,
   * it start up, but fails right away) from the case in which
   * it starts in the stopped state and never manages to start
   * running at all.
   */
  pi = __system_property_find(kSupplicantInitProperty);
  if (pi != NULL) {
    serial = __system_property_serial(pi);
  }
 
  property_set("ctl.start", kSupplicantServiceName);
  sched_yield();
 
  while (count-- > 0) {
    if (pi == NULL) {
      pi = __system_property_find(kSupplicantInitProperty);
    }
    if (pi != NULL) {
      /*
       * property serial updated means that init process is scheduled
       * after we sched_yield, further property status checking is based on this
       */
      if (__system_property_serial(pi) != serial) {
        __system_property_read(pi, NULL, supp_status);
        if (strcmp(supp_status, "running") == 0) {
          return true;
        } else if (strcmp(supp_status, "stopped") == 0) {
          return false;
        }
      }
    }
    usleep(100000);
  }
  return false;
}
和Android O一样调用到libwifi_system启动supplicant

2.14 WifiVendorHal
最后看下WifiNative的createStaIface

            Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_STA);
            if (iface == null) {
                Log.e(TAG, "Failed to allocate new STA iface");
                return null;
            }
            iface.externalListener = interfaceCallback;
            iface.name = createStaIface(iface, lowPrioritySta);
 
 
    /**
     * Helper function to handle creation of STA iface.
     * For devices which do not the support the HAL, this will bypass HalDeviceManager &
     * teardown any existing iface.
     */
    private String createStaIface(@NonNull Iface iface, boolean lowPrioritySta) {
        synchronized (mLock) {
            if (mWifiVendorHal.isVendorHalSupported()) {
                return mWifiVendorHal.createStaIface(lowPrioritySta,
                        new InterfaceDestoyedListenerInternal(iface.id));
            } else {
                Log.i(TAG, "Vendor Hal not supported, ignoring createStaIface.");
                return handleIfaceCreationWhenVendorHalNotSupported(iface);
            }
        }
    }
WifiVendorHal

    /**
     * Create a STA iface using {@link HalDeviceManager}.
     *
     * @param lowPrioritySta The requested STA has a low request priority (lower probability of
     *                       getting created, higher probability of getting destroyed).
     * @param destroyedListener Listener to be invoked when the interface is destroyed.
     * @return iface name on success, null otherwise.
     */
    public String createStaIface(boolean lowPrioritySta,
            InterfaceDestroyedListener destroyedListener) {
        synchronized (sLock) {
            IWifiStaIface iface = mHalDeviceManager.createStaIface(lowPrioritySta,
                    new StaInterfaceDestroyedListenerInternal(destroyedListener), null);
            if (iface == null) {
                mLog.err("Failed to create STA iface").flush();
                return stringResult(null);
            }
            String ifaceName = mHalDeviceManager.getName((IWifiIface) iface);
            if (TextUtils.isEmpty(ifaceName)) {
                mLog.err("Failed to get iface name").flush();
                return stringResult(null);
            }
            if (!registerStaIfaceCallback(iface)) {
                mLog.err("Failed to register STA iface callback").flush();
                return stringResult(null);
            }
            mIWifiRttController = mHalDeviceManager.createRttController();
            if (mIWifiRttController == null) {
                mLog.err("Failed to create RTT controller").flush();
                return stringResult(null);
            }
            if (!registerRttEventCallback()) {
                mLog.err("Failed to register RTT controller callback").flush();
                return stringResult(null);
            }
            if (!retrieveWifiChip((IWifiIface) iface)) {
                mLog.err("Failed to get wifi chip").flush();
                return stringResult(null);
            }
            enableLinkLayerStats(iface);
            mIWifiStaIfaces.put(ifaceName, iface);
            return ifaceName;
        }
    }
2.15 HalDeviceManager
    /**
     * Create a STA interface if possible. Changes chip mode and removes conflicting interfaces if
     * needed and permitted by priority.
     *
     * @param lowPrioritySta Indicates whether the requested STA is a low priority STA. The priority
     *                       and preemption rules for low priority STA are:
     *                       - Do not destroy any interface for it (even another low priority STA)
     *                       - Destroy it for any other request
     * @param destroyedListener Optional (nullable) listener to call when the allocated interface
     *                          is removed. Will only be registered and used if an interface is
     *                          created successfully.
     * @param handler Handler on which to dispatch listener. Null implies the listener will be
     *                invoked synchronously from the context of the client which triggered the
     *                iface destruction.
     * @return A newly created interface - or null if the interface could not be created.
     */
    public IWifiStaIface createStaIface(boolean lowPrioritySta,
            @Nullable InterfaceDestroyedListener destroyedListener, @Nullable Handler handler) {
        return (IWifiStaIface) createIface(IfaceType.STA, lowPrioritySta, destroyedListener,
                handler);
    }
 
    private IWifiIface createIface(int ifaceType, boolean lowPriority,
            InterfaceDestroyedListener destroyedListener, Handler handler) {
        if (mDbg) {
            Log.d(TAG, "createIface: ifaceType=" + ifaceType + ", lowPriority=" + lowPriority);
        }
 
        synchronized (mLock) {
            WifiChipInfo[] chipInfos = getAllChipInfo();
            if (chipInfos == null) {
                Log.e(TAG, "createIface: no chip info found");
                stopWifi(); // major error: shutting down
                return null;
            }
 
            if (!validateInterfaceCache(chipInfos)) {
                Log.e(TAG, "createIface: local cache is invalid!");
                stopWifi(); // major error: shutting down
                return null;
            }
 
            IWifiIface iface = createIfaceIfPossible(chipInfos, ifaceType, lowPriority,
                    destroyedListener, handler);
            if (iface != null) { // means that some configuration has changed
                if (!dispatchAvailableForRequestListeners()) {
                    return null; // catastrophic failure - shut down
                }
            }
 
            return iface;
        }
    }
看下createIfaceIfPossible

    private IWifiIface createIfaceIfPossible(WifiChipInfo[] chipInfos, int ifaceType,
            boolean lowPriority, InterfaceDestroyedListener destroyedListener, Handler handler) {
        if (VDBG) {
            Log.d(TAG, "createIfaceIfPossible: chipInfos=" + Arrays.deepToString(chipInfos)
                    + ", ifaceType=" + ifaceType + ", lowPriority=" + lowPriority);
        }
        synchronized (mLock) {
            IfaceCreationData bestIfaceCreationProposal = null;
            for (WifiChipInfo chipInfo: chipInfos) {
                for (IWifiChip.ChipMode chipMode: chipInfo.availableModes) {
                    for (IWifiChip.ChipIfaceCombination chipIfaceCombo : chipMode
                            .availableCombinations) {
                        int[][] expandedIfaceCombos = expandIfaceCombos(chipIfaceCombo);
                        if (VDBG) {
                            Log.d(TAG, chipIfaceCombo + " expands to "
                                    + Arrays.deepToString(expandedIfaceCombos));
                        }
 
                        for (int[] expandedIfaceCombo: expandedIfaceCombos) {
                            IfaceCreationData currentProposal = canIfaceComboSupportRequest(
                                    chipInfo, chipMode, expandedIfaceCombo, ifaceType, lowPriority);
                            if (compareIfaceCreationData(currentProposal,
                                    bestIfaceCreationProposal)) {
                                if (VDBG) Log.d(TAG, "new proposal accepted");
                                bestIfaceCreationProposal = currentProposal;
                            }
                        }
                    }
                }
            }
 
            if (bestIfaceCreationProposal != null) {
                IWifiIface iface = executeChipReconfiguration(bestIfaceCreationProposal, ifaceType);
                if (iface != null) {
                    InterfaceCacheEntry cacheEntry = new InterfaceCacheEntry();
 
                    cacheEntry.chip = bestIfaceCreationProposal.chipInfo.chip;
                    cacheEntry.chipId = bestIfaceCreationProposal.chipInfo.chipId;
                    cacheEntry.name = getName(iface);
                    cacheEntry.type = ifaceType;
                    if (destroyedListener != null) {
                        cacheEntry.destroyedListeners.add(
                                new InterfaceDestroyedListenerProxy(
                                        cacheEntry.name, destroyedListener, handler));
                    }
                    cacheEntry.creationTime = mClock.getUptimeSinceBootMillis();
                    cacheEntry.isLowPriority = lowPriority;
 
                    if (mDbg) Log.d(TAG, "createIfaceIfPossible: added cacheEntry=" + cacheEntry);
                    mInterfaceInfoCache.put(
                            Pair.create(cacheEntry.name, cacheEntry.type), cacheEntry);
                    return iface;
                }
            }
        }
 
        return null;
    }
 
    /**
     * Performs chip reconfiguration per the input:
     * - Removes the specified interfaces
     * - Reconfigures the chip to the new chip mode (if necessary)
     * - Creates the new interface
     *
     * Returns the newly created interface or a null on any error.
     */
    private IWifiIface executeChipReconfiguration(IfaceCreationData ifaceCreationData,
            int ifaceType) {
        if (mDbg) {
            Log.d(TAG, "executeChipReconfiguration: ifaceCreationData=" + ifaceCreationData
                    + ", ifaceType=" + ifaceType);
        }
        synchronized (mLock) {
            try {
                // is this a mode change?
                boolean isModeConfigNeeded = !ifaceCreationData.chipInfo.currentModeIdValid
                        || ifaceCreationData.chipInfo.currentModeId != ifaceCreationData.chipModeId;
                if (mDbg) Log.d(TAG, "isModeConfigNeeded=" + isModeConfigNeeded);
 
                // first delete interfaces/change modes
                if (isModeConfigNeeded) {
                    // remove all interfaces pre mode-change
                    // TODO: is this necessary? note that even if we don't want to explicitly
                    // remove the interfaces we do need to call the onDeleted callbacks - which
                    // this does
                    for (WifiIfaceInfo[] ifaceInfos: ifaceCreationData.chipInfo.ifaces) {
                        for (WifiIfaceInfo ifaceInfo: ifaceInfos) {
                            removeIfaceInternal(ifaceInfo.iface); // ignore return value
                        }
                    }
 
                    WifiStatus status = ifaceCreationData.chipInfo.chip.configureChip(
                            ifaceCreationData.chipModeId);
                    if (status.code != WifiStatusCode.SUCCESS) {
                        Log.e(TAG, "executeChipReconfiguration: configureChip error: "
                                + statusString(status));
                        return null;
                    }
                } else {
                    // remove all interfaces on the delete list
                    for (WifiIfaceInfo ifaceInfo: ifaceCreationData.interfacesToBeRemovedFirst) {
                        removeIfaceInternal(ifaceInfo.iface); // ignore return value
                    }
                }
 
                // create new interface
                Mutable<WifiStatus> statusResp = new Mutable<>();
                Mutable<IWifiIface> ifaceResp = new Mutable<>();
                switch (ifaceType) {
                    case IfaceType.STA:
                        ifaceCreationData.chipInfo.chip.createStaIface(
                                (WifiStatus status, IWifiStaIface iface) -> {
                                    statusResp.value = status;
                                    ifaceResp.value = iface;
                                });
                        break;
                    case IfaceType.AP:
                        ifaceCreationData.chipInfo.chip.createApIface(
                                (WifiStatus status, IWifiApIface iface) -> {
                                    statusResp.value = status;
                                    ifaceResp.value = iface;
                                });
                        break;
                    case IfaceType.P2P:
                        ifaceCreationData.chipInfo.chip.createP2pIface(
                                (WifiStatus status, IWifiP2pIface iface) -> {
                                    statusResp.value = status;
                                    ifaceResp.value = iface;
                                });
                        break;
                    case IfaceType.NAN:
                        ifaceCreationData.chipInfo.chip.createNanIface(
                                (WifiStatus status, IWifiNanIface iface) -> {
                                    statusResp.value = status;
                                    ifaceResp.value = iface;
                                });
                        break;
                }
 
                if (statusResp.value.code != WifiStatusCode.SUCCESS) {
                    Log.e(TAG, "executeChipReconfiguration: failed to create interface ifaceType="
                            + ifaceType + ": " + statusString(statusResp.value));
                    return null;
                }
 
                return ifaceResp.value;
            } catch (RemoteException e) {
                Log.e(TAG, "executeChipReconfiguration exception: " + e);
                return null;
            }
        }
    }
 

2.16 wifi_chip.cpp
Return<void> WifiChip::configureChip(ChipModeId mode_id,
                                     configureChip_cb hidl_status_cb) {
    return validateAndCallWithLock(
        this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
        &WifiChip::configureChipInternal, hidl_status_cb, mode_id);
}
 
WifiStatus WifiChip::configureChipInternal(
    /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
    ChipModeId mode_id) {
    if (!isValidModeId(mode_id)) {
        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
    }
    if (mode_id == current_mode_id_) {
        LOG(DEBUG) << "Already in the specified mode " << mode_id;
        return createWifiStatus(WifiStatusCode::SUCCESS);
    }
    WifiStatus status = handleChipConfiguration(lock, mode_id);
    if (status.code != WifiStatusCode::SUCCESS) {
        for (const auto& callback : event_cb_handler_.getCallbacks()) {
            if (!callback->onChipReconfigureFailure(status).isOk()) {
                LOG(ERROR)
                    << "Failed to invoke onChipReconfigureFailure callback";
            }
        }
        return status;
    }
    for (const auto& callback : event_cb_handler_.getCallbacks()) {
        if (!callback->onChipReconfigured(mode_id).isOk()) {
            LOG(ERROR) << "Failed to invoke onChipReconfigured callback";
        }
    }
    current_mode_id_ = mode_id;
    LOG(INFO) << "Configured chip in mode " << mode_id;
    return status;
}
 
 
WifiStatus WifiChip::handleChipConfiguration(
    /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
    ChipModeId mode_id) {
    // If the chip is already configured in a different mode, stop
    // the legacy HAL and then start it after firmware mode change.
    if (isValidModeId(current_mode_id_)) {
        LOG(INFO) << "Reconfiguring chip from mode " << current_mode_id_
                  << " to mode " << mode_id;
        invalidateAndRemoveAllIfaces();
        legacy_hal::wifi_error legacy_status =
            legacy_hal_.lock()->stop(lock, []() {});
        if (legacy_status != legacy_hal::WIFI_SUCCESS) {
            LOG(ERROR) << "Failed to stop legacy HAL: "
                       << legacyErrorToString(legacy_status);
            return createWifiStatusFromLegacyError(legacy_status);
        }
    }
    // Firmware mode change not needed for V2 devices.
    bool success = true;
    if (mode_id == kV1StaChipModeId) {
        success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA);
    } else if (mode_id == kV1ApChipModeId) {
        success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP);
    }
    if (!success) {
        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
    }
    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start();
    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
        LOG(ERROR) << "Failed to start legacy HAL: "
                   << legacyErrorToString(legacy_status);
        return createWifiStatusFromLegacyError(legacy_status);
    }
    // Every time the HAL is restarted, we need to register the
    // radio mode change callback.
    WifiStatus status = registerRadioModeChangeCallback();
    if (status.code != WifiStatusCode::SUCCESS) {
        // This probably is not a critical failure?
        LOG(ERROR) << "Failed to register radio mode change callback";
    }
    return createWifiStatus(WifiStatusCode::SUCCESS);
}
2.17 wifi_mode_controller.cpp
/hardware/interfaces/wifi/1.2/default/wifi_mode_controller.cpp

bool WifiModeController::changeFirmwareMode(IfaceType type) {
    if (!driver_tool_->ChangeFirmwareMode(
            convertIfaceTypeToFirmwareMode(type))) {
        LOG(ERROR) << "Failed to change firmware mode";
        return false;
    }
    return true;
}
切换firmwareMode也完成了

3.总结
流程看起来和以前有点不大一样,变成了

加载驱动-启动supplicant-连接supplicant-切换firmwareMode

 

常见日志

setWifiEnabled: true

WifiStateMachine ->WifiDisabledState to ClientMode ->ClientModeActiveState IdleState

WifiStateMachine: setting wifi state to: 2n (ENABLING)

SettingsProvider: content://settings/global/wifi_on

wificond->wpa_supplicant

wpa_supplicant: Successfully initialized wpa_supplicant

SupplicantStaIfaceHal: Completed initialization of ISupplicant

HalDevMgr: createIface: ifaceType=0, lowPriority=false

WifiHAL : Initializing wifi

WifiHAL : Initialized Wifi HAL Successfully
[email protected]: Adding interface handle for wlan0
[email protected]: Adding interface handle for p2p0

HalDevMgr: createIfaceIfPossible: added cacheEntry={name=wlan0
 
wpa_supplicant: Override interface parameter: ctrl_interface

wpa_supplicant: wlan0: Added interface wlan0 

WifiNative: Successfully setup Iface:{Name=wlan0,Id=1,Type=STA}

WifiClientModeManager: entering StartedState (IDLE->Started)

WifiStateMachine: setting wifi state to: 3(WIFI_STATE_ENABLED)


---------------------------------------
setWifiEnabled: false 
WifiStateMachinePrime: Switching from ClientModeActiveState to WifiDisabled
WifiClientModeManager:  currentstate: StartedState
WifiStateMachine: setting wifi state to: 0(DISABLING)

HalDevMgr: removeIfaceInternal: iface(name)=wlan0, type=0
wpa_supplicant: wlan0: Removing interface wlan0

wpa_supplicant: wlan0: Request to deauthenticate
wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED
wpa_supplicant: wlan0: State: COMPLETED -> DISCONNECTED
wpa_supplicant: wlan0: State: DISCONNECTED -> DISCONNECTED
wpa_supplicant: Remove interface wlan0 from radio phy0
DhcpClient: Read error

init    : Received control message 'stop' for 'wpa_supplicant' from pid: 1384 (/system/bin/wificond)
SupplicantStaIfaceHal: ISupplicant died: cookie=0

DhcpClient: doQuit
[email protected]: Wifi HAL stopped
 WifiVendorHal: Vendor Hal stopped

WifiStateMachine: setting wifi state to: 1 (DISABLED)

————————————————
版权声明:本文为CSDN博主「i加加」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sinat_20059415/article/details/88206937

;