开机向导无法刷新 WiFi 列表问题总结
开机向导无法刷新 WiFi 列表
问题链接:https://e.gitee.com/kunyuan-hongke/projects/842189/bugs/table?issue=IJS1GK
成功日志:pid=4837,com.ohos.setupwizard,屏幕亮屏 Screen=1
失败日志:pid=4814,com.ohos.setupwizard,屏幕息屏 Screen=2
1. 问题概述
| 维度 | 详情 |
|---|---|
| 问题描述 | 开机向导页面无法搜索到 WiFi 列表 |
| 问题概率 | 本地自测非必现,有概率在开机向导界面刷新出 WiFi 列表,但概率很低 |
| 影响因素 | 与是否已连接 WiFi 再测试、等待片刻再打开均无关 |
| 平台 | OpenHarmony 6.1, GK6780V100 |
2. 核心根因
开机时屏幕处于息屏状态(Screen=2),
SystemScanProcess走 PNO(Preferred Network Offload)路径,但首次开机无已保存网络导致 PNO 永久失败;同时 setupwizard 缺少ohos.permission.LOCATION预授权,主动扫描被拒绝,无法自救。两个因素叠加,WiFi 使能过程中无任何硬件扫描被发出,缓存永远为空,setupwizard 超时退出。
TIPS:一开始 setupwizard 检测到 WiFi 状态还没准备好就只进行了
GetScanInfoResults动作,这里依赖的就是外部的 PNO 或者系统定时扫描。等到检测到 WiFi 状态准备好之后就同时进行自身触发的Scan与GetScanInfoResults这两个动作了。
3. 关键时间线总览
3.1 失败流程时间线(Screen=2)
08:00:09 — WiFi 设备层启动
hdf device host wifi_host启动
08:00:13 — WiFi Manager 服务启动
08:00:15 — WiFi HAL 启动
- 初始判断
no need to start Wifi or scanonly
08:00:43 — 用户触发 WiFi 开启
Call wifi func: On
08:00:47 — setupwizard 进入 WiFi 页面
- 第 1/2 次轮询(此时检测到 WiFi 还没准备好,只能直接获取看有没有值)
GetScanInfoList size=0
08:00:53 — WiFi 核心初始化阶段(ScanService + wpa_supplicant + STA)
| 时间戳 | 事件 |
|---|---|
| 53.698 | ScanService Init |
| 53.712 | wpa_supplicant begin to start |
| 53.805 | SystemScanProcess 第1次 -> Screen=2 -> BeginPnoScan [失败] |
| 53.898 | wpa_supplicant start successfully! |
| 53.930 | wlan0: State: DISCONNECTED -> INACTIVE |
08:00:54 — PNO 死锁核心段
| 时间戳 | 事件 |
|---|---|
| 54.087 | staStatus=24 -> SystemScanProcess 第2次 -> BeginPnoScan [失败] |
| 54.127 | setupwizard 第 3 次轮询 -> GetScanInfoList size=0 |
| 54.138 | DealStaOpenRes -> DisableScan(disable=0) [成功] |
| 54.139 | SystemScanProcess 第3次 -> BeginPnoScan -> pno scan is allowed [成功],但是 Have no saved network [失败] 永久死路 |
08:00:57 — setupwizard 6 次主动轮询(均失败)
每次轮询固定模式:
Scan()->LOCATION PERMISSION_DENIED[失败]GetScanInfoResults->GetScanInfoList size=0
6 次轮询时间点:
| 次数 | 时间戳 |
|---|---|
| 第 1 次 | 57.112 |
| 第 2 次 | 02.112 |
| 第 3 次 | 07.113 |
| 第 4 次 | 12.115 |
| 第 5 次 | 17.115 |
| 第 6 次 | 22.117 |
ATM 日志确认:
[IsUserGrantPermPreAuthorized] Permission(ohos.permission.LOCATION) is not in the list
[IsUserGrantPermPreAuthorized] Permission(ohos.permission.APPROXIMATELY_LOCATION) is not in the list
08:01:26 — setupwizard 超时退出
MyAbilityStage.onDestroy
08:01:31 — 用户手动打开 Settings
- pid=5338, com.ohos.settings
08:01:32 — Settings 触发主动扫描
HdiWpaStaScan success[成功]
08:01:36 — wpa_supplicant 扫描完成
- 30 BSSes,耗时 3.76s
08:01:37 — Settings 展示 11 个过滤后的 WiFi
08:01:42 — 用户选择 WiFi 连接
08:01:48 — 连接完成
CTRL-EVENT-CONNECTED
3.2 成功流程时间线(Screen=1)
08:00:47 — setupwizard 进入 WiFi 页面
- 第 1/2 次轮询,
GetScanInfoList size=0
08:00:54 — WiFi 核心初始化阶段
| 时间戳 | 事件 |
|---|---|
| 54.051 | ScanService Init(同失败) |
| 54.151 | wpa_supplicant start |
| 54.158 | SystemScanProcess 第1次 -> Screen=1 -> StartSystemTimerScan -> [失败] wifi disable(等待) |
| 54.450 | staStatus=24 -> SystemScanProcess 第2次 -> StartSystemTimerScan -> [失败] wifi disable(继续等) |
| 54.489 | DealStaOpenRes -> DisableScan(disable=0) [成功] |
| 54.489 | SystemScanProcess 第3次 -> StartSystemTimerScan -> allow system timer scan [成功] |
| 54.492 | Begin call Scan -> HdiWpaStaScan success [成功] |
08:00:58 — 第 1 次扫描完成
- 28 valid results,
Save 28 scan results
08:00:57 — setupwizard 从此开始主动触发 Scan
- 附带 3 轮询 -> 轮询的结果还是
size=0
08:01:02 — setupwizard 第 4 次轮询完成
- 33 results
08:01:07 — setupwizard 第 5 次轮询
Scan()PERMISSION_DENIED 但GetScanInfoList size=33[成功]- 显示 12 个 WiFi
4. 失败流程逐阶段分析
阶段 0:WiFi 设备层 & Manager 服务启动(08:00:09~15)
// WiFi设备层启动
08:00:09.057 hdf device host wifi_host 6 start
08:00:09.512 wifi_host start loop
// WiFi Manager服务启动
08:00:13.467 Start dynamic proc:wifi_manager_service
08:00:14.014 Scheduler proc:wifi_manager_service started
08:00:14.022 Start sta service!
08:00:15.180 Wifi HAL start enter
08:00:15.218 Wifi HAL started
// 系统初始判断(无需立即启动WiFi)
08:00:15.225 Auto start scan only!
08:00:15.227 no need to start Wifi or scanonly
阶段 1:用户触发 WiFi 开启 & setupwizard 前两次轮询(08:00:43~47)
// 用户触发WiFi开启
08:00:43.932 Call wifi func: On (start)
08:00:43.950 Start scan service!
08:00:47.013 Call wifi func: EnableWifi (start)
08:00:47.030 Should start wifi or scanonly.
// setupwizard 第1次轮询
01-01 08:00:47.034 4814 4814 I C01560/WifiNAPIUtils: Call wifi func: GetScanInfoResults (start)
01-01 08:00:47.039 4081 4086 I C01560/WifiFrameWork: WifiSettings::GetScanInfoList size = 0
01-01 08:00:47.045 4814 4827 I C01560/WifiNAPIDevice: GetScanInfoList, size: 0
// setupwizard 第2次轮询
01-01 08:00:47.104 4814 4814 I C01560/WifiNAPIUtils: Call wifi func: GetScanInfoResults (start)
01-01 08:00:47.107 4081 4086 I C01560/WifiFrameWork: WifiSettings::GetScanInfoList size = 0
01-01 08:00:47.111 4814 4814 I A00500/[Settings]: WIFIWifiModel -> scan results items length is : 0
01-01 08:00:47.113 4814 4814 I A00500/[Settings]: WIFIWifiModel -> scan list results
01-01 08:00:47.117 4814 4814 I A00500/[Settings]: WIFIWifiModel -> scan list results
WiFi 尚未使能,不主动 Scan。因 Screen=2 息屏扫描失败,setupwizard 调用
GetScanInfoResults时,缓存为空。
阶段 2:WiFi 核心初始化 —— ScanService + wpa_supplicant + 第 1 次 SystemScanProcess(08:00:53)
// === wpa_supplicant 启动 ===
08:00:53.712 WifiHdiWpaClient StartWifi ifaceName:wlan0
08:00:53.794 wpa_supplicant begin to start
08:00:53.805 Successfully initialized wpa_supplicant
08:00:53.898 wpa_supplicant start successfully!
08:00:53.904 Initializing interface 'wlan0'
08:00:53.930 wlan0: State: DISCONNECTED -> INACTIVE
// === ScanService 初始化 ===
01-01 08:00:53.698 4081 4119 I C01560/WifiScanManager: CheckAndStartScanService scanState: 0
01-01 08:00:53.698 4081 4119 I C01560/WifiServiceManager: WifiServiceManager::LoadScanService
01-01 08:00:53.701 4081 4119 I C01562/ScanInterface: Enter ScanInterface::Init.
01-01 08:00:53.703 4081 4119 I C01562/ScanStateMachine: Enter InitScanStateMachine.
01-01 08:00:53.703 4081 4119 I C01562/ScanStateMachine: Enter InitCommonScanState.
01-01 08:00:53.703 4081 4119 I C01562/ScanStateMachine: Enter InitPnoScanState.
01-01 08:00:53.704 4081 4119 I C01562/ScanStateMachine: Enter BuildScanStateTree.
01-01 08:00:53.704 4081 4119 I C01562/ScanStateMachine: Enter EnrollScanStatusListener.
// === Country Code & AutoStartStaService ===
01-01 08:00:53.711 4081 4119 I C01560/WifiCountryCodeManager: notify wifi country code change, module name=ScanService_0
01-01 08:00:53.711 4081 4119 I C01562/ScanService: deal wifi country code changed, code=CN
01-01 08:00:53.712 4081 4119 I C01560/WifiHdiWpaStaImpl: HdiWpaStaStart enter! ifaceName = wlan0, instId = 0
// === 关键分叉点:第1次 SystemScanProcess ===
01-01 08:00:53.804 4081 5151 I C01562/ScanStateMachine: Enter LoadDriver.
01-01 08:00:53.805 4081 5151 I C01562/ScanService: Enter HandleScanStatusReport, status:0
01-01 08:00:53.805 4081 5151 I C01562/ScanService: Enter SystemScanProcess, scanAtOnce:1. // 第1次
01-01 08:00:53.806 4081 5151 I C01562/ScanService: Screen state(1:OPEN, 2:CLOSE): 2. // 息屏!
01-01 08:00:53.806 4081 5151 I C01562/ScanService: Enter BeginPnoScan. // 走 PNO 路径
01-01 08:00:53.806 4081 5151 W C01562/ScanService: pnoScan not allow when wifi disable // WiFi未使能
01-01 08:00:53.806 4081 5151 E C01562/ScanService: BeginPnoScan failed. // 第1次失败
01-01 08:00:53.806 4081 5151 I C01562/ScanStateMachine: Enter HardwareReady::GoInState.
01-01 08:00:53.806 4081 5151 I C01562/ScanStateMachine: ScanStateMachine::StopPnoScanHardware.
01-01 08:00:53.808 4081 5151 E C01562/ScanStateMachine: WifiStaHalInterface::GetInstance().StopPnoScan failed.
关键分叉:Screen=2(息屏)导致
SystemScanProcess走BeginPnoScan路径,而非亮屏的StartSystemTimerScan。PNO 在 WiFi 未使能时直接失败,无等待/重试机制。
阶段 3:staStatus=24 -> 第 2 次 SystemScanProcess,仍失败(08:00:54.087~090)
// === staStatus=24 触发(STA 驱动层就绪,但 WiFi Manager 层未完成) ===
01-01 08:00:54.087 4081 4121 I C01562/ScanInterface: Enter ScanInterface::OnClientModeStatusChanged, staStatus=24.
01-01 08:00:54.087 4081 4121 I C01562/ScanService: Enter SystemScanProcess, scanAtOnce:1. // 第2次
01-01 08:00:54.087 4081 4121 I C01562/ScanService: Screen state(1:OPEN, 2:CLOSE): 2. // 还是息屏
01-01 08:00:54.087 4081 4121 I C01562/ScanService: Enter BeginPnoScan. // 还是 PNO
01-01 08:00:54.088 4081 4121 W C01562/ScanService: pnoScan not allow when wifi disable // 仍未使能
01-01 08:00:54.088 4081 4121 I C01562/ScanService: AllowScanByType, scanType:4, scanStyle:0, allScanResult:1
01-01 08:00:54.088 4081 4121 E C01562/ScanService: BeginPnoScan failed. // 第2次失败
01-01 08:00:54.088 4081 4121 I C01562/ScanService: AllowScanByType, scanType:8, scanStyle:0, allScanResult:1
01-01 08:00:54.089 4081 4121 I C01562/ScanService: AllowScanByType, scanType:4, scanStyle:0, allScanResult:1
staStatus=24 只代表 STA 驱动层就绪,
DisableScan(disable=0)还未被调用。Screen=2 息屏继续走 PNO,WiFi 未使能,失败。
阶段 4:setupwizard 第 3 次轮询(08:00:54.127~146)
01-01 08:00:54.139 4814 4827 I C01560/WifiNAPIDevice: GetScanInfoList, size: 0
01-01 08:00:54.141 4814 4814 I A00500/[Settings]: WIFIWifiModel -> scan results items length is : 0
01-01 08:00:54.146 4814 4814 I A00500/[Settings]: WIFIWifiModel -> scan list results
阶段 5:DealStaOpenRes -> 第 3 次 SystemScanProcess,PNO 永久死锁(08:00:54.138~139)
// === DealStaOpenRes:WiFi 使能正式完成,DisableScan(disable=0) 解锁 ===
01-01 08:00:54.138 4081 5165 I C01560/WifiStaManager: DealStaOpenRes: wifi scan only state notify scan result!
01-01 08:00:54.138 4081 5165 I C01562/ScanInterface: Enter ScanInterface::DisableScan, disable=0. // 解锁
01-01 08:00:54.138 4081 5165 I C01560/WifiFrameWork: Enter DisableScan
// === 致命分叉:第3次 SystemScanProcess ===
01-01 08:00:54.138 4081 5165 I C01562/ScanService: Enter BeginPnoScan. // Screen=2 息屏
01-01 08:00:54.139 4081 5165 I C01562/ScanService: Enter AllowScanDuringStaScene, staScene:3, scanMode:5
01-01 08:00:54.139 4081 5165 I C01562/ScanService: pno scan is allowed // PNO 权限通过
01-01 08:00:54.139 4081 5165 I C01562/ScanService: Enter GetSavedNetworkSsidList.
01-01 08:00:54.139 4081 5165 E C01562/ScanService: Have no saved network, not need to start PNO scan. // 致命!
01-01 08:00:54.139 4081 5165 E C01562/ScanService: BeginPnoScan failed. // 永久死路
永久死锁成立:WiFi 已使能(
DisableScan(disable=0)已调用),PNO 权限通过(pno scan is allowed),但GetSavedNetworkSsidList发现首次开机无任何已保存 WiFi 网络。PNO 扫描只对已知网络有效,BeginPnoScan失败后无任何重试/回退机制。从此再无任何硬件扫描被发出,缓存永远为空。
对应源码逻辑:
if (pnoScanConfig.savedNetworkSsid.size() == 0) {
WIFI_LOGE("Have no saved network, not need to start PNO scan.\n"); // 行1132
return false; // 返回false
}
如上可以发现调用 PNO scan 是一个死循环:无值不能扫描,不能扫描则无值。
阶段 6:setupwizard 连续 7 次主动轮询 —— 全部因缺权限失败(08:00:57~08:01:22)
每次轮询固定模式:
check WiFi active status is : true— WiFi 已使能scan wifi started,调用Call wifi func: Scan (start)— 主动触发扫描PERMISSION_DENIED!— 权限被拒绝(缺 LOCATION)Read result failed, code is: 2— IPC 返回失败start scan WiFi result is : false— 主动扫描失败Call wifi func: GetScanInfoResults,结果GetScanInfoList size: 0— 尝试从缓存取,为空scan results items length is : 0,scan list results— 界面提示无结果
第 1 次主动轮询(08:00:57.108~125)
01-01 08:00:57.108 4814 4814 I C01560/WifiDeviceProxy: IsWifiActive bActive=1
01-01 08:00:57.108 4814 4814 I A00500/[Settings]: WIFIWifiModel -> check WiFi active status is : true
01-01 08:00:57.108 4814 4814 I A00500/[Settings]: WIFIWifiModel -> scan wifi started
01-01 08:00:57.108 4814 4814 I C01560/WifiNAPIUtils: Call wifi func: Scan (start)
01-01 08:00:57.111 4814 4814 I C01560/WifiCommonUtil: Get bundle name uid[20010047]: com.ohos.setupwizard
01-01 08:00:57.112 4081 5166 I C01562/WifiScanServiceImpl: Scan with bundleName: com.ohos.setupwizard, compatible: 1
01-01 08:00:57.112 4081 5166 E C01560/OHWIFI_MANAGER_PERMISSION_HELPE: has no permission_name=ohos.permission.LOCATION, pid=4814, uid=20010047
01-01 08:00:57.112 4081 5166 E C01562/WifiScanServiceImpl: Scan:VerifyGetScanInfosPermission PERMISSION_DENIED!
01-01 08:00:57.113 4814 4814 E C01560/WifiScanIpc: Read result failed, code is: 2.
01-01 08:00:57.113 4814 4814 I C01560/WifiNAPIUtils: Call wifi func: Scan (end), time cost:5059us, 5ms
01-01 08:00:57.114 4814 4814 I A00500/[Settings]: WIFIWifiModel -> start scan WiFi result is : false
01-01 08:00:57.114 4814 4814 I C01560/WifiNAPIUtils: Call wifi func: GetScanInfoResults (start)
01-01 08:00:57.117 4081 4081 I C01560/WifiFrameWork: WifiSettings::GetScanInfoList size = 0
01-01 08:00:57.121 4814 5108 I C01560/WifiNAPIDevice: GetScanInfoList, size: 0
01-01 08:00:57.122 4814 4814 I A00500/[Settings]: WIFIWifiModel -> scan results items length is : 0
01-01 08:00:57.125 4814 4814 I A00500/[Settings]: WIFIWifiModel -> scan list results
后续 6 次尝试时间点
| 次数 | 时间 | 关键结果 |
|---|---|---|
| 第 2 次 | 08:01:02.112~126 | GetScanInfoList size: 0, scan results items length is: 0 |
| 第 3 次 | 08:01:07.113~124 | PERMISSION_DENIED!, GetScanInfoList size: 0 |
| 第 4 次 | 08:01:12.115~129 | PERMISSION_DENIED!, scan results items length is: 0 |
| 第 5 次 | 08:01:17.115~126 | PERMISSION_DENIED!, scan results items length is: 0 |
| 第 6 次 | 08:01:22.117~129 | PERMISSION_DENIED!, scan results items length is: 0 |
// ATM 日志确认:setupwizard 缺少 LOCATION 预授权
ATM: [IsUserGrantPermPreAuthorized]Permission(ohos.permission.LOCATION) is not in the list
ATM: [IsUserGrantPermPreAuthorized]Permission(ohos.permission.APPROXIMATELY_LOCATION) is not in the list
ATM 日志确认:AccessToken Manager 在初始化 HAP token 时检查
preAuthorizationInfo(预授权信息),is not in the list说明系统预授权配置文件中没有为 setupwizard 授予 LOCATION 权限。两份日志(成功和失败)中 ATM 检查结果完全相同——都是not in the list,说明权限缺失在两轮测试中同等存在,setupwizard 的Scan()调用必然失败。
阶段 7:setupwizard 超时退出(08:01:26.997)
01-01 08:01:26.997 4814 4814 I A03d00/JSAPP: MyAbilityStage.onDestroy is called
setupwizard 从进入 WiFi 页面(08:00:47)到超时退出(08:01:26),等了约 39 秒,未拿到任何 WiFi 扫描结果。
阶段 8:用户手动打开 Settings,首次硬件扫描始发出(08:01:31~36)
// === Settings 打开 ===
01-01 08:01:31.875 5338 5338 I A00500/[Settings]: Settings WifiModel -> start register wifi status observer
01-01 08:01:31.961 5338 5338 I C01560/WifiNAPIUtils: Call wifi func: GetScanInfoList (start)
01-01 08:01:31.966 5338 5338 I C01560/WifiNAPIDevice: GetScanInfoList, size: 0 // 缓存仍为空
01-01 08:01:31.967 5338 5338 I A00500/[Settings]: Settings WifiModel -> refreshApScanResults start
01-01 08:01:31.971 5338 5338 I A00500/[Settings]: Settings WifiModel -> Refresh completed, final count: 0
// === Settings 触发主动扫描(com.ohos.settings 拥有 LOCATION 权限) ===
01-01 08:01:32.950 5338 5338 I A00500/[Settings]: Settings WifiModel -> check WiFi isActive : true
01-01 08:01:32.951 5338 5338 I C01560/WifiNAPIUtils: Call wifi func: StartScan (start)
01-01 08:01:32.955 4081 5166 I C01562/WifiScanServiceImpl: Scan with bundleName: com.ohos.settings, compatible: 0
01-01 08:01:32.960 4081 5152 I C01562/ScanStateMachine: Enter StartNewCommonScan.
01-01 08:01:32.960 4081 5152 I C01562/ScanStateMachine: Begin call Scan.
01-01 08:01:32.962 4081 5152 I C01560/WifiHdiWpaStaImpl: HdiWpaStaScan enter
01-01 08:01:32.964 3358 5157 I C05200/wpa_supplicant: Ready to start scan
01-01 08:01:32.965 3358 5153 I C01566/HDF_LOG_TAG: WpaInterfaceScan: StartScan successfully!
01-01 08:01:32.968 3358 5157 I C05200/wpa_supplicant: wlan0: Starting AP scan for wildcard SSID
// === wpa_supplicant 扫描完成 ===
01-01 08:01:36.733 3358 5157 I C05200/wpa_supplicant: nl80211: Drv Event 34 (NL80211_CMD_NEW_SCAN_RESULTS) received for wlan0
01-01 08:01:36.733 3358 5157 I C05200/wpa_supplicant: wlan0: Scan completed in 3.763077 seconds
01-01 08:01:36.735 3358 5157 I C05200/wpa_supplicant: nl80211: Received scan results (30 BSSes)
01-01 08:01:36.750 3358 5157 I C05200/wpa_supplicant: wlan0: Radio work 'scan'@0x7faf1f1bf0 done in 3.782080 seconds
// === ScanService 缓存写入 ===
01-01 08:01:36.791 4081 4119 I C01562/ScanService: Save 30 scan results. // 存入
01-01 08:01:36.794 4081 4119 I C01560/WifiFrameWork: WifiSettings::GetScanInfoList size = 30
// === Settings 展示结果 ===
01-01 08:01:36.954 5338 5338 I A00500/[Settings]: Settings WifiModel -> refreshApScanResults start
01-01 08:01:37.004 5338 5338 I A00500/[Settings]: Settings WifiModel -> Refresh completed, final count: 11
Settings 拥有 LOCATION 权限,其
StartScan()顺利通过权限检查,HdiWpaStaScan success,wpa_supplicant 扫描到 30 个 BSSes,Save 30 scan results,过滤后展示 11 个 WiFi。但此时 setupwizard 已于 08:01:26 销毁(早约 5 秒),永远无法展示这些结果。
5. 成功流程对照分析(作为参考基线)
成功的关键:Screen=1 亮屏,StartSystemTimerScan 有等待机制
与失败流程相同,SystemScanProcess 前两次也遇到 WiFi disable(第 1 次 08:00:54.159,第 2 次 08:00:54.451),但由于走的是 StartSystemTimerScan 路径,该路径有等待机制——WiFi disable 时不放弃,等 DealStaOpenRes 触发 DisableScan(disable=0) 后自动重试。
// 第3次 SystemScanProcess —— 成功
01-01 08:00:54.489 4103 5138 I C01560/WifiStaManager: DealStaOpenRes: wifi scan only state notify scan result!
01-01 08:00:54.489 4103 5138 I C01562/ScanInterface: Enter ScanInterface::DisableScan, disable=0. // 解锁
01-01 08:00:54.489 4103 5138 I C01562/ScanService: Enter SystemScanProcess, scanAtOnce:1. // 第3次
01-01 08:00:54.489 4103 5138 I C01562/ScanService: Screen state(1:OPEN, 2:CLOSE): 1. // 亮屏
01-01 08:00:54.489 4103 5138 I C01562/ScanService: Enter StartSystemTimerScan, scanAtOnce: 1. // 走定时扫描
01-01 08:00:54.489 4103 5138 I C01562/ScanService: allow system timer scan // 通过!
01-01 08:00:54.490 4103 5138 I C01562/ScanService: Enter Scan, scanType:3, scanStyle:0.
01-01 08:00:54.490 4103 4136 I C01562/ScanStateMachine: Begin call Scan.
01-01 08:00:54.492 4103 4136 I C01560/WifiHdiWpaStaImpl: HdiWpaStaScan enter
01-01 08:00:54.504 4103 4136 I C01560/WifiHdiWpaStaImpl: HdiWpaStaScan success. // 硬件扫描发出
扫描完成后:
01-01 08:00:58.285 total number of valid scan results: 28 // 第1次扫描 28条
01-01 08:00:58.291 Save 28 scan results. // 写入缓存
01-01 08:01:02.102 total number of valid scan results: 33 // 第2次扫描 33条
// setupwizard 第4次轮询拿到结果
01-01 08:01:02.477 GetScanInfoList, size: 33 // 拿到结果
01-01 08:01:02.499 scan results items length is : 12 // 展示12个WiFi
6. 成功 vs 失败流程对比
6.1 关键决策点对比表
| 序号 | 时间 | 事件 | 成功 (Screen=1) | 失败 (Screen=2) |
|---|---|---|---|---|
| 第 1 次 | 08:00:54 | HandleScanStatusReport(status:0) | Screen: 1 -> StartSystemTimerScan -> system timer scan not allow when wifi disable(等待重试) |
Screen: 2 -> BeginPnoScan -> pnoScan not allow when wifi disable(放弃) |
| 第 2 次 | 08:00:54 | staStatus=24 HandleStaStatusChanged | Screen: 1 -> StartSystemTimerScan -> 继续等待 |
Screen: 2 -> BeginPnoScan -> 再次放弃 |
| 第 3 次 | 08:00:54 | DealStaOpenRes | Screen: 1 -> StartSystemTimerScan -> allow system timer scan [成功] -> HdiWpaStaScan success |
Screen: 2 -> BeginPnoScan -> pno scan is allowed [成功] -> Have no saved network [失败] 永久死路 |
| 结果 | — | 硬件扫描 | 08:00:54.492 发出,28 条结果 [成功] | 从未发出硬件扫描 [失败](直到 08:01:32 Settings 手动触发) |
6.2 两条路径的本质差异
SystemScanProcess 内部决策逻辑:
if (Screen == OPEN/1)
-> StartSystemTimerScan // 亮屏:主动定时扫描
else (Screen == CLOSE/2)
-> BeginPnoScan // 息屏:PNO 省电扫描
StartSystemTimerScan(亮屏路径):
- [成功] 有等待机制:wifi disable 期间不放弃,等
DealStaOpenRes后自动重试 - [成功] 扫描所有可见 AP(wildcard SSID)
- [成功] 结果写入
WifiSettings缓存供所有进程读取
BeginPnoScan(息屏/PNO 路径):
- [失败] 无等待/重试机制:失败即永久放弃
- [失败] 只扫描已保存网络(Preferred Network Offload)
- [失败] 首次开机无已保存网络,永久死路
- [失败] 无回退到普通扫描的逻辑
6.3 权限问题一致性
| 日志 | ATM 检查结果 | setupwizard Scan() 结果 |
|---|---|---|
| 成功(Screen=1) | LOCATION not in the list |
PERMISSION_DENIED |
| 失败(Screen=2) | LOCATION not in the list |
PERMISSION_DENIED |
两份日志中 ATM 预授权检查结果完全一致,setupwizard 的
Scan()调用在两轮测试中都因权限被拒。差别仅在于:
- 成功场景:后台
StartSystemTimerScan已自动完成扫描,setupwizard 通过GetScanInfoResults(读取缓存)拿到了结果- 失败场景:后台 PNO 从未下发扫描,setupwizard 读缓存为空
7. 根因分析
7.1 直接原因(双因素叠加)
因素一:息屏走 PNO 路径 + 首次开机无已保存网络,硬件扫描从未发出
- Screen=2 息屏,
SystemScanProcess走BeginPnoScan - WiFi 未使能时:
pnoScan not allow when wifi disable(无等待) - WiFi 使能后:
pno scan is allowed[成功],但是Have no saved network, not need to start PNO scan[失败] BeginPnoScanfailed,无回退、无重试- 整个 WiFi 使能过程中 0 次硬件扫描被发出
因素二:setupwizard 缺 LOCATION 权限预授权,自救失败
- ATM
preAuthorizationInfo中无 LOCATION 权限 - setupwizard
Scan()->PERMISSION_DENIED(必然失败) - setupwizard 无法自行触发硬件扫描自救
- 只能等待后台扫描结果落入缓存
- 但因素一导致缓存永远为空
叠加效果:WiFi 使能了,但谁都没有完成一次扫描,这就是死锁。
7.2 条件触发分析
| 条件 | 开机即发生 | 说明 |
|---|---|---|
| 首次开机 | 是 | 无已保存 WiFi 网络,PNO 无目标 |
| 屏幕息屏 | 大概率 | 开机过程屏幕通常为息屏状态 |
| setupwizard 缺权限 | 是 | ATM 预授权配置中未包含 LOCATION |
三个条件在开机流程中同时满足的概率极高,因此问题在首次开机场景下几乎必现。
7.3 PNO 路径的设计缺陷
息屏状态下,WiFi 扫描流程的设计意图是省电——用 PNO(硬件级别已知网络扫描)替代完整扫描。但对于首次开机场景,这个设计存在缺陷:
- 无降级策略:PNO 失败后应回退到普通扫描,或至少等待亮屏后触发
- 无超时重试:
BeginPnoScan是一次性调用,失败即终止 - 无外部触发通道:如果此时有应用(如 Settings)主动触发扫描,硬件扫描仍可发生——但 setupwizard 恰好缺权限
8. 修复方案
8.1 推荐方案:添加 setupwizard 的 LOCATION 权限预授权
修改系统配置文件 install_list_permissions.json,为 com.ohos.setupwizard 添加 ohos.permission.LOCATION 预授权:
{
"bundle_name": "com.ohos.setupwizard",
"permissions": [
{
"name": "ohos.permission.LOCATION",
"user_cancellable": false
}
]
}
注:原有权限保持不变,此处仅展示新增项。
修复效果:
- setupwizard
Scan()调用不再被PERMISSION_DENIED拒绝 - 即使 PNO 死锁(息屏无已保存网络),setupwizard 也能主动触发完整扫描
- 兼容亮屏/息屏两种场景
8.2 可选的底层增强方案
以下方案可作为长期改进参考,不要求本次修复实现:
| 方案 | 思路 | 影响范围 |
|---|---|---|
| PNO 失败后回退到普通扫描 | BeginPnoScan 失败时(Have no saved network)回退到 StartSingleCommonScan |
ScanService 层 |
| 息屏下首次 WiFi 使能强制走一次普通扫描 | DealStaOpenRes 后,若未连接且缓存为空,忽略 Screen 状态强制扫描 |
WiFi Manager 层 |
| PNO 增加超时重试 | PNO 失败后设置定时器,亮屏时自动触发完整扫描 | ScanStateMachine 层 |
9. 修改验证
- 修改
install_list_permissions.json并重新烧录系统镜像 - 验证步骤:
- 首次开机,进入开机向导 WiFi 页面
- 确认 setupwizard 不再报
PERMISSION_DENIED - 确认 WiFi 列表在 10 秒内正常刷新
- 验证结果:OK,问题解决 [成功]
附录 A:涉及的模块与日志标签
| 模块 | PID | Tag | 功能 |
|---|---|---|---|
| setupwizard | 4814/4837 | A00500/[Settings] | 开机向导 WiFi 页面 |
| Settings | 5338 | A00500/[Settings] | 设置应用 WiFi 页面 |
| wifi_manager_service | 4081/4103 | C01560/WifiFrameWork | WiFi 框架服务 |
| wifi_scan_service | 4081/4103 | C01562/ScanService | 扫描服务 |
| wifi_scan_state_machine | 4081/4103 | C01562/ScanStateMachine | 扫描状态机 |
| wpa_supplicant | 3358/3368 | C05200/wpa_supplicant | WPA 请求者 |
| WifiHdiWpaStaImpl | 4081/4103 | C01560/WifiHdiWpaStaImpl | HDI WPA STA 实现 |
| ATM | — | ATM | AccessToken Manager |
更多推荐
所有评论(0)