# whoxamxl/aalyrics architecture

> Architecture diagram of the GitHub repository whoxamxl/aalyrics, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-23). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/whoxamxl/aalyrics
- Repository: https://github.com/whoxamxl/aalyrics

## Overview

AALyrics observes Android media playback, converts it into shared playback state, looks up and selects lyrics through independent providers, then exposes the result to phone and Android Auto surfaces. The README documents concurrent provider orchestration, playback-identity ownership, and demand-based lookup; several composition and UI links are represented at module level because their wiring was not sampled. Translation and release-update code are present in the app tree, but their runtime flow is not established by the excerpts.

Main entry points: [`core/lyrics/src/main/kotlin/io/github/whoxamxl/aalyrics/core/lyrics/LyricsCoordinator.kt`](https://github.com/whoxamxl/aalyrics/blob/main/core/lyrics/src/main/kotlin/io/github/whoxamxl/aalyrics/core/lyrics/LyricsCoordinator.kt) (Lyrics coordinator), [`app/src/main/java/io/github/whoxamxl/aalyrics/PhoneRuntimeHost.kt`](https://github.com/whoxamxl/aalyrics/blob/main/app/src/main/java/io/github/whoxamxl/aalyrics/PhoneRuntimeHost.kt) (Phone runtime host), [`core/lyrics/src/main/kotlin/io/github/whoxamxl/aalyrics/core/lyrics/PlaybackLyricsController.kt`](https://github.com/whoxamxl/aalyrics/blob/main/core/lyrics/src/main/kotlin/io/github/whoxamxl/aalyrics/core/lyrics/PlaybackLyricsController.kt) (Playback lyrics owner), [`platform/media/src/main/kotlin/io/github/whoxamxl/aalyrics/platform/media/MediaSessionListenerService.kt`](https://github.com/whoxamxl/aalyrics/blob/main/platform/media/src/main/kotlin/io/github/whoxamxl/aalyrics/platform/media/MediaSessionListenerService.kt) (Media listener)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_app["App runtime"]
  node_runtime["Phone runtime host"]
  node_appcompose["App composition"]
  node_demand["Lyrics demand gate"]
  node_translation["Translation runtime"]
end

subgraph group_media["Playback integration"]
  node_listener["Media listener"]
  node_snapshot["Snapshot adapter"]
end

subgraph group_lyrics["Lyrics engine"]
  node_playbackcontroller["Playback lyrics owner"]
  node_coordinator["Lyrics coordinator"]
  node_lifecycle["Lookup lifecycle"]
  node_models["Shared domain models<br/>[Playback.kt]"]
end

subgraph group_providers["Lyrics providers"]
  node_selection["Candidate selection"]
  node_lrclib["LRCLIB adapter<br/>[LrcLibProvider.kt]"]
  node_petit["PetitLyrics adapter"]
  node_musix["Musixmatch adapter"]
  node_sync["SyncLRC adapter<br/>[SyncLrcProvider.kt]"]
end

subgraph group_presentation["Presentation"]
  node_phoneui["Phone presentation<br/>[LyricsRoute.kt]"]
  node_autoservice["Auto browser service"]
  node_autoui["Auto presentation"]
end

node_androidmedia(("Android media sessions"))
node_providerapis(("Lyrics services"))

node_androidmedia -->|"notifies sessions"| node_listener
node_listener -->|"observes playback"| node_snapshot
node_snapshot -->|"normalizes state"| node_models
node_runtime -->|"forwards playback"| node_playbackcontroller
node_appcompose -->|"composes runtime"| node_runtime
node_demand -->|"gates lookup"| node_playbackcontroller
node_playbackcontroller -->|"starts lookup"| node_lifecycle
node_lifecycle -->|"runs lookup"| node_coordinator
node_coordinator -->|"queries provider"| node_lrclib
node_coordinator -->|"queries provider"| node_petit
node_coordinator -->|"queries provider"| node_musix
node_coordinator -->|"queries provider"| node_sync
node_lrclib -->|"requests lyrics"| node_providerapis
node_petit -->|"requests lyrics"| node_providerapis
node_musix -->|"requests lyrics"| node_providerapis
node_sync -->|"requests lyrics"| node_providerapis
node_coordinator -->|"selects winner"| node_selection
node_coordinator -->|"produces lyrics state"| node_models
node_runtime -->|"exposes app state"| node_phoneui
node_runtime -->|"exposes app state"| node_autoservice
node_autoservice -->|"renders metadata"| node_autoui

click node_listener "https://github.com/whoxamxl/aalyrics/blob/main/platform/media/src/main/kotlin/io/github/whoxamxl/aalyrics/platform/media/MediaSessionListenerService.kt"
click node_snapshot "https://github.com/whoxamxl/aalyrics/blob/main/platform/media/src/main/kotlin/io/github/whoxamxl/aalyrics/platform/media/MediaControllerSnapshotAdapter.kt"
click node_runtime "https://github.com/whoxamxl/aalyrics/blob/main/app/src/main/java/io/github/whoxamxl/aalyrics/PhoneRuntimeHost.kt"
click node_appcompose "https://github.com/whoxamxl/aalyrics/blob/main/app/src/main/java/io/github/whoxamxl/aalyrics/AALyricsApplication.kt"
click node_demand "https://github.com/whoxamxl/aalyrics/blob/main/app/src/main/java/io/github/whoxamxl/aalyrics/LyricsDemandGate.kt"
click node_playbackcontroller "https://github.com/whoxamxl/aalyrics/blob/main/core/lyrics/src/main/kotlin/io/github/whoxamxl/aalyrics/core/lyrics/PlaybackLyricsController.kt"
click node_coordinator "https://github.com/whoxamxl/aalyrics/blob/main/core/lyrics/src/main/kotlin/io/github/whoxamxl/aalyrics/core/lyrics/LyricsCoordinator.kt"
click node_lifecycle "https://github.com/whoxamxl/aalyrics/blob/main/core/lyrics/src/main/kotlin/io/github/whoxamxl/aalyrics/core/lyrics/LyricsLookupLifecycle.kt"
click node_selection "https://github.com/whoxamxl/aalyrics/blob/main/provider/selection/src/main/kotlin/io/github/whoxamxl/aalyrics/provider/selection/CrossProviderCandidateSelector.kt"
click node_lrclib "https://github.com/whoxamxl/aalyrics/blob/main/provider/lrclib/src/main/kotlin/io/github/whoxamxl/aalyrics/provider/lrclib/LrcLibProvider.kt"
click node_petit "https://github.com/whoxamxl/aalyrics/blob/main/provider/petitlyrics/src/main/kotlin/io/github/whoxamxl/aalyrics/provider/petitlyrics/PetitLyricsProvider.kt"
click node_musix "https://github.com/whoxamxl/aalyrics/blob/main/provider/musixmatch/src/main/kotlin/io/github/whoxamxl/aalyrics/provider/musixmatch/MusixmatchProvider.kt"
click node_sync "https://github.com/whoxamxl/aalyrics/blob/main/provider/synclrc/src/main/kotlin/io/github/whoxamxl/aalyrics/provider/synclrc/SyncLrcProvider.kt"
click node_models "https://github.com/whoxamxl/aalyrics/blob/main/core/model/src/main/kotlin/io/github/whoxamxl/aalyrics/core/model/Playback.kt"
click node_phoneui "https://github.com/whoxamxl/aalyrics/blob/main/ui/phone/src/main/java/io/github/whoxamxl/aalyrics/ui/phone/lyrics/LyricsRoute.kt"
click node_autoservice "https://github.com/whoxamxl/aalyrics/blob/main/ui/automotive/src/main/java/io/github/whoxamxl/aalyrics/ui/automotive/service/LyricsBrowserService.kt"
click node_autoui "https://github.com/whoxamxl/aalyrics/blob/main/ui/automotive/src/main/java/io/github/whoxamxl/aalyrics/ui/automotive/screen/NowPlayingScreen.kt"
click node_translation "https://github.com/whoxamxl/aalyrics/blob/main/app/src/main/java/io/github/whoxamxl/aalyrics/TranslationExecutionRuntime.kt"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_runtime,node_appcompose,node_demand,node_translation toneBlue
class node_listener,node_snapshot toneAmber
class node_playbackcontroller,node_coordinator,node_lifecycle,node_models toneMint
class node_selection,node_lrclib,node_petit,node_musix,node_sync toneRose
class node_phoneui,node_autoservice,node_autoui,node_androidmedia,node_providerapis toneIndigo
```

## Components

### App runtime

- [Phone runtime host](https://github.com/whoxamxl/aalyrics/blob/main/app/src/main/java/io/github/whoxamxl/aalyrics/PhoneRuntimeHost.kt): `app/src/main/java/io/github/whoxamxl/aalyrics/PhoneRuntimeHost.kt`
- [App composition](https://github.com/whoxamxl/aalyrics/blob/main/app/src/main/java/io/github/whoxamxl/aalyrics/AALyricsApplication.kt): `app/src/main/java/io/github/whoxamxl/aalyrics/AALyricsApplication.kt`
- [Lyrics demand gate](https://github.com/whoxamxl/aalyrics/blob/main/app/src/main/java/io/github/whoxamxl/aalyrics/LyricsDemandGate.kt): `app/src/main/java/io/github/whoxamxl/aalyrics/LyricsDemandGate.kt`
- [Translation runtime](https://github.com/whoxamxl/aalyrics/blob/main/app/src/main/java/io/github/whoxamxl/aalyrics/TranslationExecutionRuntime.kt): `app/src/main/java/io/github/whoxamxl/aalyrics/TranslationExecutionRuntime.kt`

### Playback integration

- [Media listener](https://github.com/whoxamxl/aalyrics/blob/main/platform/media/src/main/kotlin/io/github/whoxamxl/aalyrics/platform/media/MediaSessionListenerService.kt): `platform/media/src/main/kotlin/io/github/whoxamxl/aalyrics/platform/media/MediaSessionListenerService.kt`
- [Snapshot adapter](https://github.com/whoxamxl/aalyrics/blob/main/platform/media/src/main/kotlin/io/github/whoxamxl/aalyrics/platform/media/MediaControllerSnapshotAdapter.kt): `platform/media/src/main/kotlin/io/github/whoxamxl/aalyrics/platform/media/MediaControllerSnapshotAdapter.kt`

### Lyrics engine

- [Playback lyrics owner](https://github.com/whoxamxl/aalyrics/blob/main/core/lyrics/src/main/kotlin/io/github/whoxamxl/aalyrics/core/lyrics/PlaybackLyricsController.kt): `core/lyrics/src/main/kotlin/io/github/whoxamxl/aalyrics/core/lyrics/PlaybackLyricsController.kt`
- [Lyrics coordinator](https://github.com/whoxamxl/aalyrics/blob/main/core/lyrics/src/main/kotlin/io/github/whoxamxl/aalyrics/core/lyrics/LyricsCoordinator.kt): `core/lyrics/src/main/kotlin/io/github/whoxamxl/aalyrics/core/lyrics/LyricsCoordinator.kt`
- [Lookup lifecycle](https://github.com/whoxamxl/aalyrics/blob/main/core/lyrics/src/main/kotlin/io/github/whoxamxl/aalyrics/core/lyrics/LyricsLookupLifecycle.kt): `core/lyrics/src/main/kotlin/io/github/whoxamxl/aalyrics/core/lyrics/LyricsLookupLifecycle.kt`
- [Shared domain models](https://github.com/whoxamxl/aalyrics/blob/main/core/model/src/main/kotlin/io/github/whoxamxl/aalyrics/core/model/Playback.kt): `core/model/src/main/kotlin/io/github/whoxamxl/aalyrics/core/model/Playback.kt`

### Lyrics providers

- [Candidate selection](https://github.com/whoxamxl/aalyrics/blob/main/provider/selection/src/main/kotlin/io/github/whoxamxl/aalyrics/provider/selection/CrossProviderCandidateSelector.kt): `provider/selection/src/main/kotlin/io/github/whoxamxl/aalyrics/provider/selection/CrossProviderCandidateSelector.kt`
- [LRCLIB adapter](https://github.com/whoxamxl/aalyrics/blob/main/provider/lrclib/src/main/kotlin/io/github/whoxamxl/aalyrics/provider/lrclib/LrcLibProvider.kt): `provider/lrclib/src/main/kotlin/io/github/whoxamxl/aalyrics/provider/lrclib/LrcLibProvider.kt`
- [PetitLyrics adapter](https://github.com/whoxamxl/aalyrics/blob/main/provider/petitlyrics/src/main/kotlin/io/github/whoxamxl/aalyrics/provider/petitlyrics/PetitLyricsProvider.kt): `provider/petitlyrics/src/main/kotlin/io/github/whoxamxl/aalyrics/provider/petitlyrics/PetitLyricsProvider.kt`
- [Musixmatch adapter](https://github.com/whoxamxl/aalyrics/blob/main/provider/musixmatch/src/main/kotlin/io/github/whoxamxl/aalyrics/provider/musixmatch/MusixmatchProvider.kt): `provider/musixmatch/src/main/kotlin/io/github/whoxamxl/aalyrics/provider/musixmatch/MusixmatchProvider.kt`
- [SyncLRC adapter](https://github.com/whoxamxl/aalyrics/blob/main/provider/synclrc/src/main/kotlin/io/github/whoxamxl/aalyrics/provider/synclrc/SyncLrcProvider.kt): `provider/synclrc/src/main/kotlin/io/github/whoxamxl/aalyrics/provider/synclrc/SyncLrcProvider.kt`

### Presentation

- [Phone presentation](https://github.com/whoxamxl/aalyrics/blob/main/ui/phone/src/main/java/io/github/whoxamxl/aalyrics/ui/phone/lyrics/LyricsRoute.kt): `ui/phone/src/main/java/io/github/whoxamxl/aalyrics/ui/phone/lyrics/LyricsRoute.kt`
- [Auto browser service](https://github.com/whoxamxl/aalyrics/blob/main/ui/automotive/src/main/java/io/github/whoxamxl/aalyrics/ui/automotive/service/LyricsBrowserService.kt): `ui/automotive/src/main/java/io/github/whoxamxl/aalyrics/ui/automotive/service/LyricsBrowserService.kt`
- [Auto presentation](https://github.com/whoxamxl/aalyrics/blob/main/ui/automotive/src/main/java/io/github/whoxamxl/aalyrics/ui/automotive/screen/NowPlayingScreen.kt): `ui/automotive/src/main/java/io/github/whoxamxl/aalyrics/ui/automotive/screen/NowPlayingScreen.kt`

### Other components

- **Android media sessions**
- **Lyrics services**

## Connections

- Android media sessions → Media listener: notifies sessions
- Media listener → Snapshot adapter: observes playback
- Snapshot adapter → Shared domain models: normalizes state
- Phone runtime host → Playback lyrics owner: forwards playback
- App composition → Phone runtime host: composes runtime
- Lyrics demand gate → Playback lyrics owner: gates lookup
- Playback lyrics owner → Lookup lifecycle: starts lookup
- Lookup lifecycle → Lyrics coordinator: runs lookup
- Lyrics coordinator → LRCLIB adapter: queries provider
- Lyrics coordinator → PetitLyrics adapter: queries provider
- Lyrics coordinator → Musixmatch adapter: queries provider
- Lyrics coordinator → SyncLRC adapter: queries provider
- LRCLIB adapter → Lyrics services: requests lyrics
- PetitLyrics adapter → Lyrics services: requests lyrics
- Musixmatch adapter → Lyrics services: requests lyrics
- SyncLRC adapter → Lyrics services: requests lyrics
- Lyrics coordinator → Candidate selection: selects winner
- Lyrics coordinator → Shared domain models: produces lyrics state
- Phone runtime host → Phone presentation: exposes app state
- Phone runtime host → Auto browser service: exposes app state
- Auto browser service → Auto presentation: renders metadata
