Android Auto: Update play-from-here and library pagination
Description
This MR contains updates to play-from-here behavior, library pagination, media identifier, bi-directional formatting and media sort order. The changes have been split into several different commits for ease of review. This is a large-ish change; however, all the updates are interrelated to support the desired functionality.
Motivation and Context
The user interface previously included a "Play All" button which loaded the queue with an entire album and began playback at track 1. If a user selected an individual song we simply played that one track and did not load the entire album. If the user wanted to start playback in the middle of a large album they would have to start at track 1 and navigate down a dozen tracks using either the next hard/soft buttons, or via the queue. This behavior was partially due to the design of the media id callback which did not support encoding the necessary information. In order to resolve the media id limitations, the entire id design was re-worked and replaced with a URI which allows multiple parameters via query arguments appended to the path. The new structure is fully documented in MediaSessionBrowser.kt.
The browse-by-track menu in the library was also updated to support play-from here behavior, as we previously only played a single song. However, this was somewhat more complex due to Android Auto record size limits, and the lack of native pagination support. As part of the change, an additional menu layer is inserted if the number of records exceeds 800, which now allows the user to see their entire media collection. I originally wrote a highly optimized version which limited the number of records returned from the media library to two per page (first and last); however, it was impractical to use because Android Auto has a built-in keyboard which re-sorts media based on a modified alphabetical sort order. After much trial-and-error, I was able to re-create a high speed sort function which matches Android Auto. For maintainability I documented the equivalent regular expression in the source--regex is not used due to the significant performance penalty.
Ideally the new sort order could be incorporated into the media library down at the sqlite layer, but it is unknown if a true alphabetical (current) or modified alphabetical (Android Auto) sort is desired across all ports. For now, the results returned from the medialibrary are re-sorted before display. In order to be uniform across functions, tracks are re-sorted for the Shuffle All button as well. This yields consistency in the song number between Shuffle All and play-from-here via the library.
How Has This Been Tested?
This was tested and profiled over a period of weeks. No issues were observed.
Screenshots / GIFs (if appropriate):
The custom android auto sort allows clean separation of page content navigation via the built-in keyboard. Songs which start with "A", "An", or "The" will have their title re-ordered from "The Greatest Song" to "Greatest Song, The" for easy navigation via the intermediary pagination menu (This is the only location where the re-assembled title is used).
The pagination menu shows an abbreviation for the first song. The screenshot below shows the full song name:
The ellipsis in the pagination shown above displayed on the wrong side of Arabic and Hebrew words. In order to resolve the problem, Unicode directional marks are now added around Arabic and Hebrew (plus other RTL languages) when strings are assembled with a mixture of left-to-right and right-to-left components. This also resolves an outstanding issue with the numerator and denominator of the current track and queue size inverting due to Unicode text rules. Screenshots below are shown with the words "Artist" and "Album" in each language.
Types of changes
-
New feature (non-breaking change which adds functionality) -
Enhancement (non-breaking change which cleans up / improves existing functionality)
Checklist
-
I have read the CONTRIBUTING section of the README document.
Resolves
Fixes: #2048 (closed)