diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 2e189db2d..8b0313ec5 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -14,6 +14,8 @@
+
+
+
+
+
diff --git a/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt b/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt
index 70e9e7dae..9035c5d7c 100644
--- a/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt
@@ -34,7 +34,6 @@ import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2
-import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.tabs.TabLayoutMediator
import kotlin.math.abs
import org.oxycblt.auxio.R
@@ -95,8 +94,7 @@ class HomeFragment : ViewBindingFragment(), Toolbar.OnMenuI
binding.homeToolbar.alpha = 1f - (abs(offset.toFloat()) / (range.toFloat() / 2))
binding.homeContent.updatePadding(
- bottom = binding.homeAppbar.totalScrollRange + offset
- )
+ bottom = binding.homeAppbar.totalScrollRange + offset)
}
}
diff --git a/app/src/main/java/org/oxycblt/auxio/music/FileSystemFramework.kt b/app/src/main/java/org/oxycblt/auxio/music/FileSystemFramework.kt
index 45fb81e8d..3381e420f 100644
--- a/app/src/main/java/org/oxycblt/auxio/music/FileSystemFramework.kt
+++ b/app/src/main/java/org/oxycblt/auxio/music/FileSystemFramework.kt
@@ -75,37 +75,61 @@ sealed class Dir {
*/
data class MimeType(val fromExtension: String, val fromFormat: String?) {
fun resolveName(context: Context): String {
- // While it would be nice to have more refined mime type names (Layer I/II/III, containers,
- // etc.), it's not exactly practical with ExoPlayer. So, we go for the next best thing
- // and try to find a good enough readable name to use.
- val readableStringRes =
- if (fromFormat != null && fromFormat != MimeTypes.AUDIO_RAW) {
- // Prefer the extracted mime type, as it properly handles container formats and
- // is agnostic to the file extension
- when (fromFormat) {
- MimeTypes.AUDIO_MPEG,
- MimeTypes.AUDIO_MPEG_L1,
- MimeTypes.AUDIO_MPEG_L2 -> R.string.cdc_mp3
- MimeTypes.AUDIO_AAC -> R.string.cdc_mp4
- MimeTypes.AUDIO_VORBIS -> R.string.cdc_ogg_vorbis
- MimeTypes.AUDIO_OPUS -> R.string.cdc_ogg_opus
- MimeTypes.AUDIO_WAV -> R.string.cdc_wav
- else -> -1
- }
- } else {
- // Fall back to the file extension in the case that we have a useless
- when (fromExtension) {
- "audio/mpeg" -> R.string.cdc_mp3
- "audio/mp4" -> R.string.cdc_mp4
- "audio/ogg" -> R.string.cdc_ogg
- "audio/x-wav" -> R.string.cdc_wav
- "audio/x-matroska" -> R.string.cdc_mka
- else -> -1
- }
+ // We try our best to produce a more readable name for the common audio formats.
+ val formatName =
+ when (fromFormat) {
+ // 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 show.
+ 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
+
+ // We don't give a name to more unpopular formats.
+
+ else -> -1
}
- return if (readableStringRes > -1) {
- context.getString(readableStringRes)
+ if (formatName > -1) {
+ return context.getString(formatName)
+ }
+
+ // Fall back to the file extension in the case that we have no mime type or
+ // a useless "audio/raw" mime type. Here:
+ // - We return names for container formats instead of the inner format, as we
+ // cannot parse the file.
+ // - We are at the mercy of the Android OS, hence we check for every possible mime
+ // type for a particular format.
+ val extensionName =
+ when (fromExtension) {
+ "audio/mpeg",
+ "audio/mp3" -> R.string.cdc_mp3
+ "audio/mp4",
+ "audio/mp4a-latm",
+ "audio/mpeg4-generic" -> R.string.cdc_mp4
+ "audio/aac",
+ "audio/aacp",
+ "audio/3gpp",
+ "audio/3gpp2" -> R.string.cdc_aac
+ "audio/ogg",
+ "application/ogg",
+ "application/x-ogg" -> R.string.cdc_ogg
+ "audio/flac" -> R.string.cdc_flac
+ "audio/wav",
+ "audio/x-wav",
+ "audio/wave",
+ "audio/vnd.wave" -> R.string.cdc_wav
+ "audio/x-matroska" -> R.string.cdc_mka
+ else -> -1
+ }
+
+ return if (extensionName > -1) {
+ context.getString(extensionName)
} else {
// Fall back to the extension if we can't find a special name for this format.
MimeTypeMap.getSingleton().getExtensionFromMimeType(fromExtension)?.uppercase()
diff --git a/app/src/main/java/org/oxycblt/auxio/music/Indexer.kt b/app/src/main/java/org/oxycblt/auxio/music/Indexer.kt
index 7152c70e6..bcddeeb3a 100644
--- a/app/src/main/java/org/oxycblt/auxio/music/Indexer.kt
+++ b/app/src/main/java/org/oxycblt/auxio/music/Indexer.kt
@@ -179,7 +179,11 @@ class Indexer {
private fun indexImpl(context: Context, generation: Long): MusicStore.Library? {
emitIndexing(Indexing.Indeterminate, generation)
- // Establish the backend to use when initially loading songs.
+ // Since we have different needs for each version, we determine a "Backend" to use
+ // when loading music and then leverage that to create the initial song list.
+ // This is technically dependency injection. Except it doesn't increase your compile
+ // times by 3x. Isn't that nice.
+
val mediaStoreBackend =
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> Api30MediaStoreBackend()
diff --git a/app/src/main/java/org/oxycblt/auxio/music/IndexerService.kt b/app/src/main/java/org/oxycblt/auxio/music/IndexerService.kt
index e5441fa64..8dff997c0 100644
--- a/app/src/main/java/org/oxycblt/auxio/music/IndexerService.kt
+++ b/app/src/main/java/org/oxycblt/auxio/music/IndexerService.kt
@@ -40,7 +40,10 @@ import org.oxycblt.auxio.util.newMainPendingIntent
* A [Service] that handles the music loading process.
*
* Loading music is actually somewhat time-consuming, to the point where it's likely better suited
- * to a service that is less likely to be
+ * to a service that is less likely to be killed by the OS.
+ *
+ * You could probably do the same using WorkManager and the GooberQueue library or whatever, but the
+ * boilerplate you skip is not worth the insanity of androidx.
*
* @author OxygenCobalt
*/
diff --git a/app/src/main/java/org/oxycblt/auxio/playback/system/MediaButtonReceiver.kt b/app/src/main/java/org/oxycblt/auxio/playback/system/MediaButtonReceiver.kt
index 5fa05b885..0b3e2950e 100644
--- a/app/src/main/java/org/oxycblt/auxio/playback/system/MediaButtonReceiver.kt
+++ b/app/src/main/java/org/oxycblt/auxio/playback/system/MediaButtonReceiver.kt
@@ -37,7 +37,8 @@ class MediaButtonReceiver : BroadcastReceiver() {
val playbackManager = PlaybackStateManager.getInstance()
if (playbackManager.song != null) {
// We have a song, so we can assume that the service will start a foreground state.
- // At least, I hope.
+ // At least, I hope. Again, *this is why we don't do this, I cannot describe how
+ // stupid this is with the state of foreground services on modern android*
intent.component = ComponentName(context, PlaybackService::class.java)
ContextCompat.startForegroundService(context, intent)
}
diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml
index 9f8cb8e66..2832c3934 100644
--- a/app/src/main/res/values/donottranslate.xml
+++ b/app/src/main/res/values/donottranslate.xml
@@ -9,8 +9,8 @@
%d
- Ogg Vorbis
- Ogg Opus
+ Vorbis
+ Opus
Microsoft WAVE
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index fd0a23593..b367be498 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -185,6 +185,8 @@
MPEG-4 Audio
Ogg Audio
Matroska Audio
+ Advanced Audio Coding (AAC)
+ Free Lossless Audio Codec (FLAC)
Red