| RFC-0172:界面 activity 服务 | |
|---|---|
| 状态 | 已接受 |
| 区域 |
|
| 说明 | 关于确定用户输入活动或空闲状态并通知客户端的服务提案。 |
| 问题 | |
| Gerrit 更改 | |
| 作者 | |
| 审核人 | |
| 提交日期(年-月-日) | 2022-06-02 |
| 审核日期(年-月-日) | 2022-06-30 |
摘要
此 RFC 引入了一项新的界面 activity 服务,该服务取代了现有版本的职责并缩小了其职责范围。
提议的服务添加了两个新的 FIDL 协议:
- 一个私有 FIDL 协议
fuchsia.input.interaction.observation.Aggregator来收集用户输入活动的证据,并 - 合作伙伴 FIDL 协议
fuchsia.input.interaction.Notifier,用于向客户端通知用户输入活动状态的变化。
设计初衷
我们希望提供一项服务,用于通知系统的其他部分最近是否发生了用户输入活动。此服务可用于通知其他系统服务,例如节能协议或屏保功能。
系统中已存在一个 “Activity Service”,它将自身确立为系统中用户空闲状态的真实来源。此提案与当前方法不同,引入了新的“界面 activity 服务”,以表明责任范围更窄,仅负责用户输入 activity,而不是整个系统 activity,从而在某些产品中实现新功能,同时减少其他产品中的技术债务。
利益相关方
辅导员:
leannogasawara@google.com
审核者:
- jsankey@google.com
- neelsa@google.com
- sanjayc@google.com
- quiche@google.com
- wittrock@google.com
已咨询:
- anwilson@google.com
- comfoltey@google.com
- fmil@google.com
- kpozin@google.com
- palmer@google.com
- yaar@google.com
共同化:
在与 Fuchsia 输入团队进行文档审核期间,讨论了此 RFC,并要求进行隐私和安全审核。
设计
活动状态
活动是指用户最近与设备进行的输入互动。
最近是指产品配置的时间阈值,例如 15 分钟。
如果设备近期未收到任何活动,则会被视为处于空闲状态。
在初始实现中,用户输入互动仅限于以下列出的使用情形。
要求
以下用户互动必须导致服务进入或续订有效状态:
- 用户触摸了屏幕。
- 用户与鼠标或键盘进行了互动。
- 用户按下了媒体按钮,例如调高音量或调低音量。
以下用户互动应导致服务进入或续订有效状态:
- 用户启用了或停用了屏幕阅读器。如果用户使用上述某种输入模式执行此操作,系统会隐式捕获该操作。或者,如果通过更改 SetUI 来实现此目的,建议将其视为类似于打开设备机盖。
- 用户已打开设备盖子。
- 用户开启了设备。
以下互动不被视为活跃用户输入活动,因为它们有相应的内嵌理由。因此,它们不得导致服务进入 active 状态:
- 用户正在观看视频或收听音频文件:应使用
fuchsia.media.ActivityReporter,而不是此 RFC 中讨论的 activity 服务。
协议和服务
我们向合作伙伴 SDK 引入了新的内部 FIDL 协议 fuchsia.input.interaction.observation.Aggregator 和新的 FIDL 协议 fuchsia.input.interaction.Notifier。这些协议将由 输入流水线组件中的新 Activity 类实现和公开。
fuchsia.input.interaction.observation.Aggregator
此 API 的客户报告称,他们认为自己有用户输入活动的证据,我们会将他们的信息视为此类证据。因此,通过功能路由,访问权限仅限于树内组件。如需了解详情,请参阅安全注意事项。
library fuchsia.input.interaction.observation;
using zx;
/// The Aggregator protocol collects evidence of user activity and uses this
/// evidence to set the system's activity state.
@discoverable
protocol Aggregator {
/// Reports a discrete activity such as a keystroke.
ReportDiscreteActivity(struct {
activity DiscreteActivity;
event_time zx.time;
}) -> ();
};
与之前收集离散事件和持续事件(即具有开始时间和结束时间的 activity)的协议不同,此 RFC 定义的初始版本仅收集“离散”activity。收集持续事件的功能最初是为了支持媒体播放而引入的,而媒体播放明确不属于此 RFC 的使用情形。
fuchsia.input.interaction.Notifier
此 API 的客户端应希望订阅用户互动“活跃”状态与“空闲”状态之间的变化,这些状态的定义与 fuchsia.ui.activity.State 类似。此 RFC 计划在 fuchsia.input.interaction 库中创建一个类似的枚举,以在未来需要扩展时使用 flexible。无需限制访问权限,请参阅隐私权注意事项。例如:
- 树内:当设备进入空闲状态时,无障碍管理器会使屏幕阅读器静音,以防止其将屏幕上的变化(例如,如果显示时钟,则每分钟)读出来。
- 树外:当设备进入空闲状态时,客户端返回到主屏幕。
library fuchsia.input.interaction;
/// The Notifier protocol offers a subscription interface through
/// which clients can watch for changes in the system's activity state.
@discoverable
protocol Notifier {
/// Subscribe to changes in the system's state.
/// The server will always respond immediately with the initial state,
/// and after that whenever the system's state changes.
WatchState(table {}) -> (resource struct {
state State;
});
};
所提议的协议将不同于现有的 fuchsia.ui.activity.Notifier.WatchState 协议,因为它将使用挂起 GET 模式,从而完全无需使用 Listener 协议。它也不会发送时间戳。
盖子传感器
界面 Activity 服务可以使用 fuchsia.hardware.input FIDL 来监听盖子传感器驱动程序报告,并在收到盖子打开报告后转换为活动状态。
与输入流水线集成
空间考虑因素
在输入流水线 (IP) 组件中实现界面 Activity 服务 (A),而不是将其作为单独的组件实现,可以节省约 172 KB 的磁盘空间,具体取决于产品和主板配置。对于空间受限的产品,减小尺寸可为系统中的其他改进腾出空间。
| 构建 | A | IP | IP + 两个 FIDL |
|---|---|---|---|
| workstation_pro.chromebook-x64 | 196 KB | 1364 KB | 1388 KB |
| core.astro | 184 KB | 688 KB | 700 KB |
其他注意事项
在输入流水线中集成界面 activity 服务包括以下内容:
- 该服务应该是单线程的,因为目前没有必要或好处是多线程的。此外,输入流水线是单线程的,将该库转换为支持多线程方法会引入不必要的复杂性。
- 该服务应使用 Rust 实现,以避免引入在一个库中管理多种语言所需的复杂性。
- 由于恢复模式不使用输入流水线或场景管理器,因此该服务在恢复模式下不可用。恢复模式下缺少 activity 服务不是问题,因为根据设计,恢复模式使用单个高度集成的组件来最大限度地减少依赖项。
- 该服务不应通过标记已处理的事件或将事件发送到其他组件来处理
InputReport,因为这会使该服务了解并负责比确定活动是否最近发生过所需的信息更多的信息。 - 服务不应具有输入事件来源的特殊知识(因为这些来源应通过
fuchsia.input.interaction.observation.Aggregator进行报告)。 - 因此,该服务不应实现为
InputHandler。
可配置的空闲阈值
空闲阈值是指自上次用户活动以来,系统进入空闲状态所经过的时间。您可以在产品级的输入流水线或场景管理器组件中使用结构化配置来设置此值,对于当前产品,此值将设置为 15 分钟。
实现
该服务将按如下方式实现:
- 定义新的
fuchsia.input.interaction.observation.Aggregator和fuchsia.input.interaction.NotifierFIDL 协议。 - 实现并单元测试在输入流水线中初始化的新
Activity服务,以同时支持这两种协议。 - 通过
fuchsia.input.interaction.observation.Aggregator报告相关InputHandlers活动。注意:最好在此阶段(而非绑定阶段)报告 activity,因为InputHandlers负责将信息从InputEvents调度到其他组件或服务。 受影响的处理程序包括:
- MediaButtonsHandler
- MouseInjectorHandler
- TouchInjectorHandler
- KeypressHandler(新)
- 为以下情况添加集成测试:
fuchsia.input.interaction.observation.Aggregator通知 activity 状态- 当系统转换到活动状态时,会通知
fuchsia.input.interaction.Notifier - 当系统转换到空闲状态时,
fuchsia.input.interaction.Notifier会收到通知
=== fuchsia.input.interaction.Notifier 可供客户端使用 ===
- 弃用并移除了
fuchsia.ui.activity.Tracker、fuchsia.ui.activity.Provider和fuchsia.ui.activity.control.Control
- 将 FIDL 协议标记为已弃用,并提供有关使用新协议的说明
- 将
fuchsia.ui.activity.Provider的现有用法迁移到fuchsia.input.interaction.Notifier[在 Cobalt、Omaha 和 PowerManager 中] - 移除了
fuchsia.ui.activity.Tracker的使用(非功能性) - 删除
//src/sys/activity
性能
界面 activity 服务不得为系统中的输入事件处理添加延迟。
虽然所提出的协议不会引入异步或计算密集型逻辑,但我们可能需要对高频输入事件引入节流。例如,鼠标通常会发送大约 1000 个事件/秒,因此可能需要对从 MouseInjectorHandler 到 Activity 服务的 FIDL 调用进行速率限制。
我们可以监控预先存在的性能测试(例如输入延迟时间测试),以辨别更改是否会导致性能下降。
安全注意事项
界面 Activity 服务的主要滥用媒介是通过使用 fuchsia.input.interaction.observation.Aggregator 虚假报告 activity 来保持系统唤醒状态。例如,恶意应用可能会定期报告活动,以使系统保持唤醒状态。鉴于 fuchsia.input.interaction.observation.Aggregator 仅在树内提供,未在 SDK 中提供,并且仅供界面领域中的组件使用,因此风险较低。
任何此类服务都存在以下风险:延迟软件更新、保持屏幕解锁状态、耗尽电池电量,以及可能拒绝向设备上的其他应用提供服务。委托数据访问权限是此 RFC 未解决的风险。如果客户端依赖于空闲状态来实现上述功能,则在使用此服务时应实现自己的最大活动限制(如果相关),例如,当用户处于活动状态的时间达到 24 小时后,强制执行系统 OTA。
由于此功能必须通过 CFV2 进行路由,因此请注意,平台仅在平台级授予向输入流水线和潜在的 A11y 管理器报告活动的能力,并且产品可以进一步路由到可信组件。
隐私注意事项
虽然界面 activity 服务不会公开任何有关用户 activity 性质的信息,但它会通过 fuchsia.input.interaction.Notifier 分享在预设时间阈值内是否发生了 activity。
某人是否在特定时间位于设备旁或使用设备会影响隐私,属于敏感信息,因此我们不希望不受信任的组件能够访问这些信息。由于此功能必须通过 CFV2 进行路由,因此需要注意的是,平台应仅授予观察平台级可信活动的能力,并且产品可以进一步路由到可信组件。
具体来说,订阅者将无法使用时间戳。
测试
我们的测试策略包括
- 单元测试
- 使用现有工具进行集成测试
文档
该服务将包含自述文件概览,新的 FIDL 协议将附带内嵌注释。
缺点
输入流水线失败
如果输入流水线出现 panic 或死锁,界面 activity 服务也会失败。在这种情况下,空闲状态变化的订阅者可能希望默认采用活跃状态行为而非空闲状态行为,并且应采取其他缓解措施,例如设置最长活动超时时间,以确保关键进程仍能运行。如果输入流水线无法接收或响应输入报告,则系统可能存在更广泛的问题。
替代方案
使用现有 fuchsia.ui.activity.Tracker 协议
此方法倾向于创建新的 fuchsia.input.interaction.observation.Aggregator 协议。
- 当前协议位于合作伙伴 SDK 中,无法限制为仅供私有 SDK 使用。纳入合作伙伴 SDK 将有额外的 CTS 测试要求。
- 聚合器更清楚地表明了协议的作用。
- 当前的一组使用情形不需要使用
StartOngoingActivity或EndOngoingActivity,未来的需求可能需要重新评估当前的模式。
修改现有 fuchsia.ui.activity.Provider 协议
此方法倾向于创建新的 fuchsia.input.interaction.Notifier 协议。
- 当前协议可由
fuchsia.ui.activity.control.Control协议控制。 WatchState协议必须迁移到建议的挂起获取模式。WatchState协议不必要地发布了时间戳,我们不希望客户端在没有具体用例或公开意图的情况下依赖该时间戳。
纳入其他活动信号
在某些用户流程中,某些信号可能被视为活动,但在其他用户流程中则不然。因此,信号的解读方式是否正确会因特定设备规格或服务的需求而异。
建议使用 fuchsia.input.interaction.Notifier 协议来使用界面活动状态,并且可以结合其他形式的活动(例如来自音频、麦克风或相机的活动)进行参考,以确定一些最终的用户或系统状态,具体取决于具体情况。例如,屏保功能可能仅参考用户输入活动,而锁屏功能可能同时参考用户输入活动和用户身份验证状态。
支持配置要考虑的活动类型子集
未来,某些服务可能希望根据部分用户输入模式(例如最近的触摸操作,但不是最近的按键操作)来跟踪 activity 状态。这会在可能的输入模式之间引入指数级组合。
鉴于目前用户对更复杂的功能缺乏兴趣,我们决定不提前引入这种复杂性。
与 Fuchsia 的系统身份验证集成
系统身份验证和界面活动服务都关注某种用户行为,但实际重叠很少。例如,系统身份验证会考虑更精细的用户在场状态,包括用户与设备的距离以及用户是否是账号所有者。
虽然可以以一种同时适用于这两种使用情形的方式来跟踪用户活动,但如果没有明确的使用情形,主动集成这两个系统可能没有必要。
未来的工作
允许订阅者配置空闲时间阈值
未来,某些服务可能希望自行确定用户输入互动的近期性阈值。虽然此 RFC 未提出解决方案,但为了简化初始实现而省略了此功能,不过,所提议的协议可能会在出现具体使用情形时进行扩展以添加支持。
在先技术和参考资料
- chrome.idle API 支持“active”“idle”和“locked”状态。
- 由于未使用,移除了 Root Presenter 中的 Fuchsia activity notifier。