keyboard-service: migrate to HidDevice - #942
Open
williampMSFT wants to merge 3 commits into
Open
Conversation
williampMSFT
marked this pull request as ready for review
August 7, 2026 21:17
williampMSFT
requested review from
RobertZ2011,
felipebalbi,
jerrysxie,
tullom and
wmmc88
and
a lite review from Copilot
August 7, 2026 21:17
Contributor
There was a problem hiding this comment.
Pull request overview
This PR migrates keyboard-service off the legacy embedded_services::hid/hid-service stack onto the transport-neutral relay::hid::HidDevice trait, aligning it with the newer hidi2c-target-service direction and the runnable-service resource allocation pattern.
Changes:
- Replaced the old HID task-based keyboard implementation with a
KeyboardServiceinterface plus aKeyboardHidRelayimplementingHidDevice. - Refactored the GPIO matrix keyboard into the RunnableService pattern (
Resources+Service+Runner) and added a basic scan test. - Marked legacy HID layers (
embedded-service::hidmodule andhid-servicecrate) as deprecated and removed the old std HID example.
Reviewed changes
Copilot reviewed 11 out of 12 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| keyboard-service/src/task.rs | Removed legacy task entrypoints tied to the old HID stack. |
| keyboard-service/src/hid_kb.rs | Removed legacy HID-over-I2C keyboard backend implementation. |
| keyboard-service/src/relay.rs | Added KeyboardHidRelay implementing relay::hid::HidDevice for keyboards. |
| keyboard-service/src/interface.rs | Added a small transport-neutral KeyboardService interface and report types. |
| keyboard-service/src/lib.rs | Updated crate surface area to re-export the new interface/relay and runnable GPIO service types. |
| keyboard-service/src/gpio_kb.rs | Refactored GPIO keyboard into RunnableService pattern; added a scan test. |
| keyboard-service/Cargo.toml | Updated dependencies for runnable-service + relay HID; adjusted dev-deps for tests. |
| hid-service/src/lib.rs | Deprecated the legacy hid-service crate while keeping it buildable. |
| embedded-service/src/lib.rs | Allowed deprecated in tests to preserve deprecated HID tests without failing builds. |
| embedded-service/src/hid/mod.rs | Deprecated the legacy embedded_services::hid module. |
| examples/std/src/bin/hid.rs | Removed the std HID example tied to the deprecated HID stack. |
| Cargo.lock | Updated lockfile for dependency changes. |
Suppressed comments (1)
keyboard-service/src/relay.rs:201
- KeyboardHidRelay::reset clears the pending/subscriber queues but leaves last_report unchanged. After a reset, process_get_report can still return stale key state, which contradicts HidDevice::reset guidance to return to a known-good state.
async fn reset(&mut self) {
self.pending_input_report = None;
self.subscriber.clear();
}
Comment on lines
+148
to
+160
| async fn set_report(&mut self, report: &SetHidReport<'_>) -> Result<(), HidError> { | ||
| match report { | ||
| SetHidReport::Output(report) if report.id() == REPORT_ID => { | ||
| let flags = LedFlags::from_bits_retain(report.data().first().copied().unwrap_or(0)); | ||
| if self.service.set_leds(flags).await.is_err() { | ||
| error!("Failed to set keyboard LEDs"); | ||
| } | ||
| } | ||
| SetHidReport::Output(_) | SetHidReport::Feature(_) => {} | ||
| } | ||
|
|
||
| Ok(()) | ||
| } |
| #![no_std] | ||
| #![warn(missing_docs)] | ||
| // The deprecated `hid` module has `#[test]` functions that we want to preserve, but it looks like | ||
| // because the tests are in the `hid`` module, `allow(deprecated)` annotations on the test functions |
Comment on lines
1
to
+5
| //! HID sevices | ||
| //! See spec at <http://msdn.microsoft.com/en-us/library/windows/hardware/hh852380.aspx> | ||
| #![deprecated( | ||
| note = "this interface has been superseded by the relay::hid::HidDevice trait, which is transport-independent, doesn't depend on the comms service or require 'static lifetime on devices." | ||
| )] |
Comment on lines
+194
to
195
| for (row, pressed_bits_col) in pressed.iter().zip(pressed_bits.iter_mut()) { | ||
| for (r, &key) in row.iter().enumerate() { |
Comment on lines
+2
to
+4
| #![deprecated( | ||
| note = "this service has been superseded by the hidi2c-target-service crate, which doesn't depend on the comms service or require 'static lifetime on devices." | ||
| )] |
kurtjd
approved these changes
Aug 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Migrate the keyboard-service to leverage the new HidDevice trait, which will let it be used with the new hidi2c-target-service.
As part of this migration, switched to the RunnableService pattern for uniform resource allocation and added a simple test.
This was the last direct dependency on the legacy hid-service crate and its associated embedded-services::hid module, so marked those as deprecated. We don't have a replacement for the i2c controller piece yet so we can't remove the crate entirely, but everything else should be doable with the hidi2c-target-service crate and HidDevice trait.
This change does not attempt to meaningfully extend the scope of the keyboard interface, which means it still has some notable gaps around support for media keys/backlights/N-key rollover/etc, so this change does not create a new stable interface crate - a skeleton is in the keyboard-service for now and we can revisit making a more complete interface later.