22 · 双 flavor 差异:f3dif(A17) vs xcddif(A14) 的 WifiTrackerLib

适用范围:读日志/对代码前先确认机型对应哪套源集;两套源集的广播注册时序、扫描 gate、API 形态不同,拿错基线会得出错误结论。 源集→flavor 对应(base/WifiTrackerLib/build.gradle:11-50, 51-95):dcd→dcddif;xcd_cn_a14 / xcd_global_a14→xcddif(global 额外叠 src/global);xcd_cn_a17 / xcd_global_a17→f3dif(A17 车机在用)。f3dif 比 xcddif 多一个 PasspointUtilsStub.java(Passpoint R1 支持)。

0. 定性结论

规模:WifiPickerTracker 1634↔1438 行(924 diff 行)BaseWifiTracker 1200↔1069(590)StandardWifiEntry 1732↔1619(622)Utils 1508↔1173(658)

f3dif 是更新的 MIUI 上游基线(≈AOSP UDC/Baklava 合流);xcddif 是旧基线(≈T)再叠 MIUI 修改。差异主体是上游代次 + MIUI 合入深度,而非车机专属逻辑——两款车机业务行为基本一致,但下面 5 处会影响日志时序解读。

1. 五处必须知道的行为差异

#差异f3dif(A17)xcddif(A14)排障影响
1NETWORK_STATE_CHANGED 广播注册方式合在单一 receiver,主线程注册(:552-628)拆独立 mNetworkBroadcastReceiver(xcddif:163-176),在 onStart 的 worker runnable 里、handleOnStart()(:483)之后注册(xcddif:487-492;主 receiver :469-470 在前),且多 onDestroy() 双保险反注册(xcddif:528-553)A14 上 NETWORK_STATE 接收器在首屏取数之后才挂上,启动瞬间的连接变化可能先被错过
2扫描 gateshouldScan() = 开 && Started && !disabled && **isInteractive()**(:1073-1076)= 开 && Started(xcddif:965-966,无屏幕/无 disable 判断)A14 灭屏也可能扫;A17 灭屏必停。分析”过夜/灭屏扫描行为”先看机型
3ScanResultUpdater API新:onScanResultsAvailable(list, timeoutScans) + 5min 失败兜底(:36,59-73)旧:update(newResults) 无 timeout 参数、getScanResults(maxScanAge) 可传窗(xcddif ScanResultUpdater.java:432 构造 / BaseWifiTracker.java:871 调用)A14 无 5min 兜底窗,扫描失败更易掉条目
4handleOnStart 首刷 timeoutScansfalse(:346-349,WIFI_BugFixUpstream)——回页面不清旧扫描保持 AOSP trueA14 回页面瞬间按 15s 窗裁剪,列表闪空概率更高
5onWifiEntriesChanged 带 reasonupdateWifiEntries(reason)(:610;scan 时传 REASON_SCAN_RESULTS :372),无锁无 reason、synchronized(mLock) 全程(xcddif:571-679)A17 的 UI 可按 reason 做动画;A14 全程持锁

2. 其余差异要点(速览)

BaseWifiTracker

  • wifi state 缓存:xcddif 字段 mWifiState + 静态 sVerboseLogging(构造取一次);f3dif 全走 WifiTrackerInjector.cacheWifiState + 动态 listener(f3dif:130,479-480,574-578)。
  • scanLoop 失败日志:f3dif Log.e / xcddif Log.wtf;f3dif startScan 包 SecurityException catch(:1145-1147)。
  • xcddif NetworkRequest 加 TRANSPORT_CELLULAR(VCN-over-Wifi,xcddif:204);xcddif 有 mEnableSharedConnectivityFeature 开关(f3dif 恒开)。
  • f3dif 回调对象全改 WeakReference 防泄漏(ConnectivityDiagnostics/WifiSCListener/WorkerExecutor,:301-378),支持 Baklava WifiStateChangedListener(:493-511)。

WifiPickerTracker

  • f3dif 新增多用户逻辑:shared-network 过滤/configOwner(:663-695,:776-786)、isHotspotNetworkConnectingStateForDetailsPageEnabled 分支(:634-637,:731-749)。
  • Passpoint R1:仅 f3dif 有 mPasspointUtilsStub.updatePasspointR1EntryCache 注入点(:714-718,:1242-1246)。
  • f3dif 有 200 条扫描截断(:1256-1264)。

StandardWifiEntry

  • security/band 字符串:f3dif 委托 Utils.getSecurityString 等并支持 getCertificateInfo()(:842-851);xcddif 内联大 switch 且带 WAPI_PSK/WAPI_CERT 字符串(xcddif:761-835)。
  • 多用户 API 仅 f3dif 有(isOwnedByCurrentUser/isSharedWithOtherUsers/... :887-960;StandardWifiEntryKeymConfigOwner :1443-1477 vs xcddif 两参构造)。
  • DualWiFi MOD 两者都在(connect() 段 f3dif:543 附近/xcddif:481 附近 MIUI MOD: WIFI_DualWiFi;getSummary 段的 DualWiFi 块另在 f3dif :346-364)。

App 层接缝

MiCarWifiCollinear(flavor 钩子,“Collinear=共线”是本仓库 flavor 后缀惯例):f3dif 8 参构造;dcddif 多传 NetworkScoreManager 共 9 参(新版 API 构造);xcddif 与 f3dif 同 8 参。被 MiWifiTrackerUtils.kt:65-74 统一调用。

3. 死代码/休眠路径警示(维护者必读)

  • SlaveWifiUtilsStub/IPasspointUtils/PasspointUtilsStub 都是反射桩(类不存在则静默降级);车机唯一 worker 线程名是 MiWifiTrackerTools{...}(MiWifiTrackerUtils.kt:40-43),永远不含 “slave” → DualWiFi/MLO 副链路事实性休眠(唯一置 mIsSlave=true 的地方检查线程名含 “slave”,StandardNetworkDetailsTracker.java:98-104)。
  • CrossSubnetUtils 是三者中唯一无条件生效的活逻辑:同 networkId 换 netId 视为漫游,旧网络 VALIDATED 则给新 NetworkCapabilities 补 NET_CAPABILITY_VALIDATED(BaseWifiTracker.java:267-270),解决子网间漫游”已验证”状态丢失。
  • 读代码遇到 slave/MLO/PasspointR1 分支时不要套到车机行为上。

4. 一分钟选基线

flowchart LR
    A[拿到一台车/一份日志] --> B{机型/平台?}
    B -->|"A17(F3/8295 等)"| C[源集=f3dif<br/>本库其余文档均此基线]
    B -->|"A14(XCD)"| D[源集=xcddif<br/>注意§1五差异]
    B -->|"DCD/watt"| E[源集=dcddif<br/>Collinear 多 NetworkScoreManager]
    C --> F[先看 fingerprint 对版本<br/>再核对分支/ROM代码考古]
    D --> F
    E --> F