Revert the two verify-loop changes: zero matches in four runs

Two changes went in together and the next four runs matched nothing, including
a held press. They cannot be separated after the fact, so both come out and the
loop returns to the shape that has matched every time it was asked to.

One is definitely broken. The rising-edge recapture assumed a frame 50 ms after
detection would show a settled finger; on a quick tap the finger was already
gone, the recapture read the idle floor -- metric 133, still flagged FINGER
from the first capture -- and an empty image went to the matcher. A guaranteed
miss on exactly the case it was meant to fix.

The other is probably wrong. Dropping event 5 as a duplicate rested on
observing that event 7 alone produces a verdict -- but every such observation
was a held frame that followed an event 5 on the same press. Whether the touch
event initialises the press in the trustlet is not known, and five finger
frames with no match is not the evidence to remove it on.

The process error is the one worth writing down: two variables changed at
once, on a live user's finger, with no way to attribute the result. One at a
time from here.
This commit is contained in:
Jorijn van der Graaf 2026-09-02 23:18:42 +02:00
commit 06459a8e73
3 changed files with 31 additions and 28 deletions

View file

@ -88,14 +88,18 @@ export namespace fingerprintd::engine {
// trace. Sending event 7 on every held frame instead feeds the algorithm
// near-duplicate images from a single press.
//
// Authentication wants event 7, which reaches the matcher unconditionally,
// and ONLY event 7. Event 5 reaches it too (when device+0x10a8 is 1 or 2,
// which it is here): measured on the daemon, the rising-edge frame sent
// both and got two verdicts back from one image -- `rej rej`, `-11 -11`,
// `MATCH MATCH`. Each REPORT_EVENT that runs the matcher costs 250-300 ms,
// so the second one is a third of a second of redundant work on every
// press, on the frame where speed matters most. Enrolment keeps event 5:
// there it is the sample trigger, not a duplicate.
// Authentication does want event 7, which reaches the matcher
// unconditionally; event 5 only reaches it when device+0x10a8 is 1 or 2.
//
// Both are sent on the rising edge, and that is deliberate. On this device
// event 5 ALSO runs the matcher, so the rising frame produces two verdicts
// from one image (`rej rej`, `MATCH MATCH`) at ~300 ms each -- and an
// attempt to drop event 5 as redundant produced a run with zero matches
// across five finger frames, including a held press. Every match ever
// recorded came after an event 5 on the same press; "event 7 alone
// matches" had only ever been observed on held frames that followed one.
// Whether the touch event initialises the press in the trustlet is not
// known. It is not to be removed without a measurement that isolates it.
class TouchTracker {
public:
// Returns the events to report for this frame, in order.
@ -103,7 +107,7 @@ export namespace fingerprintd::engine {
std::vector<Event> out;
bool rising = finger && !prev_;
bool falling = !finger && prev_;
if (rising && mode == Mode::Enrol)
if (rising)
out.push_back(Event::FingerTouched);
if (finger && mode == Mode::Authenticate)
out.push_back(Event::ImageReady);