appsuite_media_api_common_frontend

Media sources library: a library to create and customize rich user interfaces for media playback.

This library has two purposes:

  • Create rich user interfaces to browse media content provided by third-party media sources. This library provides functionality to support additional media sources on top of the ones provided in the stock TomTom IndiGO distribution, and additionally enables to create an entirely new frontend.

  • Configure the stock media frontend to add and remove support for media sources.

This library expands upon appsuite_media_api_common_core, the base media support library. It doesn't target a specific media source, but it's a flexible and generic base to expand upon.

The following sections explain the two use cases.

Creating user interfaces

Whether it's about adding specific support for a source, or whether it's about creating a new frontend, this library has some useful tools. The main concepts are #panel, #media-controls and #policies, all bound together by #configuring-the-stock-media-frontend.

Panel

This library can be used to create custom media panels that fit in with the rest of the media frontend. The MediaTaskPanel is the common base class of all media panels: maximized task panels with a MediaFrontendContext to hold all relevant data.

Using this base class reduces the amount of boiler plate code to be written in panels, fragments and view models.

The media dashboard is the panel in the stock TomTom IndiGO distribution that becomes visible when selecting the "Media" menu button within TomTom IndiGO. When selecting one of the shown media sources, the framework uses the MediaTaskPanelPolicy specified in a PolicyProvider to create a panel of type MediaTaskPanel to use as root navigation level for that media source. The same factory is then used to create further types of panels, such as a search panel.

One interesting bit about panels is on the placement of media items, the layout. Items can be displayed as a list or as a grid. The LayoutPolicy determines how each item is displayed, using the properties of the currently displayed IviMediaItems and of their parent item (container).

When a user select the source they want to browse or play, multiple MediaTaskPanels can be created.

Media controls

A media control is a visual control for a media-related command. It can be used anywhere the user can interact with active media; it can transform an action into a clickable button. A media control can signal whether it's available. It is possible to base this availability on whether the media source, like an app, exposes an action as being available. When a track (or a radio station, or any kind of media) is playing, a certain number of Actions are associated with it. For example, when the last track of an album is playing, it should not be possible to skip to a next track, and thus the available actions might be: "previous", "pause", "like this song".

There are two types of media controls:

  • Standard media controls. The media controls that are built into TomTom IndiGO, see StandardMediaControls. These are used across all sources.

  • Custom media controls. All other media controls. Usually specifically created for one source, though not always restricted to it.

The most common use case for custom media controls is to implement a custom action. Custom actions can be used by a source to extend the capabilities of the standard media controls by exposing app-specific actions.

Creating a custom media control

When creating a custom media control, use one of these classes as its parent:

  • MediaControl. Use it because it is the simplest, most light-weight media control. It gives the developer full control over what the control should do.

  • ActionMediaControl. Use it to perform an Action on a media source.

Media controls are created by a MediaControlFactory. It is recommended to have the factory as an inner class of the media control:

class MyControl : MediaControl {
// ...

class Factory : MediaControlFactory {
// ...
}
}

When wanting to support a specific media control, add a MediaControlFactory creating it to the MediaControlPolicy of that source. See #policies for details.

Policies

Media content offered by media sources might be a challenge to properly display to the user. The Android standard is quite well known and documented, but there are some areas where inconsistencies can occur. Policies offer a way to level those out.

Policies are the simplest way to customize the content offered by a media source, so that the stock media user interface can display it uniformly.

With policies it is for example possible to:

  • Split artist and song name for a source, which merges them into a title.

  • Ensure playlists are shown in a list instead of a grid, when the source doesn't specify a presentation hint.

  • Add track duration information when given in a non-standard way, such as in the wrong Android Bundle extra field.

Policies are defined in the PolicyProvider class. Each constructor argument to it is a policy. All policies have default values. So, while it's possible configure every policy, it's also possible to only alter a single policy.

There are several policies customizable via the PolicyProvider class. The policies package contains all available customization policies. For more information, see the media customization guide.

Configuring the stock media frontend

The stock media frontend is configurable through the MediaPolicyFrontendExtension. This is the place to activate a PolicyProvider for a specific media source. A policy provider can alter which #panel will be opened for a source, which #media-controls the user is able to access, and more. See #policies for details on available policies.

A source does not necessarily require configuration. If an installed media source has Android Automotive support, it will be picked up by the frontend. As long as there is a fallback MediaPolicyFrontendExtension, the source will be shown and will be browsable; check that class for more info about fallbacks. Configuration is only required if a more specific PolicyProvider would be more suitable for a source.

See FrontendExtension for how to add a frontend extension.

Because a lot can be done via the configuration, it's much more likely that the stock media frontend will be reusable in a specific situation, avoiding the downsides of creating a custom frontend.

The configuration is made available inside the frontend in the MediaFrontendContext.

The configuration is based on factories. This way all panels and controls can be made at the right time, in the right context.

Packages

Media source configuration and panels; this package contains all classes to configure how the content from a media source is displayed, as well as the classes to use to create new panels to realize new user experiences for specific media sources.

Media controls; the classes in this package implement the concept of #media-controls.

Standard media controls; these are default controls which are very often made available by media sources, and were implemented for convenience.

Layout policies; these classes are used to customize how content is rendered by a MediaContentView.

Media item policies; these classes are used to customize the media frontend for a specific source.

Media view models; these classes are used as view models for data binding in the media frontend views.