Android-WIFI笔记整理(二)

本文深入解析了Android系统中WiFi功能的工作流程,包括AP扫描、连接、开启、关闭、热点开启等核心步骤。从设置界面的触发到内核驱动的交互,详细阐述了每个阶段的关键代码路径和事件传递机制。此外,还介绍了AndroidP中WiFi信号强度与图标的关系,以及系统服务的启动。

    1、AP扫描结果上传setting流程(此处为从上往下调流程)(可参考2、节中的3.节以配合理解分析!)
        WifiSettings.java->onWifiStateChanged(int state) updateAccessPointPreferences();(Called when the state of Wifi has changed)
        WifiSettings.java->updateAccessPointPreferences <final List<AccessPoint> accessPoints = mWifiTracker.getAccessPoints();>
            WifiTracker.java->getAccessPoints <return new ArrayList<>(mInternalAccessPoints);>
            用到并更新mInternalAccessPoints的地方:
                WifiTracker.java->updateAccessPoints <mInternalAccessPoints.addAll(accessPoints);>
                调用到updateAccessPoints的地方:
                WifiTracker.java->fetchScansAndConfigsAndUpdateAccessPoints <updateAccessPoints(filteredScanResults, configs);>
                    在执行updateAccessPoints(filteredScanResults, configs);之前进行了如下操作:
                    WifiTracker.java->fetchScansAndConfigsAndUpdateAccessPoints <List<ScanResult> newScanResults = mWifiManager.getScanResults();>    
                    调用fetchScansAndConfigsAndUpdateAccessPoints的地方:
                    WifiTracker.java->final BroadcastReceiver mReceiver
                    
                WifiTracker.java->newScanResults = mWifiManager.getScanResults();!!!
                    BaseWifiService.java->getScanResults(...)
                    WifiServiceImpl.java->getScanResults(...) <mScanRequestProxy.getScanResults()>
                        ScanRequestProxy.java->getScanResults() <return mLastScanResults;>
                        (即最终是从ScanRequestProxy.java中获取扫描结果,具体是如何获取的???)
    2、AP扫描流程(android P-亮屏setting下-wifi成功开启后,流程基本适用于android Q,每10秒扫描结果上传一次!见本节2.节)
        (实抓日志:
            12-04 14:48:40.506   862  1409 D WificondControl: get 21 scan results from wificond
            12-04 14:48:50.287   862  1409 D WificondControl: get 21 scan results from wificond
        )
        补充:android P-亮屏setting下-连接已扫描到的热点后,也会继续扫描wifi,即
            WifiSettings.java->onSubmit(...)->submit(...)->mWifiTracker.resumeScanning();->mScanner.resume();->...(后续可参考如下
            详细流程)
            
        1.WiFi成功开启以后,ClientModeStateMachine由CMD_START转换到StartedState。StartedState 状态机,在更新wifiState时,发送广播
        WifiManager.WIFI_STATE_CHANGED_ACTION , 通知WifiTracker开始进行Scan,即:
        
        ClientModeManager.java-> private class StartedState extends State->onUpChanged    <updateWifiState(WifiManager.WIFI_STATE_UNKNOWN,
        WifiManager.WIFI_STATE_ENABLED);>
        ->updateWifiState <final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION); mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);>
        
        2.WifiTracker 广播监听到WifiManager.WIFI_STATE_CHANGED_ACTION ,执行updateWifiState
        
        WifiTracker.java->final BroadcastReceiver mReceiver = new BroadcastReceiver() <updateWifiState(...)> -> <mScanner.resume();>
        -> <sendEmptyMessage(MSG_SCAN);>
        handleMessage(...)->mWifiManager.startScan()
        sendEmptyMessageDelayed(MSG_SCAN, WIFI_RESCAN_INTERVAL_MS);(WIFI_RESCAN_INTERVAL_MS=10*1000,即谷歌原生默认在亮屏settings界面下,
        扫描周期为10s,此处相当于延时10s,10s之后再将消息发送出去,而后再触发WifiTracker.java->handleMessage(...),执行
        mWifiManager.startScan(),如此往复循环而已!)
            WifiManager.java startScan(null) <mService.startScan(packageName);>
                WifiServiceImpl.java->startScan  <mScanRequestProxy.startScan(callingUid, packageName);>
                    ScanRequestProxy.java->startScan(...) <mWifiScanner.startScan(...);>
                        WifiScanner.java->startScan(...) <mAsyncChannel.sendMessage(CMD_START_SINGLE_SCAN, 0, key, scanParams);>
                            WifiScanningServiceImpl.java->class DriverStartedState extends State->processMessage(...) <tryToStartNewScan();
                            ->mScannerImpl.startSingleScan(...)>
                                WifiScannerImpl.java->public abstract boolean startSingleScan(...)  (注意:此类为抽象类)
                                WificondScannerImpl.java(WificondScannerImpl extends WifiScannerImpl)->startSingleScan mWifiNative.scan(...)
                                    WifiNative.java->scan <mWificondControl.scan(...)>
                                        WificondControl.java->scan <IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName);>
                                                                    <return scannerImpl.scan(settings);>
                                            scanner_impl.cpp->ScannerImpl::scan(...) <scan_utils_->Scan()>
                                                scan_utils.cpp->bool ScanUtils::Scan(...) ->trigger_scan(...,NL80211_CMD_TRIGGER_SCAN,...)
                                                注意:scan_utils (通过netlink,此处不能误解!!!此文件会包含<linux/netlink.h>和"
                                                    wificond/net/netlink_manager.h") 将 NL80211_CMD_TRIGGER_SCAN直接传递给内核wlan驱动
                                                    (而不是wpa_supplicant!!!此处实现传递的具体流程还需要验证!!!(已验证!))
                                                    (具体流程:(/system/connectivity/wificond/scanning/scan_utils.cpp)
                                                        NL80211Packet trigger_scan(
                                                            netlink_manager_->GetFamilyId(),
                                                            NL80211_CMD_TRIGGER_SCAN,
                                                            netlink_manager_->GetSequenceNumber(),
                                                            getpid());
                                                            ...
                                                            netlink_manager_->SendMessageAndGetAckOrError(trigger_scan,error_code)
                                                            (注意:此处只返回ERROR/ACK,而不是具体的扫描结果!!!)
                                                    )    
                                                (driver_nl80211_event.c)
                                                (扫描结束后先后上传如下日志:(可参考3.节进行分析!)
                                                    wpa_supplicant: nl80211: Drv Event 34 (NL80211_CMD_NEW_SCAN_RESULTS) received for wlan0
                                                    (此处34并不表示扫描结果数量)
                                                    HAL:event received NL80211_CMD_NEW_SCAN_RESULTS)
                                                
        3.扫描结果回传(PNO扫描结果的回传流程类似)
            wlan driver扫描结束后会发出NL80211_CMD_NEW_SCAN_RESULTS的广播命令(具体广播位置与流程待深究!!!),
            此处前面处理分析过程为wificond部分:(wpas部分有待深究?!!)
            netlink_manager.cpp->NetlinkManager::BroadcastHandler(...)会对其进行处理:<OnScanResultsReady(std::move(packet));>
            netlink_manager.cpp->NetlinkManager::OnScanResultsReady(...) 此处具体下操作三步操作:
                <1>向wlan driver发送NL80211_ATTR_SCAN_SSIDS以获取WiFi名称SSID
                <GetAttribute(NL80211_ATTR_SCAN_SSIDS, &ssids_attr);ssids_attr.GetListOfAttributeValues(&ssids)>
                <2>向wlan driver发送NL80211_ATTR_SCAN_FREQUENCIES以获取该SSID下对应的频率(即对应信道!!!)
                <packet->GetAttribute(NL80211_ATTR_SCAN_FREQUENCIES, &freqs_attr);freqs_attr.GetListOfAttributeValues(&freqs)>
                (以上两条命令皆是定义在nl80211.h中)
                <3>最后将扫描结果通知上层至scanner_impl.cpp(具体如何通知到上层???如何到达scanner_impl.cpp中?)
                handler->second(if_index, aborted, ssids, freqs);//Run scan result notification handler.
                
                其后scanner_impl.cpp进行如下操作:std::bind(&ScannerImpl::OnScanResultsReady, this, _1, _2, _3, _4),继而:                
                scanner_impl.cpp->ScannerImpl::OnScanResultsReady(...)
                    scan_event_handler_->OnScanResultReady();(此hander即为WificondControl.java中的private class ScanEventHandler
                    extends IScanEvent.Stub)
                        WificondControl.java->class ScanEventHandler->OnScanResultReady()->mWifiMonitor.broadcastScanResultEvent(iface, SCAN_RESULTS_EVENT);
                    注意:WificondControl.OnScanResultReady 上报 WifiMonitor,然后大致的扫描过程如下:
                        WifiMonitor -> WificondScannerImpl --> WifiScaningServiceImpl->WifiService -->
                        WifiTracker --> WifiSettings 刷新扫描结果
                        此处为过程详解:
                        WifiMonitor.java->broadcastScanResultEvent(String iface) <sendMessage(iface, SCAN_RESULTS_EVENT);>
                            然后:(WificondScannerImpl的handle收到此事件!)
                            WificondScannerImpl.java->handleMessage(Message msg) <cancelScanTimeout();>(取消定时器)
                            <pollLatestScanData();
                                (通过AIDL从wificond中先获取当前扫描结果,此处获取貌似没有任何意义?!!)
                                ->mNativeScanResults = mWifiNative.getScanResults(mIfaceName);->mWificondControl.getScanResults();->scannerImpl.getScanResults();
                                (此处WificondControl.getScanResults()中会打印类似“get 16 scan results from wificond”的日志!)
                                (若mLastScanSettings.singleScanEventHandler不为空,则发送CMD_SCAN_RESULTS_AVAILABLE,何意???)
                                ->mLastScanSettings.singleScanEventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);>
                            (此WIFI_SCAN_RESULTS_AVAILABLE定义于WifiNative.java->public static final int WIFI_SCAN_RESULTS_AVAILABLE = 0;
                            而非nl80211.h中所创建的命令!nl80211.h中的cmd应该是专门发往wlan驱动或驱动发来用的!!!)
                                然后(上面发送WIFI_SCAN_RESULTS_AVAILABLE):
                                WifiScanningServiceImpl.java->class WifiSingleScanStateMachine->onScanStatus(...) <sendMessage(CMD_SCAN_RESULTS_AVAILABLE);>
                                ->class WifiSingleScanStateMachine->class ScanningState->processMessage(Message msg) reportScanResults(
                                mScannerImpl.getLatestSingleScanResults());->entry.reportEvent(WifiScanner.CMD_SCAN_RESULT, 0, parcelableAllResults);
                                
                                    WifiScanner.java->class ServiceHandler->handleMessage(Message msg) <((ScanListener) listener).onResults(
                                    ((ParcelableScanData) msg.obj).getResults());>
                                     public interface ScanListener extends ActionListener->onResults(ScanData[] results);(接口定义)
                                    
                                        ScanRequestProxy.java->GlobalScanListener implements WifiScanner.ScanListener->onResults(...)
                                        ->mLastScanResults.addAll(Arrays.asList(scanResults));(保存扫描结果,该结果会被上层调用!!!)
                                        ->sendScanResultBroadcast(true);-><Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);mContext.
                                        sendBroadcastAsUser(intent, UserHandle.ALL);>(发送广播SCAN_RESULTS_AVAILABLE_ACTION,以提醒上层的WifiTracker
                                            wifi扫描已经完毕,可以获取扫描结果了!对应1、节中的WifiTracker.java->final BroadcastReceiver
                                            mReceiver,即广播接收器)
    3、AP扫描流程(android P-非setting界面,亮屏/屏,且有保存网络时-此保存网络是指配置文件是否已有保存的网络)
        (/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiConnectivityManager.java)
        WifiConnectivityManager.java->handleScreenStateChanged(boolean screenOn) startConnectivityScan(SCAN_ON_SCHEDULE);
        若此时屏幕仍处于亮屏状态:(默认扫描最小间隔min=20s, 最大间隔max=160s,3917已经得到验证!)
            ->startPeriodicScan(scanImmediately);->startPeriodicSingleScan();->startSingleScan(isFullBandScan, WIFI_WORK_SOURCE);
        若此时屏幕处于灭屏状态:    (PNO扫描)
            ->startDisconnectedPnoScan(); (有保存网络-此保存网络是指配置文件是否已有保存的网络,但未连接,则开启PNO扫描,且默认最小
            间隔min=20s,最大间隔max=20s*3=60s3917实际验证时并得到效果!!!)
    补充:Android Wi-Fi扫描机制(Android P)
        Android P的扫描场景可以归结为以下四种:
        1.亮屏情况下,在Wifi settings界面,固定扫描,时间间隔为10s
        2.亮屏情况下,非Wifi settings界面,二进制指数退避扫描,退避:interval*(2^n), 最小间隔min=20s, 最大间隔max=160s
        3.灭屏情况下,有保存网络时,若已连接,不扫描,否则,PNO扫描,即只扫描已保存的网络。最小间隔min=20s,最大间隔max=20s*3=60s
        (PNO 即Preferred Network Offload,用于系统在休眠的时候连接WiFi)    
        4.无保存网络情况下,固定扫描,间隔为5分钟,用于通知用户周围存在可用开放网络。(第四种情况属于Android O的逻辑,因为在P的代码里还
            没有找到关于这个扫描的代码,也可能取消了!!!)
    4、wifi开启流程(android 9.0 即P)
        大致的描述过程如下:
            WIfiEnabler->WifiManager->WifiService->WifiServiceImpl->WIfiStateMachinePrime->WIfiStateMachine->WifiNative
        此处为详解:
        1.在wifisettings activity的onStart函数中,创建一个WifiEnabler对象,用于实现wifi开关功能
        WifiSettings.java->onStart() <mWifiEnabler = createWifiEnabler();>
        2.WifiEnabler实现了SwitchWidgetController.OnSwitchChangeListener接口,所以重写了onSwitchToggled方法。WifiEnabler开关
            onSwitchToggled中会调用WifiManager.setWifiEnabled方法
        WifiEnabler.java->onSwitchToggled(boolean isChecked) <mWifiManager.setWifiEnabled(isChecked)>
            WifiManager.java->setWifiEnabled(...) <mService.setWifiEnabled(mContext.getOpPackageName(), enabled);>
        3.WifiServiceImpl中实现WifiManager的方法,在setWifiEnabled函数中向WifiController发消息:CMD_WIFI_TOGGLED
                WifiServiceImpl.java->setWifiEnabled(...) <mWifiController.sendMessage(CMD_WIFI_TOGGLED);>
                    class StaDisabledState->processMessage(Message msg) <transitionTo(mDeviceActiveState);>
                        class DeviceActiveState->enter() <mWifiStateMachinePrime.enterClientMode();>
        3.执行enterClientMode函数,给ModeStateMachine状态机发送CMD_START_CLIENT_MODE消息
        WifiStateMachinePrime.java->enterClientMode() <changeMode(ModeStateMachine.CMD_START_CLIENT_MODE);->mModeStateMachine.sendMessage(newMode);>
            class ModeStateMachine->checkForAndHandleModeChange(Message message) <mModeStateMachine.transitionTo(mClientModeActiveState);>
                class ClientModeActiveState->enter() <mManager.start();>
                    ActiveModeManager.java->interface ActiveModeManager <start()> (此处仅是一个接口)
        4.ClientModeManager!!!里首先是调用了start函数,发送消息CMD_START给ClientModeStateMachine,消息是IdleState进行处理
        ClientModeManager.java->ClientModeManager implements ActiveModeManager->start() mStateMachine.sendMessage(ClientModeStateMachine.CMD_START);
            class IdleState->processMessage(Message message) <mWifiNative.setupInterfaceForClientMode(...)>
        5.setupInterfaceForClientMode的相应处理
        WifiNative.java->setupInterfaceForClientMode(...)
            <startHal()>                                 (启动HAL,加载wlan.ko,即wlan driver!!!)
                mWifiVendorHal.startVendorHal()
                    WifiVendorHal.java->startVendorHal() <mHalDeviceManager.start()> (该层日志打印标签为WifiVendorHal)
                        HalDeviceManager.java->start() <startWifi();->WifiStatus status = mWifi.start();> (注:private IWifi mWifi;)
                        (IWifi即代表IWifi.hal,包含在/hardware/interfaces/wifi目录下,至此通过某种交互方式,如JNI、AIDL或HIDL,进入HAL层。
                            在编译后会自动产生IWifi.java文件(此处使用AIDL机制生成),之前通过mifi调用的接口都是通过它实现的)
                        (该层日志打印标签为isHalDevMgr)
                        (而HAL层的文件,一般放在hardware的wifi_hal目录下,其日志标签为WifiHAL,也算是wifi日志中最底层的信息了!)
                        (在IWifi.java->getService->asInterface中可找到IWifi对应的服务端为:wifi.cpp 如通常保存路径为:
                            /hardware/interfaces/wifi/1.3/default/,1.3可视为版本号)
            <startSupplicant()>                            (通过init的.rc或者WPAS的HIDL启动supplicant,最终都是以service形式起来!)
            <setupInterfaceForClientMode(iface.name)>    (非加载驱动,具体用处待定???)
            <mWifiMonitor.startMonitoring(iface.name);>    (启动WifiMonitor)
        补充:(android Q中5.处处理方法对应:WifiNative.java->setupInterfaceForClientInConnectivityMode(...))
            <startHal()> -> mWifiVendorHal.startVendorHal()  (此处加载驱动的地方,具体流程如下:!!!详情可见:
            https://blog.youkuaiyun.com/nilingxi/article/details/103311159)
            (/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiNative.java)
                <startVendorHal()> -> <mHalDeviceManager.start()>
                (/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiVendorHal.java)
                    <start()> -> <return startWifi();> ->     <initIWifiIfNecessary();> -> <mWifi=getWifiServiceMockable();> -> <IWifi.getService(true);>
                                                            (注:此处getService就是获取android.hardware.wifi@1.0-service,而
                                                            android.hardware.wifi@1.0-service就是我们编译生成的结果,WiFi Service层会通
                                                            过这个服务来与我们的WiFi Hal层进行通信!!!)
                                                            <mWifi.start()> (下述是紧跟着start走的!)
                    (/frameworks/opt/net/wifi/service/java/com/android/server/wifi/HalDeviceManager.java)
                        <start(...)> -> <Wifi::startInternal> -> <initializeModeControllerAndLegacyHal()> -> <mode_controller_->initialize()>
                        (/hardware/interfaces/wifi/1.3/default/wifi.cpp)
                            <initialize()> -> <driver_tool_->LoadDriver()>
                            (/hardware/interfaces/wifi/1.3/default/wifi_mode_controller.cpp)
                                <LoadDriver()> -> <wifi_load_driver()>
                                (/frameworks/opt/net/wifi/libwifi_hal/driver_tool.cpp)
                                    <wifi_load_driver()!!!> -> <insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG)>
                                    (/frameworks/opt/net/wifi/libwifi_hal/wifi_hal_common.cpp)
            <startSupplicant()>                                                (启动supplicant)
            <mWificondControl.setupInterfaceForClientMode(iface.name)>        (开启wificond服务,Setup interface for client mode via wificond)
            <mSupplicantStaIfaceHal.setupIface(iface.name)>                    (Setup a STA interface for the specified iface name)
            (注:此处interface为何要安装两次???)
            <mWifiMonitor.startMonitoring(iface.name)>                        (启动WifiMonitor)                
    5、Android P wifi连接流程
        1.WifiSettings.java->onSubmit(WifiDialog dialog) <submit(mDialog.getController());->connect(...);->mWifiManager.
        connect(config, mConnectListener);>
            WifiManager.java->connect(...) <getChannel().sendMessage(CONNECT_NETWORK, WifiConfiguration.INVALID_NETWORK_ID,
            putListener(listener), config);>
                WifiServiceImpl.java->class ClientHandler->case WifiManager.CONNECT_NETWORK <mWifiStateMachine.sendMessage
                (Message.obtain(msg));>
                    (注意:android Q中此处不再用WifiStateMachine.java,而是用ClientModeImpl.java!!!,此处可具体情况具体分析)
                    WifiStateMachine.java->class ConnectModeState->connectToUserSelectNetwork(...) <startConnectToNetwork(...);->
                    sendMessage(CMD_START_CONNECT, networkId, uid, bssid);>
        2.从save network 连接热点又一次转化, 转为CMD_START_CONNECT送到内部状态机(ConnectModeState )处理送到WifiNative 进行处理
        Connect
        WifiStateMachine.java->class ConnectModeState->processMessage(Message message) <mWifiNative.connectToNetwork(mInterfaceName,
        config)>
        3.WifiNative –> SupplicantStaIfaceHal -> SupplicantStaNetworkHal -> WifMonitor(关联阶段)
            SupplicantStaIfaceHal -> SupplicantStaNetworkHal添加网络,select(实则通过hidl将connect 传给到 wpa_supplicant)
            wpa_supplicant完成一系列与路由器的之间的beacon帧(probe、assoc(之前还要完成必要的authentication)、4way-handshake 、
                group-handshake)后,再能取到路由器的颁发的认可证(既是拿到最后的compelted)
            最后,通过wifiMonitor上报wpa_supplicant 任务已完成,既是完成连接的第一阶段(关联阶段)
            WiFiMonitor上报的事件是,NETWORK_CONNECTION_EVENT (又一次回到WifiStateMachine)
        4.获取IP阶段
            WifMonitor --> WifiStateMachine
            WifiStateMachine.java->class ConnectModeState->processMessage(Message message) case WifiMonitor.NETWORK_CONNECTION_EVENT:
            sendNetworkStateChangeBroadcast(mLastBssid);transitionTo(mObtainingIpState);
            class ObtainingIpState->enter()
                setNetworkDetailedState(DetailedState.OBTAINING_IPADDR);
                clearTargetBssid("ObtainingIpAddress");
                stopIpClient();
                mIpClient.setHttpProxy(currentConfig.getHttpProxy());
                IpClient.buildProvisioningConfiguration();
            注:ObtainingIpState 获取IP 的流程中规中矩,先是update 系统的State
                停掉IpClient (自从Android N 后,获取IP已废弃了dhcpd,扶持了另一位的IpClient 、IpManager来完成自己的事业 !!!)
                清掉bssid以避免其影响到漫游导致断链
                Ipclient 开始接管舞台(启动获取IP) (此处dhcp协议,后续学习并更新)
                
    6、wifi关闭流程(android Q-3917)
        由前面4、节可知framework层提供的wifi开关接口都是setWifiEnabled,只是参数不同而已。true表示开启wifi、false表示关闭wifi。
        WifiEnabler.java->onSwitchToggled(boolean isChecked) -> <mWifiManager.setWifiEnabled(isChecked)>
            WifiManager.java->setWifiEnabled(...) <mService.setWifiEnabled(mContext.getOpPackageName(), enabled);>
                WifiServiceImpl.java->setWifiEnabled(...) <mWifiController.sendMessage(CMD_WIFI_TOGGLED);>    
                    (wifi开启的时候,WifiController中状态为DeviceActiveState(其父状态为StaEnabledState),故
                    以下是StaEnabledState对CMD_WIFI_TOGGLED消息的处理)
                    class StaEnabledState processMessage(...)->CMD_WIFI_TOGGLED:transitionTo(mStaDisabledWithScanState);或transitionTo(mStaDisabledState);
                        (注:isWifiToggleEnabled为false表示要关闭wifi,则将状态切换到StaDisabledWithScanState(如果可以一直扫描)或
                        ApStaDisabledState。下面主要看切换到ApStaDisabledState状态的流程操作)
                    class StaDisabledState enter()->mActiveModeWarden.disableWifi();
                    ActiveModeWarden.java->changeMode(ModeStateMachine.CMD_DISABLE_WIFI);
                        class ModeStateMachine checkForAndHandleModeChange(...)->mModeStateMachine.transitionTo(mWifiDisabledState);
                        class WifiDisabledState enter()->空空如也,有待深究???
    7、热点开启流程(到WifiNative层,android Q验证所得结果!)
        ./packages/apps/Settings/src/com/android/settings/wifi/tether/WifiTetherSwitchBarController.java
            ->onSwitchToggled mWifiManager.isWifiApEnabled()+startTether();
                ->startTether mConnectivityManager.startTethering
        ./frameworks/base/core/java/android/net/ConnectivityManager.java
        ./frameworks/base/services/core/java/com/android/server/ConnectivityService.java
        ./frameworks/base/services/core/java/com/android/server/connectivity/Tethering.java
        ./frameworks/base/wifi/java/android/net/wifi/WifiManager.java
        ./frameworks/base/wifi/java/com/android/server/wifi/BaseWifiService.java
        ./frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiServiceImpl.java
        ./frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiController.java

        ./frameworks/opt/net/wifi/service/java/com/android/server/wifi/ActiveModeWarden.java
        ./frameworks/opt/net/wifi/service/java/com/android/server/wifi/ActiveModeManager.java  (interface)
        ./frameworks/opt/net/wifi/service/java/com/android/server/wifi/SoftApManager.java
        ./frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiNative.java
        ./frameworks/opt/net/wifi/service/java/com/android/server/wifi/SoftApManager.java
        ...
        注意:具体可参加见log验证结果截图-tetherOpen
        
        SoftApManager.java的处理:
        SoftApManager!!!里首先是调用了start函数,发送消息CMD_START给SoftApStateMachine,消息是IdleState进行处理
        1、    mApInterfaceName = mWifiNative.setupInterfaceForSoftApMode(...),如下:
        (android Q中WifiNative处理方法对应:WifiNative.java->setupInterfaceForSoftApMode(...))
        <startHal()> -> mWifiVendorHal.startVendorHal() (此处加载驱动的部分基本与本篇.4节中STA模式下开启wifi时所分析的流程一致!)
        <startHostapd()>                                                (通过hostapd的HIDL启动Hostapd,最终是以service形式起来!)
        <mWificondControl.setupInterfaceForSoftApMode(iface.name)>        (开启wificond服务,Setup interface for softAp mode via wificond)
        以上完成了加载驱动和通过hostapd安装接口的部分,后续开始按所提供的配置开启AP:
        2、result = startSoftAp((WifiConfiguration) message.obj);
            <mWifiNative.startSoftAp(mApInterfaceName, localConfig, mSoftApListener)>
        
    注意:Android 基本套路大框架还是不变的: apps – services – native – drv(kernel)!!!(此处不包括services通过wificond与drv交互的情况!)
    
    8、HandlerThread("WifiService")线程的创建与使用(有何用???)
        (注:类似这样的线程还有:ClientModeImpl、WifiP2pService,都是在WifiInjector.java中定义!)
        (/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiInjector.java)
        class WifiInjector:
            mWifiServiceHandlerThread = new HandlerThread("WifiService");(注:HandlerThread extends Thread !)
            mWifiServiceHandlerThread.start();    (启动该线程)
            getWifiServiceHandlerThread()->return mWifiServiceHandlerThread;
        (/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiServiceImpl.java)
        public WifiServiceImpl():
            HandlerThread wifiServiceHandlerThread = mWifiInjector.getWifiServiceHandlerThread(); (线程实例的创建)
            mClientModeImplHandler = new ClientModeImplHandler(TAG, wifiServiceHandlerThread.getLooper(), asyncChannel); (handle实例的创建)
            (注:ClientModeImplHandler extends WifiHandler,而HandlerThread extends Thread!在ClientModeImplHandler中
            handleMessage(Message msg)一般会被重写!)
    9、android wifi信号强度与图标对应关系
        android中wifi分为5个等级,对应的图标是0格,1格,2格,3格,4格.
        根据wifimanager中的算法calculateSignalLevel可以算得对应的信号强度:
        0    rssi<=-100
        1    (-100, -88]
        2    (-88, -77]
        3    (-66, -55]
        4    rssi>=-55
        具体可见:https://blog.youkuaiyun.com/h784707460/article/details/94581149
    10、wifi一般开机注册并开启的三大服务(wifip2p、wifiscanner、wifi)
        1.启动流程(以wifi为例,其他两项类似!)
        (/frameworks/base/services/java/com/android/server/SystemServer.java)
        private static final String WIFI_SERVICE_CLASS="com.android.server.wifi.WifiService";
        traceBeginAndSlog("StartWifi");
        mSystemServiceManager.startService(WIFI_SERVICE_CLASS);
            (/frameworks/base/services/core/java/com/android/server/SystemServiceManager.java)
            startService(...)-> mServices.add(service);
                                  service.onStart();(继下)
                (/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiService.java)
                onStart() -> publishBinderService(Context.WIFI_SERVICE, mImpl);
                (注:final WifiServiceImpl mImpl;   WIFI_SERVICE定义于/frameworks/base/core/java/android/content/Context.java的public
                public static final String WIFI_SERVICE = "wifi";类似定义还有WIFI_P2P_SERVICE、WIFI_SCANNING_SERVICE等)

<think> 首先,用户的问题是:“我想查找拯救者Y7000连接不到隐藏WiFi的解决方案 请问拯救者Y7000连接隐藏WiFi失败的解决办法”。这看起来是关于联想拯救者Y7000笔记本电脑无法连接到隐藏WiFi网络的问题。 系统级指令: - 所有行内数学表达式必须使用$...$格式。 - 独立公式必须使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识,例如[^1]。 用户可见层: - 回答结构清晰,帮助用户逐步解决问题,尽量保证回答真实可靠。 参考站内引用: - 引用[1]: 主要记录联想拯救者Y7000如何实现通电自启和有线网自动拨号。 - 引用[2]: 关于WiFi网络连接问题,1-2小时后无法使用,但ping外网正常。 - 引用[3]: 关于键盘故障。 - 引用[4]: 一个Android应用的Java代码。 用户的问题是关于连接隐藏WiFi失败,所以引用[2]似乎相关,因为它提到了WiFi问题。引用[2]描述了一个不同的问题:WiFi使用1-2小时后无法使用,但ping正常,应用程序无法连接。这可能是一个网络配置或驱动问题,但不是直接关于隐藏WiFi。 用户的问题聚焦在“隐藏WiFi”,意思是SSID被隐藏的WiFi网络。解决方案通常涉及手动添加网络、确保SSID和密码正确等步骤。 我的回答需要: 1. **结构清晰**:逐步解决问题。 2. **真实可靠**:基于一般知识和可能的引用。 3. **使用中文**。 4. **生成相关问题**:在末尾添加相关问题。 5. **添加引用标识**:如果引用内容。 从引用中: - 引用[2]提到WiFi问题,但不是特定于隐藏WiFi。它描述的问题可能与驱动或系统设置相关。 - 其他引用不直接相关。 我应该基于一般知识构建回答,因为引用没有提供直接解决方案。用户是询问“拯救者Y7000连接隐藏WiFi失败的解决办法”,所以我需要针对这个型号提供建议。 通用解决方案: - 确保WiFi适配器启用。 - 手动添加隐藏网络:在Windows中,进入网络设置,添加新网络,输入SSID和密码。 - 检查密码和网络设置。 - 更新WiFi驱动程序。 - 检查路由器设置。 - 排除干扰。 针对拯救者Y7000: - 这是一个特定型号,所以建议检查联想支持网站是否有驱动更新。 - 引用[2]提到用户有WiFi问题,但不是隐藏WiFi。我可以参考它作为可能的相关问题。 回答结构: 1. **引言**:确认问题并概述步骤。 2. **步骤**:逐步解决连接隐藏WiFi的失败。 - 步骤1:手动添加隐藏网络。 - 步骤2:检查SSID和密码。 - 步骤3:更新驱动程序。 - 步骤4:其他故障排除。 3. **引用相关部分**:如果适用。 4. **结束**:建议如果问题持续。 5. **生成相关问题**:添加相关问题部分。 添加引用: - 引用[2]提到WiFi问题,我可以说类似问题可能由驱动引起,但需要谨慎引用。 - 例如:“类似问题如引用[2]中所述,可能由驱动程序或系统设置导致。” LaTeX:用户问题中没有数学内容,所以可能不需要。但指令说“所有行内数学表达式”,如果没有,就不需要。 生成相关问题: - 基于主题:WiFi连接问题、驱动更新、联想拯救者支持等。 - 例如: 1. 如何更新联想拯救者Y7000的WiFi驱动程序? 2. Windows 10中如何解决一般WiFi连接问题? 3. 隐藏WiFi网络的安全性如何? 确保回答真实可靠:提供一般性建议,鼓励用户检查官方支持。 完整回答框架: - 开头:理解问题。 - 步骤: 1. 检查WiFi开关和设置。 2. 手动添加隐藏网络。 3. 验证SSID和密码。 4. 更新网络驱动程序。 5. 重启路由器和电脑。 6. 检查Windows网络诊断。 - 如果问题持续,联系联想支持。 - 引用[2]作为参考:类似问题可能由驱动引起。 - 相关问题部分。 </think>### 拯救者Y7000连接隐藏WiFi失败的解决方案 针对联想拯救者Y7000笔记本电脑无法连接到隐藏WiFi网络的问题,我为您整理了分步解决方案。隐藏WiFi(SSID未广播的网络)需要手动配置,常见失败原因包括驱动问题、网络设置错误或系统冲突。以下步骤基于常见故障排除方法,并结合类似问题(如引用[2]中提到的WiFi连接异常)进行优化。请按顺序操作,确保操作前保存所有工作。 #### 步骤1: 手动添加隐藏WiFi网络 - **操作说明**: 1. 打开Windows设置(Win + I),进入“网络和Internet” > “WiFi” > “管理已知网络”。 2. 点击“添加新网络”,输入隐藏WiFi的确切SSID(区分大小写)、安全类型(如WPA2-Personal)和密码。 3. 勾选“即使此网络未广播也连接”,然后保存。 4. 重启电脑并尝试连接。 - **注意**: 如果SSID或密码错误,连接会失败。建议从路由器后台核对信息。路由器设置方法通常需在浏览器输入192.168.1.1(具体地址参考路由器手册)。 #### 步骤2: 更新或回滚WiFi驱动程序 - **原因分析**: 驱动程序过时或损坏是常见问题(类似引用[2]中描述的WiFi异常)。拯救者Y7000常使用Intel或Realtek无线网卡,驱动兼容性需优先检查。 - **操作说明**: 1. 右键点击“开始菜单”,选择“设备管理器” > “网络适配器”,找到无线网卡(如“Intel Wireless-AC 9560”)。 2. 右键选择“更新驱动程序”,使用自动搜索更新。 3. 如果更新后问题依旧,尝试“回滚驱动程序”:在驱动属性中选择“回滚驱动程序”(仅当之前更新过)。 4. 或从联想官网下载最新驱动: - 访问[联想支持网站](https://support.lenovo.com),输入Y7000型号,下载对应无线驱动。 - 安装后重启电脑。 - **引用支持**: 类似驱动问题可能导致间歇性故障[^2]。 #### 步骤3: 检查系统和网络设置 - **操作说明**: 1. **运行网络诊断**: - 在任务栏右键点击WiFi图标,选择“疑难解答”。Windows会自动检测问题(如IP冲突或协议错误)。 2. **重置网络栈**: - 以管理员身份打开命令提示符(Win + X > “命令提示符(管理员)”),依次输入: ``` netsh winsock reset netsh int ip reset ipconfig /release ipconfig /renew ``` 完成后重启电脑。 3. **禁用省电模式**: - 在“设备管理器”中找到无线网卡,右键选择“属性” > “电源管理”,取消勾选“允许计算机关闭此设备以节约电源”。 #### 步骤4: 排除路由器和环境干扰 - **操作说明**: 1. **重启路由器**: 拔掉路由器电源30秒后重新插上,等待重启完成。 2. **检查频段和信道**: - 登录路由器后台,确保隐藏WiFi使用2.4GHz频段(兼容性更好),避免拥挤信道(如1、6、11)。 - 暂时关闭路由器的“MAC地址过滤”或“防火墙”测试。 3. **减少干扰**: 将电脑靠近路由器,避开微波炉、蓝牙设备等干扰源。 #### 步骤5: 其他高级方案 - **使用系统还原**: 如果问题近期出现,尝试还原到之前正常的状态(设置 > 更新和安全 > 恢复 > 系统还原)。 - **联系联想支持**: 如果以上步骤无效,可能是硬件故障(如网卡损坏)。参考拯救者Y7000的保修服务,或提供设备日志给联想技术支持。 ### 总结 多数隐藏WiFi连接问题可通过手动添加网络、更新驱动或重置网络解决。如果您的设备出现类似引用[2]中的长时间使用后故障,优先更新驱动[^2]。若问题持续,建议备份数据并联系联想官方支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值