diff options
| author | Claude <noreply@anthropic.com> | 2026-09-21 20:25:01 +0000 |
|---|---|---|
| committer | Claude <noreply@anthropic.com> | 2026-09-21 20:25:01 +0000 |
| commit | 8d980bb234b8303f17908621501620cb898d17ef (patch) | |
| tree | 0a6e09addc5f1d4ad70beb1f50461cc2fdf7e5bd /settings.gradle.kts | |
| parent | f7e7719bd1ed8a40765ce8b31ef8fa2c600bc7d0 (diff) | |
Android Auto support, and give the car its skip-forward button
Two things from the car.
Skip-forward was missing: a head unit shows about three transport controls,
and leaving previous/next track available meant they took the slots. Previous
does nothing useful for a single episode anyway, so those commands are now
removed in onConnect and the seek buttons get the room.
Auto did not recognise Listen as driving-friendly, so it could only be
controlled from the phone. That needs a browsable library, which means a
MediaLibraryService rather than a MediaSessionService, plus a tree: Up Next
and Podcasts at the root, shows beneath, episodes beneath those, capped at 100
because one real feed here holds 2753.
Three things were each individually fatal and none failed loudly:
- The automotive_app_desc meta-data has to sit at application level. A
search-and-replace put a copy inside each activity as well, where it is
simply ignored.
- The service must be exported, because the controller is another process.
- onConnect must grant DEFAULT_SESSION_AND_LIBRARY_COMMANDS. With plain
DEFAULT_SESSION_COMMANDS a browser connects successfully and then gets
PERMISSION_DENIED on the library root -- the connection looks healthy and
browsing is dead. Found by logging the result code rather than assuming.
Voice search too, since in a car it is the only interaction that keeps your
eyes on the road. Shows rank before episodes: asking for a show by name is the
common case, and a show is browsable, so the driver still picks the episode.
MediaBrowseTest drives all of this over the real session protocol from a
MediaBrowser. It must run on the main thread and await rather than block --
MediaController rejects calls from another thread, and blocking the main
thread on a future that completes there deadlocks.
Also: XML comments cannot contain "--", which made the manifest unparseable
with a merge error that never named the line; and the reachability guard was
reporting a method reference (LibraryTree::subscription) as dead because it
only matched call syntax with parens.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018AwnALZL6bD4VBtATDVv3B
Diffstat (limited to 'settings.gradle.kts')
0 files changed, 0 insertions, 0 deletions
