cf52bb854e42f4511be1c96a18f3dd22d2215854
Builds the single MediaSession-backed player that in-app playback, offline downloads (Phase 5), and Android Auto (Phase 6) will all share, per the Phase 2+ roadmap's Phase 4. - DeepwavePlaybackService: ExoPlayer + MediaLibrarySession, built as a MediaLibraryService from day one (not the plainer MediaSessionService) so Android Auto only has to add browse-tree content later, never rebuild the service. Browse tree is a stub for now (MediaLibrarySession.Callback's defaults deny browsing). - LocalOrRemoteDataSource: the entire "prefer a downloaded file over streaming" mechanism as a ResolvingDataSource.Resolver, backed by an in-memory LocalTrackFiles registry that stays empty until Phase 5 populates it from Room - reused unmodified by Android Auto later. - ExoPlayer's OkHttpDataSource shares the same signed OkHttpClient as Retrofit/Coil, so SubsonicRequestInterceptor signs stream requests identically to every other Subsonic call - streamUrl() builds the request URL the same way coverArtUrl() does for Coil. - PlaybackController: app-facing facade over a MediaController, exposing Flow<PlaybackUiState> - same facade convention as ServerRepository. NowPlayingScreen (new, full-screen: artwork, seek bar, play/pause/skip) and MiniPlayerBar (now real, replacing Phase 2/3's static placeholder) both consume it. - Track clicks in AlbumDetailScreen (queues the whole album from the clicked index) and SearchScreen (single-song queue) now actually play, via PlaybackController injected into their ViewModels. - Scrobbling: submission=false when a track starts, submission=true for the outgoing track on each transition - a simplified heuristic rather than a played-percentage threshold, feeding Navidrome's play-count data that Phase 3's getAlbumList2(frequent/recent) rows read from. - Runtime POST_NOTIFICATIONS request added to MainActivity for API 33+ (declared in the manifest but easy to forget the runtime half of - without it the service still plays, but its notification never shows). Split MainScreen into a thin PlayerViewModel-resolving wrapper plus a previewable MainContent, rather than having MainScreen call hiltViewModel() directly - preserves the interactive Android Studio preview from last session, which a direct Hilt dependency would have broken. media3 pinned to 1.11.1 (built against Kotlin 2.2.0, matching this project's 2.2.10 - learned from Phase 3's Coil version conflict to check this before picking a version this time). Verified extensively on-device against the real Navidrome server: real tracks play with correct metadata/artwork, pause/resume and queue auto-advance work, the real Android MediaSession exposes correct state (checked independently via `dumpsys media_session`, not just the app's own UI), background playback survives foregrounding/backgrounding, and no crashes across the whole session. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Description
Deepwave is a navidrome client for android
322 KiB
Languages
Kotlin
100%