App 2.4.0: pair with the server by QR code

The Server tab gets "Pair with phone" right under the server URL, which
is now pre-filled with https://car.stinnesbeck.com. It opens a dialog
with a QR code and the short code, polls the server, and on approval
saves this car's own token like Save would — nothing to type in the
car. Denied, expired, and pairing switched off on the server are each
reported. PairingClient is tested against a stand-in for the server.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QLJfZQZeAKAwSqViTmLzki
This commit is contained in:
2026-10-17 16:16:52 +02:00
co-authored by Claude Opus 5.5
parent d5f68e1bd9
commit c578a882bd
7 changed files with 384 additions and 3 deletions
@@ -27,6 +27,9 @@ final class ServerConfig {
"^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$",
Pattern.CASE_INSENSITIVE);
/** Pre-filled so pairing needs no typing in the car; can still be changed. */
static final String DEFAULT_URL = "https://car.stinnesbeck.com";
/** The server refuses shorter ingest tokens outright. */
static final int MIN_TOKEN_LENGTH = 24;
@@ -58,7 +61,7 @@ final class ServerConfig {
id = UUID.randomUUID().toString();
prefs.edit().putString(KEY_INSTALLATION_ID, id).apply();
}
current = new ServerConfig(prefs.getString(KEY_URL, ""), prefs.getString(KEY_TOKEN, ""), id);
current = new ServerConfig(prefs.getString(KEY_URL, DEFAULT_URL), prefs.getString(KEY_TOKEN, ""), id);
return current;
}
}