Commit Graph
3 Commits
Author SHA1 Message Date
KeelrLeek fbc6a0268b android auto: the UI is four tabs and a colour, not a screen — the design, decided
An earlier pass in this repo mocked a car UI from imagination: a tab strip, a
header with search and queue icons, a bottom mini-player, a big-art playback
view with a linear progress bar. None of those exist. Google's line is flat —
"You don't draw your user interface directly on Android Auto; the framework
has two well-defined UIs that are created automatically" — and the reference
frames confirm it. The bottom bar is the SYSTEM's (home, notifications,
Assistant). Progress is a RING around play/pause. The artwork sits small at
the left behind a blur of itself. About THREE rows fit on screen, not eight.

So the artifact that was needed was never a layout. It is the short list of
slots the app actually fills, and this commit decides them:

  tabs      Recent · Albums · Artists · Saved
  style     albums grid, artists and tracks list
  actions   Shuffle · Save, 2 of the 6 allowed
  reach     amber dot on rows that need the app; Save shows a tick when down
  accent    brand teal #31C0CB

Playlists loses its tab because the phone holds exactly one, and an empty tab
is a dead quarter of the only four we get. Saved takes it because it is the
set that plays with the app shut, which is the one thing genuinely different
about this app in a car. Grid-vs-list is not density — the car fits three
either way — it is what identifies the row: a record by its sleeve, an artist
by name, a track only by text. Save is the highest-value button on the screen:
hear it, save it, it plays cold on the way home. The dot marks the RISKY row
rather than the safe one, and thins out on its own as more music is saved.

Auto allows one accent pair, set at build time, and it cannot follow the
artwork the way the app does everywhere else — so it has to be the constant,
the falcon's teal.

None of this can ship before round 48. The card is MediaSessionCompat today,
Auto needs a MediaLibraryService, and two live sessions is not a safe
intermediate. Order is unchanged: 44 → 45 → 46 → 47 → 48, soak, then 49–52
build the table above.

The mockup that settles it is research/auto-mockup (gitignored): both real
libraries — the handset's three albums and the desktop's 418 — inside the real
template, at the three DHU resolutions, with an overlay that outlines which
pixels are the car's and which are ours.
2026-09-15 07:04:14 -05:00
KeelrLeek 07dad65ca5 android: the keep rules, and the release build that proves them
Every APK this port has produced is `assembleArm64Debug`, and the generated
project turns R8 on for `release` and only for `release` — while tauri finds a
plugin class by string, files every `@Command` under `commands[method.name]`,
and lets Jackson fill every `@InvokeArg` field by field. Minification breaks
exactly that, and it breaks it without a word: the app compiles, installs,
launches, shows Home, and then a tap on Library folder answers "No command
pickFolder found for plugin ..." in logcat and nothing on screen. So each
plugin module now carries its own `consumer-rules.pro` naming its own
reflected surface — the shape tauri-android and tauri-plugin-dialog already
use in this build, and one that travels with the plugin into a regenerated
`gen/android`, which a rule written into that gitignored tree would not.

What belongs to no single plugin is in `src-tauri/android/proguard-soulstream.pro`,
copied into the generated project by the build script because the app's own
Gradle file is regenerated: the runtime annotation attributes, a `-dontwarn`
pair for the two `java.beans` classes jackson-databind references and Android
does not have (R8 turns a missing class into a build error, so without them
there may be no APK at all), and a keep for the four `@Command` methods
declared on `app.tauri.plugin.Plugin` itself. Tauri's own rule matches classes
annotated `@TauriPlugin` and the members they declare; the base class carries
no such annotation, so nothing names `registerListener` — which is what the
lock-screen card's buttons and the download notice's Cancel and Open ride on.

`build.sh` grows `--release`: the release profile, `--features tauri/devtools`
so the walk can still attach at all, `assembleArm64Release`, and a zipalign and
sign with the same debug key the phone already trusts, so the APK installs over
the app rather than forcing an uninstall that would take Kyle's settings with
it. With no argument the script is what it has always been, cargo line for
cargo line, so deploy.sh and ship.sh keep the path they run every twenty
minutes. And it has been built. Not on the phone and not as arm64 — as **x86_64**, on an
emulator, because that is what this machine can run — but the flavour is the
only difference: the same Gradle, the same R8, the same rules, the same
zipalign and apksigner. `minifyX86_64ReleaseWithR8` succeeded and wrote **no**
`missing_rules.txt` at all, which is the `-dontwarn` pair doing its job;
`lintVitalX86_64Release` passed, so the `-x lintVital` advice is for a failure
that has not happened. The signed APK went over the debug app with
`adb install -r` and left its data alone, exactly as the same-key argument
above says it must.

Then the minified app was walked: Home, the record, playback, the queue, the
sheets, the lyrics, the drags, the export — **131 of 131, no exceptions, no
console errors, every step as expected**, and nothing in logcat about a missing
command or class. That is the failure this round exists to prevent, looked for
and not found.

What it does not cover is the hands-only list in ANDROID.md — the pickers, the
notification buttons, the share sheet — which no walk reaches, and the four
`@Command` methods on `Plugin` itself remain a precaution rather than a
diagnosed bug. The document says so, command by command.
2026-09-14 11:09:33 -05:00
KeelrLeek 9f0601027c android: the handoff — the pending rounds, the pipeline, and what is unverified
Everything written this session that has not been through the device: rounds 43
to 48 (each patch adversarially verified, 43's transient-notice expectation
fixed), a partial round 49, the pipeline scripts, the Android Auto design and
the icon comparison mock. Also the two harness changes that were never A/B'd —
adaptive waits, which may only shorten a declared wait and never lengthen it,
and a ship that runs the mock walk and the deploy at the same time. The A/B and
its 255-step baseline are in handoff/tools; main stays at what the phone has
actually walked.
2026-09-14 07:57:41 -05:00