Skip to content

feat(testing): pointer-trace recorder + capture format (#20)#67

Merged
AsafMah merged 1 commit into
devfrom
feat/a3a-trace-recorder
Jun 7, 2026
Merged

feat(testing): pointer-trace recorder + capture format (#20)#67
AsafMah merged 1 commit into
devfrom
feat/a3a-trace-recorder

Conversation

@AsafMah

@AsafMah AsafMah commented Jun 7, 2026

Copy link
Copy Markdown
Owner

Implements #20 (A3a) — a debug capture mode that dumps real gesture sessions to replayable trace files, building toward the JUnit replay harness (#21) and, through it, the ability to verify the gated spacing/recognition epics.

What

When the new debug pref PREF_RECORD_INPUT_TRACES (Settings → Debug, default off) is on, each completed gesture/batch session is written to filesDir/input_traces/trace-<epochMillis>.json.

Format (v1, documented in TraceRecorder KDoc)

{ "version":1, "createdAt":<ms>,
  "keyboard": {"width":<px>,"height":<px>,"mainLayout":"qwerty","locale":"<bcp47>"},
  "committedWord":"<word>",
  "pointers":[{"id":<int>,"x":<int>,"y":<int>,"t":<ms>}, ...] }

pointers is the InputPointers flattened in index order — the exact trace fed to the recognizer (a merged trail for multi-part gestures), which is the most faithful replay input.

Implementation notes

  • Hook: InputLogic.onUpdateTailBatchInputCompleted — chosen over onEndBatchInput because that's where the committed word (composedText), mWordComposer.getInputPointers(), and the keyboard are all synchronously available on the UI thread (the word is computed async by InputLogicHandler).
  • Thread-safety: TraceRecorder copies the pointer arrays synchronously on the caller thread (InputPointers is mutable/reused), then writes off a single-threaded executor. Uses the application context (no IME-service leak).
  • Cost: default off → one boolean check on the gesture-commit path; nothing in normal use.

Verification

  • Compiles (Java+Kotlin); :app:testOfflineRunTestsUnitTest = 4 failed, all the Windows-only ParserTest set — zero new failures.
  • On-device: flip the debug toggle, swipe some words, pull input_traces/*.json — not yet exercised end-to-end by me; worth a quick check when convenient.

Next: #21 (JUnit replay harness + golden corpus) consumes this format. Built by a subagent; coordinator reviewed (thread-safety, hook correctness), compiled, ran the suite. Base dev.

Debug capture mode: when DebugSettings.PREF_RECORD_INPUT_TRACES is on, each
completed gesture session is dumped to filesDir/input_traces/trace-<ms>.json
(InputPointers x/y/t/id + committed word + keyboard geometry/locale), for the
JUnit replay harness (#21).

- Hooked in onUpdateTailBatchInputCompleted (where committed word + InputPointers
  + keyboard are all synchronously available on the UI thread), not onEndBatchInput.
- TraceRecorder copies the pointer arrays synchronously (InputPointers isn't
  thread-safe) then writes off a single-threaded executor; app context, no IME leak.
- Default off -> a single boolean check in normal use. Format documented in KDoc.
@AsafMah
AsafMah merged commit 25ef023 into dev Jun 7, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant