all: cleanup
This commit is contained in:
parent
924e3d1801
commit
f0dda6c43e
9 changed files with 134 additions and 242 deletions
|
@ -36,7 +36,8 @@ import org.oxycblt.auxio.music.service.MusicServiceFragment
|
||||||
import org.oxycblt.auxio.playback.service.PlaybackServiceFragment
|
import org.oxycblt.auxio.playback.service.PlaybackServiceFragment
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class AuxioService : MediaBrowserServiceCompat(), ForegroundListener, MusicServiceFragment.Invalidator {
|
class AuxioService :
|
||||||
|
MediaBrowserServiceCompat(), ForegroundListener, MusicServiceFragment.Invalidator {
|
||||||
@Inject lateinit var playbackFragment: PlaybackServiceFragment
|
@Inject lateinit var playbackFragment: PlaybackServiceFragment
|
||||||
|
|
||||||
@Inject lateinit var musicFragment: MusicServiceFragment
|
@Inject lateinit var musicFragment: MusicServiceFragment
|
||||||
|
@ -88,10 +89,8 @@ class AuxioService : MediaBrowserServiceCompat(), ForegroundListener, MusicServi
|
||||||
musicFragment.getItem(itemId, result)
|
musicFragment.getItem(itemId, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onLoadChildren(
|
override fun onLoadChildren(parentId: String, result: Result<MutableList<MediaItem>>) =
|
||||||
parentId: String,
|
throw NotImplementedError()
|
||||||
result: Result<MutableList<MediaItem>>
|
|
||||||
) = throw NotImplementedError()
|
|
||||||
|
|
||||||
override fun onLoadChildren(
|
override fun onLoadChildren(
|
||||||
parentId: String,
|
parentId: String,
|
||||||
|
@ -99,12 +98,7 @@ class AuxioService : MediaBrowserServiceCompat(), ForegroundListener, MusicServi
|
||||||
options: Bundle
|
options: Bundle
|
||||||
) = musicFragment.getChildren(parentId, result)
|
) = musicFragment.getChildren(parentId, result)
|
||||||
|
|
||||||
|
override fun onSearch(query: String, extras: Bundle?, result: Result<MutableList<MediaItem>>) {
|
||||||
override fun onSearch(
|
|
||||||
query: String,
|
|
||||||
extras: Bundle?,
|
|
||||||
result: Result<MutableList<MediaItem>>
|
|
||||||
) {
|
|
||||||
musicFragment.search(query, result)
|
musicFragment.search(query, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Auxio Project
|
* Copyright (c) 2024 Auxio Project
|
||||||
* IndexerServiceFragment.kt is part of Auxio.
|
* Indexer.kt is part of Auxio.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -28,7 +28,6 @@ import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import org.oxycblt.auxio.BuildConfig
|
import org.oxycblt.auxio.BuildConfig
|
||||||
import org.oxycblt.auxio.ForegroundListener
|
import org.oxycblt.auxio.ForegroundListener
|
||||||
import org.oxycblt.auxio.ForegroundServiceNotification
|
|
||||||
import org.oxycblt.auxio.music.IndexingState
|
import org.oxycblt.auxio.music.IndexingState
|
||||||
import org.oxycblt.auxio.music.MusicRepository
|
import org.oxycblt.auxio.music.MusicRepository
|
||||||
import org.oxycblt.auxio.music.MusicSettings
|
import org.oxycblt.auxio.music.MusicSettings
|
||||||
|
|
|
@ -78,7 +78,8 @@ sealed interface MediaSessionUID {
|
||||||
}
|
}
|
||||||
return when (parts[0]) {
|
return when (parts[0]) {
|
||||||
ID_CATEGORY ->
|
ID_CATEGORY ->
|
||||||
CategoryItem(when (parts[1]) {
|
CategoryItem(
|
||||||
|
when (parts[1]) {
|
||||||
Category.ROOT.id -> Category.ROOT
|
Category.ROOT.id -> Category.ROOT
|
||||||
Category.MORE.id -> Category.MORE
|
Category.MORE.id -> Category.MORE
|
||||||
Category.SONGS.id -> Category.SONGS
|
Category.SONGS.id -> Category.SONGS
|
||||||
|
@ -107,7 +108,8 @@ sealed interface MediaSessionUID {
|
||||||
typealias Sugar = Bundle.(Context) -> Unit
|
typealias Sugar = Bundle.(Context) -> Unit
|
||||||
|
|
||||||
fun header(@StringRes nameRes: Int): Sugar = {
|
fun header(@StringRes nameRes: Int): Sugar = {
|
||||||
putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, it.getString(nameRes))
|
putString(
|
||||||
|
MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, it.getString(nameRes))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Category.toMediaItem(context: Context): MediaItem {
|
fun Category.toMediaItem(context: Context): MediaItem {
|
||||||
|
@ -119,7 +121,8 @@ fun Category.toMediaItem(context: Context): MediaItem {
|
||||||
MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_LIST_ITEM)
|
MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_LIST_ITEM)
|
||||||
}
|
}
|
||||||
val mediaSessionUID = MediaSessionUID.CategoryItem(this)
|
val mediaSessionUID = MediaSessionUID.CategoryItem(this)
|
||||||
val description = MediaDescriptionCompat.Builder()
|
val description =
|
||||||
|
MediaDescriptionCompat.Builder()
|
||||||
.setMediaId(mediaSessionUID.toString())
|
.setMediaId(mediaSessionUID.toString())
|
||||||
.setTitle(context.getString(nameRes))
|
.setTitle(context.getString(nameRes))
|
||||||
.setExtras(extras)
|
.setExtras(extras)
|
||||||
|
@ -130,7 +133,11 @@ fun Category.toMediaItem(context: Context): MediaItem {
|
||||||
return MediaItem(description.build(), MediaItem.FLAG_BROWSABLE)
|
return MediaItem(description.build(), MediaItem.FLAG_BROWSABLE)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Song.toMediaItem(context: Context, parent: MusicParent? = null, vararg sugar: Sugar): MediaItem {
|
fun Song.toMediaItem(
|
||||||
|
context: Context,
|
||||||
|
parent: MusicParent? = null,
|
||||||
|
vararg sugar: Sugar
|
||||||
|
): MediaItem {
|
||||||
val mediaSessionUID =
|
val mediaSessionUID =
|
||||||
if (parent == null) {
|
if (parent == null) {
|
||||||
MediaSessionUID.SingleItem(uid)
|
MediaSessionUID.SingleItem(uid)
|
||||||
|
@ -138,7 +145,8 @@ fun Song.toMediaItem(context: Context, parent: MusicParent? = null, vararg sugar
|
||||||
MediaSessionUID.ChildItem(parent.uid, uid)
|
MediaSessionUID.ChildItem(parent.uid, uid)
|
||||||
}
|
}
|
||||||
val extras = Bundle().apply { sugar.forEach { this.it(context) } }
|
val extras = Bundle().apply { sugar.forEach { this.it(context) } }
|
||||||
val description = MediaDescriptionCompat.Builder()
|
val description =
|
||||||
|
MediaDescriptionCompat.Builder()
|
||||||
.setMediaId(mediaSessionUID.toString())
|
.setMediaId(mediaSessionUID.toString())
|
||||||
.setTitle(name.resolve(context))
|
.setTitle(name.resolve(context))
|
||||||
.setSubtitle(artists.resolveNames(context))
|
.setSubtitle(artists.resolveNames(context))
|
||||||
|
@ -150,14 +158,19 @@ fun Song.toMediaItem(context: Context, parent: MusicParent? = null, vararg sugar
|
||||||
return MediaItem(description, MediaItem.FLAG_PLAYABLE)
|
return MediaItem(description, MediaItem.FLAG_PLAYABLE)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Album.toMediaItem(context: Context, parent: MusicParent? = null, vararg sugar: Sugar): MediaItem {
|
fun Album.toMediaItem(
|
||||||
|
context: Context,
|
||||||
|
parent: MusicParent? = null,
|
||||||
|
vararg sugar: Sugar
|
||||||
|
): MediaItem {
|
||||||
val mediaSessionUID =
|
val mediaSessionUID =
|
||||||
if (parent == null) {
|
if (parent == null) {
|
||||||
MediaSessionUID.SingleItem(uid)
|
MediaSessionUID.SingleItem(uid)
|
||||||
} else {
|
} else {
|
||||||
MediaSessionUID.ChildItem(parent.uid, uid)
|
MediaSessionUID.ChildItem(parent.uid, uid)
|
||||||
}
|
}
|
||||||
val description = MediaDescriptionCompat.Builder()
|
val description =
|
||||||
|
MediaDescriptionCompat.Builder()
|
||||||
.setMediaId(mediaSessionUID.toString())
|
.setMediaId(mediaSessionUID.toString())
|
||||||
.setTitle(name.resolve(context))
|
.setTitle(name.resolve(context))
|
||||||
.setSubtitle(artists.resolveNames(context))
|
.setSubtitle(artists.resolveNames(context))
|
||||||
|
@ -181,7 +194,8 @@ fun Artist.toMediaItem(context: Context, vararg sugar: Sugar): MediaItem {
|
||||||
} else {
|
} else {
|
||||||
context.getString(R.string.def_song_count)
|
context.getString(R.string.def_song_count)
|
||||||
})
|
})
|
||||||
val description = MediaDescriptionCompat.Builder()
|
val description =
|
||||||
|
MediaDescriptionCompat.Builder()
|
||||||
.setMediaId(mediaSessionUID.toString())
|
.setMediaId(mediaSessionUID.toString())
|
||||||
.setTitle(name.resolve(context))
|
.setTitle(name.resolve(context))
|
||||||
.setSubtitle(counts)
|
.setSubtitle(counts)
|
||||||
|
@ -198,7 +212,8 @@ fun Genre.toMediaItem(context: Context, vararg sugar: Sugar): MediaItem {
|
||||||
} else {
|
} else {
|
||||||
context.getString(R.string.def_song_count)
|
context.getString(R.string.def_song_count)
|
||||||
}
|
}
|
||||||
val description = MediaDescriptionCompat.Builder()
|
val description =
|
||||||
|
MediaDescriptionCompat.Builder()
|
||||||
.setMediaId(mediaSessionUID.toString())
|
.setMediaId(mediaSessionUID.toString())
|
||||||
.setTitle(name.resolve(context))
|
.setTitle(name.resolve(context))
|
||||||
.setSubtitle(counts)
|
.setSubtitle(counts)
|
||||||
|
@ -215,7 +230,8 @@ fun Playlist.toMediaItem(context: Context, vararg sugar: Sugar): MediaItem {
|
||||||
} else {
|
} else {
|
||||||
context.getString(R.string.def_song_count)
|
context.getString(R.string.def_song_count)
|
||||||
}
|
}
|
||||||
val description = MediaDescriptionCompat.Builder()
|
val description =
|
||||||
|
MediaDescriptionCompat.Builder()
|
||||||
.setMediaId(mediaSessionUID.toString())
|
.setMediaId(mediaSessionUID.toString())
|
||||||
.setTitle(name.resolve(context))
|
.setTitle(name.resolve(context))
|
||||||
.setSubtitle(counts)
|
.setSubtitle(counts)
|
||||||
|
|
|
@ -19,16 +19,9 @@
|
||||||
package org.oxycblt.auxio.music.service
|
package org.oxycblt.auxio.music.service
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Bundle
|
|
||||||
import android.support.v4.media.MediaBrowserCompat.MediaItem
|
import android.support.v4.media.MediaBrowserCompat.MediaItem
|
||||||
import androidx.annotation.StringRes
|
|
||||||
import androidx.media.utils.MediaConstants
|
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import javax.inject.Inject
|
||||||
import kotlinx.coroutines.Deferred
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import kotlinx.coroutines.async
|
|
||||||
import org.oxycblt.auxio.R
|
import org.oxycblt.auxio.R
|
||||||
import org.oxycblt.auxio.list.ListSettings
|
import org.oxycblt.auxio.list.ListSettings
|
||||||
import org.oxycblt.auxio.list.sort.Sort
|
import org.oxycblt.auxio.list.sort.Sort
|
||||||
|
@ -41,9 +34,6 @@ import org.oxycblt.auxio.music.Playlist
|
||||||
import org.oxycblt.auxio.music.Song
|
import org.oxycblt.auxio.music.Song
|
||||||
import org.oxycblt.auxio.music.device.DeviceLibrary
|
import org.oxycblt.auxio.music.device.DeviceLibrary
|
||||||
import org.oxycblt.auxio.music.user.UserLibrary
|
import org.oxycblt.auxio.music.user.UserLibrary
|
||||||
import org.oxycblt.auxio.search.SearchEngine
|
|
||||||
import javax.inject.Inject
|
|
||||||
import kotlin.math.min
|
|
||||||
|
|
||||||
class MusicBrowser
|
class MusicBrowser
|
||||||
@Inject
|
@Inject
|
||||||
|
@ -112,10 +102,8 @@ constructor(
|
||||||
is MediaSessionUID.CategoryItem -> return uid.category.toMediaItem(context)
|
is MediaSessionUID.CategoryItem -> return uid.category.toMediaItem(context)
|
||||||
is MediaSessionUID.SingleItem ->
|
is MediaSessionUID.SingleItem ->
|
||||||
musicRepository.find(uid.uid)?.let { musicRepository.find(it.uid) }
|
musicRepository.find(uid.uid)?.let { musicRepository.find(it.uid) }
|
||||||
|
|
||||||
is MediaSessionUID.ChildItem ->
|
is MediaSessionUID.ChildItem ->
|
||||||
musicRepository.find(uid.childUid)?.let { musicRepository.find(it.uid) }
|
musicRepository.find(uid.childUid)?.let { musicRepository.find(it.uid) }
|
||||||
|
|
||||||
null -> null
|
null -> null
|
||||||
}
|
}
|
||||||
?: return null
|
?: return null
|
||||||
|
@ -147,44 +135,33 @@ constructor(
|
||||||
return when (val mediaSessionUID = MediaSessionUID.fromString(id)) {
|
return when (val mediaSessionUID = MediaSessionUID.fromString(id)) {
|
||||||
is MediaSessionUID.CategoryItem -> {
|
is MediaSessionUID.CategoryItem -> {
|
||||||
when (mediaSessionUID.category) {
|
when (mediaSessionUID.category) {
|
||||||
Category.ROOT ->
|
Category.ROOT -> Category.IMPORTANT.map { it.toMediaItem(context) }
|
||||||
Category.IMPORTANT.map { it.toMediaItem(context) }
|
|
||||||
|
|
||||||
Category.MORE -> TODO()
|
Category.MORE -> TODO()
|
||||||
|
|
||||||
Category.SONGS ->
|
Category.SONGS ->
|
||||||
listSettings.songSort.songs(deviceLibrary.songs).map {
|
listSettings.songSort.songs(deviceLibrary.songs).map {
|
||||||
it.toMediaItem(context, null)
|
it.toMediaItem(context, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
Category.ALBUMS ->
|
Category.ALBUMS ->
|
||||||
listSettings.albumSort.albums(deviceLibrary.albums).map {
|
listSettings.albumSort.albums(deviceLibrary.albums).map {
|
||||||
it.toMediaItem(context)
|
it.toMediaItem(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
Category.ARTISTS ->
|
Category.ARTISTS ->
|
||||||
listSettings.artistSort.artists(deviceLibrary.artists).map {
|
listSettings.artistSort.artists(deviceLibrary.artists).map {
|
||||||
it.toMediaItem(context)
|
it.toMediaItem(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
Category.GENRES ->
|
Category.GENRES ->
|
||||||
listSettings.genreSort.genres(deviceLibrary.genres).map {
|
listSettings.genreSort.genres(deviceLibrary.genres).map {
|
||||||
it.toMediaItem(context)
|
it.toMediaItem(context)
|
||||||
}
|
}
|
||||||
|
Category.PLAYLISTS -> userLibrary.playlists.map { it.toMediaItem(context) }
|
||||||
Category.PLAYLISTS ->
|
|
||||||
userLibrary.playlists.map { it.toMediaItem(context) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is MediaSessionUID.SingleItem -> {
|
is MediaSessionUID.SingleItem -> {
|
||||||
getChildMediaItems(mediaSessionUID.uid)
|
getChildMediaItems(mediaSessionUID.uid)
|
||||||
}
|
}
|
||||||
|
|
||||||
is MediaSessionUID.ChildItem -> {
|
is MediaSessionUID.ChildItem -> {
|
||||||
getChildMediaItems(mediaSessionUID.childUid)
|
getChildMediaItems(mediaSessionUID.childUid)
|
||||||
}
|
}
|
||||||
|
|
||||||
null -> {
|
null -> {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -195,118 +172,28 @@ constructor(
|
||||||
return when (val item = musicRepository.find(uid)) {
|
return when (val item = musicRepository.find(uid)) {
|
||||||
is Album -> {
|
is Album -> {
|
||||||
val songs = listSettings.albumSongSort.songs(item.songs)
|
val songs = listSettings.albumSongSort.songs(item.songs)
|
||||||
songs.map { it.toMediaItem(context, item, header(R.string.lbl_songs))}
|
songs.map { it.toMediaItem(context, item, header(R.string.lbl_songs)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
is Artist -> {
|
is Artist -> {
|
||||||
val albums = ARTIST_ALBUMS_SORT.albums(item.explicitAlbums + item.implicitAlbums)
|
val albums = ARTIST_ALBUMS_SORT.albums(item.explicitAlbums + item.implicitAlbums)
|
||||||
val songs = listSettings.artistSongSort.songs(item.songs)
|
val songs = listSettings.artistSongSort.songs(item.songs)
|
||||||
albums.map { it.toMediaItem(context, null, header(R.string.lbl_songs)) } +
|
albums.map { it.toMediaItem(context, null, header(R.string.lbl_songs)) } +
|
||||||
songs.map { it.toMediaItem(context, item, header(R.string.lbl_songs)) }
|
songs.map { it.toMediaItem(context, item, header(R.string.lbl_songs)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
is Genre -> {
|
is Genre -> {
|
||||||
val artists = GENRE_ARTISTS_SORT.artists(item.artists)
|
val artists = GENRE_ARTISTS_SORT.artists(item.artists)
|
||||||
val songs = listSettings.genreSongSort.songs(item.songs)
|
val songs = listSettings.genreSongSort.songs(item.songs)
|
||||||
artists.map { it.toMediaItem(context, header(R.string.lbl_songs)) } +
|
artists.map { it.toMediaItem(context, header(R.string.lbl_songs)) } +
|
||||||
songs.map { it.toMediaItem(context, null, header(R.string.lbl_songs)) }
|
songs.map { it.toMediaItem(context, null, header(R.string.lbl_songs)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
is Playlist -> {
|
is Playlist -> {
|
||||||
item.songs.map { it.toMediaItem(context, null, header(R.string.lbl_songs)) }
|
item.songs.map { it.toMediaItem(context, null, header(R.string.lbl_songs)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
is Song,
|
is Song,
|
||||||
null -> return null
|
null -> return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// suspend fun prepareSearch(query: String, controller: String) {
|
|
||||||
// searchSubscribers[controller] = query
|
|
||||||
// val existing = searchResults[query]
|
|
||||||
// if (existing == null) {
|
|
||||||
// val new = searchTo(query)
|
|
||||||
// searchResults[query] = new
|
|
||||||
// new.await()
|
|
||||||
// } else {
|
|
||||||
// val items = existing.await()
|
|
||||||
// invalidator?.invalidate(controller, query, items.count())
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// suspend fun getSearchResult(
|
|
||||||
// query: String,
|
|
||||||
// page: Int,
|
|
||||||
// pageSize: Int,
|
|
||||||
// ): List<MediaItem>? {
|
|
||||||
// val deferred = searchResults[query] ?: searchTo(query).also { searchResults[query] = it }
|
|
||||||
// return deferred.await().concat().paginate(page, pageSize)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private fun SearchEngine.Items.concat(): MutableList<MediaItem> {
|
|
||||||
// val music = mutableListOf<MediaItem>()
|
|
||||||
// if (songs != null) {
|
|
||||||
// music.addAll(songs.map { it.toMediaItem(context, null) })
|
|
||||||
// }
|
|
||||||
// if (albums != null) {
|
|
||||||
// music.addAll(albums.map { it.toMediaItem(context) })
|
|
||||||
// }
|
|
||||||
// if (artists != null) {
|
|
||||||
// music.addAll(artists.map { it.toMediaItem(context) })
|
|
||||||
// }
|
|
||||||
// if (genres != null) {
|
|
||||||
// music.addAll(genres.map { it.toMediaItem(context) })
|
|
||||||
// }
|
|
||||||
// if (playlists != null) {
|
|
||||||
// music.addAll(playlists.map { it.toMediaItem(context) })
|
|
||||||
// }
|
|
||||||
// return music
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private fun SearchEngine.Items.count(): Int {
|
|
||||||
// var count = 0
|
|
||||||
// if (songs != null) {
|
|
||||||
// count += songs.size
|
|
||||||
// }
|
|
||||||
// if (albums != null) {
|
|
||||||
// count += albums.size
|
|
||||||
// }
|
|
||||||
// if (artists != null) {
|
|
||||||
// count += artists.size
|
|
||||||
// }
|
|
||||||
// if (genres != null) {
|
|
||||||
// count += genres.size
|
|
||||||
// }
|
|
||||||
// if (playlists != null) {
|
|
||||||
// count += playlists.size
|
|
||||||
// }
|
|
||||||
// return count
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private fun searchTo(query: String) =
|
|
||||||
// searchScope.async {
|
|
||||||
// if (query.isEmpty()) {
|
|
||||||
// return@async SearchEngine.Items()
|
|
||||||
// }
|
|
||||||
// val deviceLibrary = musicRepository.deviceLibrary ?: return@async SearchEngine.Items()
|
|
||||||
// val userLibrary = musicRepository.userLibrary ?: return@async SearchEngine.Items()
|
|
||||||
// val items =
|
|
||||||
// SearchEngine.Items(
|
|
||||||
// deviceLibrary.songs,
|
|
||||||
// deviceLibrary.albums,
|
|
||||||
// deviceLibrary.artists,
|
|
||||||
// deviceLibrary.genres,
|
|
||||||
// userLibrary.playlists
|
|
||||||
// )
|
|
||||||
// val results = searchEngine.search(items, query)
|
|
||||||
// for (entry in searchSubscribers.entries) {
|
|
||||||
// if (entry.value == query) {
|
|
||||||
// invalidator?.invalidate(entry.key, query, results.count())
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// results
|
|
||||||
// }
|
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
// TODO: Rely on detail item gen logic?
|
// TODO: Rely on detail item gen logic?
|
||||||
val ARTIST_ALBUMS_SORT = Sort(Sort.Mode.ByDate, Sort.Direction.DESCENDING)
|
val ARTIST_ALBUMS_SORT = Sort(Sort.Mode.ByDate, Sort.Direction.DESCENDING)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Auxio Project
|
* Copyright (c) 2024 Auxio Project
|
||||||
* IndexerServiceFragment.kt is part of Auxio.
|
* MusicServiceFragment.kt is part of Auxio.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -23,6 +23,7 @@ import android.support.v4.media.MediaBrowserCompat.MediaItem
|
||||||
import androidx.media.MediaBrowserServiceCompat
|
import androidx.media.MediaBrowserServiceCompat
|
||||||
import androidx.media.MediaBrowserServiceCompat.BrowserRoot
|
import androidx.media.MediaBrowserServiceCompat.BrowserRoot
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
import javax.inject.Inject
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
|
@ -35,7 +36,6 @@ import org.oxycblt.auxio.music.MusicSettings
|
||||||
import org.oxycblt.auxio.search.SearchEngine
|
import org.oxycblt.auxio.search.SearchEngine
|
||||||
import org.oxycblt.auxio.util.logD
|
import org.oxycblt.auxio.util.logD
|
||||||
import org.oxycblt.auxio.util.logW
|
import org.oxycblt.auxio.util.logW
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
class MusicServiceFragment
|
class MusicServiceFragment
|
||||||
@Inject
|
@Inject
|
||||||
|
@ -76,7 +76,6 @@ constructor(
|
||||||
invalidator = null
|
invalidator = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun invalidateMusic(ids: Set<String>) {
|
override fun invalidateMusic(ids: Set<String>) {
|
||||||
ids.forEach { mediaId ->
|
ids.forEach { mediaId ->
|
||||||
requireNotNull(invalidator) { "Invalidator not available" }.invalidateMusic(mediaId)
|
requireNotNull(invalidator) { "Invalidator not available" }.invalidateMusic(mediaId)
|
||||||
|
@ -131,8 +130,7 @@ constructor(
|
||||||
fun getChildren(
|
fun getChildren(
|
||||||
mediaId: String,
|
mediaId: String,
|
||||||
result: MediaBrowserServiceCompat.Result<MutableList<MediaItem>>
|
result: MediaBrowserServiceCompat.Result<MutableList<MediaItem>>
|
||||||
) =
|
) = result.dispatch { musicBrowser.getChildren(mediaId)?.toMutableList() }
|
||||||
result.dispatch { musicBrowser.getChildren(mediaId)?.toMutableList() }
|
|
||||||
|
|
||||||
fun search(query: String, result: MediaBrowserServiceCompat.Result<MutableList<MediaItem>>) =
|
fun search(query: String, result: MediaBrowserServiceCompat.Result<MutableList<MediaItem>>) =
|
||||||
result.dispatchAsync {
|
result.dispatchAsync {
|
||||||
|
@ -148,12 +146,10 @@ constructor(
|
||||||
deviceLibrary.albums,
|
deviceLibrary.albums,
|
||||||
deviceLibrary.artists,
|
deviceLibrary.artists,
|
||||||
deviceLibrary.genres,
|
deviceLibrary.genres,
|
||||||
userLibrary.playlists
|
userLibrary.playlists)
|
||||||
)
|
|
||||||
searchEngine.search(items, query).concat()
|
searchEngine.search(items, query).concat()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun SearchEngine.Items.concat(): MutableList<MediaItem> {
|
private fun SearchEngine.Items.concat(): MutableList<MediaItem> {
|
||||||
val music = mutableListOf<MediaItem>()
|
val music = mutableListOf<MediaItem>()
|
||||||
if (songs != null) {
|
if (songs != null) {
|
||||||
|
|
|
@ -46,7 +46,6 @@ import org.oxycblt.auxio.image.ImageSettings
|
||||||
import org.oxycblt.auxio.music.MusicParent
|
import org.oxycblt.auxio.music.MusicParent
|
||||||
import org.oxycblt.auxio.music.MusicRepository
|
import org.oxycblt.auxio.music.MusicRepository
|
||||||
import org.oxycblt.auxio.music.Song
|
import org.oxycblt.auxio.music.Song
|
||||||
import org.oxycblt.auxio.music.service.toMediaItem
|
|
||||||
import org.oxycblt.auxio.playback.PlaybackSettings
|
import org.oxycblt.auxio.playback.PlaybackSettings
|
||||||
import org.oxycblt.auxio.playback.persist.PersistenceRepository
|
import org.oxycblt.auxio.playback.persist.PersistenceRepository
|
||||||
import org.oxycblt.auxio.playback.replaygain.ReplayGainAudioProcessor
|
import org.oxycblt.auxio.playback.replaygain.ReplayGainAudioProcessor
|
||||||
|
@ -141,10 +140,7 @@ class ExoPlaybackStateHolder(
|
||||||
} else {
|
} else {
|
||||||
emptyList()
|
emptyList()
|
||||||
}
|
}
|
||||||
return RawQueue(
|
return RawQueue(heap.mapNotNull { it.song }, shuffledMapping, player.currentMediaItemIndex)
|
||||||
heap.mapNotNull { it.song },
|
|
||||||
shuffledMapping,
|
|
||||||
player.currentMediaItemIndex)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleDeferred(action: DeferredPlayback): Boolean {
|
override fun handleDeferred(action: DeferredPlayback): Boolean {
|
||||||
|
@ -533,12 +529,10 @@ class ExoPlaybackStateHolder(
|
||||||
currentSaveJob = saveScope.launch { block() }
|
currentSaveJob = saveScope.launch { block() }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Song.buildMediaItem() = MediaItem.Builder()
|
private fun Song.buildMediaItem() = MediaItem.Builder().setUri(uri).setTag(this).build()
|
||||||
.setUri(uri)
|
|
||||||
.setTag(this)
|
|
||||||
.build()
|
|
||||||
|
|
||||||
private val MediaItem.song: Song? get() = this.localConfiguration?.tag as? Song?
|
private val MediaItem.song: Song?
|
||||||
|
get() = this.localConfiguration?.tag as? Song?
|
||||||
|
|
||||||
private fun Player.unscrambleQueueIndices(): List<Int> {
|
private fun Player.unscrambleQueueIndices(): List<Int> {
|
||||||
val timeline = currentTimeline
|
val timeline = currentTimeline
|
||||||
|
|
|
@ -95,7 +95,13 @@ private constructor(
|
||||||
) {
|
) {
|
||||||
fun create(context: Context) =
|
fun create(context: Context) =
|
||||||
MediaSessionHolder(
|
MediaSessionHolder(
|
||||||
context, playbackManager, playbackSettings, commandFactory, musicRepository, bitmapProvider, imageSettings)
|
context,
|
||||||
|
playbackManager,
|
||||||
|
playbackSettings,
|
||||||
|
commandFactory,
|
||||||
|
musicRepository,
|
||||||
|
bitmapProvider,
|
||||||
|
imageSettings)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val mediaSession =
|
private val mediaSession =
|
||||||
|
@ -234,11 +240,13 @@ private constructor(
|
||||||
super.onAddQueueItem(description)
|
super.onAddQueueItem(description)
|
||||||
val deviceLibrary = musicRepository.deviceLibrary ?: return
|
val deviceLibrary = musicRepository.deviceLibrary ?: return
|
||||||
val uid = MediaSessionUID.fromString(description.mediaId ?: return) ?: return
|
val uid = MediaSessionUID.fromString(description.mediaId ?: return) ?: return
|
||||||
val song = when (uid) {
|
val song =
|
||||||
|
when (uid) {
|
||||||
is MediaSessionUID.SingleItem -> deviceLibrary.findSong(uid.uid)
|
is MediaSessionUID.SingleItem -> deviceLibrary.findSong(uid.uid)
|
||||||
is MediaSessionUID.ChildItem -> deviceLibrary.findSong(uid.childUid)
|
is MediaSessionUID.ChildItem -> deviceLibrary.findSong(uid.childUid)
|
||||||
else -> null
|
else -> null
|
||||||
} ?: return
|
}
|
||||||
|
?: return
|
||||||
playbackManager.addToQueue(song)
|
playbackManager.addToQueue(song)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,11 +254,13 @@ private constructor(
|
||||||
super.onRemoveQueueItem(description)
|
super.onRemoveQueueItem(description)
|
||||||
val deviceLibrary = musicRepository.deviceLibrary ?: return
|
val deviceLibrary = musicRepository.deviceLibrary ?: return
|
||||||
val uid = MediaSessionUID.fromString(description.mediaId ?: return) ?: return
|
val uid = MediaSessionUID.fromString(description.mediaId ?: return) ?: return
|
||||||
val song = when (uid) {
|
val song =
|
||||||
|
when (uid) {
|
||||||
is MediaSessionUID.SingleItem -> deviceLibrary.findSong(uid.uid)
|
is MediaSessionUID.SingleItem -> deviceLibrary.findSong(uid.uid)
|
||||||
is MediaSessionUID.ChildItem -> deviceLibrary.findSong(uid.childUid)
|
is MediaSessionUID.ChildItem -> deviceLibrary.findSong(uid.childUid)
|
||||||
else -> null
|
else -> null
|
||||||
} ?: return
|
}
|
||||||
|
?: return
|
||||||
val queueIndex = playbackManager.queue.indexOf(song)
|
val queueIndex = playbackManager.queue.indexOf(song)
|
||||||
if (queueIndex > -1) {
|
if (queueIndex > -1) {
|
||||||
playbackManager.removeQueueItem(queueIndex)
|
playbackManager.removeQueueItem(queueIndex)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Auxio Project
|
* Copyright (c) 2024 Auxio Project
|
||||||
* MediaSessionServiceFragment.kt is part of Auxio.
|
* PlaybackServiceFragment.kt is part of Auxio.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -109,8 +109,6 @@ constructor(
|
||||||
foregroundListener?.updateForeground(ForegroundListener.Change.MEDIA_SESSION)
|
foregroundListener?.updateForeground(ForegroundListener.Change.MEDIA_SESSION)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// override fun onGetLibraryRoot(
|
// override fun onGetLibraryRoot(
|
||||||
// session: MediaLibrarySession,
|
// session: MediaLibrarySession,
|
||||||
// browser: MediaSession.ControllerInfo,
|
// browser: MediaSession.ControllerInfo,
|
||||||
|
|
|
@ -61,9 +61,7 @@ interface SearchEngine {
|
||||||
val artists: Collection<Artist>? = null,
|
val artists: Collection<Artist>? = null,
|
||||||
val genres: Collection<Genre>? = null,
|
val genres: Collection<Genre>? = null,
|
||||||
val playlists: Collection<Playlist>? = null
|
val playlists: Collection<Playlist>? = null
|
||||||
) {
|
) {}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class SearchEngineImpl @Inject constructor(@ApplicationContext private val context: Context) :
|
class SearchEngineImpl @Inject constructor(@ApplicationContext private val context: Context) :
|
||||||
|
|
Loading…
Reference in a new issue