music: use factory pattern in service components
This commit is contained in:
parent
d2aed8ee23
commit
8418dccdc6
4 changed files with 54 additions and 33 deletions
|
@ -41,13 +41,14 @@ class AuxioService :
|
||||||
MediaBrowserServiceCompat(), ForegroundListener, MusicServiceFragment.Invalidator {
|
MediaBrowserServiceCompat(), ForegroundListener, MusicServiceFragment.Invalidator {
|
||||||
@Inject lateinit var playbackFragment: PlaybackServiceFragment
|
@Inject lateinit var playbackFragment: PlaybackServiceFragment
|
||||||
|
|
||||||
@Inject lateinit var musicFragment: MusicServiceFragment
|
@Inject lateinit var musicFragmentFactory: MusicServiceFragment.Factory
|
||||||
|
lateinit var musicFragment: MusicServiceFragment
|
||||||
|
|
||||||
@SuppressLint("WrongConstant")
|
@SuppressLint("WrongConstant")
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
sessionToken = playbackFragment.attach(this)
|
sessionToken = playbackFragment.attach(this)
|
||||||
musicFragment.attach(this, this)
|
musicFragment = musicFragmentFactory.create(this, this, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
|
|
|
@ -36,10 +36,9 @@ import org.oxycblt.auxio.playback.state.PlaybackStateManager
|
||||||
import org.oxycblt.auxio.util.getSystemServiceCompat
|
import org.oxycblt.auxio.util.getSystemServiceCompat
|
||||||
import org.oxycblt.auxio.util.logD
|
import org.oxycblt.auxio.util.logD
|
||||||
|
|
||||||
class Indexer
|
class Indexer private constructor(
|
||||||
@Inject
|
override val workerContext: Context,
|
||||||
constructor(
|
private val foregroundListener: ForegroundListener,
|
||||||
@ApplicationContext override val workerContext: Context,
|
|
||||||
private val playbackManager: PlaybackStateManager,
|
private val playbackManager: PlaybackStateManager,
|
||||||
private val musicRepository: MusicRepository,
|
private val musicRepository: MusicRepository,
|
||||||
private val musicSettings: MusicSettings,
|
private val musicSettings: MusicSettings,
|
||||||
|
@ -50,10 +49,21 @@ constructor(
|
||||||
MusicRepository.IndexingListener,
|
MusicRepository.IndexingListener,
|
||||||
MusicRepository.UpdateListener,
|
MusicRepository.UpdateListener,
|
||||||
MusicSettings.Listener {
|
MusicSettings.Listener {
|
||||||
|
class Factory @Inject constructor(
|
||||||
|
private val playbackManager: PlaybackStateManager,
|
||||||
|
private val musicRepository: MusicRepository,
|
||||||
|
private val musicSettings: MusicSettings,
|
||||||
|
private val imageLoader: ImageLoader,
|
||||||
|
private val contentObserver: SystemContentObserver
|
||||||
|
) {
|
||||||
|
fun create(context: Context, listener: ForegroundListener) =
|
||||||
|
Indexer(context, listener, playbackManager,
|
||||||
|
musicRepository, musicSettings, imageLoader, contentObserver)
|
||||||
|
}
|
||||||
|
|
||||||
private val indexJob = Job()
|
private val indexJob = Job()
|
||||||
private val indexScope = CoroutineScope(indexJob + Dispatchers.IO)
|
private val indexScope = CoroutineScope(indexJob + Dispatchers.IO)
|
||||||
private var currentIndexJob: Job? = null
|
private var currentIndexJob: Job? = null
|
||||||
private var foregroundListener: ForegroundListener? = null
|
|
||||||
private val indexingNotification = IndexingNotification(workerContext)
|
private val indexingNotification = IndexingNotification(workerContext)
|
||||||
private val observingNotification = ObservingNotification(workerContext)
|
private val observingNotification = ObservingNotification(workerContext)
|
||||||
private val wakeLock =
|
private val wakeLock =
|
||||||
|
@ -62,8 +72,7 @@ constructor(
|
||||||
.newWakeLock(
|
.newWakeLock(
|
||||||
PowerManager.PARTIAL_WAKE_LOCK, BuildConfig.APPLICATION_ID + ":IndexingComponent")
|
PowerManager.PARTIAL_WAKE_LOCK, BuildConfig.APPLICATION_ID + ":IndexingComponent")
|
||||||
|
|
||||||
fun attach(listener: ForegroundListener) {
|
init {
|
||||||
foregroundListener = listener
|
|
||||||
musicSettings.registerListener(this)
|
musicSettings.registerListener(this)
|
||||||
musicRepository.addUpdateListener(this)
|
musicRepository.addUpdateListener(this)
|
||||||
musicRepository.addIndexingListener(this)
|
musicRepository.addIndexingListener(this)
|
||||||
|
@ -77,7 +86,6 @@ constructor(
|
||||||
musicRepository.addIndexingListener(this)
|
musicRepository.addIndexingListener(this)
|
||||||
musicRepository.addUpdateListener(this)
|
musicRepository.addUpdateListener(this)
|
||||||
musicRepository.removeIndexingListener(this)
|
musicRepository.removeIndexingListener(this)
|
||||||
foregroundListener = null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun requestIndex(withCache: Boolean) {
|
override fun requestIndex(withCache: Boolean) {
|
||||||
|
@ -91,7 +99,7 @@ constructor(
|
||||||
override val scope = indexScope
|
override val scope = indexScope
|
||||||
|
|
||||||
override fun onIndexingStateChanged() {
|
override fun onIndexingStateChanged() {
|
||||||
foregroundListener?.updateForeground(ForegroundListener.Change.INDEXER)
|
foregroundListener.updateForeground(ForegroundListener.Change.INDEXER)
|
||||||
val state = musicRepository.indexingState
|
val state = musicRepository.indexingState
|
||||||
if (state is IndexingState.Indexing) {
|
if (state is IndexingState.Indexing) {
|
||||||
wakeLock.acquireSafe()
|
wakeLock.acquireSafe()
|
||||||
|
@ -132,7 +140,7 @@ constructor(
|
||||||
// the music loading process ends.
|
// the music loading process ends.
|
||||||
if (musicRepository.indexingState == null) {
|
if (musicRepository.indexingState == null) {
|
||||||
logD("Not loading, updating idle session")
|
logD("Not loading, updating idle session")
|
||||||
foregroundListener?.updateForeground(ForegroundListener.Change.INDEXER)
|
foregroundListener.updateForeground(ForegroundListener.Change.INDEXER)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,24 +37,31 @@ import org.oxycblt.auxio.music.Playlist
|
||||||
import org.oxycblt.auxio.music.Song
|
import org.oxycblt.auxio.music.Song
|
||||||
import org.oxycblt.auxio.search.SearchEngine
|
import org.oxycblt.auxio.search.SearchEngine
|
||||||
|
|
||||||
class MusicBrowser
|
class MusicBrowser private constructor(
|
||||||
@Inject
|
private val context: Context,
|
||||||
constructor(
|
private val invalidator: Invalidator,
|
||||||
@ApplicationContext private val context: Context,
|
|
||||||
private val musicRepository: MusicRepository,
|
private val musicRepository: MusicRepository,
|
||||||
private val searchEngine: SearchEngine,
|
private val searchEngine: SearchEngine,
|
||||||
private val listSettings: ListSettings,
|
private val listSettings: ListSettings,
|
||||||
homeGeneratorFactory: HomeGenerator.Factory
|
homeGeneratorFactory: HomeGenerator.Factory
|
||||||
) : MusicRepository.UpdateListener, HomeGenerator.Invalidator {
|
) : MusicRepository.UpdateListener, HomeGenerator.Invalidator {
|
||||||
|
|
||||||
|
class Factory @Inject constructor(
|
||||||
|
private val musicRepository: MusicRepository,
|
||||||
|
private val searchEngine: SearchEngine,
|
||||||
|
private val listSettings: ListSettings,
|
||||||
|
private val homeGeneratorFactory: HomeGenerator.Factory
|
||||||
|
) {
|
||||||
|
fun create(context: Context, invalidator: Invalidator): MusicBrowser =
|
||||||
|
MusicBrowser(context, invalidator, musicRepository, searchEngine, listSettings, homeGeneratorFactory)
|
||||||
|
}
|
||||||
interface Invalidator {
|
interface Invalidator {
|
||||||
fun invalidateMusic(ids: Set<String>)
|
fun invalidateMusic(ids: Set<String>)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val homeGenerator = homeGeneratorFactory.create(this)
|
private val homeGenerator = homeGeneratorFactory.create(this)
|
||||||
private var invalidator: Invalidator? = null
|
|
||||||
|
|
||||||
fun attach(invalidator: Invalidator) {
|
init {
|
||||||
this.invalidator = invalidator
|
|
||||||
musicRepository.addUpdateListener(this)
|
musicRepository.addUpdateListener(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +71,7 @@ constructor(
|
||||||
|
|
||||||
override fun invalidateMusic(type: MusicType, instructions: UpdateInstructions) {
|
override fun invalidateMusic(type: MusicType, instructions: UpdateInstructions) {
|
||||||
val id = MediaSessionUID.Tab(TabNode.Home(type)).toString()
|
val id = MediaSessionUID.Tab(TabNode.Home(type)).toString()
|
||||||
invalidator?.invalidateMusic(setOf(id))
|
invalidator.invalidateMusic(setOf(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun invalidateTabs() {
|
override fun invalidateTabs() {
|
||||||
|
@ -72,7 +79,7 @@ constructor(
|
||||||
// TODO: Temporary bodge, move the amount parameter to a bundle extra
|
// TODO: Temporary bodge, move the amount parameter to a bundle extra
|
||||||
val rootId = MediaSessionUID.Tab(TabNode.Root(i)).toString()
|
val rootId = MediaSessionUID.Tab(TabNode.Root(i)).toString()
|
||||||
val moreId = MediaSessionUID.Tab(TabNode.More(i)).toString()
|
val moreId = MediaSessionUID.Tab(TabNode.More(i)).toString()
|
||||||
invalidator?.invalidateMusic(setOf(rootId, moreId))
|
invalidator.invalidateMusic(setOf(rootId, moreId))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,35 +39,40 @@ import org.oxycblt.auxio.util.logW
|
||||||
class MusicServiceFragment
|
class MusicServiceFragment
|
||||||
@Inject
|
@Inject
|
||||||
constructor(
|
constructor(
|
||||||
@ApplicationContext private val context: Context,
|
private val context: Context,
|
||||||
private val indexer: Indexer,
|
foregroundListener: ForegroundListener,
|
||||||
private val musicBrowser: MusicBrowser,
|
private val invalidator: Invalidator,
|
||||||
|
indexerFactory: Indexer.Factory,
|
||||||
|
musicBrowserFactory: MusicBrowser.Factory,
|
||||||
private val musicRepository: MusicRepository
|
private val musicRepository: MusicRepository
|
||||||
) : MusicBrowser.Invalidator {
|
) : MusicBrowser.Invalidator {
|
||||||
private var invalidator: Invalidator? = null
|
private val indexer = indexerFactory.create(context, foregroundListener)
|
||||||
|
private val musicBrowser = musicBrowserFactory.create(context, this)
|
||||||
private val dispatchJob = Job()
|
private val dispatchJob = Job()
|
||||||
private val dispatchScope = CoroutineScope(dispatchJob + Dispatchers.Default)
|
private val dispatchScope = CoroutineScope(dispatchJob + Dispatchers.Default)
|
||||||
|
|
||||||
interface Invalidator {
|
class Factory @Inject constructor(
|
||||||
fun invalidateMusic(mediaId: String)
|
private val indexerFactory: Indexer.Factory,
|
||||||
|
private val musicBrowserFactory: MusicBrowser.Factory,
|
||||||
|
private val musicRepository: MusicRepository
|
||||||
|
) {
|
||||||
|
fun create(context: Context, foregroundListener: ForegroundListener, invalidator: Invalidator): MusicServiceFragment =
|
||||||
|
MusicServiceFragment(context, foregroundListener, invalidator, indexerFactory, musicBrowserFactory, musicRepository)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun attach(foregroundListener: ForegroundListener, invalidator: Invalidator) {
|
interface Invalidator {
|
||||||
this.invalidator = invalidator
|
fun invalidateMusic(mediaId: String)
|
||||||
indexer.attach(foregroundListener)
|
|
||||||
musicBrowser.attach(this)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun release() {
|
fun release() {
|
||||||
dispatchJob.cancel()
|
dispatchJob.cancel()
|
||||||
musicBrowser.release()
|
musicBrowser.release()
|
||||||
indexer.release()
|
indexer.release()
|
||||||
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)
|
invalidator.invalidateMusic(mediaId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue