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 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