This repository is the Power Ampache 2 plugin template — a companion app that provides Android Auto browse and playback for a self-hosted Ampache music server, powered by Power Ampache 2 as the host app.
Built with Clean Architecture across four modules: domain, data, app, and PowerAmpache2Theme.
The plugin is an IPC client of the main Power Ampache 2 app. It does not talk to the Ampache server directly — all data comes through the host app via a Messenger-based IPC bridge.
┌─────────────────────┐ Messenger IPC ┌──────────────────────────┐
│ Power Ampache 2 │ ◄─────────────────► │ Plugin (this app) │
│ (host app) │ (bidirectional) │ │
│ │ │ PA2DataFetchService │
│ - Ampache API │ ─── sends data ───► │ └─ MusicFetcherImpl │
│ - Stream URLs │ │ └─ StateFlows │
│ - Playback queue │ │ │
│ │ ◄── requests data ── │ Pa2MediaLibraryService │
│ │ │ └─ ExoPlayer │
│ │ │ └─ Media3 Session │
└─────────────────────┘ └──────────────────────────┘
│
Android Auto (car head unit)
browses via Media3 library
-
Plugin binds to host. When
Pa2MediaLibraryServicestarts, it starts and binds toPA2DataFetchService(in thedatamodule). This service exposes aMessengerinterface — the host app connects as a client and registers itself viaregister_client. -
Host pushes data. The host app sends JSON-serialized playlists, albums, artists, and songs through the Messenger.
PA2DataFetchServiceparses these with Gson and updatesMusicFetcherImpl'sStateFlows (playlistsFlow,albumsFlow,albumSongsMapFlow, etc.). -
Plugin requests data. When Android Auto drills into a browse node (e.g. an album),
Pa2MediaLibraryServicecalls domain use cases (GetSongsFromAlbumUseCase, etc.) which flow throughMusicFetcherImpl→MusicFetcherListener→PA2DataFetchService, which sends a Messenger request to the host. The host responds asynchronously with the JSON data, which updates the relevantStateFlow. -
Auto browses the library.
Pa2MediaLibraryServiceimplements Media3'sMediaLibraryService. Android Auto callsonGetLibraryRoot,onGetChildren, andonGetItemto navigate a browse tree: root → sections (playlists, favourite/recent/latest/highest albums) → items → songs. -
Playback via ExoPlayer. When a user taps a song on the car display, Android Auto sends a
MediaItemwith only amediaId(no URI — the framework stripslocalConfigurationfor privacy). TheonAddMediaItems/onSetMediaItemscallbacks resolve the ID back to aSongobject, re-attach the stream URL fromsong.songUrl, and expand a single song into a full album/playlist queue so skip/next works. ExoPlayer then streams the Ampache URL directly with properAudioAttributes, audio focus handling, and wake lock. -
Host queue mirroring. When the host app plays audio on the phone, it pushes its queue via
MusicFetcher.currentQueueFlow. The plugin mirrors this queue into ExoPlayer (paused) so Android Auto shows Now Playing metadata without requiring the head unit to have initiated playback.
- Media3 / ExoPlayer — Android Auto browse tree, playback session, and audio streaming
- Dagger Hilt — dependency injection
- Gson — JSON deserialization of host app data into domain models
- Jetpack Compose + Material3 — phone UI