package com.evsuite.abrp; /** * Spots a double press of one steering-wheel key from the head unit's key broadcasts. * * The broadcast format is not documented, so this copes with all the shapes it could take: * - no up/down information at all: every broadcast is one press; * - separate down and up broadcasts: only releases count. If the meaning of the action field * is the other way round, downs count instead — still exactly one per press, so a double * press is found either way; * - a long press resets, so holding the key never opens anything. * * Android-free and unit-tested; the window is longer than the stock 300 ms, because a * deliberate double press on a steering wheel is slower than one on a touch screen. */ final class DoublePressDetector { static final long WINDOW_MS = 500; private final int keyCode; private long lastPressAt = Long.MIN_VALUE; DoublePressDetector(int keyCode) { this.keyCode = keyCode; } /** * @param down true for a key-down, false for a release, null when the broadcast does not say * @param longPress true when the broadcast marks a long press * @return true exactly once per double press */ synchronized boolean accept(int code, Boolean down, boolean longPress, long atMillis) { if (code != keyCode) return false; if (longPress) { lastPressAt = Long.MIN_VALUE; return false; } if (Boolean.TRUE.equals(down)) return false; if (lastPressAt != Long.MIN_VALUE && atMillis - lastPressAt <= WINDOW_MS) { lastPressAt = Long.MIN_VALUE; // a third press starts over return true; } lastPressAt = atMillis; return false; } }