Android WiFi 连接

Android WiFi 连接

  • 1、设置中WiFi显示
  • 2、WiFi 连接流程
    • 2.1 获取PrimaryClientModeManager
    • 2.2 ClientModeImpl状态机ConnectableState
    • 2.3 ISupplicantStaNetworkCallback 回调监听
  • 3、 简要时序图
  • 4、原生低层驱动
  • 5、关键日志

1、设置中WiFi显示

Android WiFi基础概览
packages/apps/Settings/src/com/android/settings/network/NetworkProviderSettings.java
packages/apps/Settings/src/com/android/settings/wifi/WifiPickerTrackerHelper.java
frameworks/opt/net/wifi/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java
frameworks/opt/net/wifi/libs/WifiTrackerLib/src/com/android/wifitrackerlib/BaseWifiTracker.java
frameworks/opt/net/wifi/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java

  • mWifiPickerTracker.getConnectedWifiEntry() 当前连接的WiFi
  • mWifiPickerTracker.getWifiEntries() 搜索的WiFi
  • mAddWifiNetworkPreference 添加WiFi项
  • WifiManager.java#connectStandardWifiEntry.java#connect->WifiManager.java#connect 连接WiFi
    protected void updateWifiEntryPreferences() {
        // bypass the update if the activity and the view are not ready, or it's restricted UI.
        if (getActivity() == null || getView() == null || mIsRestricted) {
            return;
        }
        // in case state has changed
        if (mWifiPickerTracker == null
                || mWifiPickerTracker.getWifiState() != WifiManager.WIFI_STATE_ENABLED) {
            return;
        }

        boolean hasAvailableWifiEntries = false;
        mWifiEntryPreferenceCategory.setVisible(true);

        final WifiEntry connectedEntry = mWifiPickerTracker.getConnectedWifiEntry();
        PreferenceCategory connectedWifiPreferenceCategory = getConnectedWifiPreferenceCategory();
        connectedWifiPreferenceCategory.setVisible(connectedEntry != null);
        if (connectedEntry != null) {
            final LongPressWifiEntryPreference connectedPref =
                    connectedWifiPreferenceCategory.findPreference(connectedEntry.getKey());
            if (connectedPref == null || connectedPref.getWifiEntry() != connectedEntry) {
                connectedWifiPreferenceCategory.removeAll();
                final ConnectedWifiEntryPreference pref =
                        createConnectedWifiEntryPreference(connectedEntry);
                pref.setKey(connectedEntry.getKey());
                pref.refresh();
                connectedWifiPreferenceCategory.addPreference(pref);
                pref.setOnPreferenceClickListener(preference -> {
                    if (connectedEntry.canSignIn()) {
                        connectedEntry.signIn(null /* callback */);
                    } else {
                        launchNetworkDetailsFragment(pref);
                    }
                    return true;
                });
                pref.setOnGearClickListener(preference -> {
                    launchNetworkDetailsFragment(pref);
                });

                if (mClickedConnect) {
                    mClickedConnect = false;
                    scrollToPreference(connectedWifiPreferenceCategory);
                }
            }
        } else {
            connectedWifiPreferenceCategory.removeAll();
        }

        int index = 0;
        cacheRemoveAllPrefs(mWifiEntryPreferenceCategory);
        List<WifiEntry> wifiEntries = mWifiPickerTracker.getWifiEntries();
        for (WifiEntry wifiEntry : wifiEntries) {
            hasAvailableWifiEntries = true;

            String key = wifiEntry.getKey();
            LongPressWifiEntryPreference pref =
                    (LongPressWifiEntryPreference) getCachedPreference(key);
            if (pref != null) {
                if (pref.getWifiEntry() == wifiEntry) {
                    pref.setOrder(index++);
                    continue;
                } else {
                    // Create a new preference if the underlying WifiEntry object has changed
                    removePreference(key);
                }
            }

            pref = createLongPressWifiEntryPreference(wifiEntry);
            pref.setKey(wifiEntry.getKey());
            pref.setOrder(index++);
            pref.refresh();

            if (wifiEntry.getHelpUriString() != null) {
                pref.setOnButtonClickListener(preference -> {
                    openSubscriptionHelpPage(wifiEntry);
                });
            }
            mWifiEntryPreferenceCategory.addPreference(pref);
        }
        removeCachedPrefs(mWifiEntryPreferenceCategory);

        if (!hasAvailableWifiEntries) {
            setProgressBarVisible(true);
            Preference pref = new Preference(getPrefContext());
            pref.setSelectable(false);
            pref.setSummary(R.string.wifi_empty_list_wifi_on);
            pref.setOrder(index++);
            pref.setKey(PREF_KEY_EMPTY_WIFI_LIST);
            mWifiEntryPreferenceCategory.addPreference(pref);
        } else {
            // Continuing showing progress bar for an additional delay to overlap with animation
            getView().postDelayed(mHideProgressBarRunnable, 1700 /* delay millis */);
        }

        mAddWifiNetworkPreference.setOrder(index++);
        mWifiEntryPreferenceCategory.addPreference(mAddWifiNetworkPreference);
        setAdditionalSettingsSummaries();
    }

2、WiFi 连接流程

2.1 获取PrimaryClientModeManager

packages/modules/Wifi/framework/java/android/net/wifi/WifiManager.java
packages/modules/Wifi/service/java/com/android/server/wifi/WifiServiceImpl.java
packages/modules/Wifi/service/java/com/android/server/wifi/ConnectHelper.java
packages/modules/Wifi/service/java/com/android/server/wifi/ActiveModeWarden.java
packages/modules/Wifi/service/java/com/android/server/wifi/ConcreteClientModeManager.java
packages/modules/Wifi/service/java/com/android/server/wifi/ClientModeImpl.java
packages/modules/Wifi/service/java/com/android/server/wifi/WifiNative.java
packages/modules/Wifi/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
packages/modules/Wifi/service/java/com/android/server/wifi/ISupplicantStaIfaceHal.java

WifiManager.java#connect > WifiServiceImpl.java#connect > ConnectHelper.java#connectToNetwork > ActiveModeWarden.java#getPrimaryClientModeManager/getPrimaryClientModeManagerNullable/getClientModeManagerInRole(ROLE_CLIENT_PRIMARY)

Android WiFi 连接_第1张图片

2.2 ClientModeImpl状态机ConnectableState

packages/modules/Wifi/service/java/com/android/server/wifi/ConnectHelper.java
packages/modules/Wifi/service/java/com/android/server/wifi/ConcreteClientModeManager.java
packages/modules/Wifi/service/java/com/android/server/wifi/ClientModeImpl.java
packages/modules/Wifi/service/java/com/android/server/wifi/WifiNative.java
packages/modules/Wifi/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
packages/modules/Wifi/service/java/com/android/server/wifi/SupplicantStaIfaceHalAidlImpl.java

ConnectHelper.java#connectToNetwork > ConcreteClientModeManager.java#connectToNetwork > ClientModeImpl.java#connectNetwork > ConnectableState#CMD_CONNECT_NETWORK > ClientModeImpl.java#connectToUserSelectNetwork > ClientModeImpl.java#connectToUserSelectNetwork > ConnectableState#CMD_START_CONNECT > ClientModeImpl.java#connectToNetwork > WifiNative.java#connectToNetwork > SupplicantStaIfaceHal.java#connectToNetwork > SupplicantStaIfaceHalAidlImpl.java#connectToNetwork

    class ConnectableState extends State {
        private boolean mIsScreenStateChangeReceiverRegistered = false;
        BroadcastReceiver mScreenStateChangeReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                if (TextUtils.equals(action, Intent.ACTION_SCREEN_ON)) {
                    sendMessage(CMD_SCREEN_STATE_CHANGED, 1);
                } else if (TextUtils.equals(action, Intent.ACTION_SCREEN_OFF)) {
                    sendMessage(CMD_SCREEN_STATE_CHANGED, 0);
                }
            }
        };

        @Override
        public void enter() {
            Log.d(getTag(), "entering ConnectableState: ifaceName = " + mInterfaceName);

            setSuspendOptimizationsNative(SUSPEND_DUE_TO_HIGH_PERF, true);

            mWifiStateTracker.updateState(mInterfaceName, WifiStateTracker.INVALID);
            mIpClientCallbacks = new IpClientCallbacksImpl();
            Log.d(getTag(), "Start makeIpClient ifaceName = " + mInterfaceName);
            mFacade.makeIpClient(mContext, mInterfaceName, mIpClientCallbacks);
            mIpClientCallbacks.awaitCreation();
        }

        private void continueEnterSetup(IpClientManager ipClientManager) {
            mIpClient = ipClientManager;
            setupClientMode();

            IntentFilter filter = new IntentFilter();
            filter.addAction(Intent.ACTION_SCREEN_ON);
            filter.addAction(Intent.ACTION_SCREEN_OFF);
            if (!mIsScreenStateChangeReceiverRegistered) {
                mContext.registerReceiver(mScreenStateChangeReceiver, filter);
                mIsScreenStateChangeReceiverRegistered = true;
            }
            // Learn the initial state of whether the screen is on.
            // We update this field when we receive broadcasts from the system.
            handleScreenStateChanged(mContext.getSystemService(PowerManager.class).isInteractive());

            if (!mWifiNative.removeAllNetworks(mInterfaceName)) {
                loge("Failed to remove networks on entering connect mode");
            }
            mWifiInfo.reset();
            mWifiInfo.setSupplicantState(SupplicantState.DISCONNECTED);

            sendNetworkChangeBroadcast(DetailedState.DISCONNECTED);

            // Inform metrics that Wifi is Enabled (but not yet connected)
            mWifiMetrics.setWifiState(mInterfaceName, WifiMetricsProto.WifiLog.WIFI_DISCONNECTED);
            mWifiMetrics.logStaEvent(mInterfaceName, StaEvent.TYPE_WIFI_ENABLED);
            mWifiScoreCard.noteSupplicantStateChanged(mWifiInfo);
        }

        @Override
        public void exit() {
            // Inform metrics that Wifi is being disabled (Toggled, airplane enabled, etc)
            mWifiMetrics.setWifiState(mInterfaceName, WifiMetricsProto.WifiLog.WIFI_DISABLED);
            mWifiMetrics.logStaEvent(mInterfaceName, StaEvent.TYPE_WIFI_DISABLED);

            if (!mWifiNative.removeAllNetworks(mInterfaceName)) {
                loge("Failed to remove networks on exiting connect mode");
            }
            if (mIsScreenStateChangeReceiverRegistered) {
                mContext.unregisterReceiver(mScreenStateChangeReceiver);
                mIsScreenStateChangeReceiverRegistered = false;
            }

            stopClientMode();
            mWifiScoreCard.doWrites();
        }

        @Override
        public boolean processMessage(Message message) {
            switch (message.what) {
                case CMD_CONNECTABLE_STATE_SETUP:
                    if (mIpClient != null) {
                        loge("Setup connectable state again when IpClient is ready?");
                    } else {
                        IpClientManager ipClientManager = (IpClientManager) message.obj;
                        continueEnterSetup(ipClientManager);
                    }
                    break;
                case CMD_ENABLE_RSSI_POLL: {
                    mEnableRssiPolling = (message.arg1 == 1);
                    break;
                }
                case CMD_SCREEN_STATE_CHANGED: {
                    handleScreenStateChanged(message.arg1 != 0);
                    break;
                }
                case WifiP2pServiceImpl.DISCONNECT_WIFI_REQUEST: {
                    if (mIpClient == null) {
                        logd("IpClient is not ready, "
                                + "WifiP2pServiceImpl.DISCONNECT_WIFI_REQUEST dropped");
                        break;
                    }
                    if (mWifiP2pConnection.shouldTemporarilyDisconnectWifi()) {
                        mWifiMetrics.logStaEvent(mInterfaceName, StaEvent.TYPE_FRAMEWORK_DISCONNECT,
                                StaEvent.DISCONNECT_P2P_DISCONNECT_WIFI_REQUEST);
                        mWifiNative.disconnect(mInterfaceName);
                    } else {
                        mWifiNative.reconnect(mInterfaceName);
                    }
                    break;
                }
                case CMD_RECONNECT: {
                    WorkSource workSource = (WorkSource) message.obj;
                    mWifiConnectivityManager.forceConnectivityScan(workSource);
                    break;
                }
                case CMD_REASSOCIATE: {
                    if (mIpClient != null) {
                        logd("IpClient is not ready, REASSOCIATE dropped");

                        mWifiNative.reassociate(mInterfaceName);
                    }
                    break;
                }
                case CMD_START_CONNECT: {
                    if (mIpClient == null) {
                        logd("IpClient is not ready, START_CONNECT dropped");

                        break;
                    }
                    /* connect command coming from auto-join */
                    int netId = message.arg1;
                    int uid = message.arg2;
                    String bssid = (String) message.obj;
                    mSentHLPs = false;
                    // Stop lingering (if it was lingering before) if we start a new connection.
                    // This means that the ClientModeManager was reused for another purpose, so it
                    // should no longer be in lingering mode.
                    mClientModeManager.setShouldReduceNetworkScore(false);

                    if (!hasConnectionRequests()) {
                        if (mNetworkAgent == null) {
                            loge("CMD_START_CONNECT but no requests and not connected,"
                                    + " bailing");
                            break;
                        } else if (!mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)) {
                            loge("CMD_START_CONNECT but no requests and connected, but app "
                                    + "does not have sufficient permissions, bailing");
                            break;
                        }
                    }
                    WifiConfiguration config =
                            mWifiConfigManager.getConfiguredNetworkWithoutMasking(netId);
                    logd("CMD_START_CONNECT "
                            + " my state " + getCurrentState().getName()
                            + " nid=" + netId
                            + " roam=" + mIsAutoRoaming);
                    if (config == null) {
                        loge("CMD_START_CONNECT and no config, bail out...");
                        break;
                    }
                    mCurrentConnectionDetectedCaptivePortal = false;
                    mTargetNetworkId = netId;
                    // Update scorecard while there is still state from existing connection
                    mLastScanRssi = mWifiConfigManager.findScanRssi(netId,
                            mWifiHealthMonitor.getScanRssiValidTimeMs());
                    mWifiScoreCard.noteConnectionAttempt(mWifiInfo, mLastScanRssi, config.SSID);
                    mWifiBlocklistMonitor.setAllowlistSsids(config.SSID, Collections.emptyList());
                    mWifiBlocklistMonitor.updateFirmwareRoamingConfiguration(Set.of(config.SSID));

                    updateWifiConfigOnStartConnection(config, bssid);
                    reportConnectionAttemptStart(config, mTargetBssid,
                            WifiMetricsProto.ConnectionEvent.ROAM_UNRELATED);

                    String currentMacAddress = mWifiNative.getMacAddress(mInterfaceName);
                    mWifiInfo.setMacAddress(currentMacAddress);
                    Log.i(getTag(), "Connecting with " + currentMacAddress + " as the mac address");

                    mTargetWifiConfiguration = config;
                    mNetworkNotFoundEventCount = 0;
                    /* Check for FILS configuration again after updating the config */
                    if (config.isFilsSha256Enabled() || config.isFilsSha384Enabled()) {
                        boolean isIpClientStarted = startIpClient(config, true);
                        if (isIpClientStarted) {
                            mIpClientWithPreConnection = true;
                            transitionTo(mL2ConnectingState);
                            break;
                        }
                    }
                    mInsecureEapNetworkHandler.prepareConnection(mTargetWifiConfiguration);
                    setSelectedRcoiForPasspoint(config);
                    connectToNetwork(config);
                    break;
                }
                case CMD_START_FILS_CONNECTION: {
                    if (mIpClient == null) {
                        logd("IpClient is not ready, START_FILS_CONNECTION dropped");
                        break;
                    }
                    mWifiMetrics.incrementConnectRequestWithFilsAkmCount();
                    List<Layer2PacketParcelable> packets;
                    packets = (List<Layer2PacketParcelable>) message.obj;
                    if (mVerboseLoggingEnabled) {
                        Log.d(getTag(), "Send HLP IEs to supplicant");
                    }
                    addLayer2PacketsToHlpReq(packets);
                    WifiConfiguration config = mTargetWifiConfiguration;
                    connectToNetwork(config);
                    break;
                }
                case CMD_CONNECT_NETWORK: {
                    ConnectNetworkMessage cnm = (ConnectNetworkMessage) message.obj;
                    if (mIpClient == null) {
                        logd("IpClient is not ready, CONNECT_NETWORK dropped");
                        cnm.listener.sendFailure(WifiManager.ActionListener.FAILURE_INTERNAL_ERROR);
                        break;
                    }
                    NetworkUpdateResult result = cnm.result;
                    int netId = result.getNetworkId();
                    connectToUserSelectNetwork(
                            netId, message.sendingUid, result.hasCredentialChanged(),
                            cnm.packageName);
                    mWifiMetrics.logStaEvent(mInterfaceName, StaEvent.TYPE_CONNECT_NETWORK,
                            mWifiConfigManager.getConfiguredNetwork(netId));
                    cnm.listener.sendSuccess();
                    break;
                }
                case CMD_SAVE_NETWORK: {
                    ConnectNetworkMessage cnm = (ConnectNetworkMessage) message.obj;
                    if (mIpClient == null) {
                        logd("IpClient is not ready, SAVE_NETWORK dropped");
                        cnm.listener.sendFailure(WifiManager.ActionListener.FAILURE_INTERNAL_ERROR);
                        break;
                    }
                    NetworkUpdateResult result = cnm.result;
                    int netId = result.getNetworkId();
                    if (mWifiInfo.getNetworkId() == netId) {
                        if (result.hasCredentialChanged()) {
                            // The network credentials changed and we're connected to this network,
                            // start a new connection with the updated credentials.
                            logi("CMD_SAVE_NETWORK credential changed for nid="
                                    + netId + ". Reconnecting.");
                            startConnectToNetwork(netId, message.sendingUid, SUPPLICANT_BSSID_ANY);
                        } else {
                            if (result.hasProxyChanged()) {
                                if (mIpClient != null) {
                                    log("Reconfiguring proxy on connection");
                                    WifiConfiguration currentConfig =
                                            getConnectedWifiConfigurationInternal();
                                    if (currentConfig != null) {
                                        mIpClient.setHttpProxy(currentConfig.getHttpProxy());
                                    } else {
                                        Log.w(getTag(),
                                                "CMD_SAVE_NETWORK proxy change - but no current "
                                                        + "Wi-Fi config");
                                    }
                                }
                            }
                            if (result.hasIpChanged()) {
                                // The current connection configuration was changed
                                // We switched from DHCP to static or from static to DHCP, or the
                                // static IP address has changed.
                                log("Reconfiguring IP on connection");
                                WifiConfiguration currentConfig =
                                        getConnectedWifiConfigurationInternal();
                                if (currentConfig != null) {
                                    transitionTo(mL3ProvisioningState);
                                } else {
                                    Log.w(getTag(), "CMD_SAVE_NETWORK Ip change - but no current "
                                            + "Wi-Fi config");
                                }
                            }
                        }
                    } else if (mWifiInfo.getNetworkId() == WifiConfiguration.INVALID_NETWORK_ID
                            && result.hasCredentialChanged()) {
                        logi("CMD_SAVE_NETWORK credential changed for nid="
                                + netId + " while disconnected. Connecting.");
                        WifiConfiguration config =
                                mWifiConfigManager.getConfiguredNetwork(netId);
                        if (!mWifiPermissionsUtil.isAdminRestrictedNetwork(config)) {
                            startConnectToNetwork(netId, message.sendingUid, SUPPLICANT_BSSID_ANY);
                        }
                    } else if (result.hasCredentialChanged()) {
                        WifiConfiguration currentConfig =
                                getConnectedWifiConfigurationInternal();
                        WifiConfiguration updatedConfig =
                                mWifiConfigManager.getConfiguredNetwork(netId);
                        if (currentConfig != null && currentConfig.isLinked(updatedConfig)) {
                            logi("current network linked config saved, update linked networks");
                            updateLinkedNetworks(currentConfig);
                        }
                    }
                    cnm.listener.sendSuccess();
                    break;
                }
                case CMD_BLUETOOTH_CONNECTION_STATE_CHANGE: {
                    mWifiNative.setBluetoothCoexistenceScanMode(
                            mInterfaceName, mWifiGlobals.isBluetoothConnected());
                    break;
                }
                case CMD_SET_SUSPEND_OPT_ENABLED: {
                    if (message.arg1 == 1) {
                        setSuspendOptimizationsNative(SUSPEND_DUE_TO_SCREEN, true);
                        if (message.arg2 == 1) {
                            mSuspendWakeLock.release();
                        }
                    } else {
                        setSuspendOptimizationsNative(SUSPEND_DUE_TO_SCREEN, false);
                    }
                    break;
                }
                case WifiMonitor.ANQP_DONE_EVENT: {
                    mPasspointManager.notifyANQPDone((AnqpEvent) message.obj);
                    break;
                }
                case CMD_STOP_IP_PACKET_OFFLOAD: {
                    int slot = message.arg1;
                    int ret = stopWifiIPPacketOffload(slot);
                    if (mNetworkAgent != null) {
                        mNetworkAgent.sendSocketKeepaliveEvent(slot, ret);
                    }
                    break;
                }
                case WifiMonitor.RX_HS20_ANQP_ICON_EVENT: {
                    mPasspointManager.notifyIconDone((IconEvent) message.obj);
                    break;
                }
                case WifiMonitor.HS20_DEAUTH_IMMINENT_EVENT:
                    mPasspointManager.handleDeauthImminentEvent((WnmData) message.obj,
                            getConnectedWifiConfigurationInternal());
                    break;
                case WifiMonitor.HS20_TERMS_AND_CONDITIONS_ACCEPTANCE_REQUIRED_EVENT:
                    mWifiMetrics
                            .incrementTotalNumberOfPasspointConnectionsWithTermsAndConditionsUrl();
                    mTermsAndConditionsUrl = mPasspointManager
                            .handleTermsAndConditionsEvent((WnmData) message.obj,
                            getConnectedWifiConfigurationInternal());
                    if (mTermsAndConditionsUrl == null) {
                        loge("Disconnecting from Passpoint network due to an issue with the "
                                + "Terms and Conditions URL");
                        sendMessage(CMD_DISCONNECT, StaEvent.DISCONNECT_PASSPOINT_TAC);
                    }
                    break;
                case WifiMonitor.HS20_REMEDIATION_EVENT:
                    mPasspointManager.receivedWnmFrame((WnmData) message.obj);
                    break;
                case WifiMonitor.MBO_OCE_BSS_TM_HANDLING_DONE: {
                    handleBssTransitionRequest((BtmFrameData) message.obj);
                    break;
                }
                case CMD_CONFIG_ND_OFFLOAD: {
                    final boolean enabled = (message.arg1 > 0);
                    mWifiNative.configureNeighborDiscoveryOffload(mInterfaceName, enabled);
                    break;
                }
                // Link configuration (IP address, DNS, ...) changes notified via netlink
                case CMD_UPDATE_LINKPROPERTIES: {
                    updateLinkProperties((LinkProperties) message.obj);
                    break;
                }
                case CMD_START_IP_PACKET_OFFLOAD:
                case CMD_ADD_KEEPALIVE_PACKET_FILTER_TO_APF:
                case CMD_REMOVE_KEEPALIVE_PACKET_FILTER_FROM_APF: {
                    if (mNetworkAgent != null) {
                        mNetworkAgent.sendSocketKeepaliveEvent(message.arg1,
                                SocketKeepalive.ERROR_INVALID_NETWORK);
                    }
                    break;
                }
                case CMD_INSTALL_PACKET_FILTER: {
                    mCachedPacketFilter = (byte[]) message.obj;
                    if (mContext.getResources().getBoolean(
                            R.bool.config_wifiEnableApfOnNonPrimarySta)
                            || isPrimary()) {
                        mWifiNative.installPacketFilter(mInterfaceName, mCachedPacketFilter);
                    } else {
                        Log.v(TAG, "Not applying packet filter on non primary CMM");
                    }
                    break;
                }
                case CMD_READ_PACKET_FILTER: {
                    final byte[] packetFilter;
                    if (mContext.getResources().getBoolean(
                            R.bool.config_wifiEnableApfOnNonPrimarySta)
                            || isPrimary()) {
                        packetFilter = mWifiNative.readPacketFilter(mInterfaceName);
                    } else {
                        Log.v(TAG, "Retrieving cached packet filter on non primary CMM");
                        packetFilter = mCachedPacketFilter;
                    }
                    if (mIpClient != null) {
                        mIpClient.readPacketFilterComplete(packetFilter);
                    }
                    break;
                }
                case CMD_SET_FALLBACK_PACKET_FILTERING: {
                    if ((boolean) message.obj) {
                        mWifiNative.startFilteringMulticastV4Packets(mInterfaceName);
                    } else {
                        mWifiNative.stopFilteringMulticastV4Packets(mInterfaceName);
                    }
                    break;
                }
                case CMD_DIAGS_CONNECT_TIMEOUT: {
                    mWifiDiagnostics.reportConnectionEvent(
                            WifiDiagnostics.CONNECTION_EVENT_TIMEOUT, mClientModeManager);
                    break;
                }
                case WifiP2pServiceImpl.P2P_CONNECTION_CHANGED:
                case CMD_RESET_SIM_NETWORKS:
                case WifiMonitor.NETWORK_CONNECTION_EVENT:
                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
                case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
                case WifiMonitor.ASSOCIATION_REJECTION_EVENT:
                case CMD_RSSI_POLL:
                case CMD_ONESHOT_RSSI_POLL:
                case CMD_PRE_DHCP_ACTION:
                case CMD_PRE_DHCP_ACTION_COMPLETE:
                case CMD_POST_DHCP_ACTION:
                case WifiMonitor.SUP_REQUEST_IDENTITY:
                case WifiMonitor.SUP_REQUEST_SIM_AUTH:
                case WifiMonitor.TARGET_BSSID_EVENT:
                case WifiMonitor.ASSOCIATED_BSSID_EVENT:
                case WifiMonitor.TRANSITION_DISABLE_INDICATION:
                case CMD_UNWANTED_NETWORK:
                case CMD_CONNECTING_WATCHDOG_TIMER:
                case WifiMonitor.NETWORK_NOT_FOUND_EVENT:
                case CMD_ROAM_WATCHDOG_TIMER: {
                    // no-op: all messages must be handled in the base state in case it was missed
                    // in one of the child states.
                    break;
                }
                case CMD_ACCEPT_EAP_SERVER_CERTIFICATE:
                case CMD_REJECT_EAP_SERVER_CERTIFICATE:
                case CMD_START_ROAM:
                case CMD_START_RSSI_MONITORING_OFFLOAD:
                case CMD_STOP_RSSI_MONITORING_OFFLOAD:
                case CMD_IP_CONFIGURATION_SUCCESSFUL:
                case CMD_IP_CONFIGURATION_LOST:
                case CMD_IP_REACHABILITY_LOST:
                case CMD_IP_REACHABILITY_FAILURE: {
                    mMessageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD;
                    break;
                }
                case 0: {
                    // We want to notice any empty messages (with what == 0) that might crop up.
                    // For example, we may have recycled a message sent to multiple handlers.
                    Log.wtf(getTag(), "Error! empty message encountered");
                    break;
                }
                default: {
                    loge("Error! unhandled message" + message);
                    break;
                }
            }

            logStateAndMessage(message, this);
            return HANDLED;
        }
    }

2.3 ISupplicantStaNetworkCallback 回调监听

packages/modules/Wifi/service/java/com/android/server/wifi/SupplicantStaNetworkHalAidlImpl.java
packages/modules/Wifi/service/java/com/android/server/wifi/SupplicantStaNetworkCallbackAidlImpl.java

SupplicantStaIfaceHalAidlImpl.java#connectToNetwork / addNetworkAndSaveConfig > SupplicantStaNetworkHalAidlImpl.java#saveWifiConfiguration / registerNewCallback / registerCallback > mISupplicantStaNetwork.registerCallback(callback)

3、 简要时序图

Android WiFi 连接_第2张图片

4、原生低层驱动

external/wpa_supplicant_8

Android WiFi 连接_第3张图片

5、关键日志

WifiService: connect uid=|WifiConfigManager: Adding/Updating network|WifiConfigManager: Enable disabled network:|WifiConfigManager: Enabling network|WifiConfigManager: Update network last connect|WifiPickerTracker: Received broadcast:|WifiClientModeImpl.*entering.*State|WifiClientModeImpl.*entering|WifiClientModeImpl.*connectToUserSelectNetwork netId|WifiClientModeImpl.*CMD_START_CONNECT|WifiClientModeImpl.*Select candidate security params for|WifiClientModeImpl.*Connecting with|SupplicantStaIfaceHalAidlImpl: connectToNetwork|SupplicantStaNetworkHalAidlImpl: Successfully set SSID|SupplicantStaNetworkHalAidlImpl: The target security params|SupplicantStaIfaceHalAidlImpl: ISupplicantStaIfaceCallback|wpa_supplicant:.* State:|wpa_supplicant: Notifying state change event|wpa_supplicant: wlan

wpa_supplicant: wlan|wpa_supplicant:

你可能感兴趣的:(Android,WiFI,Android,WiFi)