This displays a progress bar with the amount of used/free space in each
storage location to make it easier to identify storage devices. This is
particularly useful for devices that use non-standard names.
Reference: #3049
This is in preparation to add a progress bar displaying the amount of
used/free space in the dialog (#3049). Since we'll need a custom view to
do it, this extracts the layout beforehand.
Previously, when the user clicked the search button, the context menu
would be hidden and the refresh button would move way too close to the
edge of the screen.
This makes sure that when a user clicks the search button on the
episodes screen, the remaining actionbar items (refresh and context
menu) stay where they are.
This reworks the sort algorithm used in smart shuffle so that episodes
are spread out evenly, which avoids episodes bunching up at the bottom
of the queue when one feed has more episodes than others, and avoids
running through feeds with few episodes very quickly.
Signed-off-by: Stephen Kitt <steve@sk2.org>
The Android internal media player blocks its `start()` call until the
seek listener completes. The seek listener is called on the main thread
even though `start()` is called on the executor. This makes the main
thread wait for the lock and the executor (which has the lock) wait for the
main thread to finish the call to the listener.
The cover fragment would hide both podcast and episode names in small
screen devices or multi-window mode.
This replaces the deprecated PercentRelativeLayout in favor of a regular
LinearLayout with weights to make sure that each section of the fragment
(podcast title, image, episode name) will have the necessary space in
the screen.
Since PercentRelativeLayout was only being used here, it also removes
the dependencies from the gradle files.
Closes: #3169
Callbacks are called on the thread that created the MediaPlayer.
For Sonic, this is the executor. For ExoPlayer, this is the main thread.
When calling executor.submit, every thread waiting for the runnable to
complete gets blocked.
Because the callback is called in the thread that created the player,
we can simply remove the call to executor.submit and still be sure
that a background thread is used.