Repository navigation
1.2.8 - HID 收得到事件,真正的问题是 usage 匹配(已放宽)+ 设置里显示计数
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 的修改
- 放宽匹配:现在接受三种候选 usage,其余按键(音量、Home、媒体键等)仍然一律不匹配,不会误停:
Consumer 0x0C / 0x30(Power)AppleVendor 0xFF01 / 0x0B(Screensave,iPhone 锁屏键常见上报方式)Keyboard 0x07 / 0x66(Power)
- 事件投递更可靠:1.2.7 把客户端挂到 imagent 的主 run loop 上,而没人保证主线程在跑默认模式。现在优先使用
IOHIDEventSystemClientSetDispatchQueue(完全不依赖 run loop),没有该符号时改用独立线程 + 自己的 run loop。 - 把原始计数显示在设置里(这样下一次测试就能直接读出答案,无需终端):
已启动 · 电源键监听(HID)· 事件 N/键盘 M · 末次 0x<page>/0x<usage>↓事件一直涨 → 客户端在被喂数据;键盘 M在你按电源键/音量键后 +1;末次 0x…/0x…就是这颗设备真实的 page/usage —— 如果电源键不是上面三种之一,把这两个值发我,我直接加进匹配表即可。
顺带修掉一个真 bug
英文 Localizable.strings 里少了一个分号("RuntimeHIDLast" = "…%@;"),导致设置面板 bundle 编译失败、一直用旧二进制——这也是为什么 1.2.7 里看不到计数。现已修复并加了 plutil -lint 验证。
请这样测
- 安装 1.2.8;
- 进「诊断 → 提醒服务状态」,先按一下音量键(故意产生一个键盘事件)→ 看
事件/键盘是否增长、末次 0x…/0x…出现什么值; - 触发一次提醒(「立即测试提醒」),提醒中按电源键 → 应从 1.2.8 起能停止;
- 若仍不能停止,把状态行整行(含
末次与括号内容)发我。
核验
- 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