09 · 架构总图
35 个 Gradle 子模块的全景视图。所有事实经源码核实,详见《08-对抗验证记录》。
图 1 · 四层架构总览(35 模块)
╔══════════════════════════════════════════╗
║ MiCarSettings · 35 个子模块 ║
║ com.android.car.settings (系统特权应用) ║
║ sharedUserId=android.uid.system ║
╚══════════════════════════════════════════╝
┌──────────────────────────────────────────────────────────────────┐
│ ① app (1 个 application) —— 应用入口、首页壳 │
│ │
│ SettingsApplication ──→ AppStartTaskDispatcher (主+异步双任务) │
│ BaseCarSettingsActivity ── 左菜单 + 右内容 (双面板) │
│ TopLevelMenuFragment · DeeplinkActivity · PageRouterConfig │
└──────────────────────────────┬─────────────────────────────────────┘
│ implementation (引入 16 个业务模块)
▼
┌──────────────────────────────────────────────────────────────────┐
│ ② settingsPage (16 个 library) —— 各功能业务页面 │
│ │
│ ┌─────────┬─────────┬─────────┬─────────┬─────────┐ │
│ │车辆控制 │ 灯光 │锁车门窗 │ 驾驶 │辅助驾驶 │ │
│ │VehicleBody│ Light │ Lock │ Driving │AutoPilot │ │
│ ├─────────┼─────────┼─────────┼─────────┼─────────┤ │
│ │充电能量 │ 连接 │ 显示 │音量声音 │智能设备 │ │
│ │ Charge │Connect │ Display │ Volume │ Iot │ │
│ ├─────────┼─────────┼─────────┼─────────┼─────────┤ │
│ │安全安防 │ 系统 │小爱语音 │ 媒体 │ 快照 │ │
│ │ Safety │ System │ XiaoAi │ Media │Snapshot │ │
│ └─────────┴─────────┴─────────┴─────────┴─────────┘ │
│ + globalOnly (海外专属:隐私/位置/锁屏PIN,仅 global 引入) │
│ │
│ 统一范式: Fragment(XML声明) + N个PreferenceController + 路由四件套 │
└──────────────────────────────┬─────────────────────────────────────┘
│ implementation / api
▼
┌──────────────────────────────────────────────────────────────────┐
│ ③ base (11 个 library) —— 基础能力与车辆抽象 │
│ │
│ settingsVehicleLib ◀── 车辆信号抽象 (CarPropertyManager 封装) │
│ ▲ 缓存/超时/生命周期/Flow │
│ settingsBaseUi ◀── UI 基类+控件 (PreferenceController 体系) │
│ ▲ Fragment/Preference 控件/主题 │
│ settingsBaseLib ◀── 非 UI 设施 (账号/MQTT/许可/埋点/IoT) │
│ ▲ AppStartTaskDispatcher/MiCarPropertyIds │
│ settingsBasePB ◀── Protobuf (昵称/数字钥匙/远程位置) │
│ │
│ 叶子库: settingsLibAndroid → settingsLibUtils │
│ settingsLibAdaptiveIcon → settingsLibTile │
│ iconloaderlib · WifiTrackerLib · settingsLibDisplayUtils │
└──────────────────────────────┬─────────────────────────────────────┘
│ kapt (代码生成) + implementation
▼
┌──────────────────────────────────────────────────────────────────┐
│ ④ settingsCommon (7 个) —— 编译期 APT + 运行时中间件 │
│ │
│ plugin/router/{annotation, routerApt, routerManager} 路由 APT │
│ plugin/voice/{voicesearchannotation, voicesearchapt} 语音 APT │
│ rtiLib ◀── RTI Connext DDS 车载跨域发布/订阅中间件 │
│ tools/qualitytools │
└──────────────────────────────┬─────────────────────────────────────┘
│ compileOnly (编译期注入)
▼
╔══════════════════════════════════════╗
║ 小米车机 platform framework.jar ║
║ dcd : javalib_watt (msmnile 平台) ║
║ xcd : xcd_javalib (新一代平台) ║
║ global : 复用 xcd + 海外资源/Manifest ║
╚══════════════════════════════════════╝
模块数对账:app(1) + settingsPage(16) + base(11) + settingsCommon(7) = 35。
图 2 · 请求 / 数据流(用户拨开关 → 车辆硬件 → UI 回流)
┌─────────────────────────────────────────────────────────────┐
│ [用户] 拨动开关 │
└────────────────────────┬────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ MiCarNewSwitchPreference ← XML 声明 (settingsPage/res/xml) │
│ settings:controller="...XxxController" │
└────────────────────────┬────────────────────────────────────┘
│ OnPreferenceChangeListener (自动注册)
▼
┌─────────────────────────────────────────────────────────────┐
│ XxxController.handlePreferenceChanged ← 业务层 (settingsPage)│
└────────────────────────┬────────────────────────────────────┘
│ extends
▼
┌─────────────────────────────────────────────────────────────┐
│ BaseVehicleNewSwitchPrefController (base/settingsVehicleLib)│
│ └ 二次确认 / loading / 埋点 │
└────────────────────────┬────────────────────────────────────┘
│ extends + 持有
▼
┌─────────────────────────────────────────────────────────────┐
│ CarPropertyMgrPreferenceController<V> │
│ implements CarPropertyManagerCallback │
└────────────────────────┬────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ SettingsCarPropertyManager.kt [693 行] │
│ 每页一个·非单例·绑 Lifecycle 自动 release │
│ 缓存 + 超时监控(500/750/1000/2000/4000ms) + mock │
└────────────────────────┬────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ VehicleControlManager (Car.PROPERTY_SERVICE 包装) │
│ ThreadPoolUtils.ASYNC.execute(...) 异步下发 │
└────────────────────────┬────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ LocalCarManager [进程单例] → Car.createCar(WAIT_FOREVER) │
└────────────────────────┬────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ android.car.CarPropertyManager (framework) │
└────────────────────────┬────────────────────────────────────┘
│ Binder IPC
▼
Car Service (系统进程) → Vehicle HAL → 车辆硬件
⋮ 信号回流(反向链路)
▼
CarPropertyCacheManager [多路复用·同propId只注册一次]
│
▼
SettingsCarPropertyEventCallback.onChangeEvent
├ cachePropVal
├ processTimeout (REMOVE/RESTART/CONTINUE)
└ onPropertyChanged → onHandlePropertyChange → setChecked
│
▼
[UI 刷新]
超时/错误 → restorePropertyToPrevious → UI 回滚
图 3 · 三 Flavor 构建产物(一套代码 → 三个 APK)
┌─────────────────────────────┐
│ 同一套源码 (35 模块) │
└──────────────┬──────────────┘
│
┌────────────────────────┼────────────────────────┐
▼ ▼ ▼
╔═════════════╗ ╔═════════════╗ ╔═════════════╗
║ dcd ║ ║ xcd ║ ║ global ║
╠═════════════╣ ╠═════════════╣ ╠═════════════╣
║ platform: ║ ║ platform: ║ ║ 复用 xcd jar ║
║ msmnile ║ ║ 新一代平台 ║ ║ + region/ ║
║ (watt分支) ║ ║ (xcd前缀) ║ ║ global ║
║ ║ ║ ║ ║ + globalOnly ║
║ region: cn ║ ║ region: cn ║ ║ 模块 ║
║ + dcddif ║ ║ + xcddif ║ ║ + 换Manifest ║
╚═══════╤═════╝ ╚═══════╤═════╝ ╚═══════╤═════╝
│ │ │
▼ ▼ ▼
MiCarSettings MiCarSettings MiCarSettings
-dcd.apk -xcd.apk -global.apk
(国内老平台) (国内新平台) (海外/ECE)
图 4 · Mermaid 版(可在 GitHub / VSCode 渲染)
graph TD subgraph L1["① app (1 模块) — 应用入口/首页壳"] APP["SettingsApplication<br/>BaseCarSettingsActivity<br/>双面板: TopLevelMenuFragment + fragment_container<br/>DeeplinkActivity / PageRouterConfig"] end subgraph L2["② settingsPage (16 模块) — 功能业务页面"] direction LR P1["VehicleBody 车辆控制"] P2["Light 灯光"] P3["Lock 锁车门窗"] P4["Driving 驾驶"] P5["AutoPilot 辅助驾驶"] P6["Charge 充电能量"] P7["Connection 连接"] P8["Display 显示"] P9["Volume 音量"] P10["Iot 智能设备"] P11["Safety 安全安防"] P12["System 系统"] P13["XiaoAi 小爱"] P14["Media 媒体"] P15["Snapshot 快照"] P16["globalOnly 海外专属"] end subgraph L3["③ base (11 模块) — 基础能力"] B1["settingsVehicleLib<br/>车辆信号抽象<br/>CarPropertyManager 封装"] B2["settingsBaseUi<br/>UI基类+控件<br/>PreferenceController 体系"] B3["settingsBaseLib<br/>非UI设施<br/>账号/MQTT/许可/埋点/IoT"] B4["settingsBasePB<br/>Protobuf 协议"] B5["叶子库×7<br/>LibAndroid/Utils/Tile/<br/>AdaptiveIcon/DisplayUtils/<br/>iconloaderlib/WifiTrackerLib"] B1 --> B2 --> B3 --> B4 B3 --> B5 end subgraph L4["④ settingsCommon (7 模块) — APT+中间件"] C1["router APT×3<br/>annotation/routerApt/routerManager"] C2["voice APT×2<br/>voicesearchannotation/<br/>voicesearchapt"] C3["rtiLib<br/>RTI DDS 中间件"] C4["qualitytools"] end subgraph EXT["平台 jar (compileOnly)"] JAR["framework.jar<br/>dcd=watt / xcd=xcd<br/>global 复用 xcd"] end APP -->|implementation| L2 L2 -->|implementation/api| L3 L2 -.->|kapt 代码生成| L4 L3 -.->|kapt| L4 L3 -->|compileOnly| JAR classDef app fill:#ffe4b5,stroke:#333 classDef page fill:#b5e4ff,stroke:#333 classDef base fill:#d4edda,stroke:#333 classDef common fill:#f0d4ff,stroke:#333 class APP app class P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16 page class B1,B2,B3,B4,B5 base class C1,C2,C3,C4 common
每层作用一句话
| 层 | 模块数 | 作用 |
|---|---|---|
| app | 1 | 「壳」—— 启动初始化、双面板首页、入口路由 |
| settingsPage | 16 | 「业务」—— 每个功能域 = N 个 Fragment + N 个 Controller + XML |
| base | 11 | 「底座」—— UI 范式(BaseUi) + 非UI设施(BaseLib) + 车辆抽象(VehicleLib) + 协议(PB) + 移植工具库 |
| settingsCommon | 7 | 「横切」—— 编译期代码生成(路由/语音 APT) + 运行时中间件(RTI DDS) + 工具 |