How watermelon-music/watermelon-apk works
Purpose and runtime
Watermelon is a modular Android 8.0+ music-streaming client written in Kotlin. It uses Jetpack Compose for UI, Media3/ExoPlayer for playback, Coroutines/Flow for state, and Hilt for dependency injection. Gradle assembles a single application shell plus feature, domain, data, and core modules.
Paths: app/src/main/java/com/watermelon/app/WatermelonApplication.kt, app/build.gradle.kts, settings.gradle.kts
Application entry and UI composition
MainActivity is the Android/UI entry point. The app shell owns top-level navigation, bottom navigation, configuration/ads/updating hooks, and integrates independently built feature Compose screens. Routes are shared through core/navigation; features expose screen/ViewModel pairs and should not directly own remote or database plumbing.
Paths: app/src/main/java/com/watermelon/app/MainActivity.kt, app/src/main/java/com/watermelon/app/navigation/WatermelonNavHost.kt, core/navigation/src/main/java/com/watermelon/core/navigation/Routes.kt
Feature layer and state flow
Feature modules implement presentation workflows: home/discovery, search, library, playlists, downloads, auth, settings, and player. Compose observes ViewModel state; ViewModels invoke domain repository contracts, preserving unidirectional UI → ViewModel → repository → state flow. App-owned screens cover radio, profiles, premium, onboarding, and artists.
Paths: feature-home/src/main/java/com/watermelon/feature/home/HomeViewModel.kt, feature-search/src/main/java/com/watermelon/feature/search/SearchViewModel.kt, feature-player/src/main/java/com/watermelon/feature/player/PlayerViewModel.kt
Playback, queue, and autoplay boundary
Playback is process/service-oriented rather than tied to a screen: PlaybackService hosts media playback, while player UI dispatches commands and observes playback/queue state. QueueAwareForwardingPlayer customizes queue advancement. When queues exhaust, candidate fetching and the domain autoplay engine use listening signals, scoring, and transition tracking to select follow-on songs.
Paths: app/src/main/java/com/watermelon/app/PlaybackService.kt, feature-player/src/main/java/com/watermelon/feature/player/CandidateFetcher.kt, domain/src/main/java/com/watermelon/domain/autoplay/AutoplayEngine.kt
Domain contracts and business model
The domain module is the dependency boundary: it defines music, playlist, user, radio, download, and remote-config models plus repository interfaces. It also contains recommendation rules and a playback command abstraction, allowing presentation to depend on stable contracts rather than concrete APIs, Room, or extraction engines.
Paths: domain/src/main/java/com/watermelon/domain/model/Song.kt, domain/src/main/java/com/watermelon/domain/repository/MusicRepository.kt, domain/src/main/java/com/watermelon/domain/player/PlaybackCommandDispatcher.kt
Data integration and persistence
data implements domain contracts and wires sources through Hilt modules. Room persists cached songs/playlists, downloads, play history, skips, transitions, scoring, and user actions—supporting offline playback and local recommendation inputs. Repositories mediate cache/local state and remote responses.
Paths: data/src/main/java/com/watermelon/data/local/AppDatabase.kt, data/src/main/java/com/watermelon/data/repository/MusicRepositoryImpl.kt, data/src/main/java/com/watermelon/data/di/RepositoryModule.kt
External services and operational integrations
Network adapters use Retrofit/OkHttp for the companion Watermelon Node/Express API (search/audio extraction), YouTube/NewPipe extraction, Audius, Jamendo, Podcast Index, lyrics, and Radio Browser. Supabase provides auth and cloud social/playlist/profile data; SQL migrations define its expected schema. Payments support premium flows; Google services config and an in-app updater are app-level integrations.
Paths: data/src/main/java/com/watermelon/data/remote/watermelon/WatermelonApi.kt, data/src/main/java/com/watermelon/data/di/SupabaseModule.kt, supabase_setup.sql
Shared UX and release boundary
The design-system module centralizes Compose theme, responsive window sizing, animation, and reusable UI primitives. Release automation is GitHub Actions based; the Android app’s updater checks and installs newer APK releases.
Paths: core/designsystem/src/main/java/com/watermelon/core/designsystem/theme/Theme.kt, app/src/main/java/com/watermelon/app/updater/AppUpdater.kt, .github/workflows/release.yml
Main entry points: MusicRepositoryImpl.kt Repository implementations · WatermelonApplication.kt Watermelon application · MainActivity.kt Main activity & app shell · WatermelonNavHost.kt Navigation host
Components 19
Android app
- Gradle module assembly · Builds the app shell and modular feature layers.
settings.gradle.kts - Watermelon application · Initializes the Android process and dependency graph.
app/src/main/java/com/watermelon/app/WatermelonApplication.kt - Main activity & app shell · Hosts top-level navigation, bottom navigation, and app integrations.
app/src/main/java/com/watermelon/app/MainActivity.kt - Navigation host
app/src/main/java/com/watermelon/app/navigation/WatermelonNavHost.kt - Playback service · Process-oriented owner of media playback and queue state.
app/src/main/java/com/watermelon/app/PlaybackService.kt - APK updater · Checks and installs newer APK releases.
app/src/main/java/com/watermelon/app/updater/AppUpdater.kt
Presentation
- Shared routes
core/navigation/src/main/java/com/watermelon/core/navigation/Routes.kt - Feature screens · Home, search, library, playlists, downloads, auth, settings, and player workflows.
feature-home/src/main/java/com/watermelon/feature/home/HomeViewModel.kt - Feature ViewModels · Invoke repository contracts and expose Flow-backed UI state.
feature-search/src/main/java/com/watermelon/feature/search/SearchViewModel.kt - Player UI & commands · Dispatches playback commands and observes service state.
feature-player/src/main/java/com/watermelon/feature/player/PlayerViewModel.kt - Design system · Provides theme, responsive sizing, animation, and UI primitives.
core/designsystem/src/main/java/com/watermelon/core/designsystem/theme/Theme.kt
Domain
- Models & repository contracts · Stable music, playlist, user, radio, download, and config contracts.
domain/src/main/java/com/watermelon/domain/repository/MusicRepository.kt - Playback command contract
domain/src/main/java/com/watermelon/domain/player/PlaybackCommandDispatcher.kt - Autoplay engine · Scores listening signals and selects follow-on songs.
domain/src/main/java/com/watermelon/domain/autoplay/AutoplayEngine.kt
Data & integrations
- Repository implementations · Mediate remote responses, cache, and local state.
data/src/main/java/com/watermelon/data/repository/MusicRepositoryImpl.kt - Room cache & listening data · Stores offline media, playlists, history, skips, transitions, scores, and actions.
data/src/main/java/com/watermelon/data/local/AppDatabase.kt - Music service adapters · Connects Watermelon API, extractors, catalogs, lyrics, podcasts, and radio.
data/src/main/java/com/watermelon/data/remote/watermelon/WatermelonApi.kt - Supabase cloud data · Provides authentication and cloud profiles, social data, and playlists.
data/src/main/java/com/watermelon/data/di/SupabaseModule.kt
Platform & delivery
- Release automation · Publishes APK releases consumed by the updater.
.github/workflows/release.yml
Connections 19
- Gradle module assembly → Watermelon application: assembles
- Watermelon application → Main activity & app shell: starts
- Main activity & app shell → Navigation host: hosts
- Navigation host → Shared routes: uses
- Navigation host → Feature screens: navigates to
- Feature screens → Feature ViewModels: observes state from
- Feature screens → Design system: renders with
- Feature ViewModels → Models & repository contracts: depends on
- Player UI & commands → Playback command contract: dispatches
- Player UI & commands → Playback service: observes and controls
- Playback service → Autoplay engine: requests next song
- Autoplay engine → Repository implementations: uses listening inputs
- Repository implementations → Models & repository contracts: implements
- Repository implementations → Room cache & listening data: reads and writes
- Repository implementations → Music service adapters: fetches catalog and audio
- Repository implementations → Supabase cloud data: syncs auth and cloud data
- Watermelon application → Repository implementations: Hilt wires
- Main activity & app shell → APK updater: integrates
- APK updater → Release automation: checks releases