安卓15 wifi 打开源码分析-从上层到wifi驱动及wpa_supplicant启动

WifiManager.java

wifi 设置获取到 WifiManager 这个代理调用setWifiEnabled 打开 wifi

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

WifiServiceImpl.java

这里主要做鉴权


/**
     * 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) {
    if (enforceChangePermission(packageName) != MODE_ALLOWED) {
        return false;
    }
    int callingUid = Binder.getCallingUid();
    int callingPid = Binder.getCallingPid();
    boolean isPrivileged = isPrivileged(callingPid, callingUid);
    boolean isThirdParty = !isPrivileged
    && !isDeviceOrProfileOwner(callingUid, packageName)
    && !mWifiPermissionsUtil.isSystem(packageName, callingUid);
    boolean isTargetSdkLessThanQ = mWifiPermissionsUtil.isTargetSdkLessThan(packageName,
                                                                            Build.VERSION_CODES.Q, callingUid) && !isGuestUser();
    mWifiPermissionsUtil.checkPackage(callingUid, packageName);
    if (isThirdParty && !isTargetSdkLessThanQ) {
        mLog.info("setWifiEnabled not allowed for uid=%").c(callingUid).flush();
        return false;
    }

    // If Satellite mode is enabled, Wifi can not be turned on/off
    if (mSettingsStore.isSatelliteModeOn()) {
        mLog.info("setWifiEnabled not allowed as satellite mode is on.").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
    if (!isPrivileged && mTetheredSoftApTracker.getState() == WIFI_AP_STATE_ENABLED) {
        mLog.err("setWifiEnabled with SoftAp enabled: only Settings can toggle wifi").flush();
        return false;
    }

    // If user restriction is set, only DO/PO is allowed to toggle wifi
    if (SdkLevel.isAtLeastT() && mUserManager.hasUserRestrictionForUser(
        UserManager.DISALLOW_CHANGE_WIFI_STATE,
        UserHandle.getUserHandleForUid(callingUid))
        && !isDeviceOrProfileOwner(callingUid, packageName)) {
        mLog.err("setWifiEnabled with user restriction: only DO/PO can toggle wifi").flush();
        return false;
    }

    // Show a user-confirmation dialog for legacy third-party apps targeting less than Q.
    if (enable && isTargetSdkLessThanQ && isThirdParty
        && showDialogWhenThirdPartyAppsEnableWifi()) {
        mLog.info("setWifiEnabled must show user confirmation dialog for uid=%").c(callingUid)
        .flush();
        mWifiThreadRunner.post(() -> {
            if (mActiveModeWarden.getWifiState()
                == WIFI_STATE_ENABLED) {
                    // Wi-Fi already enabled; don't need to show dialog.
                    return;
                }
                showWifiEnableRequestDialog(callingUid, callingPid, packageName);
            });
            return true;
        }
        setWifiEnabledInternal(packageName, enable, callingUid, callingPid, isPrivileged);
        return true;
    }

    @AnyThread
    private void setWifiEnabledInternal(String packageName, boolean enable,
            int callingUid, int callingPid, boolean isPrivileged) {
        mLog.info("setWifiEnabled package=% uid=% enable=% isPrivileged=%").c(packageName)
                .c(callingUid).c(enable).c(isPrivileged).flush();
        long ident = Binder.clearCallingIdentity();
        try {
            if (!mSettingsStore.handleWifiToggled(enable)) {
                // Nothing to do if wifi cannot be toggled
                return;
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
        if (enable) {
            // Clear out all outstanding wifi enable request dialogs.
            mWifiThreadRunner.post(() -> {
                for (int i = 0; i < mWifiEnableRequestDialogHandles.size(); i++) {
                    mWifiEnableRequestDialogHandles.valueAt(i).dismissDialog();
                }
                mWifiEnableRequestDialogHandles.clear();
            });
        }
        if (mWifiPermissionsUtil.checkNetworkSettingsPermission(callingUid)) {
            if (enable) {
                mWifiThreadRunner.post(
                        () -> mWifiConnectivityManager.setAutoJoinEnabledExternal(true, false));
                mWifiMetrics.logUserActionEvent(UserActionEvent.EVENT_TOGGLE_WIFI_ON);
            } else {
                WifiInfo wifiInfo = mActiveModeWarden.getConnectionInfo();
                mWifiMetrics.logUserActionEvent(UserActionEvent.EVENT_TOGGLE_WIFI_OFF,
                        wifiInfo == null ? -1 : wifiInfo.getNetworkId());
            }
        }
        if (!enable) {
            mWifiInjector.getInterfaceConflictManager().reset();
        }
        mWifiMetrics.incrementNumWifiToggles(isPrivileged, enable);
        mWifiMetrics.reportWifiStateChanged(enable, mWifiInjector.getWakeupController().isUsable(),
                false);
        mActiveModeWarden.wifiToggled(new WorkSource(callingUid, packageName));
        mLastCallerInfoManager.put(WifiManager.API_WIFI_ENABLED, Process.myTid(),
                callingUid, callingPid, packageName, enable);
    }

\packages\modules\Wifi\service\java\com\android\server\wifi\ActiveModeWarden.java

向状态机发送CMD_WIFI_TOGGLED 消息

    /** Wifi has been toggled. */
    public void wifiToggled(WorkSource requestorWs) {
        mWifiController.sendMessage(WifiController.CMD_WIFI_TOGGLED, requestorWs);
    }

这个消息由 DisabledState 处理


            @Override
            public boolean processMessageFiltered(Message msg) {
                switch (msg.what) {
                    case CMD_WIFI_TOGGLED:
                    case CMD_SCAN_ALWAYS_MODE_CHANGED:
                        handleStaToggleChangeInDisabledState((WorkSource) msg.obj);
                        break;
                    case CMD_SET_AP:
                        // note: CMD_SET_AP is handled/dropped in ECM mode - will not start here
                        if (msg.arg1 == 1) {
                            Pair<SoftApModeConfiguration, WorkSource> softApConfigAndWs =
                                    (Pair) msg.obj;
                            startSoftApModeManager(
                                    softApConfigAndWs.first, softApConfigAndWs.second);
                            transitionTo(mEnabledState);
                        }
                        break;
                    case CMD_RECOVERY_RESTART_WIFI:
                        log("Recovery triggered, already in disabled state");
                        sendMessageDelayed(CMD_RECOVERY_RESTART_WIFI_CONTINUE,
                                Collections.emptyList(), readWifiRecoveryDelay());
                        break;
                    case CMD_DEFERRED_RECOVERY_RESTART_WIFI:
                        // wait mRecoveryDelayMillis for letting driver clean reset.
                        sendMessageDelayed(CMD_RECOVERY_RESTART_WIFI_CONTINUE,
                                msg.obj, readWifiRecoveryDelay());
                        break;
                    case CMD_RECOVERY_RESTART_WIFI_CONTINUE:
                        log("Recovery in progress, start wifi");
                        List<ActiveModeManager> modeManagersBeforeRecovery = (List) msg.obj;
                        // No user controlled mode managers before recovery, so check if wifi
                        // was toggled on.
                        if (modeManagersBeforeRecovery.isEmpty()) {
                            if (shouldEnableSta()) {
                                startPrimaryOrScanOnlyClientModeManager(
                                        // Assumes user toggled it on from settings before.
                                        mFacade.getSettingsWorkSource(mContext));
                                transitionTo(mEnabledState);
                            }
                            break;
                        }
                        for (ActiveModeManager activeModeManager : modeManagersBeforeRecovery) {
                            if (activeModeManager instanceof ConcreteClientModeManager) {
                                startPrimaryOrScanOnlyClientModeManager(
                                        activeModeManager.getRequestorWs());
                            } else if (activeModeManager instanceof SoftApManager) {
                                SoftApManager softApManager = (SoftApManager) activeModeManager;
                                startSoftApModeManager(
                                        softApManager.getSoftApModeConfiguration(),
                                        softApManager.getRequestorWs());
                            }
                        }
                        transitionTo(mEnabledState);
                        int numCallbacks = mRestartCallbacks.beginBroadcast();
                        for (int i = 0; i < numCallbacks; i++) {
                            try {
                                mRestartCallbacks.getBroadcastItem(i).onSubsystemRestarted();
                            } catch (RemoteException e) {
                                Log.e(TAG, "Failure calling onSubsystemRestarted" + e);
                            }
                        }
                        mRestartCallbacks.finishBroadcast();
                        mWifiInjector.getSelfRecovery().onRecoveryCompleted();
                        break;
                    default:
                        return NOT_HANDLED;
                }
                return HANDLED;
            }
        private void handleStaToggleChangeInDisabledState(WorkSource requestorWs) {
            if (shouldEnableSta()) {
                startPrimaryOrScanOnlyClientModeManager(requestorWs);
                transitionTo(mEnabledState);
            }
        }
    /**
     * Method to enable a new primary client mode manager.
     */
    private boolean startPrimaryOrScanOnlyClientModeManager(WorkSource requestorWs) {
        ActiveModeManager.ClientRole role = getRoleForPrimaryOrScanOnlyClientModeManager();
        if (role == ROLE_CLIENT_PRIMARY) {
            return startPrimaryClientModeManager(requestorWs);
        } else if (role == ROLE_CLIENT_SCAN_ONLY) {
            return startScanOnlyClientModeManager(requestorWs);
        } else {
            return false;
        }
    }
    /**
     * Method to enable a new primary client mode manager in connect mode.
     */
    private boolean startPrimaryClientModeManager(WorkSource requestorWs) {
        if (hasPrimaryOrScanOnlyModeManager()) {
            Log.e(TAG, "Unexpected state - primary CMM should not be started when a primary "
                    + "or scan only CMM is already present.");
            if (!mIsMultiplePrimaryBugreportTaken) {
                mIsMultiplePrimaryBugreportTaken = true;
                mWifiDiagnostics.takeBugReport("Wi-Fi ActiveModeWarden bugreport",
                        "Trying to start primary mode manager when one already exists.");
            }
            return false;
        }
        Log.d(TAG, "Starting primary ClientModeManager in connect mode");
        ConcreteClientModeManager manager = mWifiInjector.makeClientModeManager(
                new ClientListener(), requestorWs, ROLE_CLIENT_PRIMARY, mVerboseLoggingEnabled);
        mClientModeManagers.add(manager);
        mLastPrimaryClientModeManagerRequestorWs = requestorWs;
        return true;
    }

\packages\modules\Wifi\service\java\com\android\server\wifi\WifiInjector.java

    /**
     * Create a ClientModeManager
     *
     * @param listener listener for ClientModeManager state changes
     * @return a new instance of ClientModeManager
     */
    public ConcreteClientModeManager makeClientModeManager(
            @NonNull ClientModeManager.Listener<ConcreteClientModeManager> listener,
            @NonNull WorkSource requestorWs,
            @NonNull ActiveModeManager.ClientRole role,
            boolean verboseLoggingEnabled) {
        return new ConcreteClientModeManager(
                mContext, mWifiHandlerThread.getLooper(), mClock,
                mWifiNative, listener, mWifiMetrics, mWakeupController,
                this, mSelfRecovery, mWifiGlobals, mDefaultClientModeManager,
                mClock.getElapsedSinceBootMillis(), requestorWs, role, mBroadcastQueue,
                verboseLoggingEnabled);
    }

\packages\modules\Wifi\service\java\com\android\server\wifi\ConcreteClientModeManager.java

ConcreteClientModeManager 的构造函数中向状态机发送了CMD_START 消息

    ConcreteClientModeManager(
            Context context, @NonNull Looper looper, Clock clock,
            WifiNative wifiNative, @NonNull Listener<ConcreteClientModeManager> listener,
            WifiMetrics wifiMetrics,
            WakeupController wakeupController, WifiInjector wifiInjector,
            SelfRecovery selfRecovery, WifiGlobals wifiGlobals,
            DefaultClientModeManager defaultClientModeManager, long id,
            @NonNull WorkSource requestorWs, @NonNull ClientRole role,
            @NonNull ClientModeManagerBroadcastQueue broadcastQueue,
            boolean verboseLoggingEnabled) {
        mContext = context;
        mClock = clock;
        mWifiNative = wifiNative;
        mModeListener = listener;
        mWifiMetrics = wifiMetrics;
        mWakeupController = wakeupController;
        mWifiInjector = wifiInjector;
        mStateMachine = new ClientModeStateMachine(looper);
        mDeferStopHandler = new DeferStopHandler(looper);
        mSelfRecovery = selfRecovery;
        mWifiGlobals = wifiGlobals;
        mDefaultClientModeManager = defaultClientModeManager;
        mId = id;
        mTargetRoleChangeInfo = new RoleChangeInfo(role, requestorWs, listener);
        mBroadcastQueue = broadcastQueue;
        enableVerboseLogging(verboseLoggingEnabled);
        mStateMachine.sendMessage(ClientModeStateMachine.CMD_START, mTargetRoleChangeInfo);
    }

这个消息由IdleState 处理


            @Override
            public boolean processMessageImpl(Message message) {
                if (mVerboseLoggingEnabled) {
                    Log.d(getTag(),
                            getName() + " cmd = " + getWhatToString(message.what) + " "
                                    + message.toString());
                }
                switch (message.what) {
                    case CMD_START:
                        // Always start in scan mode first.
                        RoleChangeInfo roleChangeInfo = (RoleChangeInfo) message.obj;
                        mClientInterfaceName = mWifiNative.setupInterfaceForClientInScanMode(
                                mWifiNativeInterfaceCallback, roleChangeInfo.requestorWs,
                                ConcreteClientModeManager.this);
                        if (TextUtils.isEmpty(mClientInterfaceName)) {
                            Log.e(getTag(), "Failed to create ClientInterface. Sit in Idle");
                            takeBugReportInterfaceFailureIfNeeded(
                                    "Wi-Fi BugReport (scan STA interface failure):",
                                    "Failed to create client interface in idle state");
                            mModeListener.onStartFailure(ConcreteClientModeManager.this);
                            break;
                        }
                        mWifiNative.setWifiNativeInterfaceEventCallback(
                                mWifiNativeInterfaceEventCallback);
                        if (roleChangeInfo.role instanceof ClientConnectivityRole) {
                            sendMessage(CMD_SWITCH_TO_CONNECT_MODE, roleChangeInfo);
                            transitionTo(mStartedState);
                        } else {
                            mScanRoleChangeInfoToSetOnTransition = roleChangeInfo;
                            transitionTo(mScanOnlyModeState);
                        }
                        break;
                    case CMD_INTERFACE_ADDED:
                        Log.d(getTag(), "IdleState received CMD_INTERFACE_ADDED");
                        mSelfRecovery.trigger(SelfRecovery.REASON_IFACE_ADDED);
                        break;
                    default:
                        Log.d(getTag(), getName() + ", received an invalid message: " + message);
                        return NOT_HANDLED;
                }
                return HANDLED;
            }

\packages\modules\Wifi\service\java\com\android\server\wifi\WifiNative.java

setupInterfaceForClientInScanMode 函数主要做底层的初始化包括 wifi 驱动加载,一般来说在 boot 阶段 wifi 驱动已经被 insmod 了


    /**
     * Setup an interface for client mode (for scan) operations.
     *
     * This method configures an interface in STA mode in the native daemons
     * (wificond, vendor HAL).
     *
     * @param interfaceCallback Associated callback for notifying status changes for the iface.
     * @param requestorWs Requestor worksource.
     * @param concreteClientModeManager ConcreteClientModeManager requesting the interface.
     * @return Returns the name of the allocated interface, will be null on failure.
     */
    public String setupInterfaceForClientInScanMode(
            @NonNull InterfaceCallback interfaceCallback, @NonNull WorkSource requestorWs,
            @NonNull ConcreteClientModeManager concreteClientModeManager) {
        synchronized (mLock) {
            if (!startHal()) {
                Log.e(TAG, "Failed to start Hal");
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
                return null;
            }
            Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_STA_FOR_SCAN);
            if (iface == null) {
                Log.e(TAG, "Failed to allocate new STA iface");
                return null;
            }
            iface.externalListener = interfaceCallback;
            iface.name = createStaIface(iface, requestorWs, concreteClientModeManager);
            if (TextUtils.isEmpty(iface.name)) {
                Log.e(TAG, "Failed to create iface in vendor HAL");
                mIfaceMgr.removeIface(iface.id);
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
                return null;
            }
            if (!mWifiCondManager.setupInterfaceForClientMode(iface.name, Runnable::run,
                    new NormalScanEventCallback(iface.name),
                    new PnoScanEventCallback(iface.name))) {
                Log.e(TAG, "Failed to setup iface in wificond=" + iface.name);
                teardownInterface(iface.name);
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToWificond();
                return null;
            }
            registerInterfaceObserver();
            iface.networkObserver = new NetworkObserverInternal(iface.id);
            if (!registerNetworkObserver(iface.networkObserver)) {
                Log.e(TAG, "Failed to register network observer for iface=" + iface.name);
                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));
            mWifiVendorHal.enableLinkLayerStats(iface.name);
            Log.i(TAG, "Successfully setup " + iface);

            iface.featureSet = getSupportedFeatureSetInternal(iface.name);
            updateSupportedBandForStaInternal(iface);

            mWifiVendorHal.enableStaChannelForPeerNetwork(mContext.getResources().getBoolean(
                            R.bool.config_wifiEnableStaIndoorChannelForPeerNetwork),
                    mContext.getResources().getBoolean(
                            R.bool.config_wifiEnableStaDfsChannelForPeerNetwork));
            return iface.name;
        }
    }
    /** 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;
                    }
                    if (SdkLevel.isAtLeastS()) {
                        mWifiVendorHal.setCoexUnsafeChannels(
                                mCachedCoexUnsafeChannels, mCachedCoexRestrictions);
                    }
                } else {
                    Log.i(TAG, "Vendor Hal not supported, ignoring start.");
                }
            }
            registerWificondListenerIfNecessary();
            return true;
        }
    }

\packages\modules\Wifi\service\java\com\android\server\wifi\WifiVendorHal.java

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

\packages\modules\Wifi\service\java\com\android\server\wifi\HalDeviceManager.java

    /**
     * Attempts to start Wi-Fi. Returns the success (true) or failure (false) or
     * the start operation. Will also dispatch any registered ManagerStatusCallback.onStart() on
     * success.
     */
    public boolean start() {
        return startWifi();
    }

    private boolean startWifi() {
        if (VDBG) Log.d(TAG, "startWifi");
        initializeInternal();
        synchronized (mLock) {
            int triedCount = 0;
            while (triedCount <= START_HAL_RETRY_TIMES) {
                int status = mWifiHal.start();
                if (status == WifiHal.WIFI_STATUS_SUCCESS) {
                    managerStatusListenerDispatch();
                    if (triedCount != 0) {
                        Log.d(TAG, "start IWifi succeeded after trying "
                                 + triedCount + " times");
                    }
                    WifiChipInfo[] wifiChipInfos = getAllChipInfo();
                    if (wifiChipInfos == null) {
                        Log.e(TAG, "Started wifi but could not get current chip info.");
                    }
                    return true;
                } else if (status == WifiHal.WIFI_STATUS_ERROR_NOT_AVAILABLE) {
                    // Should retry. Hal might still be stopping. the registered event
                    // callback will not be cleared.
                    Log.e(TAG, "Cannot start wifi because unavailable. Retrying...");
                    try {
                        Thread.sleep(START_HAL_RETRY_INTERVAL_MS);
                    } catch (InterruptedException ignore) {
                        // no-op
                    }
                    triedCount++;
                } else {
                    // Should not retry on other failures.
                    // Will be handled in the onFailure event.
                    Log.e(TAG, "Cannot start IWifi. Status: " + status);
                    return false;
                }
            }
            Log.e(TAG, "Cannot start IWifi after trying " + triedCount + " times");
            return false;
        }
    }

\packages\modules\Wifi\service\java\com\android\server\wifi\hal\WifiHal.java

    /**
     * See comments for {@link IWifiHal#start()}
     */
    public @WifiStatusCode int start() {
        return validateAndCall("start", WIFI_STATUS_ERROR_UNKNOWN,
                () -> mWifiHal.start());
    }

\packages\modules\Wifi\service\java\com\android\server\wifi\hal\WifiHalHidlImpl.java

    /**
     * See comments for {@link IWifiHal#start()}
     */
    @Override
    public @WifiHal.WifiStatusCode int start() {
        synchronized (mLock) {
            final String methodStr = "start";
            return validateAndCall(methodStr, WifiHal.WIFI_STATUS_ERROR_UNKNOWN,
                    () -> startInternal(methodStr));
        }
    }
    private @WifiHal.WifiStatusCode int startInternal(String methodStr) {
        try {
            WifiStatus status = mWifi.start();
            return halToFrameworkWifiStatusCode(status.code);
        } catch (RemoteException e) {
            handleRemoteException(e, methodStr);
            return WifiHal.WIFI_STATUS_ERROR_UNKNOWN;
        }
    }

hardware/interfaces/wifi/aidl/default/wifi.cpp

ndk::ScopedAStatus Wifi::start() {
    return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::startInternal);
}

这里调用完initializeModeControllerAndLegacyHal 还会创建WifiChip 和一些事件回调

ndk::ScopedAStatus Wifi::startInternal() {
    if (run_state_ == RunState::STARTED) {
        return ndk::ScopedAStatus::ok();
    } else if (run_state_ == RunState::STOPPING) {
        return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, "HAL is stopping");
    }
    ndk::ScopedAStatus wifi_status = initializeModeControllerAndLegacyHal();
    if (wifi_status.isOk()) {
        // Register the callback for subsystem restart
        const auto& on_subsystem_restart_callback = [this](const std::string& error) {
            ndk::ScopedAStatus wifi_status = createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, error);
            for (const auto& callback : event_cb_handler_.getCallbacks()) {
                LOG(INFO) << "Attempting to invoke onSubsystemRestart "
                             "callback";
                WifiStatusCode errorCode =
                        static_cast<WifiStatusCode>(wifi_status.getServiceSpecificError());
                if (!callback->onSubsystemRestart(errorCode).isOk()) {
                    LOG(ERROR) << "Failed to invoke onSubsystemRestart callback";
                } else {
                    LOG(INFO) << "Succeeded to invoke onSubsystemRestart "
                                 "callback";
                }
            }
        };

        // Create the chip instance once the HAL is started.
        int32_t chipId = kPrimaryChipId;
        for (auto& hal : legacy_hals_) {
            chips_.push_back(
                    WifiChip::create(chipId, chipId == kPrimaryChipId, hal, mode_controller_,
                                     std::make_shared<iface_util::WifiIfaceUtil>(iface_tool_, hal),
                                     feature_flags_, on_subsystem_restart_callback, false));
            chipId++;
        }
        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()) {
            WifiStatusCode errorCode =
                    static_cast<WifiStatusCode>(wifi_status.getServiceSpecificError());
            if (!callback->onFailure(errorCode).isOk()) {
                LOG(ERROR) << "Failed to invoke onFailure callback";
            }
        }
        LOG(ERROR) << "Wifi HAL start failed";
        // Clear the event callback objects since the HAL start failed.
        event_cb_handler_.invalidate();
    }
    return wifi_status;
}
ndk::ScopedAStatus Wifi::initializeModeControllerAndLegacyHal() {
    if (!mode_controller_->initialize()) {
        LOG(ERROR) << "Failed to initialize firmware mode controller";
        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
    }

    legacy_hals_ = legacy_hal_factory_->getHals();
    if (legacy_hals_.empty()) return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
    int index = 0;  // for failure log
    for (auto& hal : legacy_hals_) {
        legacy_hal::wifi_error legacy_status = hal->initialize();
        if (legacy_status != legacy_hal::WIFI_SUCCESS) {
            // Currently WifiLegacyHal::initialize does not allocate extra mem,
            // only initializes the function table. If this changes, need to
            // implement WifiLegacyHal::deinitialize and deinitalize the
            // HALs already initialized
            LOG(ERROR) << "Failed to initialize legacy HAL index: " << index
                       << " error: " << legacyErrorToString(legacy_status);
            return createWifiStatusFromLegacyError(legacy_status);
        }
        index++;
    }
    return ndk::ScopedAStatus::ok();
}

hardware/interfaces/wifi/aidl/default/wifi_mode_controller.cpp

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

frameworks/opt/net/wifi/libwifi_hal/driver_tool.cpp

bool DriverTool::LoadDriver() {
  return ::wifi_load_driver() == 0;
}

frameworks/opt/net/wifi/libwifi_hal/wifi_hal_common.cpp

一般在 boot 阶段 wifi 驱动已经安装了,这里主要是调用字符设备驱动写接口告诉 hdd_driver wifi 打开了

int wifi_load_driver() {
#ifdef WIFI_DRIVER_MODULE_PATH
  if (is_wifi_driver_loaded()) {
    return 0;
  }

  if (insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG) < 0) return -1;
#endif

#ifdef WIFI_DRIVER_STATE_CTRL_PARAM
  if (is_wifi_driver_loaded()) {
    return 0;
  }

  if (wifi_change_driver_state(WIFI_DRIVER_STATE_ON) < 0) {
#ifdef WIFI_DRIVER_MODULE_PATH
    PLOG(WARNING) << "Driver unloading, err='fail to change driver state'";
    if (rmmod(DRIVER_MODULE_NAME) == 0) {
      PLOG(DEBUG) << "Driver unloaded";
    } else {
      // Set driver prop to "ok", expect HL to restart Wi-Fi.
      PLOG(DEBUG) << "Driver unload failed! set driver prop to 'ok'.";
      property_set(DRIVER_PROP_NAME, "ok");
    }
#endif
    return -1;
  }
#endif
  is_driver_loaded = true;
  return 0;
}
#ifdef WIFI_DRIVER_STATE_CTRL_PARAM
int wifi_change_driver_state(const char *state) {
  int len;
  int fd;
  int ret = 0;
  struct timespec req;
  req.tv_sec = 0;
  req.tv_nsec = kDriverStateAccessRetrySleepMillis * 1000000L;
  int count = 5; /* wait at most 1 second for completion. */

  if (!state) return -1;
  do {
    if (access(WIFI_DRIVER_STATE_CTRL_PARAM, W_OK) == 0)
      break;
    nanosleep(&req, (struct timespec *)NULL);
  } while (--count > 0);
  if (count == 0) {
    PLOG(ERROR) << "Failed to access driver state control param "
                << strerror(errno) << ", " << errno;
    return -1;
  }
  fd = TEMP_FAILURE_RETRY(open(WIFI_DRIVER_STATE_CTRL_PARAM, O_WRONLY));
  if (fd < 0) {
    PLOG(ERROR) << "Failed to open driver state control param";
    return -1;
  }
  len = strlen(state) + 1;
  if (TEMP_FAILURE_RETRY(write(fd, state, len)) != len) {
    PLOG(ERROR) << "Failed to write driver state control param";
    ret = -1;
  }
  close(fd);
  return ret;
}
#endif

以高通 wifi 驱动为例,insmod 的时候会调用 hdd_driver 的 init 函数,其会调用对外的字符设备驱动提供的 write 函数wlan_hdd_state_ctrl_param_write

回到\packages\modules\Wifi\service\java\com\android\server\wifi\ConcreteClientModeManager.java 中CMD_START 的处理其后续向状态机发送了CMD_SWITCH_TO_CONNECT_MODE 消息,并转到 StartedState

这里调用了switchClientInterfaceToConnectivityMode 切换到连接模式


@Override
public boolean processMessageImpl(Message message) {
if (mVerboseLoggingEnabled) {
    Log.d(getTag(),
          getName() + " cmd = " + getWhatToString(message.what) + " "
          + message.toString());
}
switch (message.what) {
    case CMD_START:
        // Already started, ignore this command.
        break;
    case CMD_SWITCH_TO_CONNECT_MODE: {
        RoleChangeInfo roleChangeInfo = (RoleChangeInfo) message.obj;
        updateConnectModeState(roleChangeInfo.role,
                               WifiManager.WIFI_STATE_ENABLING,
                               WifiManager.WIFI_STATE_DISABLED);
        if (!mWifiNative.switchClientInterfaceToConnectivityMode(
            mClientInterfaceName, roleChangeInfo.requestorWs)) {
            updateConnectModeState(roleChangeInfo.role,
                                   WifiManager.WIFI_STATE_UNKNOWN,
                                   WifiManager.WIFI_STATE_ENABLING);
            updateConnectModeState(roleChangeInfo.role,
                                   WifiManager.WIFI_STATE_DISABLED,
                                   WifiManager.WIFI_STATE_UNKNOWN);
            takeBugReportInterfaceFailureIfNeeded(
                "Wi-Fi BugReport (STA interface failure):",
                "Fail to switch to connection mode in started state");
            mModeListener.onStartFailure(ConcreteClientModeManager.this);
            break;
        }
        // Role set in the enter of ConnectModeState.
        mConnectRoleChangeInfoToSetOnTransition = roleChangeInfo;
        transitionTo(mConnectModeState);
        break;
    }
    case CMD_SWITCH_TO_SCAN_ONLY_MODE:
        updateConnectModeState(mRole, WifiManager.WIFI_STATE_DISABLING,
                               WifiManager.WIFI_STATE_ENABLED);
        mDeferStopHandler.start(getWifiOffDeferringTimeMs());
        break;
    case CMD_SWITCH_TO_SCAN_ONLY_MODE_CONTINUE: {
        RoleChangeInfo roleChangeInfo = (RoleChangeInfo) message.obj;
        mScanRoleChangeInfoToSetOnTransition = roleChangeInfo;
        transitionTo(mScanOnlyModeState);
        break;
    }
    case CMD_INTERFACE_DOWN:
        Log.e(getTag(),
              getName() + ", detected an interface down, reporting failure to "
              + "SelfRecovery");
        mSelfRecovery.trigger(SelfRecovery.REASON_STA_IFACE_DOWN);
                        // once interface down, nothing else to do...  stop the state machine
                        captureObituaryAndQuitNow();
                        break;
                    case CMD_INTERFACE_STATUS_CHANGED:
                        boolean isUp = message.arg1 == 1;
                        onUpChanged(isUp);
                        break;
                    case CMD_INTERFACE_DESTROYED:
                        Log.e(getTag(), getName() + ", interface destroyed - client mode stopping");
                        mClientInterfaceName = null;
                        // once interface destroyed, nothing else to do...  stop the state machine
                        captureObituaryAndQuitNow();
                        break;
                    default:
                        return NOT_HANDLED;
                }
                return HANDLED;
            }

\packages\modules\Wifi\service\java\com\android\server\wifi\WifiNative.java


    /**
     * Switches an existing Client mode interface from scan mode
     * {@link Iface#IFACE_TYPE_STA_FOR_SCAN} to connectivity mode
     * {@link Iface#IFACE_TYPE_STA_FOR_CONNECTIVITY}.
     *
     * @param ifaceName Name of the interface.
     * @param requestorWs Requestor worksource.
     * @return true if the operation succeeded, false if there is an error or the iface is already
     * in scan mode.
     */
    public boolean switchClientInterfaceToConnectivityMode(@NonNull String ifaceName,
            @NonNull WorkSource requestorWs) {
        synchronized (mLock) {
            final Iface iface = mIfaceMgr.getIface(ifaceName);
            if (iface == null) {
                Log.e(TAG, "Trying to switch to connectivity mode on an invalid iface="
                        + ifaceName);
                return false;
            }
            if (iface.type == Iface.IFACE_TYPE_STA_FOR_CONNECTIVITY) {
                Log.e(TAG, "Already in connectivity mode on iface=" + ifaceName);
                return true;
            }
            if (mWifiVendorHal.isVendorHalSupported()
                    && !mWifiVendorHal.replaceStaIfaceRequestorWs(iface.name, requestorWs)) {
                Log.e(TAG, "Failed to replace requestor ws on " + iface);
                teardownInterface(iface.name);
                return false;
            }
            if (!startSupplicant()) {
                Log.e(TAG, "Failed to start supplicant");
                teardownInterface(iface.name);
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
                return false;
            }
            if (!mSupplicantStaIfaceHal.setupIface(iface.name)) {
                Log.e(TAG, "Failed to setup iface in supplicant on " + iface);
                teardownInterface(iface.name);
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
                return false;
            }
            if (mContext.getResources().getBoolean(
                    R.bool.config_wifiNetworkCentricQosPolicyFeatureEnabled)) {
                mQosPolicyFeatureEnabled = mSupplicantStaIfaceHal
                        .setNetworkCentricQosPolicyFeatureEnabled(iface.name, true);
                if (!mQosPolicyFeatureEnabled) {
                    Log.e(TAG, "Failed to enable QoS policy feature for iface " + iface.name);
                }
            }
            iface.type = Iface.IFACE_TYPE_STA_FOR_CONNECTIVITY;
            iface.featureSet = getSupportedFeatureSetInternal(iface.name);
            saveCompleteFeatureSetInConfigStoreIfNecessary(iface.featureSet);
            updateSupportedBandForStaInternal(iface);
            mIsEnhancedOpenSupported = (iface.featureSet & WIFI_FEATURE_OWE) != 0;
            Log.i(TAG, "Successfully switched to connectivity mode on iface=" + iface);
            return true;
        }
    }

    /** Helper method invoked to start supplicant if there were no STA ifaces */
    private boolean startSupplicant() {
        synchronized (mLock) {
            if (!mIfaceMgr.hasAnyStaIfaceForConnectivity()) {
                if (!startAndWaitForSupplicantConnection()) {
                    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 startAndWaitForSupplicantConnection() {
        // Start initialization if not already started.
        if (!mSupplicantStaIfaceHal.isInitializationStarted()
                && !mSupplicantStaIfaceHal.initialize()) {
            return false;
        }
        if (!mSupplicantStaIfaceHal.startDaemon()) {
            Log.e(TAG, "Failed to startup supplicant");
            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;
    }

\packages\modules\Wifi\service\java\com\android\server\wifi\SupplicantStaIfaceHal.java


    /**
     * Initialize the STA Iface HAL. Creates the internal ISupplicantStaIfaceHal
     * object and calls its initialize method.
     *
     * @return true if the initialization succeeded
     */
    public boolean initialize() {
        synchronized (mLock) {
            if (mStaIfaceHal == null) {
                Log.wtf(TAG, "Internal ISupplicantStaIfaceHal instance does not exist.");
                return false;
            }
            if (!mStaIfaceHal.initialize()) {
                Log.e(TAG, "Failed to init ISupplicantStaIfaceHal, stopping startup.");
                return false;
            }
            return true;
        }
    }

\packages\modules\Wifi\service\java\com\android\server\wifi\SupplicantStaIfaceHalHidlImpl.java


    /**
     * Registers a service notification for the ISupplicant service, which triggers initialization
     * of the ISupplicantStaIface
     * @return true if the service notification was successfully registered
     */
    public boolean initialize() {
        synchronized (mLock) {
            if (mVerboseLoggingEnabled) {
                Log.i(TAG, "Registering ISupplicant service ready callback.");
            }
            mISupplicant = null;
            mISupplicantStaIfaces.clear();
            if (mIServiceManager != null) {
                // Already have an IServiceManager and serviceNotification registered, don't
                // don't register another.
                return true;
            }
            try {
                mIServiceManager = getServiceManagerMockable();
                if (mIServiceManager == null) {
                    Log.e(TAG, "Failed to get HIDL Service Manager");
                    return false;
                }
                if (!linkToServiceManagerDeath()) {
                    return false;
                }
                /* TODO(b/33639391) : Use the new ISupplicant.registerForNotifications() once it
                   exists */
                if (!mIServiceManager.registerForNotifications(
                        ISupplicant.kInterfaceName, "", mServiceNotificationCallback)) {
                    Log.e(TAG, "Failed to register for notifications to "
                            + ISupplicant.kInterfaceName);
                    mIServiceManager = null; // Will need to register a new ServiceNotification
                    return false;
                }
            } catch (RemoteException e) {
                Log.e(TAG, "Exception while trying to register a listener for "
                        + "ISupplicant service: " + e);
                supplicantServiceDiedHandler(mDeathRecipientCookie);
            }
            return true;
        }
    }

回到startAndWaitForSupplicantConnection,其调用了startDaemon 启动 wpa_supplicant

\packages\modules\Wifi\service\java\com\android\server\wifi\SupplicantStaIfaceHal.java

    /**
     * Start the supplicant daemon.
     *
     * @return true on success, false otherwise.
     */
    public boolean startDaemon() {
        synchronized (mLock) {
            String methodStr = "startDaemon";
            if (mStaIfaceHal == null) {
                return handleNullHal(methodStr);
            }
            return mStaIfaceHal.startDaemon();
        }
    }

\packages\modules\Wifi\service\java\com\android\server\wifi\SupplicantStaIfaceHalHidlImpl.java


    /**
     * Start the supplicant daemon.
     *
     * @return true on success, false otherwise.
     */
    public boolean startDaemon() {
        synchronized (mLock) {
            try {
                if (isV1_1()) {
                    Log.i(TAG, "Starting supplicant using HIDL 1.1");
                    mISupplicant = getSupplicantMockableV1_1();
                } else {
                    Log.i(TAG, "Starting supplicant using init");
                    if (!mFrameworkFacade.startSupplicant()) {
                        return false;
                    }
                    mISupplicant = getSupplicantMockable();
                }
                setLogLevel(mVerboseHalLoggingEnabled);
            } catch (RemoteException | NoSuchElementException e) {
                Log.e(TAG, "Exception while trying to start supplicant: " + e);
                supplicantServiceDiedHandler(mDeathRecipientCookie);
                return false;
            }
        }
        return true;
    }

    protected android.hardware.wifi.supplicant.V1_1.ISupplicant getSupplicantMockableV1_1()
            throws RemoteException, NoSuchElementException {
        synchronized (mLock) {
            android.hardware.wifi.supplicant.V1_1.ISupplicant iSupplicantDerived =
                    android.hardware.wifi.supplicant.V1_1.ISupplicant.castFrom(
                            getSupplicantMockable());
            if (iSupplicantDerived == null) {
                throw new NoSuchElementException("Cannot cast to V1.1 service.");
            }
            return iSupplicantDerived;
        }
    }

    protected ISupplicant getSupplicantMockable() throws RemoteException, NoSuchElementException {
        synchronized (mLock) {
            ISupplicant iSupplicant = ISupplicant.getService(true);
            if (iSupplicant == null) {
                throw new NoSuchElementException("Cannot get ISupplicant default service.");
            }
            return iSupplicant;
        }
    }

ISupplicant.h

/**
     * This gets the service of this type with the specified instance name. If the
     * service is not in the VINTF manifest on a Trebilized device, this will return
     * nullptr. If the service is not available, this will wait for the service to
     * become available. If the service is a lazy service, this will start the service
     * and return when it becomes available. If getStub is true, this will try to
     * return an unwrapped passthrough implementation in the same process. This is
     * useful when getting an implementation from the same partition/compilation group.
     */
static ::android::sp<ISupplicant> getService(const std::string &serviceName="default", bool getStub=false);
/**
     * Deprecated. See getService(std::string, bool)
     */
static ::android::sp<ISupplicant> getService(const char serviceName[], bool getStub=false)  { std::string str(serviceName ? serviceName : "");      return getService(str, getStub); }
/**
     * Deprecated. See getService(std::string, bool)
     */
static ::android::sp<ISupplicant> getService(const ::android::hardware::hidl_string& serviceName, bool getStub=false)  { std::string str(serviceName.c_str());      return getService(str, getStub); }
/**
     * Calls getService("default", bool). This is the recommended instance name for singleton services.
     */
static ::android::sp<ISupplicant> getService(bool getStub) { return getService("default", getStub); }

ServiceManager.cpp

static void tryStartService(const std::string& fqName, const std::string& name) {
    using ::android::base::SetProperty;

    // The "happy path" here is starting up a service that is configured as a
    // lazy HAL, but we aren't sure that is the case. If the service doesn't
    // have an 'interface' entry in its .rc file OR if the service is already
    // running, then this will be a no-op. So, for instance, if a service is
    // deadlocked during startup, you will see this message repeatedly.
    LOG(INFO) << "Since " << fqName << "/" << name
              << " is not registered, trying to start it as a lazy HAL (if it's not configured to "
                 "be a lazy HAL, it may be stuck starting or still starting).";

    std::thread([=] {
        if (!SetProperty("ctl.interface_start", fqName + "/" + name)) {
            LOG(INFO) << "Tried to start " << fqName << "/" << name
                      << " as a lazy service, but was unable to. Usually this happens when a "
                         "service is not installed, but if the service is intended to be used as a "
                         "lazy service, then it may be configured incorrectly.";
        }
    }).detach();
}

后续就是启动 wpa_supplicant 了

回到CMD_SWITCH_TO_CONNECT_MODE 这条消息的处理,其后续转到了ConnectModeState

来看看这个状态的 enter 方法

@Override
public void enterImpl() {
    Log.d(getTag(), "entering ConnectModeState, starting ClientModeImpl");
    if (mClientInterfaceName == null) {
        Log.e(getTag(), "Supposed to start ClientModeImpl, but iface is null!");
    } else {
        if (mClientModeImpl != null) {
            Log.e(getTag(), "ConnectModeState.enter(): mClientModeImpl is already "
                  + "instantiated?!");
        }
        mClientModeImpl = mWifiInjector.makeClientModeImpl(
            mClientInterfaceName, ConcreteClientModeManager.this,
            mVerboseLoggingEnabled);
        mClientModeImpl.setShouldReduceNetworkScore(mShouldReduceNetworkScore);
    }
    if (mConnectRoleChangeInfoToSetOnTransition == null
        || !(mConnectRoleChangeInfoToSetOnTransition.role
             instanceof ClientConnectivityRole)) {
        Log.wtf(TAG, "Unexpected mConnectRoleChangeInfoToSetOnTransition: "
                + mConnectRoleChangeInfoToSetOnTransition);
        // Should never happen, but fallback to primary to avoid a crash.
        mConnectRoleChangeInfoToSetOnTransition =
        new RoleChangeInfo(ROLE_CLIENT_PRIMARY);
    }

    // Could be any one of possible connect mode roles.
    setRoleInternalAndInvokeCallback(mConnectRoleChangeInfoToSetOnTransition);
    updateConnectModeState(mConnectRoleChangeInfoToSetOnTransition.role,
                           WIFI_STATE_ENABLED, WIFI_STATE_ENABLING);
}

\packages\modules\Wifi\service\java\com\android\server\wifi\WifiInjector.java

/**
     * Create a ClientModeImpl
     * @param ifaceName interface name for the ClientModeImpl
     * @param clientModeManager ClientModeManager that will own the ClientModeImpl
     */
public ClientModeImpl makeClientModeImpl(
    @NonNull String ifaceName,
    @NonNull ConcreteClientModeManager clientModeManager,
    boolean verboseLoggingEnabled) {
    ExtendedWifiInfo wifiInfo = new ExtendedWifiInfo(mWifiGlobals, ifaceName);
    SupplicantStateTracker supplicantStateTracker = new SupplicantStateTracker(
        mContext, mWifiConfigManager, mBatteryStats, mWifiHandlerThread.getLooper(),
        mWifiMonitor, ifaceName, clientModeManager, mBroadcastQueue);
    supplicantStateTracker.enableVerboseLogging(verboseLoggingEnabled);
    return new ClientModeImpl(mContext, mWifiMetrics, mClock,
                              mWifiScoreCard, mWifiStateTracker, mWifiPermissionsUtil, mWifiConfigManager,
                              mPasspointManager, mWifiMonitor, mWifiDiagnostics,
                              mWifiDataStall, mScoringParams, mWifiThreadRunner,
                              mWifiNetworkSuggestionsManager, mWifiHealthMonitor, mThroughputPredictor,
                              mDeviceConfigFacade, mScanRequestProxy, wifiInfo, mWifiConnectivityManager,
                              mWifiBlocklistMonitor, mConnectionFailureNotifier,
                              REGULAR_NETWORK_CAPABILITIES_FILTER, mWifiNetworkFactory,
                              mUntrustedWifiNetworkFactory, mOemWifiNetworkFactory, mRestrictedWifiNetworkFactory,
                              mMultiInternetManager, mWifiLastResortWatchdog, mWakeupController,
                              mLockManager, mFrameworkFacade, mWifiHandlerThread.getLooper(),
                              mWifiNative, new WrongPasswordNotifier(mContext, mFrameworkFacade,
                                                                     mWifiNotificationManager),
                              mWifiTrafficPoller, mLinkProbeManager, mClock.getElapsedSinceBootMillis(),
                              mBatteryStats, supplicantStateTracker, mMboOceController, mWifiCarrierInfoManager,
                              mWifiPseudonymManager,
                              new EapFailureNotifier(mContext, mFrameworkFacade, mWifiCarrierInfoManager,
                                                     mWifiNotificationManager),
                              mSimRequiredNotifier,
                              new WifiScoreReport(mScoringParams, mClock, mWifiMetrics, wifiInfo,
                                                  mWifiNative, mWifiBlocklistMonitor, mWifiThreadRunner, mWifiScoreCard,
                                                  mDeviceConfigFacade, mContext, mAdaptiveConnectivityEnabledSettingObserver,
                                                  ifaceName, mExternalScoreUpdateObserverProxy, mSettingsStore, mWifiGlobals,
                                                  mActiveModeWarden, mWifiConnectivityManager, mWifiConfigManager),
                              mWifiP2pConnection, mWifiGlobals, ifaceName, clientModeManager,
                              mCmiMonitor, mBroadcastQueue, mWifiNetworkSelector, makeTelephonyManager(),
                              this, mSettingsConfigStore, verboseLoggingEnabled, mWifiNotificationManager);
}

这里的构造方法主要是初始化状态机,初始状态为DisconnectedState,会依次调用其父状态的 enter 方法,其父状态是ConnectableState

/** Note that this constructor will also start() the StateMachine. */
public ClientModeImpl(
    @NonNull WifiContext context,
    @NonNull WifiMetrics wifiMetrics,
    @NonNull Clock clock,
    @NonNull WifiScoreCard wifiScoreCard,
    @NonNull WifiStateTracker wifiStateTracker,
    @NonNull WifiPermissionsUtil wifiPermissionsUtil,
    @NonNull WifiConfigManager wifiConfigManager,
    @NonNull PasspointManager passpointManager,
    @NonNull WifiMonitor wifiMonitor,
    @NonNull WifiDiagnostics wifiDiagnostics,
    @NonNull WifiDataStall wifiDataStall,
    @NonNull ScoringParams scoringParams,
    @NonNull WifiThreadRunner wifiThreadRunner,
    @NonNull WifiNetworkSuggestionsManager wifiNetworkSuggestionsManager,
    @NonNull WifiHealthMonitor wifiHealthMonitor,
    @NonNull ThroughputPredictor throughputPredictor,
    @NonNull DeviceConfigFacade deviceConfigFacade,
    @NonNull ScanRequestProxy scanRequestProxy,
    @NonNull ExtendedWifiInfo wifiInfo,
    @NonNull WifiConnectivityManager wifiConnectivityManager,
    @NonNull WifiBlocklistMonitor wifiBlocklistMonitor,
    @NonNull ConnectionFailureNotifier connectionFailureNotifier,
    @NonNull NetworkCapabilities networkCapabilitiesFilter,
    @NonNull WifiNetworkFactory networkFactory,
    @NonNull UntrustedWifiNetworkFactory untrustedWifiNetworkFactory,
    @NonNull OemWifiNetworkFactory oemPaidWifiNetworkFactory,
    @NonNull RestrictedWifiNetworkFactory restrictedWifiNetworkFactory,
    @NonNull MultiInternetManager multiInternetManager,
    @NonNull WifiLastResortWatchdog wifiLastResortWatchdog,
    @NonNull WakeupController wakeupController,
    @NonNull WifiLockManager wifiLockManager,
    @NonNull FrameworkFacade facade,
    @NonNull Looper looper,
    @NonNull WifiNative wifiNative,
    @NonNull WrongPasswordNotifier wrongPasswordNotifier,
    @NonNull WifiTrafficPoller wifiTrafficPoller,
    @NonNull LinkProbeManager linkProbeManager,
    long id,
    @NonNull BatteryStatsManager batteryStatsManager,
    @NonNull SupplicantStateTracker supplicantStateTracker,
    @NonNull MboOceController mboOceController,
    @NonNull WifiCarrierInfoManager wifiCarrierInfoManager,
    @NonNull WifiPseudonymManager wifiPseudonymManager,
    @NonNull EapFailureNotifier eapFailureNotifier,
    @NonNull SimRequiredNotifier simRequiredNotifier,
    @NonNull WifiScoreReport wifiScoreReport,
    @NonNull WifiP2pConnection wifiP2pConnection,
    @NonNull WifiGlobals wifiGlobals,
    @NonNull String ifaceName,
    @NonNull ConcreteClientModeManager clientModeManager,
    @NonNull ClientModeImplMonitor cmiMonitor,
    @NonNull ClientModeManagerBroadcastQueue broadcastQueue,
    @NonNull WifiNetworkSelector wifiNetworkSelector,
    @NonNull TelephonyManager telephonyManager,
    @NonNull WifiInjector wifiInjector,
    @NonNull WifiSettingsConfigStore settingsConfigStore,
    boolean verboseLoggingEnabled,
    @NonNull WifiNotificationManager wifiNotificationManager) {
    super(TAG, looper);
    mWifiMetrics = wifiMetrics;
    mClock = clock;
    mWifiScoreCard = wifiScoreCard;
    mContext = context;
    mFacade = facade;
    mWifiNative = wifiNative;
    mWrongPasswordNotifier = wrongPasswordNotifier;
    mId = id;
    mEapFailureNotifier = eapFailureNotifier;
    mSimRequiredNotifier = simRequiredNotifier;
    mWifiTrafficPoller = wifiTrafficPoller;
    mLinkProbeManager = linkProbeManager;
    mMboOceController = mboOceController;
    mWifiCarrierInfoManager = wifiCarrierInfoManager;
    mWifiPseudonymManager = wifiPseudonymManager;
    mBroadcastQueue = broadcastQueue;
    mNetworkAgentState = DetailedState.DISCONNECTED;

    mBatteryStatsManager = batteryStatsManager;
    mWifiStateTracker = wifiStateTracker;

    mWifiPermissionsUtil = wifiPermissionsUtil;
    mWifiConfigManager = wifiConfigManager;

    mPasspointManager = passpointManager;

    mWifiMonitor = wifiMonitor;
    mWifiDiagnostics = wifiDiagnostics;
    mWifiDataStall = wifiDataStall;
    mThroughputPredictor = throughputPredictor;
    mDeviceConfigFacade = deviceConfigFacade;

    mWifiInfo = wifiInfo;
    mSupplicantStateTracker = supplicantStateTracker;
    mWifiConnectivityManager = wifiConnectivityManager;
    mWifiBlocklistMonitor = wifiBlocklistMonitor;
    mConnectionFailureNotifier = connectionFailureNotifier;

    mLinkProperties = new LinkProperties();
    mMcastLockManagerFilterController = new McastLockManagerFilterController();
    mActivityManager = context.getSystemService(ActivityManager.class);

    mLastBssid = null;
    mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
    mLastSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
    mLastSimBasedConnectionCarrierName = null;
    mLastSignalLevel = -1;

    mScoringParams = scoringParams;
    mWifiThreadRunner = wifiThreadRunner;
    mScanRequestProxy = scanRequestProxy;
    mWifiScoreReport = wifiScoreReport;

    mNetworkCapabilitiesFilter = networkCapabilitiesFilter;
    mNetworkFactory = networkFactory;

    mUntrustedNetworkFactory = untrustedWifiNetworkFactory;
    mOemWifiNetworkFactory = oemPaidWifiNetworkFactory;
    mRestrictedWifiNetworkFactory = restrictedWifiNetworkFactory;
    mMultiInternetManager = multiInternetManager;

    mWifiLastResortWatchdog = wifiLastResortWatchdog;
    mWakeupController = wakeupController;
    mWifiLockManager = wifiLockManager;

    mWifiNetworkSuggestionsManager = wifiNetworkSuggestionsManager;
    mWifiHealthMonitor = wifiHealthMonitor;
    mWifiP2pConnection = wifiP2pConnection;
    mWifiGlobals = wifiGlobals;

    mInterfaceName = ifaceName;
    mClientModeManager = clientModeManager;
    mCmiMonitor = cmiMonitor;
    mTelephonyManager = telephonyManager;
    mSettingsConfigStore = settingsConfigStore;
    updateInterfaceCapabilities();

    PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);

    mSuspendWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WifiSuspend");
    mSuspendWakeLock.setReferenceCounted(false);

    mOnNetworkUpdateListener = new OnNetworkUpdateListener();
    mWifiConfigManager.addOnNetworkUpdateListener(mOnNetworkUpdateListener);

    mOnCarrierOffloadDisabledListener = new OnCarrierOffloadDisabledListener();
    mWifiCarrierInfoManager.addOnCarrierOffloadDisabledListener(
        mOnCarrierOffloadDisabledListener);

    mWifiNetworkSelector = wifiNetworkSelector;
    mWifiInjector = wifiInjector;
    mQosPolicyRequestHandler = new QosPolicyRequestHandler(mInterfaceName, mWifiNative, this,
                                                           mWifiInjector.getWifiHandlerThread());

    mRssiMonitor = new RssiMonitor(mWifiGlobals, mWifiThreadRunner, mWifiInfo, mWifiNative,
                                   mInterfaceName,
                                   () -> {
                                       updateCapabilities();
                                       updateCurrentConnectionInfo();
                                   },
                                   mDeviceConfigFacade);

    enableVerboseLogging(verboseLoggingEnabled);

    mNotificationManager = wifiNotificationManager;
    mInsecureEapNetworkHandlerCallbacksImpl =
    new InsecureEapNetworkHandler.InsecureEapNetworkHandlerCallbacks() {
        @Override
        public void onAccept(String ssid, int networkId) {
            log("Accept Root CA cert for " + ssid);
            sendMessage(CMD_ACCEPT_EAP_SERVER_CERTIFICATE, networkId);
        }

        @Override
        public void onReject(String ssid, boolean disconnectRequired) {
            log("Reject Root CA cert for " + ssid);
            sendMessage(CMD_REJECT_EAP_INSECURE_CONNECTION,
                        WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_REJECTED_BY_USER,
                        disconnectRequired ? 1 : 0, ssid);
        }

        @Override
        public void onError(String ssid) {
            log("Insecure EAP network error for " + ssid);
            sendMessage(CMD_REJECT_EAP_INSECURE_CONNECTION,
                        WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_EAP_FAILURE,
                        0, ssid);
        }};
    mInsecureEapNetworkHandler = new InsecureEapNetworkHandler(
        mContext,
        mWifiConfigManager,
        mWifiNative,
        mFacade,
        mNotificationManager,
        mWifiInjector.getWifiDialogManager(),
        isTrustOnFirstUseSupported(),
        mWifiGlobals.isInsecureEnterpriseConfigurationAllowed(),
        mInsecureEapNetworkHandlerCallbacksImpl,
        mInterfaceName,
        getHandler());

    mPseudonymUpdatingListener = this::updatePseudonymFromOob;
    mApplicationQosPolicyRequestHandler = mWifiInjector.getApplicationQosPolicyRequestHandler();

    final int threshold =  mContext.getResources().getInteger(
        R.integer.config_wifiConfigurationWifiRunnerThresholdInMs);
    mConnectableState = new ConnectableState(threshold);
    mConnectingOrConnectedState = new ConnectingOrConnectedState(threshold);
    mL2ConnectingState = new L2ConnectingState(threshold);
    mL2ConnectedState = new L2ConnectedState(threshold);
    mWaitBeforeL3ProvisioningState = new WaitBeforeL3ProvisioningState(threshold);
    mL3ProvisioningState = new L3ProvisioningState(threshold);
    mL3ConnectedState = new L3ConnectedState(threshold);
    mRoamingState = new RoamingState(threshold);
    mDisconnectedState = new DisconnectedState(threshold);

    addState(mConnectableState); {
        addState(mConnectingOrConnectedState, mConnectableState); {
            addState(mL2ConnectingState, mConnectingOrConnectedState);
            addState(mL2ConnectedState, mConnectingOrConnectedState); {
                addState(mWaitBeforeL3ProvisioningState, mL2ConnectedState);
                addState(mL3ProvisioningState, mL2ConnectedState);
                addState(mL3ConnectedState, mL2ConnectedState);
                addState(mRoamingState, mL2ConnectedState);
            }
        }
        addState(mDisconnectedState, mConnectableState);
    }

    setInitialState(mDisconnectedState);

    setLogOnlyTransitions(false);

    // Start the StateMachine
    start();

    // update with initial role for ConcreteClientModeManager
    onRoleChanged();
    // Update current connection wifiInfo
    updateCurrentConnectionInfo();
}

设置 mac 地址,然后makeIpClient

@Override
public void enterImpl() {
    Log.d(getTag(), "entering ConnectableState: ifaceName = " + mInterfaceName);
    setSuspendOptimizationsNative(SUSPEND_DUE_TO_HIGH_PERF, true);
    if (mWifiGlobals.isConnectedMacRandomizationEnabled()) {
        mFailedToResetMacAddress = !mWifiNative.setStaMacAddress(
            mInterfaceName, MacAddressUtils.createRandomUnicastAddress());
        if (mFailedToResetMacAddress) {
            Log.e(getTag(), "Failed to set random MAC address on ClientMode creation");
        }
    }
    mWifiInfo.setMacAddress(mWifiNative.getMacAddress(mInterfaceName));
    updateCurrentConnectionInfo();
    mWifiStateTracker.updateState(mInterfaceName, WifiStateTracker.INVALID);
    makeIpClient();
}

这里的IpClient 是为连接后的 dhcp 作准备的


    private void makeIpClient() {
        mIpClientCallbacks = new IpClientCallbacksImpl();
        mFacade.makeIpClient(mContext, mInterfaceName, mIpClientCallbacks);
        mIpClientCallbacks.awaitCreation();
    }

然后调用DisconnectedState 的 enter 方法

@Override
public void enterImpl() {
    Log.i(getTag(), "disconnectedstate enter");
    // We don't scan frequently if this is a temporary disconnect
    // due to p2p
    if (mWifiP2pConnection.shouldTemporarilyDisconnectWifi()) {
        // TODO(b/161569371): P2P should wait for all ClientModeImpls to enter
        //  DisconnectedState, not just one instance.
        // (Does P2P Service support STA+P2P concurrency?)
        mWifiP2pConnection.sendMessage(WifiP2pServiceImpl.DISCONNECT_WIFI_RESPONSE);
        return;
    }

    if (mVerboseLoggingEnabled) {
        logd(" Enter DisconnectedState screenOn=" + mScreenOn);
    }

    /** clear the roaming state, if we were roaming, we failed */
    mIsAutoRoaming = false;
    mTargetNetworkId = WifiConfiguration.INVALID_NETWORK_ID;

    mWifiConnectivityManager.handleConnectionStateChanged(
        mClientModeManager,
        WifiConnectivityManager.WIFI_STATE_DISCONNECTED);

    if (mDeviceConfigFacade.isOobPseudonymEnabled()) {
        if (mVerboseLoggingEnabled) {
            logd("unregister PseudonymUpdatingListener");
        }
        // unregister it any way, if it was not registered, it's no OP.
        mWifiPseudonymManager
        .unregisterPseudonymUpdatingListener(mPseudonymUpdatingListener);
    }
}

后续会继续更新 wpa_supplicant 源码分析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值