Low-severity items from the 1.4.2 review (#44, second round, verified at 53308c9). Individually small; grouped to keep the tracker clean.
IPC / lifecycle
app/src/main/aidl/.../IInputInjector.aidl — the four new methods were inserted before destroy(), shifting its transaction code; only the SERVICE_VERSION bump prevents a cached old daemon from mis-serving stale codes. Append new methods after destroy() next time so existing codes stay stable.
InputInjectorService.attachClient (:357-371) — unlinkToDeath failures are swallowed, and binderDied() tears down unconditionally, so an in-flight death notification for a replaced token can destroy devices a new client just created. Stamp a generation and act only if the dead token is still current.
InputInjectorService.kt:286-295 — the Enter-warp log assumes the AOSP seed position rather than reading it, and reports planned-not-applied counts after a partial write; it will mislead the next field debug.
HidMouseEnterWarp.kt:56-64 — on a partial HID write the warp keeps pending but returns the full plan list, so the client re-sends the entire snap and double-applies the prefix that already reached the device.
Timing / math
MousePointerCompensation.gainForSpeedMmPerS — CURVE_SEGMENTS.first { speed <= it.max } throws NoSuchElementException for NaN input; the pre-1.4.2 fallback degraded gracefully instead. Not reachable via current callers, but it is a public entry point.
WheelNotchAccumulator / ShizukuInputInjector — notches beyond the HID report's ±127 clamp are silently dropped on huge deltas; and since 53308c9 keeps the mouse attached across a Leave, a partial notch banked before a Leave now survives into the next Enter (reset() is wired to detach/disconnect only).
HidMouseEnterWarp.kt:12-13 — defaults nowMs to System.currentTimeMillis(); every other timestamp in the repo is SystemClock.uptimeMillis(), and an NTP step would skew dtMs fed into MouseEdgeAnchor.planSnap.
Concurrency
ConnectionService hidMouseIdleJob / leaveDebounceJob — plain fields written from Main and from the IO event-loop thread; currently benign only because the firing coroutine re-checks the volatile pointerOnScreen + generation. Confine to one dispatcher or annotate.
Docs / surface
UhidProtocol.kt KDoc labels UHID_OUTPUT "Device→host"; it is host→device.
- New test seams
internal constructor + deathRecipientForTest() (InputInjectorService.kt:26, :383) have no precedent in the repo; house idiom is a forTesting companion factory or injected functions (cf. UhidChannel.forTesting, UhidReadinessConfig). Consider moving the attach/death bookkeeping into an internal collaborator and testing that.
- The death-watch wiring (link succeeded, token replaced, unlink on destroy) is unasserted — Robolectric's
linkToDeath is a no-op, so the already-dead-token inline teardown branch has no coverage; a comment marking it emulator-only would be honest.
Tests / nits
- Duplicated
uhid_event packet-walking helpers in InputInjectorServiceClientDeathTest and InputInjectorServiceEnterTest — a testutil/UhidPacketReader matches the existing testutil/ precedent (a third walker is implicit in UhidChannelReadinessTest).
- New tests end with trailing
service.closeVirtualMouse() / channel.close() cleanup instead of @After/use — a failed assertion mid-test leaks the reader thread (repo precedent for the safer form: TransportProberTest, AeadBlobTest).
UhidChannel.kt import block now has android.util.Log before android.os.ParcelFileDescriptor (repo is alphabetically sorted); ShizukuInputInjector.kt:195 wheelNotches.reset() is indented 8 spaces inside a 12-space block.
MarkdownContent link parsing: [a](http://x "title") yields url http://x \"title\" which passes the http(s) prefix check and becomes a junk ACTION_VIEW URI — reject whitespace in isDispatchableUrl or strip a trailing title.
Low-severity items from the 1.4.2 review (#44, second round, verified at
53308c9). Individually small; grouped to keep the tracker clean.IPC / lifecycle
app/src/main/aidl/.../IInputInjector.aidl— the four new methods were inserted beforedestroy(), shifting its transaction code; only theSERVICE_VERSIONbump prevents a cached old daemon from mis-serving stale codes. Append new methods afterdestroy()next time so existing codes stay stable.InputInjectorService.attachClient(:357-371) —unlinkToDeathfailures are swallowed, andbinderDied()tears down unconditionally, so an in-flight death notification for a replaced token can destroy devices a new client just created. Stamp a generation and act only if the dead token is still current.InputInjectorService.kt:286-295— the Enter-warp log assumes the AOSP seed position rather than reading it, and reports planned-not-applied counts after a partial write; it will mislead the next field debug.HidMouseEnterWarp.kt:56-64— on a partial HID write the warp keepspendingbut returns the full plan list, so the client re-sends the entire snap and double-applies the prefix that already reached the device.Timing / math
MousePointerCompensation.gainForSpeedMmPerS—CURVE_SEGMENTS.first { speed <= it.max }throwsNoSuchElementExceptionfor NaN input; the pre-1.4.2 fallback degraded gracefully instead. Not reachable via current callers, but it is a public entry point.WheelNotchAccumulator/ShizukuInputInjector— notches beyond the HID report's ±127 clamp are silently dropped on huge deltas; and since53308c9keeps the mouse attached across a Leave, a partial notch banked before a Leave now survives into the next Enter (reset()is wired to detach/disconnect only).HidMouseEnterWarp.kt:12-13— defaultsnowMstoSystem.currentTimeMillis(); every other timestamp in the repo isSystemClock.uptimeMillis(), and an NTP step would skewdtMsfed intoMouseEdgeAnchor.planSnap.Concurrency
ConnectionServicehidMouseIdleJob/leaveDebounceJob— plain fields written from Main and from the IO event-loop thread; currently benign only because the firing coroutine re-checks the volatilepointerOnScreen+ generation. Confine to one dispatcher or annotate.Docs / surface
UhidProtocol.ktKDoc labelsUHID_OUTPUT"Device→host"; it is host→device.internal constructor+deathRecipientForTest()(InputInjectorService.kt:26, :383) have no precedent in the repo; house idiom is aforTestingcompanion factory or injected functions (cf.UhidChannel.forTesting,UhidReadinessConfig). Consider moving the attach/death bookkeeping into an internal collaborator and testing that.linkToDeathis a no-op, so the already-dead-token inline teardown branch has no coverage; a comment marking it emulator-only would be honest.Tests / nits
uhid_eventpacket-walking helpers inInputInjectorServiceClientDeathTestandInputInjectorServiceEnterTest— atestutil/UhidPacketReadermatches the existingtestutil/precedent (a third walker is implicit inUhidChannelReadinessTest).service.closeVirtualMouse()/channel.close()cleanup instead of@After/use— a failed assertion mid-test leaks the reader thread (repo precedent for the safer form:TransportProberTest,AeadBlobTest).UhidChannel.ktimport block now hasandroid.util.Logbeforeandroid.os.ParcelFileDescriptor(repo is alphabetically sorted);ShizukuInputInjector.kt:195wheelNotches.reset()is indented 8 spaces inside a 12-space block.MarkdownContentlink parsing:[a](http://x "title")yields urlhttp://x \"title\"which passes thehttp(s)prefix check and becomes a junkACTION_VIEWURI — reject whitespace inisDispatchableUrlor strip a trailing title.