all: tie up loose ends

Tie up some loose ends before 3.0.0's release.
This commit is contained in:
Alexander Capehart 2022-12-28 15:44:44 -07:00
parent 94e1b71d9b
commit 32db8a591a
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
8 changed files with 43 additions and 39 deletions

View file

@ -45,6 +45,7 @@ audio focus was lost
- "Show covers" and "Ignore MediaStore covers" have been unified into "Album covers"
#### Dev/Meta
- Created new wiki with more information about app functionality
- Completed migration to reactive playback system
- Refactor music backends into a unified chain of extractors
- Add bluetooth connection reciever (No functionality in app yet)

View file

@ -345,7 +345,7 @@ class Song constructor(raw: Raw, settings: Settings) : Music() {
val mimeType =
MimeType(
fromExtension = requireNotNull(raw.extensionMimeType) { "Invalid raw: No mime type" },
fromFormat = raw.formatMimeType)
fromFormat = null)
/** The size of the audio file, in bytes. */
val size = requireNotNull(raw.size) { "Invalid raw: No size" }
@ -547,8 +547,6 @@ class Song constructor(raw: Raw, settings: Settings) : Music() {
var durationMs: Long? = null,
/** @see Song.mimeType */
var extensionMimeType: String? = null,
/** @see Song.mimeType */
var formatMimeType: String? = null,
/** @see Music.UID */
var musicBrainzId: String? = null,
/** @see Music.rawName */

View file

@ -132,7 +132,6 @@ class ReadWriteCacheExtractor(private val context: Context) : WriteOnlyCacheExtr
rawSong.size = cachedRawSong.size
rawSong.durationMs = cachedRawSong.durationMs
rawSong.formatMimeType = cachedRawSong.formatMimeType
rawSong.track = cachedRawSong.track
rawSong.disc = cachedRawSong.disc
@ -180,7 +179,6 @@ private class CacheDatabase(context: Context) :
append("${Columns.DATE_MODIFIED} LONG NOT NULL,")
append("${Columns.SIZE} LONG NOT NULL,")
append("${Columns.DURATION} LONG NOT NULL,")
append("${Columns.FORMAT_MIME_TYPE} STRING,")
append("${Columns.MUSIC_BRAINZ_ID} STRING,")
append("${Columns.NAME} STRING NOT NULL,")
append("${Columns.SORT_NAME} STRING,")
@ -236,7 +234,6 @@ private class CacheDatabase(context: Context) :
val sizeIndex = cursor.getColumnIndexOrThrow(Columns.SIZE)
val durationIndex = cursor.getColumnIndexOrThrow(Columns.DURATION)
val formatMimeTypeIndex = cursor.getColumnIndexOrThrow(Columns.FORMAT_MIME_TYPE)
val musicBrainzIdIndex = cursor.getColumnIndexOrThrow(Columns.MUSIC_BRAINZ_ID)
val nameIndex = cursor.getColumnIndexOrThrow(Columns.NAME)
@ -275,7 +272,6 @@ private class CacheDatabase(context: Context) :
raw.size = cursor.getLong(sizeIndex)
raw.durationMs = cursor.getLong(durationIndex)
raw.formatMimeType = cursor.getStringOrNull(formatMimeTypeIndex)
raw.musicBrainzId = cursor.getStringOrNull(musicBrainzIdIndex)
raw.name = cursor.getString(nameIndex)
@ -341,7 +337,6 @@ private class CacheDatabase(context: Context) :
put(Columns.SIZE, rawSong.size)
put(Columns.DURATION, rawSong.durationMs)
put(Columns.FORMAT_MIME_TYPE, rawSong.formatMimeType)
put(Columns.MUSIC_BRAINZ_ID, rawSong.name)
put(Columns.NAME, rawSong.name)
@ -407,8 +402,6 @@ private class CacheDatabase(context: Context) :
const val SIZE = "size"
/** @see Song.Raw.durationMs */
const val DURATION = "duration"
/** @see Song.Raw.formatMimeType */
const val FORMAT_MIME_TYPE = "fmt_mime"
/** @see Song.Raw.musicBrainzId */
const val MUSIC_BRAINZ_ID = "mbid"
/** @see Song.Raw.name */

View file

@ -160,10 +160,6 @@ class Task(context: Context, private val raw: Song.Raw) {
return raw
}
// Populate the format mime type if we have one.
// TODO: Check if this is even useful or not.
format.sampleMimeType?.let { raw.formatMimeType = it }
val metadata = format.metadata
if (metadata != null) {
populateWithMetadata(metadata)

View file

@ -22,6 +22,7 @@ import android.view.LayoutInflater
import androidx.appcompat.app.AlertDialog
import androidx.core.view.children
import com.google.android.material.checkbox.MaterialCheckBox
import org.oxycblt.auxio.BuildConfig
import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.DialogSeparatorsBinding
import org.oxycblt.auxio.settings.Settings
@ -34,7 +35,6 @@ import org.oxycblt.auxio.util.context
* @author Alexander Capehart (OxygenCobalt)
*/
class SeparatorsDialog : ViewBindingDialogFragment<DialogSeparatorsBinding>() {
// TODO: Add saved state for pending configurations.
private val settings: Settings by lifecycleObject { binding -> Settings(binding.context) }
override fun onCreateBinding(inflater: LayoutInflater) =
@ -45,17 +45,7 @@ class SeparatorsDialog : ViewBindingDialogFragment<DialogSeparatorsBinding>() {
.setTitle(R.string.set_separators)
.setNegativeButton(R.string.lbl_cancel, null)
.setPositiveButton(R.string.lbl_save) { _, _ ->
// Create the separator list based on the checked configuration of each
// view element. It's generally more stable to duplicate this code instead
// of use a mapping that could feasibly drift from the actual layout.
var separators = ""
val binding = requireBinding()
if (binding.separatorComma.isChecked) separators += SEPARATOR_COMMA
if (binding.separatorSemicolon.isChecked) separators += SEPARATOR_SEMICOLON
if (binding.separatorSlash.isChecked) separators += SEPARATOR_SLASH
if (binding.separatorPlus.isChecked) separators += SEPARATOR_PLUS
if (binding.separatorAnd.isChecked) separators += SEPARATOR_AND
settings.musicSeparators = separators
settings.musicSeparators = getCurrentSeparators()
}
}
@ -71,7 +61,7 @@ class SeparatorsDialog : ViewBindingDialogFragment<DialogSeparatorsBinding>() {
// More efficient to do one iteration through the separator list and initialize
// the corresponding CheckBox for each character instead of doing an iteration
// through the separator list for each CheckBox.
settings.musicSeparators?.forEach {
(savedInstanceState?.getString(KEY_PENDING_SEPARATORS) ?: settings.musicSeparators)?.forEach {
when (it) {
SEPARATOR_COMMA -> binding.separatorComma.isChecked = true
SEPARATOR_SEMICOLON -> binding.separatorSemicolon.isChecked = true
@ -83,7 +73,28 @@ class SeparatorsDialog : ViewBindingDialogFragment<DialogSeparatorsBinding>() {
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putString(KEY_PENDING_SEPARATORS, getCurrentSeparators())
}
/** Get the current separator string configuration from the UI. */
private fun getCurrentSeparators(): String {
// Create the separator list based on the checked configuration of each
// view element. It's generally more stable to duplicate this code instead
// of use a mapping that could feasibly drift from the actual layout.
var separators = ""
val binding = requireBinding()
if (binding.separatorComma.isChecked) separators += SEPARATOR_COMMA
if (binding.separatorSemicolon.isChecked) separators += SEPARATOR_SEMICOLON
if (binding.separatorSlash.isChecked) separators += SEPARATOR_SLASH
if (binding.separatorPlus.isChecked) separators += SEPARATOR_PLUS
if (binding.separatorAnd.isChecked) separators += SEPARATOR_AND
return separators
}
companion object {
private val KEY_PENDING_SEPARATORS = BuildConfig.APPLICATION_ID + ".key.PENDING_SEPARATORS"
// TODO: Move these to a more "Correct" location?
private const val SEPARATOR_COMMA = ','
private const val SEPARATOR_SEMICOLON = ';'

View file

@ -18,6 +18,8 @@
package org.oxycblt.auxio.music.storage
import android.content.Context
import android.media.MediaExtractor
import android.media.MediaFormat
import android.os.storage.StorageManager
import android.os.storage.StorageVolume
import android.webkit.MimeTypeMap
@ -153,17 +155,12 @@ data class MimeType(val fromExtension: String, val fromFormat: String?) {
// We start with the extracted mime types, as they are more consistent. Note that
// we do not include container formats at all with these names. It is only the
// inner codec that we bother with.
MimeTypes.AUDIO_MPEG,
MimeTypes.AUDIO_MPEG_L1,
MimeTypes.AUDIO_MPEG_L2 -> R.string.cdc_mp3
MimeTypes.AUDIO_AAC -> R.string.cdc_aac
MimeTypes.AUDIO_VORBIS -> R.string.cdc_vorbis
MimeTypes.AUDIO_OPUS -> R.string.cdc_opus
MimeTypes.AUDIO_FLAC -> R.string.cdc_flac
MimeTypes.AUDIO_WAV -> R.string.cdc_wav
MediaFormat.MIMETYPE_AUDIO_MPEG -> R.string.cdc_mp3
MediaFormat.MIMETYPE_AUDIO_AAC -> R.string.cdc_aac
MediaFormat.MIMETYPE_AUDIO_VORBIS -> R.string.cdc_vorbis
MediaFormat.MIMETYPE_AUDIO_OPUS -> R.string.cdc_opus
MediaFormat.MIMETYPE_AUDIO_FLAC -> R.string.cdc_flac
// We don't give a name to more unpopular formats.
else -> -1
}

View file

@ -276,9 +276,10 @@ class ReplayGainAudioProcessor(context: Context) : BaseAudioProcessor() {
/**
* A raw ReplayGain adjustment.
* @param key The tag's key.
* @param value The tag's adjustment, in dB. TODO: Try to phasse this out.
* @param value The tag's adjustment, in dB.
*/
private data class GainTag(val key: String, val value: Float)
// TODO: Try to phase this out
companion object {
private const val TAG_RG_TRACK = "replaygain_track_gain"

View file

@ -165,8 +165,15 @@ class Settings(private val context: Context, private val callback: Callback? = n
unlikelyToBeNull(callback).onSettingChanged(key)
}
/** TODO: Rework this */
/**
* Simplified callback for settings changes.
*/
interface Callback {
// TODO: Refactor this lifecycle
/**
* Called when a setting has changed.
* @param key The key of the setting that changed.
*/
fun onSettingChanged(key: String)
}