xref: /aosp_15_r20/frameworks/base/packages/SystemUI/docs/media-controls.md (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1*d57664e9SAndroid Build Coastguard Worker# SysUI Media Controls Pipeline
2*d57664e9SAndroid Build Coastguard Worker
3*d57664e9SAndroid Build Coastguard Worker[TOC]
4*d57664e9SAndroid Build Coastguard Worker
5*d57664e9SAndroid Build Coastguard Worker## Purpose
6*d57664e9SAndroid Build Coastguard Worker
7*d57664e9SAndroid Build Coastguard WorkerDescribe how events flow through the media controls pipeline, and provide a high level overview of what the different components do.
8*d57664e9SAndroid Build Coastguard Worker
9*d57664e9SAndroid Build Coastguard Worker## Pipeline Diagram
10*d57664e9SAndroid Build Coastguard Worker
11*d57664e9SAndroid Build Coastguard Worker![media controls pipeline](media-controls-pipeline.png)
12*d57664e9SAndroid Build Coastguard Worker
13*d57664e9SAndroid Build Coastguard Worker* Orange: External inputs
14*d57664e9SAndroid Build Coastguard Worker* Blue: Internal listeners; all except `MediaDataManager` and `ResumeMediaBrowser` implement [`MediaDataManager.Listener`](/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt#711) and receive `onMediaDataLoaded` and `onMediaDataRemoved` events
15*d57664e9SAndroid Build Coastguard Worker
16*d57664e9SAndroid Build Coastguard Worker## Classes
17*d57664e9SAndroid Build Coastguard Worker
18*d57664e9SAndroid Build Coastguard WorkerFiles under [`systemui/media/`](/packages/SystemUI/src/com/android/systemui/media/):
19*d57664e9SAndroid Build Coastguard Worker
20*d57664e9SAndroid Build Coastguard Worker* UI
21*d57664e9SAndroid Build Coastguard Worker   * `dialog/`
22*d57664e9SAndroid Build Coastguard Worker      * Output switcher dialog (maintained by Settings team)
23*d57664e9SAndroid Build Coastguard Worker   * IlluminationDrawable.kt
24*d57664e9SAndroid Build Coastguard Worker   * LightSourceDrawable.kt
25*d57664e9SAndroid Build Coastguard Worker      * These create the glow animation when you tap on a button (see [`qs_media_light_source`](/packages/SystemUI/res/drawable/qs_media_light_source.xml)). Should be reusable in other layouts.
26*d57664e9SAndroid Build Coastguard Worker   * Carousel:
27*d57664e9SAndroid Build Coastguard Worker      * MediaCarouselController.kt
28*d57664e9SAndroid Build Coastguard Worker         * Keeps the carousel view up to date and handles state changes (e.g. expansion)
29*d57664e9SAndroid Build Coastguard Worker         * Handles settings gear and page indicator
30*d57664e9SAndroid Build Coastguard Worker      * MediaCarouselScrollHandler.kt
31*d57664e9SAndroid Build Coastguard Worker         * Handles scrolling between players in the carousel
32*d57664e9SAndroid Build Coastguard Worker      * MediaScrollView.kt
33*d57664e9SAndroid Build Coastguard Worker         * Scrollview used in the carousel layout, has some custom measurement code
34*d57664e9SAndroid Build Coastguard Worker   * Individual players:
35*d57664e9SAndroid Build Coastguard Worker      * KeyguardMediaController.kt
36*d57664e9SAndroid Build Coastguard Worker         * Lockscreen media controls have a special wrapper in order to work with the existing lockscreen notification layout
37*d57664e9SAndroid Build Coastguard Worker      * MediaControlPanel.java
38*d57664e9SAndroid Build Coastguard Worker         * Main class for media control UI
39*d57664e9SAndroid Build Coastguard Worker      * SeekBarObserver.kt
40*d57664e9SAndroid Build Coastguard Worker         * Updates seekbar state
41*d57664e9SAndroid Build Coastguard Worker      * SeekBarViewModel.kt
42*d57664e9SAndroid Build Coastguard Worker         * Implements its own `computePosition()` for the seekbar (to avoid continually polling the `PlaybackState`, which involves binder calls)
43*d57664e9SAndroid Build Coastguard Worker         * Does some touch falsing (ignore flings, require drags to start near the thumb - otherwise users would often accidentally trigger the seekbar when they meant to move the carousel or shade)
44*d57664e9SAndroid Build Coastguard Worker      * MediaViewHolder.kt
45*d57664e9SAndroid Build Coastguard Worker         * Holds references to the UI elements in the panel
46*d57664e9SAndroid Build Coastguard Worker* Animation support:
47*d57664e9SAndroid Build Coastguard Worker   * MediaHierarchyManager.kt
48*d57664e9SAndroid Build Coastguard Worker      * Responsible for placement of media view and animation between hosts
49*d57664e9SAndroid Build Coastguard Worker   * MediaHost.kt
50*d57664e9SAndroid Build Coastguard Worker      * Every location that a media player could be located needs a `MediaHost`
51*d57664e9SAndroid Build Coastguard Worker      * Tracks configuration (if it should show inactive media, needs falsing, etc.)
52*d57664e9SAndroid Build Coastguard Worker   * MediaHostStatesManager.kt
53*d57664e9SAndroid Build Coastguard Worker      * Manages the various media host states and coordinates heights between different players
54*d57664e9SAndroid Build Coastguard Worker      * Has the most up to date state for any location
55*d57664e9SAndroid Build Coastguard Worker   * MediaViewController.kt
56*d57664e9SAndroid Build Coastguard Worker      * Controls a single instance of a media player, keeps the media view states up to date
57*d57664e9SAndroid Build Coastguard Worker* Backend
58*d57664e9SAndroid Build Coastguard Worker   * MediaData.kt
59*d57664e9SAndroid Build Coastguard Worker      * Holds all the media data (track info, active/resume state, etc.)
60*d57664e9SAndroid Build Coastguard Worker   * MediaDataCombineLatest.kt
61*d57664e9SAndroid Build Coastguard Worker      * Combines update events from `MediaDataManager` and `MediaDeviceManager`, so that downstream listeners will have device info
62*d57664e9SAndroid Build Coastguard Worker   * MediaDataFilter.kt
63*d57664e9SAndroid Build Coastguard Worker      * Filters media data based on the current user
64*d57664e9SAndroid Build Coastguard Worker      * Exit point for the pipeline: "external listeners" (currently `MediaHost` and `MediaCarouselController`), while they should be added via `MediaDataManager.addListener()`, will actually be listening to this output
65*d57664e9SAndroid Build Coastguard Worker   * MediaDataManager.kt
66*d57664e9SAndroid Build Coastguard Worker      * Entry point for the pipeline; initializes listener connections and assigns external listeners to the correct exit point
67*d57664e9SAndroid Build Coastguard Worker      * Converts media notifications and resumable media info into `MediaData`
68*d57664e9SAndroid Build Coastguard Worker   * MediaDeviceManager.kt
69*d57664e9SAndroid Build Coastguard Worker      * Handles device updates
70*d57664e9SAndroid Build Coastguard Worker   * MediaFeatureFlag.kt
71*d57664e9SAndroid Build Coastguard Worker      * Utility to check whether media controls are enabled
72*d57664e9SAndroid Build Coastguard Worker   * MediaSessionBasedFilter.kt
73*d57664e9SAndroid Build Coastguard Worker      * Filters media events based on media session. This prevents duplicate controls in situations like casting where we might get both a local and remote object for the same media session.
74*d57664e9SAndroid Build Coastguard Worker   * MediaTimeoutListener.kt
75*d57664e9SAndroid Build Coastguard Worker      * Listens to `PlaybackState` and marks controls inactive after the media has been paused/stopped for 10 minutes (value can be adjusted locally with `adb shell setprop debug.sysui.media_timeout [ms]`)
76*d57664e9SAndroid Build Coastguard Worker   * MediaResumeListener.kt
77*d57664e9SAndroid Build Coastguard Worker      * Listens for new media data and attempts to find a valid `MediaBrowserService` for the app. If successful, sends the information back to the `MediaDataManager`
78*d57664e9SAndroid Build Coastguard Worker      * Saves up to 5 valid `MediaBrowserService` components found this way, and queries them for recent media on boot or user change
79*d57664e9SAndroid Build Coastguard Worker      * Note: the user can disable this feature completely (or block certain apps from being resumable) in [Settings](https://source.corp.google.com/android/packages/apps/Settings/src/com/android/settings/sound/ResumableMediaAppsController.java), in which case this listener will do nothing (or ignore updates from the blocked apps).
80*d57664e9SAndroid Build Coastguard Worker   * ResumeMediaBrowser.java
81*d57664e9SAndroid Build Coastguard Worker      * Connects to an app's [`MediaBrowser`](https://developer.android.com/reference/android/media/browse/MediaBrowser) to determine whether SystemUI is able to connect and find a recent [`MediaItem`](https://developer.android.com/reference/android/media/browse/MediaBrowser.MediaItem)
82*d57664e9SAndroid Build Coastguard Worker* Factory classes (for unit testing):
83*d57664e9SAndroid Build Coastguard Worker   * LocalMediaManagerFactory.kt
84*d57664e9SAndroid Build Coastguard Worker   * MediaBrowserFactory.java
85*d57664e9SAndroid Build Coastguard Worker   * MediaControllerFactory.java
86*d57664e9SAndroid Build Coastguard Worker   * ResumeMediaBrowserFactory.java
87*d57664e9SAndroid Build Coastguard Worker
88*d57664e9SAndroid Build Coastguard Worker## Miscellaneous
89*d57664e9SAndroid Build Coastguard Worker
90*d57664e9SAndroid Build Coastguard WorkerOther useful documents:
91*d57664e9SAndroid Build Coastguard Worker
92*d57664e9SAndroid Build Coastguard Worker* [go/sysui-media-resumption-requirements](https://goto.google.com/sysui-media-resumption-requirements) - Internal documentation for app developers about how to work with media resumption
93*d57664e9SAndroid Build Coastguard Worker* [Playing nicely with media controls](https://android-developers.googleblog.com/2020/08/playing-nicely-with-media-controls.html) - blog post on the Android 11 updates
94*d57664e9SAndroid Build Coastguard Worker* [Media Controls developer guide](https://developer.android.com/guide/topics/media/media-controls)
95