all: start injecting shared objects

Start injecting shared object instances.

This is not a 100% conversion, as certain portions of the code are not
really ready for 100% DI constructors just yet.
This commit is contained in:
Alexander Capehart 2023-02-02 20:53:41 -07:00
parent 2a3e81889b
commit 8536c3da31
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
31 changed files with 97 additions and 95 deletions

View file

@ -50,12 +50,11 @@ import org.oxycblt.auxio.util.*
class DetailViewModel class DetailViewModel
@Inject @Inject
constructor( constructor(
private val musicRepository: MusicRepository,
private val audioInfoProvider: AudioInfo.Provider, private val audioInfoProvider: AudioInfo.Provider,
private val musicSettings: MusicSettings, private val musicSettings: MusicSettings,
private val playbackSettings: PlaybackSettings private val playbackSettings: PlaybackSettings
) : ViewModel(), MusicRepository.Listener { ) : ViewModel(), MusicRepository.Listener {
private val musicRepository = MusicRepository.get()
private var currentSongJob: Job? = null private var currentSongJob: Job? = null
// --- SONG --- // --- SONG ---

View file

@ -39,10 +39,9 @@ class HomeViewModel
constructor( constructor(
private val homeSettings: HomeSettings, private val homeSettings: HomeSettings,
private val playbackSettings: PlaybackSettings, private val playbackSettings: PlaybackSettings,
private val musicRepository: MusicRepository,
private val musicSettings: MusicSettings private val musicSettings: MusicSettings
) : ViewModel(), MusicRepository.Listener, HomeSettings.Listener { ) : ViewModel(), MusicRepository.Listener, HomeSettings.Listener {
private val musicRepository = MusicRepository.get()
private val _songsList = MutableStateFlow(listOf<Song>()) private val _songsList = MutableStateFlow(listOf<Song>())
/** A list of [Song]s, sorted by the preferred [Sort], to be shown in the home view. */ /** A list of [Song]s, sorted by the preferred [Sort], to be shown in the home view. */
val songsList: StateFlow<List<Song>> val songsList: StateFlow<List<Song>>

View file

@ -18,6 +18,8 @@
package org.oxycblt.auxio.list.selection package org.oxycblt.auxio.list.selection
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.*
@ -27,9 +29,9 @@ import org.oxycblt.auxio.music.library.Library
* A [ViewModel] that manages the current selection. * A [ViewModel] that manages the current selection.
* @author Alexander Capehart (OxygenCobalt) * @author Alexander Capehart (OxygenCobalt)
*/ */
class SelectionViewModel : ViewModel(), MusicRepository.Listener { @HiltViewModel
private val musicRepository = MusicRepository.get() class SelectionViewModel @Inject constructor(private val musicRepository: MusicRepository) :
ViewModel(), MusicRepository.Listener {
private val _selected = MutableStateFlow(listOf<Music>()) private val _selected = MutableStateFlow(listOf<Music>())
/** the currently selected items. These are ordered in earliest selected and latest selected. */ /** the currently selected items. These are ordered in earliest selected and latest selected. */
val selected: StateFlow<List<Music>> val selected: StateFlow<List<Music>>

View file

@ -23,11 +23,15 @@ import dagger.Provides
import dagger.hilt.InstallIn import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
import org.oxycblt.auxio.music.metadata.AudioInfo import org.oxycblt.auxio.music.metadata.AudioInfo
import org.oxycblt.auxio.music.system.Indexer
@Module @Module
@InstallIn(SingletonComponent::class) @InstallIn(SingletonComponent::class)
class MusicModule { class MusicModule {
@Singleton @Provides fun musicRepository() = MusicRepository.new()
@Singleton @Provides fun indexer() = Indexer.new()
@Provides fun settings(@ApplicationContext context: Context) = MusicSettings.from(context) @Provides fun settings(@ApplicationContext context: Context) = MusicSettings.from(context)
@Provides @Provides
fun audioInfoProvider(@ApplicationContext context: Context) = AudioInfo.Provider.from(context) fun audioInfoProvider(@ApplicationContext context: Context) = AudioInfo.Provider.from(context)

View file

@ -62,24 +62,11 @@ interface MusicRepository {
} }
companion object { companion object {
@Volatile private var INSTANCE: MusicRepository? = null
/** /**
* Get a singleton instance. * Create a new instance.
* @return The (possibly newly-created) singleton instance. * @return A newly-created implementation of [MusicRepository].
*/ */
fun get(): MusicRepository { fun new(): MusicRepository = RealMusicRepository()
val currentInstance = INSTANCE
if (currentInstance != null) {
return currentInstance
}
synchronized(this) {
val newInstance = RealMusicRepository()
INSTANCE = newInstance
return newInstance
}
}
} }
} }

View file

@ -18,6 +18,8 @@
package org.oxycblt.auxio.music package org.oxycblt.auxio.music
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import org.oxycblt.auxio.music.system.Indexer import org.oxycblt.auxio.music.system.Indexer
@ -26,8 +28,9 @@ import org.oxycblt.auxio.music.system.Indexer
* A [ViewModel] providing data specific to the music loading process. * A [ViewModel] providing data specific to the music loading process.
* @author Alexander Capehart (OxygenCobalt) * @author Alexander Capehart (OxygenCobalt)
*/ */
class MusicViewModel : ViewModel(), Indexer.Listener { @HiltViewModel
private val indexer = Indexer.get() class MusicViewModel @Inject constructor(private val indexer: Indexer) :
ViewModel(), Indexer.Listener {
private val _indexerState = MutableStateFlow<Indexer.State?>(null) private val _indexerState = MutableStateFlow<Indexer.State?>(null)
/** The current music loading state, or null if no loading is going on. */ /** The current music loading state, or null if no loading is going on. */

View file

@ -31,10 +31,9 @@ import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.yield import kotlinx.coroutines.yield
import org.oxycblt.auxio.music.MusicSettings import org.oxycblt.auxio.music.MusicSettings
import org.oxycblt.auxio.music.library.RawSong import org.oxycblt.auxio.music.library.RawSong
import org.oxycblt.auxio.music.library.RealSong
import org.oxycblt.auxio.music.metadata.Date import org.oxycblt.auxio.music.metadata.Date
import org.oxycblt.auxio.music.parsing.parseId3v2PositionField import org.oxycblt.auxio.music.metadata.parseId3v2PositionField
import org.oxycblt.auxio.music.parsing.transformPositionField import org.oxycblt.auxio.music.metadata.transformPositionField
import org.oxycblt.auxio.music.storage.Directory import org.oxycblt.auxio.music.storage.Directory
import org.oxycblt.auxio.music.storage.contentResolverSafe import org.oxycblt.auxio.music.storage.contentResolverSafe
import org.oxycblt.auxio.music.storage.directoryCompat import org.oxycblt.auxio.music.storage.directoryCompat
@ -282,10 +281,10 @@ private abstract class RealMediaStoreExtractor(private val context: Context) : M
protected abstract fun addDirToSelector(dir: Directory, args: MutableList<String>): Boolean protected abstract fun addDirToSelector(dir: Directory, args: MutableList<String>): Boolean
/** /**
* Populate a [RawSong] with the "File Data" of the given [MediaStore] [Cursor], which * Populate a [RawSong] with the "File Data" of the given [MediaStore] [Cursor], which is the
* is the data that cannot be cached. This includes any information not intrinsic to the file * data that cannot be cached. This includes any information not intrinsic to the file and
* and instead dependent on the file-system, which could change without invalidating the cache * instead dependent on the file-system, which could change without invalidating the cache due
* due to volume additions or removals. * to volume additions or removals.
* @param cursor The [Cursor] to read from. * @param cursor The [Cursor] to read from.
* @param rawSong The [RawSong] to populate. * @param rawSong The [RawSong] to populate.
* @see populateMetadata * @see populateMetadata
@ -302,9 +301,9 @@ private abstract class RealMediaStoreExtractor(private val context: Context) : M
} }
/** /**
* Populate a [RawSong] with the Metadata of the given [MediaStore] [Cursor], which is * Populate a [RawSong] with the Metadata of the given [MediaStore] [Cursor], which is the data
* the data about a [RawSong] that can be cached. This includes any information * about a [RawSong] that can be cached. This includes any information intrinsic to the file or
* intrinsic to the file or it's file format, such as music tags. * it's file format, such as music tags.
* @param cursor The [Cursor] to read from. * @param cursor The [Cursor] to read from.
* @param rawSong The [RawSong] to populate. * @param rawSong The [RawSong] to populate.
* @see populateFileData * @see populateFileData

View file

@ -30,10 +30,9 @@ import androidx.room.TypeConverter
import androidx.room.TypeConverters import androidx.room.TypeConverters
import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.library.RawSong import org.oxycblt.auxio.music.library.RawSong
import org.oxycblt.auxio.music.library.RealSong
import org.oxycblt.auxio.music.metadata.Date import org.oxycblt.auxio.music.metadata.Date
import org.oxycblt.auxio.music.parsing.correctWhitespace import org.oxycblt.auxio.music.metadata.correctWhitespace
import org.oxycblt.auxio.music.parsing.splitEscaped import org.oxycblt.auxio.music.metadata.splitEscaped
import org.oxycblt.auxio.util.* import org.oxycblt.auxio.util.*
/** /**

View file

@ -24,11 +24,10 @@ import com.google.android.exoplayer2.MetadataRetriever
import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.yield import kotlinx.coroutines.yield
import org.oxycblt.auxio.music.library.RawSong import org.oxycblt.auxio.music.library.RawSong
import org.oxycblt.auxio.music.library.RealSong
import org.oxycblt.auxio.music.metadata.Date import org.oxycblt.auxio.music.metadata.Date
import org.oxycblt.auxio.music.metadata.TextTags import org.oxycblt.auxio.music.metadata.TextTags
import org.oxycblt.auxio.music.parsing.parseId3v2PositionField import org.oxycblt.auxio.music.metadata.parseId3v2PositionField
import org.oxycblt.auxio.music.parsing.parseVorbisPositionField import org.oxycblt.auxio.music.metadata.parseVorbisPositionField
import org.oxycblt.auxio.music.storage.toAudioUri import org.oxycblt.auxio.music.storage.toAudioUri
import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.logW import org.oxycblt.auxio.util.logW

View file

@ -22,7 +22,10 @@ import org.oxycblt.auxio.music.*
import org.oxycblt.auxio.music.metadata.* import org.oxycblt.auxio.music.metadata.*
import org.oxycblt.auxio.music.storage.Directory import org.oxycblt.auxio.music.storage.Directory
/** Raw information about a [RealSong] obtained from the filesystem/Extractor instances. */ /**
* Raw information about a [RealSong] obtained from the filesystem/Extractor instances.
* @author Alexander Capehart (OxygenCobalt)
*/
class RawSong( class RawSong(
/** /**
* The ID of the [RealSong]'s audio file, obtained from MediaStore. Note that this ID is highly * The ID of the [RealSong]'s audio file, obtained from MediaStore. Note that this ID is highly
@ -83,7 +86,10 @@ class RawSong(
var genreNames: List<String> = listOf() var genreNames: List<String> = listOf()
) )
/** Raw information about an [RealAlbum] obtained from the component [RealSong] instances. */ /**
* Raw information about an [RealAlbum] obtained from the component [RealSong] instances.
* @author Alexander Capehart (OxygenCobalt)
*/
class RawAlbum( class RawAlbum(
/** /**
* The ID of the [RealAlbum]'s grouping, obtained from MediaStore. Note that this ID is highly * The ID of the [RealAlbum]'s grouping, obtained from MediaStore. Note that this ID is highly
@ -128,6 +134,7 @@ class RawAlbum(
/** /**
* Raw information about an [RealArtist] obtained from the component [RealSong] and [RealAlbum] * Raw information about an [RealArtist] obtained from the component [RealSong] and [RealAlbum]
* instances. * instances.
* @author Alexander Capehart (OxygenCobalt)
*/ */
class RawArtist( class RawArtist(
/** @see Music.UID */ /** @see Music.UID */
@ -166,7 +173,10 @@ class RawArtist(
} }
} }
/** Raw information about a [RealGenre] obtained from the component [RealSong] instances. */ /**
* Raw information about a [RealGenre] obtained from the component [RealSong] instances.
* @author Alexander Capehart (OxygenCobalt)
*/
class RawGenre( class RawGenre(
/** @see Music.rawName */ /** @see Music.rawName */
val name: String? = null val name: String? = null

View file

@ -34,8 +34,8 @@ import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.metadata.Date import org.oxycblt.auxio.music.metadata.Date
import org.oxycblt.auxio.music.metadata.Disc import org.oxycblt.auxio.music.metadata.Disc
import org.oxycblt.auxio.music.metadata.ReleaseType import org.oxycblt.auxio.music.metadata.ReleaseType
import org.oxycblt.auxio.music.parsing.parseId3GenreNames import org.oxycblt.auxio.music.metadata.parseId3GenreNames
import org.oxycblt.auxio.music.parsing.parseMultiValue import org.oxycblt.auxio.music.metadata.parseMultiValue
import org.oxycblt.auxio.music.storage.MimeType import org.oxycblt.auxio.music.storage.MimeType
import org.oxycblt.auxio.music.storage.Path import org.oxycblt.auxio.music.storage.Path
import org.oxycblt.auxio.music.storage.toAudioUri import org.oxycblt.auxio.music.storage.toAudioUri

View file

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package org.oxycblt.auxio.music.parsing package org.oxycblt.auxio.music.metadata
/** /**
* Defines the allowed separator characters that can be used to delimit multi-value tags. * Defines the allowed separator characters that can be used to delimit multi-value tags.

View file

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package org.oxycblt.auxio.music.parsing package org.oxycblt.auxio.music.metadata
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater

View file

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package org.oxycblt.auxio.music.parsing package org.oxycblt.auxio.music.metadata
import org.oxycblt.auxio.music.MusicSettings import org.oxycblt.auxio.music.MusicSettings
import org.oxycblt.auxio.util.nonZeroOrNull import org.oxycblt.auxio.util.nonZeroOrNull

View file

@ -21,7 +21,6 @@ import com.google.android.exoplayer2.metadata.Metadata
import com.google.android.exoplayer2.metadata.id3.InternalFrame import com.google.android.exoplayer2.metadata.id3.InternalFrame
import com.google.android.exoplayer2.metadata.id3.TextInformationFrame import com.google.android.exoplayer2.metadata.id3.TextInformationFrame
import com.google.android.exoplayer2.metadata.vorbis.VorbisComment import com.google.android.exoplayer2.metadata.vorbis.VorbisComment
import org.oxycblt.auxio.music.parsing.correctWhitespace
/** /**
* Processing wrapper for [Metadata] that allows organized access to text-based audio tags. * Processing wrapper for [Metadata] that allows organized access to text-based audio tags.

View file

@ -200,8 +200,6 @@ interface Indexer {
} }
companion object { companion object {
@Volatile private var INSTANCE: Indexer? = null
/** /**
* A version-compatible identifier for the read external storage permission required by the * A version-compatible identifier for the read external storage permission required by the
* system to load audio. * system to load audio.
@ -215,21 +213,10 @@ interface Indexer {
} }
/** /**
* Get a singleton instance. * Create a new instance.
* @return The (possibly newly-created) singleton instance. * @return A newly-created implementation of [Indexer].
*/ */
fun get(): Indexer { fun new(): Indexer = RealIndexer()
val currentInstance = INSTANCE
if (currentInstance != null) {
return currentInstance
}
synchronized(this) {
val newInstance = RealIndexer()
INSTANCE = newInstance
return newInstance
}
}
} }
} }

View file

@ -27,6 +27,7 @@ import android.os.PowerManager
import android.provider.MediaStore import android.provider.MediaStore
import coil.imageLoader import coil.imageLoader
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
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
@ -55,9 +56,9 @@ import org.oxycblt.auxio.util.logD
*/ */
@AndroidEntryPoint @AndroidEntryPoint
class IndexerService : Service(), Indexer.Controller, MusicSettings.Listener { class IndexerService : Service(), Indexer.Controller, MusicSettings.Listener {
private val indexer = Indexer.get() @Inject lateinit var indexer: Indexer
private val musicRepository = MusicRepository.get() @Inject lateinit var musicRepository: MusicRepository
private val playbackManager = PlaybackStateManager.get() @Inject lateinit var playbackManager: PlaybackStateManager
private val serviceJob = Job() private val serviceJob = Job()
private val indexScope = CoroutineScope(serviceJob + Dispatchers.IO) private val indexScope = CoroutineScope(serviceJob + Dispatchers.IO)
private var currentIndexJob: Job? = null private var currentIndexJob: Job? = null

View file

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package org.oxycblt.auxio.music.picker package org.oxycblt.auxio.picker
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup

View file

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package org.oxycblt.auxio.music.picker package org.oxycblt.auxio.picker
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels

View file

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package org.oxycblt.auxio.music.picker package org.oxycblt.auxio.picker
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater

View file

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package org.oxycblt.auxio.music.picker package org.oxycblt.auxio.picker
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels

View file

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package org.oxycblt.auxio.music.picker package org.oxycblt.auxio.picker
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup

View file

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package org.oxycblt.auxio.music.picker package org.oxycblt.auxio.picker
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater

View file

@ -15,9 +15,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package org.oxycblt.auxio.music.picker package org.oxycblt.auxio.picker
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.*
@ -29,8 +31,9 @@ import org.oxycblt.auxio.util.unlikelyToBeNull
* contain the music themselves and then exit if the library changes. * contain the music themselves and then exit if the library changes.
* @author Alexander Capehart (OxygenCobalt) * @author Alexander Capehart (OxygenCobalt)
*/ */
class PickerViewModel : ViewModel(), MusicRepository.Listener { @HiltViewModel
private val musicRepository = MusicRepository.get() class PickerViewModel @Inject constructor(private val musicRepository: MusicRepository) :
ViewModel(), MusicRepository.Listener {
private val _currentItem = MutableStateFlow<Music?>(null) private val _currentItem = MutableStateFlow<Music?>(null)
/** The current item whose artists should be shown in the picker. Null if there is no item. */ /** The current item whose artists should be shown in the picker. Null if there is no item. */

View file

@ -24,10 +24,13 @@ import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent import dagger.hilt.components.SingletonComponent
import org.oxycblt.auxio.playback.persist.PersistenceRepository import org.oxycblt.auxio.playback.persist.PersistenceRepository
import org.oxycblt.auxio.playback.state.PlaybackStateManager
@Module @Module
@InstallIn(SingletonComponent::class) @InstallIn(SingletonComponent::class)
class PlaybackModule { class PlaybackModule {
@Provides fun playbackStateManager() = PlaybackStateManager.get()
@Provides fun settings(@ApplicationContext context: Context) = PlaybackSettings.from(context) @Provides fun settings(@ApplicationContext context: Context) = PlaybackSettings.from(context)
@Provides @Provides

View file

@ -39,12 +39,12 @@ import org.oxycblt.auxio.playback.state.*
class PlaybackViewModel class PlaybackViewModel
@Inject @Inject
constructor( constructor(
private val persistenceRepository: PersistenceRepository, private val playbackManager: PlaybackStateManager,
private val playbackSettings: PlaybackSettings, private val playbackSettings: PlaybackSettings,
private val persistenceRepository: PersistenceRepository,
private val musicRepository: MusicRepository,
private val musicSettings: MusicSettings private val musicSettings: MusicSettings
) : ViewModel(), PlaybackStateManager.Listener { ) : ViewModel(), PlaybackStateManager.Listener {
private val playbackManager = PlaybackStateManager.get()
private val musicRepository = MusicRepository.get()
private var lastPositionJob: Job? = null private var lastPositionJob: Job? = null
private val _song = MutableStateFlow<Song?>(null) private val _song = MutableStateFlow<Song?>(null)

View file

@ -18,6 +18,8 @@
package org.oxycblt.auxio.playback.queue package org.oxycblt.auxio.playback.queue
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import org.oxycblt.auxio.list.adapter.BasicListInstructions import org.oxycblt.auxio.list.adapter.BasicListInstructions
@ -30,8 +32,9 @@ import org.oxycblt.auxio.playback.state.PlaybackStateManager
* *
* @author Alexander Capehart (OxygenCobalt) * @author Alexander Capehart (OxygenCobalt)
*/ */
class QueueViewModel : ViewModel(), PlaybackStateManager.Listener { @HiltViewModel
private val playbackManager = PlaybackStateManager.get() class QueueViewModel @Inject constructor(private val playbackManager: PlaybackStateManager) :
ViewModel(), PlaybackStateManager.Listener {
private val _queue = MutableStateFlow(listOf<Song>()) private val _queue = MutableStateFlow(listOf<Song>())
/** The current queue. */ /** The current queue. */

View file

@ -39,6 +39,7 @@ import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory
import com.google.android.exoplayer2.mediacodec.MediaCodecSelector import com.google.android.exoplayer2.mediacodec.MediaCodecSelector
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory import com.google.android.exoplayer2.source.DefaultMediaSourceFactory
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
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
@ -93,11 +94,11 @@ class PlaybackService :
private val systemReceiver = PlaybackReceiver() private val systemReceiver = PlaybackReceiver()
// Shared components // Shared components
private val playbackManager = PlaybackStateManager.get() @Inject lateinit var playbackManager: PlaybackStateManager
private lateinit var playbackSettings: PlaybackSettings @Inject lateinit var playbackSettings: PlaybackSettings
private lateinit var persistenceRepository: PersistenceRepository @Inject lateinit var persistenceRepository: PersistenceRepository
private val musicRepository = MusicRepository.get() @Inject lateinit var musicRepository: MusicRepository
private lateinit var musicSettings: MusicSettings @Inject lateinit var musicSettings: MusicSettings
// State // State
private lateinit var foregroundManager: ForegroundManager private lateinit var foregroundManager: ForegroundManager
@ -148,8 +149,6 @@ class PlaybackService :
.also { it.addListener(this) } .also { it.addListener(this) }
replayGainProcessor.addToListeners(player) replayGainProcessor.addToListeners(player)
// Initialize the core service components // Initialize the core service components
musicSettings = MusicSettings.from(this)
playbackSettings = PlaybackSettings.from(this)
persistenceRepository = PersistenceRepository.from(this) persistenceRepository = PersistenceRepository.from(this)
foregroundManager = ForegroundManager(this) foregroundManager = ForegroundManager(this)
// Initialize any listener-dependent components last as we wouldn't want a listener race // Initialize any listener-dependent components last as we wouldn't want a listener race

View file

@ -44,11 +44,11 @@ import org.oxycblt.auxio.util.logD
class SearchViewModel class SearchViewModel
@Inject @Inject
constructor( constructor(
private val musicRepository: MusicRepository,
private val searchEngine: SearchEngine, private val searchEngine: SearchEngine,
private val searchSettings: SearchSettings, private val searchSettings: SearchSettings,
private val playbackSettings: PlaybackSettings, private val playbackSettings: PlaybackSettings,
) : ViewModel(), MusicRepository.Listener { ) : ViewModel(), MusicRepository.Listener {
private val musicRepository = MusicRepository.get()
private var lastQuery: String? = null private var lastQuery: String? = null
private var currentSearchJob: Job? = null private var currentSearchJob: Job? = null

View file

@ -30,7 +30,7 @@
<dialog <dialog
android:id="@+id/artist_playback_picker_dialog" android:id="@+id/artist_playback_picker_dialog"
android:name="org.oxycblt.auxio.music.picker.ArtistPlaybackPickerDialog" android:name="org.oxycblt.auxio.picker.ArtistPlaybackPickerDialog"
android:label="artist_playback_picker_dialog" android:label="artist_playback_picker_dialog"
tools:layout="@layout/dialog_music_picker"> tools:layout="@layout/dialog_music_picker">
<argument <argument
@ -40,7 +40,7 @@
<dialog <dialog
android:id="@+id/artist_navigation_picker_dialog" android:id="@+id/artist_navigation_picker_dialog"
android:name="org.oxycblt.auxio.music.picker.ArtistNavigationPickerDialog" android:name="org.oxycblt.auxio.picker.ArtistNavigationPickerDialog"
android:label="artist_navigation_picker_dialog" android:label="artist_navigation_picker_dialog"
tools:layout="@layout/dialog_music_picker"> tools:layout="@layout/dialog_music_picker">
<argument <argument
@ -50,7 +50,7 @@
<dialog <dialog
android:id="@+id/genre_playback_picker_dialog" android:id="@+id/genre_playback_picker_dialog"
android:name="org.oxycblt.auxio.music.picker.GenrePlaybackPickerDialog" android:name="org.oxycblt.auxio.picker.GenrePlaybackPickerDialog"
android:label="genre_playback_picker_dialog" android:label="genre_playback_picker_dialog"
tools:layout="@layout/dialog_music_picker"> tools:layout="@layout/dialog_music_picker">
<argument <argument
@ -148,7 +148,7 @@
tools:layout="@layout/dialog_music_dirs" /> tools:layout="@layout/dialog_music_dirs" />
<dialog <dialog
android:id="@+id/separators_dialog" android:id="@+id/separators_dialog"
android:name="org.oxycblt.auxio.music.parsing.SeparatorsDialog" android:name="org.oxycblt.auxio.music.metadata.SeparatorsDialog"
android:label="music_dirs_dialog" android:label="music_dirs_dialog"
tools:layout="@layout/dialog_separators" /> tools:layout="@layout/dialog_separators" />

View file

@ -20,6 +20,12 @@ package org.oxycblt.auxio.music.parsing
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Test import org.junit.Test
import org.oxycblt.auxio.music.FakeMusicSettings import org.oxycblt.auxio.music.FakeMusicSettings
import org.oxycblt.auxio.music.metadata.correctWhitespace
import org.oxycblt.auxio.music.metadata.parseId3GenreNames
import org.oxycblt.auxio.music.metadata.parseId3v2PositionField
import org.oxycblt.auxio.music.metadata.parseMultiValue
import org.oxycblt.auxio.music.metadata.parseVorbisPositionField
import org.oxycblt.auxio.music.metadata.splitEscaped
class ParsingUtilTest { class ParsingUtilTest {
@Test @Test