风景优美的 View、View 树和 ViewRefs

风景

想要提供用户可见内容的界面客户端必须将其放在景观视图中,后者是客户端本地的基于会话资源。任何资源都无法被在其拥有的 Views Session 范围之外直接引用。

ViewRef 引用了景观视图

特别是对于视图资源,拥有稳定且一致的视图引用(可跨组件边界使用)非常有用。

我们定义了一个具有一些所需属性的 fuchsia.ui.views.ViewRef FIDL 数据类型:

  • ViewRef 在整个操作系统中都是全局唯一的,无法伪造。此属性源自 ViewRef 的底层内核对象,即事件对。
  • ViewRef 在操作系统的生命周期内是全局唯一的,永远不会被重复使用。此属性源自 Zircon 对内核对象的 KOID 唯一性保证。
  • 您可以在前馈模式中使用 ViewRef 来创建场景视图。参与 View 创建的协议和组件不必“通过隧道返回”相应的 ViewRef。
  • ViewRef 容器可以通过监听底层 event 对对象上的 ZX_EVENTPAIR_PEER_CLOSED Zircon 信号来实现生命周期管理。

每个景观视图都有一个关联的 ViewRef。

视图树

全局场景图可以视为一个 View 树,其中的每个 View 都包含界面内容并嵌入其他 View。由于每个 View 都有一个 ViewRef,因此我们还可以将视图树视为 ViewRef 树。

在视图树中,父视图比子视图具有巨大的能力:可以调整子视图的位置、在子视图上强制实施裁剪边界、隐藏子视图的界面内容等。由于视图层次结构的固有功能,我们将其用作除了 View 之外层次结构的基础。这种层次结构会根据视图聚焦而动态变化,用“焦点链”表示。

如何使用 ViewRef?

通常,界面客户端使用 ViewRef 将自身标识为管理器类型的程序。

由于视图创建的前馈特性,因此在 在“景观”中创建视图之前,管理器程序可以开始处理特定于视图的逻辑。

以下是一些用法示例。无障碍功能管理器使用 ViewRef 来识别和管理客户端内容;IME 管理器使用 ViewRef 识别 IME 客户端,Shortcuts Manager 使用 ViewRef 识别和管理客户端编写的键盘快捷键,Sys 界面使用 ViewRef 识别和管理子视图的焦点。

ViewRef 和 ViewToken 是一回事吗?

不能。这些 FIDL 数据类型都由事件对提供支持,但用途不同。

ViewToken 供 Sense 在内部使用。它会将 View 资源连接到场景图中的相应 ViewHolder 资源。语义之所以有效,是因为事件对的每一侧都由 View(子)和 ViewHolder(父)唯一持有。

ViewRef 用在“scape”以外的地方。界面客户端和管理者组件用它来引用视图。

ViewRef 不用于身份验证

ViewRef 可以轻松地跨协议边界传播。因此,请务必不要使用 ViewRef 作为身份验证机制:仅保留 ViewRef 不应向持有者授予权限。应改为使用功能路由将使用 ViewRef 的协议安全地分发到可信组件。

例如,fuchsia.ui.views.ViewRefCompleted 协议,该协议允许客户端确定 Sense 何时在视图树中安装了 ViewRef。

ViewRef 设计权衡

前馈模式本身并不安全;可信客户端在将 ViewRef 和 ViewRefControl 对馈送给 Look 时,不会创建 ViewRefControl 的秘密副本。