DriverUI

传统上,仪表板界面位于方向盘后方的单独显示屏中。OEM 逐渐将仪表板和 IVI 合并到单个显示屏中。这个组合界面就是 DriverUI。

DriverUI

图 1. DriverUI。

DriverUI 是一款 Android 系统应用,可渲染整个仪表板显示屏,但不包括由高可用性渲染程序 (HAR) 渲染的安全相关或监管元素。DriverUI 会显示与媒体播放、电话、地图、导航等相关的信息,并实现适用于 Compose 的 Automotive 设计。

DriverUI 作为默认集群 activity

DriverUI 在 Android 中作为特权集群应用运行,AAOS 会自动启动它。

AAOS 使用 ClusterHomeManager 类(也称为 Cluster2)来构建仪表板。此类指定了识别仪表板实现以及 AAOS 与其交互方式所需的配置。Google 提供了 Cluster2 API 的参考实现。

平台

您可以在 SDV 上构建和运行 Display Safety。软件定义汽车 (SDV) 平台:

  • 需要两个客户虚拟机。
  • 在客户虚拟机中运行 SDV 媒体(也称为快速启动虚拟机)中的 HAR。
  • 在另一个客机 SDV IVI 虚拟机中运行 DriverUI。
  • 在 SDV 媒体虚拟机上运行安全监控器。

SDV 平台架构

图 2. SDV 平台架构。

混合 HAR 和 DriverUI 输出

HAR 和 DriverUI 使用不同的显示屏来呈现其界面。这两个输出是复合的,在 DriverUI 中显示为一个图片。

为此,HAR 会根据来自 DriverUI 的心跳消息,控制 Android 输出所在区域的透明度。当 DriverUI 不可用时,HAR 会检测到缺少心跳信号,并将 DriverUI 区域呈现为不透明并显示占位符。收到心跳信号后,系统会移除占位符,并将 DriverUI 区域设置为透明。

HAR 和 DriverUI 组合

图 3. HAR 和 DriverUI 组合。

排查 Alpha 合成和穿透问题

由于 HAR 对安全至关重要,因此其硬件显示平面位于 Android IVI 显示平面之上。在 HAR 中构建或调试自定义视图或外部 OpenGL ES Surface 时,请验证 Alpha 值的设置方式:

  • HAR 平面下缺少 DriverUI 输出:虽然 HAR 会从 DriverUI 接收有效的 HeartbeatRequest 消息,但 HAR 必须将 DriverUI 视口区域清除为透明 (alpha = 0.0),以便底层的 Android 仪表板界面显示出来。如果自定义 HAR 图层或背景在 DriverUI 区域上绘制不透明像素 (alpha = 1.0),则会遮挡下方的 Android 输出。
  • 自定义 3D 或 OpenGL 表面中出现意外的透明孔洞:当您将外部 OpenGL ES 或 3D 表面渲染到 HAR 节点(例如,写入 RGB 像素且未使用的 Alpha 字节保留为 0x00 的自定义 3D 仪表或场景)时,请将不透明像素的 Alpha 通道显式设置为 0xFF (alpha = 1.0)。如果将 Alpha 字节保留为 0x00,会导致合成器将这些像素视为透明 (alpha = 0.0),并直接在 HAR 层中打一个孔,直达底层的 Android IVI 平面。
  • 跨虚拟机显示诊断:由于 HAR (sdv_media_har_cf) 和 Android IVI (sdv_ivi_cf_ds) 在不同的客户虚拟机中运行,因此在 Android IVI 虚拟机上运行 adb shell dumpsys SurfaceFlinger 只能检查 Android 层,而无法查看上层的 HAR 平面。

DriverUI 和 HAR 通信

DriverUI 和 HAR 使用远程过程调用 (RPC) 相互通信。心跳消息是通过 RPC 通道发送的数据示例,其中一个字段包含时间戳。

gRPC 用于 RPC。在 SDV 上,SDV 通信提供 SDV Gateway Client,用于发现并建立从 DriverUI 到 HAR 的通道。gRPC 服务定义了一个协议缓冲区文件:


// Heartbeat.
rpc Heartbeat(HeartbeatRequest) returns (HeartbeatResponse) {}

// Document switched in the DriverUI.
rpc DocumentSwitched(DocumentSwitchedRequest) returns (DocumentSwitchedResponse) {}

// Document updated in the DriverUI. Unary RPC.
rpc DocumentUpdated(DocumentUpdatedRequest) returns (DocumentUpdatedResponse) {}

// Document updated in the DriverUI. Requests are streamed with each request
// containing a part of the document and the entire document is assembled from these
// chunks by the server.
rpc DocumentUpdatedStreaming(stream DocumentUpdatedRequest) returns (DocumentUpdatedResponse) {}

/// Request for HAR to change design tokens.
rpc DesignTokenUpdate(DesignTokenUpdateRequest) returns (DesignTokenUpdateResponse) {}

// Request to change the current locale used in HAR.
rpc LocaleUpdate(LocaleUpdateRequest) returns (LocaleUpdateResponse) {}

// Requests to swap a certain variant at a Figma node.
rpc ChangeVariant(ChangeVariantRequest) returns (ChangeVariantResponse) {}

// Requests to change the container (display/root node) configuration (dpi, size) in HAR.
rpc ChangeContainerConfiguration(ChangeContainerConfigurationRequest) returns (ChangeContainerConfigurationResponse) {}

请求和响应详细信息位于 ub-automotive 源代码库中 packages/apps/Car/DriverUI/proto/driverui.proto 的 Display Safety 源代码中。

在 SDV 平台上,SDV 通信提供 SDV Gateway Client,用于发现并建立从 DriverUI 到 HAR 的 gRPC 通道。

使用 IVI 终端执行这些命令会将通信发送到 SDV Media,从而触发整个集群的主题更新。

adb shell cmd car_service inject-key -d 1 9 # Purple Theme
adb shell cmd car_service inject-key -d 1 8 # Blue Theme

用于更改 DriverUI 和 HAR 主题的 RPC 通信。

图 4. 用于更改 DriverUI 和 HAR 主题的 RPC 通信。

在仪表板上显示媒体、地图和电话信息

通过与 IVI 通信,DriverUI 可以在参考仪表板中显示媒体、地图和电话信息。虽然在参考实现中,媒体是默认状态,但显示内容会根据活跃服务按以下优先级进行更新:

  1. 地图
  2. 电话
  3. 媒体

系统会自动优先显示地图导航或活跃的电话服务,而不是默认的媒体状态。

下图展示了各种 DriverUI 显示状态:

DriverUI 在整个仪表板中展示媒体和电话部分。

图 5. DriverUI 在整个仪表板中展示“媒体”和“电话”部分。

Automotive Design for Compose 集成

DriverUI 实现了适用于 Compose 的 Automotive Design,以便在 Android 应用中直接展示设计 (Figma) 并进行迭代。这种集成通过在运行时环境中呈现设计文档,弥合了设计与开发之间的差距。

获取设计资源

DriverUI 的示例 Figma 文档是代码库的一部分。如需访问和修改这些设计,请执行以下操作:

  1. 使用 packages/apps/Car/DriverUI/src/main/assets/figma/*.dcf 中的本地 Automotive Design for Compose DCF 设计文件启动 DriverUI。
  2. 找到 packages/apps/Car/DriverUI/src/main/assets/DriverUI.fig 资源文件。
  3. 将此文件导入 Figma 即可查看源设计或进行更改。

Automotive Design for Compose 版本

  • Gradle 会使用 packages/apps/Car/libs/aaos-apps-gradle-project/gradle/libs.versions.toml 中为 designcompose 指定的 Automotive Design for Compose 版本。
  • Automotive Design for Compose 版本可在版本页面上找到。

实时动态配置

Automotive Design for Compose 支持在开发模式下实时动态,让 Figma 中所做的更改能够立即在 DriverUI 中呈现。这有助于快速测试和更快的迭代设计周期。

运行以下命令,为 DriverUI 设置 Figma 令牌:

adb shell am startservice \
  -n "com.android.car.driverui/com.android.designcompose.ApiKeyService" \
  -a setApiKey \
  -e ApiKey $FIGMA_ACCESS_TOKEN \
  --user 0

双虚拟机设计文档同步

在双虚拟机设置中,设计更新必须跨边界传播,以保持一致性。

  • DriverUI 会提取最新的 Figma 设计文档,并使用本页中详述的 gRPC 通信渠道将其传输到 HAR。
  • 因此,整个集群会更新为最新的 Figma 设计迭代,使两个虚拟机都与设计源保持同步。

将设计文档从 Figma 实时更新到 DriverUI 和 HAR。

图 6. 将设计文档从 Figma 实时更新到 DriverUI 和 HAR。

保护 gRPC 通道

gRPC 具有 SSL 和 TLS 集成,并提倡使用 SSL 和 TLS 来对服务器进行身份验证,以及对客户端和服务器之间交换的所有数据进行加密。客户端可以使用可选机制来提供用于双向身份验证的证书。如需详细了解 gRPC 身份验证,请参阅身份验证。