Skip to content

1.2.8 - HID 收得到事件,真正的问题是 usage 匹配(已放宽)+ 设置里显示计数

Choose a tag to compare

@CangWeiohh CangWeiohh released this 10 Oct 01:41
· 6 commits to main since this release

1.2.8:HID 事件其实收得到 —— 真正的问题是"匹配不到电源键"

你给的那行状态是决定性证据

你看到的是 已启动 · 电源键监听(HID)。这行文案只在 HID 事件真的到达时才会显示(收不到事件时显示的是「HID 已注册但收不到事件」)。所以:

imagent 完全有权接收 HID 事件,客户端也真的在被喂数据 —— 我之前担心的 entitlement / 沙箱拦截并不存在。

那按电源键为什么没反应?只剩一个解释:这台设备的电源键事件不是我匹配的那个 usage。1.2.7 只接受 Consumer 页 0x0C / usage 0x30,而 iPhone 的锁屏/电源键在很多机型上是以 AppleVendor 页 0xFF01 / usage 0x0B(Screensave) 上报的。

1.2.8 的修改

  1. 放宽匹配:现在接受三种候选 usage,其余按键(音量、Home、媒体键等)仍然一律不匹配,不会误停:
    • Consumer 0x0C / 0x30(Power)
    • AppleVendor 0xFF01 / 0x0B(Screensave,iPhone 锁屏键常见上报方式)
    • Keyboard 0x07 / 0x66(Power)
  2. 事件投递更可靠:1.2.7 把客户端挂到 imagent 的主 run loop 上,而没人保证主线程在跑默认模式。现在优先使用 IOHIDEventSystemClientSetDispatchQueue(完全不依赖 run loop),没有该符号时改用独立线程 + 自己的 run loop。
  3. 把原始计数显示在设置里(这样下一次测试就能直接读出答案,无需终端):
    已启动 · 电源键监听(HID)· 事件 N/键盘 M · 末次 0x<page>/0x<usage>↓
    • 事件 一直涨 → 客户端在被喂数据;
    • 键盘 M 在你按电源键/音量键后 +1;
    • 末次 0x…/0x… 就是这颗设备真实的 page/usage —— 如果电源键不是上面三种之一,把这两个值发我,我直接加进匹配表即可。

顺带修掉一个真 bug

英文 Localizable.strings 里少了一个分号("RuntimeHIDLast" = "…%@;"),导致设置面板 bundle 编译失败、一直用旧二进制——这也是为什么 1.2.7 里看不到计数。现已修复并加了 plutil -lint 验证。

请这样测

  1. 安装 1.2.8;
  2. 进「诊断 → 提醒服务状态」,先按一下音量键(故意产生一个键盘事件)→ 看 事件/键盘 是否增长、末次 0x…/0x… 出现什么值;
  3. 触发一次提醒(「立即测试提醒」),提醒中按电源键 → 应从 1.2.8 起能停止;
  4. 若仍不能停止,把状态行整行(含 末次 与括号内容)发我。

核验

  • host 单测 48 passed / 0 failed(新增 4 项 usage 匹配用例:AppleVendor/Screensave 接受、Keyboard/Power 接受、Screensave 抬起忽略、Consumer/Menu 不误判)
  • detector:投递改为 dispatch-queue/独立 run loop、键盘事件带 page/usage/down 日志、零 Hook、未链接 AVFoundation、无 SpringBoard 组件与 LaunchDaemon
  • 两个 .strings 均通过 plutil -lint