Further refine the Indexer and ExoPlayerBackend implementations.
These fixes were primarily focused on ensuring stable grouping through
stable sorting order, and more graceful handling of edge cases in
ExoPlayerBackend.
Switch from LiveData to StateFlow.
While LiveData is a pretty good data storage/observer mechanism, it has
a few flaws:
- Values are always nullable in LiveData, even if you make them
non-null.
- LiveData can only be mutated on Dispatchers.Main, which frustrates
possible additions like a more fine-grained music status system.
- LiveData's perks are exclusive to ViewModels, which made coupling
with shared objects somewhat cumbersome.
StateFlow solves all of these by being a native coroutine solution with
proper android bindings. Use it instead.
Add an ExoPlayer-based metadata backend.
This backend finally allows Auxio to parse metadata internally, which
has been a highly requested feature given how many unfixable MediaStore
issues it would fix.
However, this is not fully ready for production yet. The loading
process becomes much larger with manual parsing, the current
implementation still allocates picture metadata (terrible for
efficiency), and there is no good indicator in the app to keep
track of music loading.
As a result, this backend is disabled until it can be fully integrated
into Auxio's architecture.
Revert the introduction of the thin/tiny widgets, but keep the new
cover layout I created while working on them.
There is simply no way I can cram controls and metadata within the
size bucket that the thin widget occupies. I have decided to give up
and revert the widget to it's old form.
I understand why the thin widget is not appealing. However, the sizing
at which a widget can properly accomodate a taller widget is just too
precise and not really large enough to justify it's existance.
Also use the gesture insets on playback panel.
Turns out when the panel uses normal insets, the playback panel is
extremely close to the system bars. Fix this by using the bigger
gesture insets.
Resolves#137.
Hack around more insane lollipop bugs, such as:
- The angular auxio icon crashing the system UI
- Optimized icons being corrupted
- Setting image alpha not working properly
I really wish I could drop support for this horrible version, but I
either have to wait for a major library to drop support or for the
usage numbers to reach 1%.
Do some miscellanious formatting reworks.
1. Remove all instances of m in favor of _. _ is only used when names
collide or if something should be internal.
2. Make fragments apply their own click listeners.
3. Remove instances of inc/dec and replace them with the more
straightfoward + 1 or - 1.
Rework the style of all album covers in the app to be more in line with
the new track number style.
This is mostly comprised of adding a new background to all cover views
and rescaling error icons to be smaller than they would normally be.
This also includes a change in the cover/track background color from
colorSurfaceVariant to colorOnSurfaceInverse, which seems to provide
the best visibility in all cases.
These changes also apply to the track number views.
Implement support for positive ReplayGain values.
Turns out the blocker for this with the new AudioProcessor was that
I did not properly clamp PCM data when I manipulated the data,
resulting in target samples like 75491 being truncated to lower
values like 9955, which resulted in popping. This is a niche addition,
but also puts Auxio in a category that no other (FOSS) android music
player currently occupies. Yay.
Resolves#115.
Rework audio focus to rely on the native ExoPlayer implementation
instead of a custom implementation.
Previously, we avoided ExoPlayer's AudioFocus system as it never
played after a transient lost. A few versions later now through,
now it does, so we may as well switch to it. This does introduce
a bug where ReplayGain functionality will conflict with audio
focus, but I hope to eliminate this with #115 as I switch to
an AudioProcessor instead of a callback.
Audit null safety to remove extraneous and stupid calls while
optimizing certain checks here and there.
This commit is primarily centered around the introduction of a new
utility: unlikelyToBeNull. This call uses requireNotNull on debug
builds and !! on release builds, which allows for bug catching in
an easier manner on normal builds while also allowing for
optimizations on the release builds.
Completely rework the base adapter class to require less boilerplate
and properly handle cases such as diffing. The major adapters have
been migrated to this system, but the other adapters have not been
changed so far.
This is only part 1 of a multi-part rework, as this is an incredibly
complex system.
Remove databinding entirely.
Databinding was a terrible idea for Auxio. I rarely leveraged it, and
when I did, it produced messy code and bloated build times. Dumpster it
for just viewbinding, which is good. This reduces building times by
nearly 2/3, and generally makes the codebase more coherent and usable.
Move all fragment instances to the new ViewBindingFragment paradigm,
which should help immensely with reducing memory leaks from list
bindings and to really alleviate the overloaded onCreate functions.
Migrate to a centralized constant table for easier management.
Previously, Auxio would tie constants to the class itself, which
led to a largely disjointed system that relied on an internal table
so that it would stay sane. This commit moves all of those constants
to a single table for easier usage and management.
Switch to the spotless linter with ktfmt used as a backend instead of
ktlint.
This switch was done for two reasons:
1. ktfmt is more thorough than ktlint
2. License headers can be added more effectively with spotless than
the default Android Studio behavior.
Dump all of the changes now so I don't have to deal with it over a long
period of time. I don't care.
Turn the headset focus setting into the headset autoplay setting.
The way auxio handles headsets is...odd. Sometimes the MediaSession
handles it and Auxio could not care less, and sometimes Auxio actually
needs to handle it. As a result, the idea of being able to disable
headset focus is more or less moot because it will only apply to some
devices and not others.
On the other end, the way Auxio automatically begins playback once a
headset is plugged in is also quite weird. It only works on wired
headsets, and when it does, it overrides all other apps that might
also be playing audio. It's not to say that it's a bad feature, but
it's also one that I don't want to make the defualt. Auxio should
still play along within the confines of Android's expectations, after
all.
Replacing the existing "Headset focus" setting with a new "Headset
autoplay" setting solves both of these issues, as it prevents a
mis-guided disabling of the setting that doesn't actually disable
the feature and it relegates the quirky autoplay behavior to an
setting not enabled by default.
Rework logging to be clearer and more standardized.
Rework all usages of lossing to follow a single unified style,
introducing a new "warn" option alongside this.
Fix an issue where headset focus would restart playback unexpectedly.
At some point during the broadcast refactor, I accidentally switched
the values of CONNECTED and DISCONNECTED when handling
AudioManager.ACTION_HEADSET_PLUG. This resulted in playback starting
for no reason in some situations.
Completely rework the Context extensions for resources.
Previously, Auxio has used a strange hodge-podge of context extensions
and verbose code to get resources. Fix this by unifying most of the
resource accesses under a single, unified set of extensions. The only
ones excluded for now is the getString call, as that is used in far too
many places to effectively replace.
When using gesture navigation, swipe up events might conflict with the
slide up behavior of the playback layout. To fix this, inset the
playback bar based on the gesture insets instead of the system bar
insets.
Extend edge-to-edge to versions below Android Oreo. This is done
through tinting the navigation bar colors on those versions,
circumventing the coloring issue.
Add ReplayGain support leveraging ExoPlayer. This was a widely
requested feature, but since I thought I needed MediaStore to
expose the fields, I never considered it. Turns out ExoPlayer
automatically exposes metadata for ID3v2 and Xiph tags, so we
can implement it just fine.
Resolves#7.
Change CompactPlaybackFragment into a View. This completely fixes the
issue I tried to band-aid in ae39054. The code is a bit uglier, but
that's tolerable.
Make MusicLoader instantiation fully asynchronous. This implementation
changes a lot about Auxio. For one, the loading screen is now gone.
However, many parts of the app now run under the fact that MusicStore
might not be available. However, I don't think there will be too much bugs
from it. Some more changes will be made to improve this implementation.
Instead of having a play/pause header at the top of the song list, use
a FAB instead. This allows people to shuffle all of their songs even if
the songs tab isn't enabled, and it can be tranformed into a create FAB
when playlists are added.
Enhance widgets in a couple of ways:
1. Make the cover art expand to fit it's aspect ratio with padding
instead of the entire widget. This does the cover art justice and
is more visually appealing in general.
2. Add two new widget forms: Terminal, which applies to only the
smallest widgets, and Minimal, which applies to short and wide
widgets
Add edge-to-edge on the Home, Detail, and Search fragments. This
solution is not ideal at all, relying on viewModel state to make
sure that the padding is only applied when the playback bar is not
present. However, it works. I'll likely replace it with a better
layout once I can figure out how similar layouts like Material
Files' PersistentBarLyout work.
Improve the queue UI some more:
- Fixed an issue where clearing the user queue by clearing all items would
result in it bugging out
- Queue items now show a Material-y background when they are swiped
away. This was way harder than you might think it was.
Mostly migrate to Material 3/Material You.
- Auxio should now follow dynamic colors on Android 12
- Accents have been regenerated to align with the new color roles
- Some colors have been tweaked here and there to line up with the
new design system
- Dialogs were not fully migrated, but that's because Material3 dialogs
look god-awful.
- Accent class was reworked to take up less memory
Now that this is out of the way, I can focus on other UI things before
the release of 2.0.0.