1*d57664e9SAndroid Build Coastguard Worker# The Scene Framework 2*d57664e9SAndroid Build Coastguard Worker 3*d57664e9SAndroid Build Coastguard WorkerKnown internally as "Flexiglass", this framework defines a graph where each node 4*d57664e9SAndroid Build Coastguard Workeris a "scene" and each edge between the scenes is a transition. The scenes are 5*d57664e9SAndroid Build Coastguard Workerthe main components of System UI, on phones these are: the lockscreen, bouncer, 6*d57664e9SAndroid Build Coastguard Workershade, and quick settings panels/views/screens). Each scene is a standalone 7*d57664e9SAndroid Build Coastguard Workerexperience. 8*d57664e9SAndroid Build Coastguard Worker 9*d57664e9SAndroid Build Coastguard WorkerThe **main goal** of the framework is to increase code health by applying 10*d57664e9SAndroid Build Coastguard Worker[Separation of concerns](https://en.wikipedia.org/wiki/Separation_of_concerns) 11*d57664e9SAndroid Build Coastguard Workerover several dimensions: 12*d57664e9SAndroid Build Coastguard Worker 13*d57664e9SAndroid Build Coastguard Worker1. Each scene is a standalone piece of UI; their code doesn't need to concern 14*d57664e9SAndroid Build Coastguard Worker itself with either transition animations or anything in other scenes. This 15*d57664e9SAndroid Build Coastguard Worker frees the developer to be able to focus only on the content of the UI for 16*d57664e9SAndroid Build Coastguard Worker that scene. 17*d57664e9SAndroid Build Coastguard Worker2. Transition definitions (which scene leads to which other scene following 18*d57664e9SAndroid Build Coastguard Worker which user action) are pulled out and separated from the content of the UI. 19*d57664e9SAndroid Build Coastguard Worker3. Transition animations (the effects that happen alongside the gradual change 20*d57664e9SAndroid Build Coastguard Worker from one scene to another) are also pulled out and separated from the 21*d57664e9SAndroid Build Coastguard Worker content of the UI. 22*d57664e9SAndroid Build Coastguard Worker 23*d57664e9SAndroid Build Coastguard WorkerIn addition to the above, some of the **secondary goals** are: 24*d57664e9SAndroid Build Coastguard Worker 25*d57664e9SAndroid Build Coastguard Worker4. Make **customization easier**: by separating scenes to standalone pieces, it 26*d57664e9SAndroid Build Coastguard Workerbecomes possible for variant owners and OEMs to exclude or replace certain scenes 27*d57664e9SAndroid Build Coastguard Workeror to add brand-new scenes. 28*d57664e9SAndroid Build Coastguard Worker5. **Enable modularization**: by separating scenes to standalone pieces, it 29*d57664e9SAndroid Build Coastguard Workerbecomes possible to break down System UI into smaller codebases, each one of 30*d57664e9SAndroid Build Coastguard Workerwhich could be built on its own. Note: this isn't part of the scene framework 31*d57664e9SAndroid Build Coastguard Workeritself but is something that can be done more easily once the scene framework 32*d57664e9SAndroid Build Coastguard Workeris in place. 33*d57664e9SAndroid Build Coastguard Worker 34*d57664e9SAndroid Build Coastguard Worker## Terminology 35*d57664e9SAndroid Build Coastguard Worker 36*d57664e9SAndroid Build Coastguard Worker* **Scene** a collection of UI elements in a layout that, together, make up a 37*d57664e9SAndroid Build Coastguard Worker "screen" or "page" that is as large as the container. Scenes can be 38*d57664e9SAndroid Build Coastguard Worker navigated between / transition to/from. To learn more, please see 39*d57664e9SAndroid Build Coastguard Worker [this section](#Defining-a-scene). 40*d57664e9SAndroid Build Coastguard Worker* **Element** (or "UI element") a single unit of UI within a scene. One scene 41*d57664e9SAndroid Build Coastguard Worker can arrange multiple elements within a layout structure. 42*d57664e9SAndroid Build Coastguard Worker* **Transition** the gradual switching from one scene to another scene. There 43*d57664e9SAndroid Build Coastguard Worker are two kinds: [user-driven](Scene-navigation) and 44*d57664e9SAndroid Build Coastguard Worker [automatic](Automatic-scene-transitions) scene transitions. 45*d57664e9SAndroid Build Coastguard Worker* **Transition animation** the set of UI effects that occurs while/during a 46*d57664e9SAndroid Build Coastguard Worker transition. These can apply to the entire scene or to specific elements in 47*d57664e9SAndroid Build Coastguard Worker the scene. To learn more, please see 48*d57664e9SAndroid Build Coastguard Worker [this section](#Scene-transition-animations). 49*d57664e9SAndroid Build Coastguard Worker* **Scene container** (or just "container") the root piece of UI (typically a 50*d57664e9SAndroid Build Coastguard Worker `@Composable` function) that sets up all the scenes, their transitions, etc. 51*d57664e9SAndroid Build Coastguard Worker To learn more, please see [this section](#Scene-container). 52*d57664e9SAndroid Build Coastguard Worker* **Container configuration** (or just "configuration") the collection of 53*d57664e9SAndroid Build Coastguard Worker scenes and some added information about the desired behaviour of a 54*d57664e9SAndroid Build Coastguard Worker container. To learn more, please see 55*d57664e9SAndroid Build Coastguard Worker [this section](#Scene-container-configuration). 56*d57664e9SAndroid Build Coastguard Worker 57*d57664e9SAndroid Build Coastguard Worker## Enabling the framework 58*d57664e9SAndroid Build Coastguard Worker 59*d57664e9SAndroid Build Coastguard WorkerAs of the end of 2023, the scene framework is under development; as such, it is 60*d57664e9SAndroid Build Coastguard Workerdisabled by default. For those who are interested in a preview, please follow 61*d57664e9SAndroid Build Coastguard Workerthe instructions below to turn it on. 62*d57664e9SAndroid Build Coastguard Worker 63*d57664e9SAndroid Build Coastguard WorkerNOTE: in case these instructions become stale and don't actually enable the 64*d57664e9SAndroid Build Coastguard Workerframework, please make sure `SceneContainerFlag.isEnabled` in the 65*d57664e9SAndroid Build Coastguard Worker[`SceneContainerFlag.kt`](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlag.kt) 66*d57664e9SAndroid Build Coastguard Workerfile evaluates to `true`. 67*d57664e9SAndroid Build Coastguard Worker 68*d57664e9SAndroid Build Coastguard Worker1. Set a collection of **aconfig flags** to `true` by running the following 69*d57664e9SAndroid Build Coastguard Worker commands: 70*d57664e9SAndroid Build Coastguard Worker ```console 71*d57664e9SAndroid Build Coastguard Worker $ adb shell device_config override systemui com.android.systemui.keyguard_bottom_area_refactor true 72*d57664e9SAndroid Build Coastguard Worker $ adb shell device_config override systemui com.android.systemui.keyguard_wm_state_refactor true 73*d57664e9SAndroid Build Coastguard Worker $ adb shell device_config override systemui com.android.systemui.migrate_clocks_to_blueprint true 74*d57664e9SAndroid Build Coastguard Worker $ adb shell device_config override systemui com.android.systemui.notification_avalanche_throttle_hun true 75*d57664e9SAndroid Build Coastguard Worker $ adb shell device_config override systemui com.android.systemui.predictive_back_sysui true 76*d57664e9SAndroid Build Coastguard Worker $ adb shell device_config override systemui com.android.systemui.scene_container true 77*d57664e9SAndroid Build Coastguard Worker ``` 78*d57664e9SAndroid Build Coastguard Worker2. **Restart** System UI by issuing the following command: 79*d57664e9SAndroid Build Coastguard Worker ```console 80*d57664e9SAndroid Build Coastguard Worker $ adb shell am crash com.android.systemui 81*d57664e9SAndroid Build Coastguard Worker ``` 82*d57664e9SAndroid Build Coastguard Worker3. **Verify** that the scene framework was turned on. There are two ways to do 83*d57664e9SAndroid Build Coastguard Worker this: 84*d57664e9SAndroid Build Coastguard Worker 85*d57664e9SAndroid Build Coastguard Worker *(a)* look for the sash/ribbon UI at the bottom-right corner of the display: 86*d57664e9SAndroid Build Coastguard Worker  87*d57664e9SAndroid Build Coastguard Worker 88*d57664e9SAndroid Build Coastguard Worker NOTE: this will be removed proper to the actual release of the framework. 89*d57664e9SAndroid Build Coastguard Worker 90*d57664e9SAndroid Build Coastguard Worker *(b)* Turn on logging and look for the logging statements in `logcat`: 91*d57664e9SAndroid Build Coastguard Worker ```console 92*d57664e9SAndroid Build Coastguard Worker 93*d57664e9SAndroid Build Coastguard Worker # Turn on logging from the framework: 94*d57664e9SAndroid Build Coastguard Worker 95*d57664e9SAndroid Build Coastguard Worker $ adb shell cmd statusbar echo -b SceneFramework:verbose 96*d57664e9SAndroid Build Coastguard Worker 97*d57664e9SAndroid Build Coastguard Worker### Checking if the framework is enabled 98*d57664e9SAndroid Build Coastguard Worker 99*d57664e9SAndroid Build Coastguard WorkerLook for the log statements from the framework: 100*d57664e9SAndroid Build Coastguard Worker 101*d57664e9SAndroid Build Coastguard Worker```console 102*d57664e9SAndroid Build Coastguard Worker$ adb logcat -v time SceneFramework:* *:S 103*d57664e9SAndroid Build Coastguard Worker``` 104*d57664e9SAndroid Build Coastguard Worker 105*d57664e9SAndroid Build Coastguard Worker### Disabling the framework 106*d57664e9SAndroid Build Coastguard Worker 107*d57664e9SAndroid Build Coastguard WorkerTo **disable** the framework, simply turn off the main aconfig flag: 108*d57664e9SAndroid Build Coastguard Worker 109*d57664e9SAndroid Build Coastguard Worker```console 110*d57664e9SAndroid Build Coastguard Worker$ adb shell device_config put systemui com.android.systemui.scene_container false 111*d57664e9SAndroid Build Coastguard Worker``` 112*d57664e9SAndroid Build Coastguard Worker 113*d57664e9SAndroid Build Coastguard Worker## Defining a scene 114*d57664e9SAndroid Build Coastguard Worker 115*d57664e9SAndroid Build Coastguard WorkerBy default, the framework ships with fully functional scenes as enumarated 116*d57664e9SAndroid Build Coastguard Worker[here](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneKey.kt). 117*d57664e9SAndroid Build Coastguard WorkerShould a variant owner or OEM want to replace or add a new scene, they could 118*d57664e9SAndroid Build Coastguard Workerdo so by defining their own scene. This section describes how to do that. 119*d57664e9SAndroid Build Coastguard Worker 120*d57664e9SAndroid Build Coastguard WorkerEach scene is defined as an implementation of the 121*d57664e9SAndroid Build Coastguard Worker[`Scene`](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/Scene.kt) 122*d57664e9SAndroid Build Coastguard Workerinterface, which has three parts: 1. The `key` property returns the 123*d57664e9SAndroid Build Coastguard Worker[`SceneKey`](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneKey.kt) 124*d57664e9SAndroid Build Coastguard Workerthat uniquely identifies that scene 2. The `userActions` `Flow` returns 125*d57664e9SAndroid Build Coastguard Workerthe (potentially ever-changing) set of navigation edges to other content, based 126*d57664e9SAndroid Build Coastguard Workeron user-actions, which is how the navigation graph is defined (see 127*d57664e9SAndroid Build Coastguard Worker[the Scene navigation](#Scene-navigation) section for more) 3. The `Content` 128*d57664e9SAndroid Build Coastguard Workerfunction which uses 129*d57664e9SAndroid Build Coastguard Worker[Jetpack Compose](https://developer.android.com/jetpack/compose) to declare of 130*d57664e9SAndroid Build Coastguard Workerthe UI itself. This is the UI "at rest", e.g. once there is no transition 131*d57664e9SAndroid Build Coastguard Workerbetween any two scenes. The Scene Framework has other ways to define how the 132*d57664e9SAndroid Build Coastguard Workercontent of your UI changes with and throughout a transition to learn more please 133*d57664e9SAndroid Build Coastguard Workersee the [Scene transition animations](#Scene-transition-animations) section 134*d57664e9SAndroid Build Coastguard Worker 135*d57664e9SAndroid Build Coastguard WorkerFor example: 136*d57664e9SAndroid Build Coastguard Worker 137*d57664e9SAndroid Build Coastguard Worker```kotlin 138*d57664e9SAndroid Build Coastguard Worker@SysUISingleton class YourScene @Inject constructor( /* your dependencies here */ ) : Scene { 139*d57664e9SAndroid Build Coastguard Worker override val key = SceneKey.YourScene 140*d57664e9SAndroid Build Coastguard Worker 141*d57664e9SAndroid Build Coastguard Worker override val userActions: StateFlow<Map<UserAction, SceneModel>> = 142*d57664e9SAndroid Build Coastguard Worker MutableStateFlow<Map<UserAction, SceneModel>>( 143*d57664e9SAndroid Build Coastguard Worker mapOf( 144*d57664e9SAndroid Build Coastguard Worker // This is where scene navigation is defined, more on that below. 145*d57664e9SAndroid Build Coastguard Worker ) 146*d57664e9SAndroid Build Coastguard Worker ).asStateFlow() 147*d57664e9SAndroid Build Coastguard Worker 148*d57664e9SAndroid Build Coastguard Worker @Composable 149*d57664e9SAndroid Build Coastguard Worker override fun SceneScope.Content( 150*d57664e9SAndroid Build Coastguard Worker modifier: Modifier, 151*d57664e9SAndroid Build Coastguard Worker ) { 152*d57664e9SAndroid Build Coastguard Worker // This is where the UI is defined using Jetpack Compose. 153*d57664e9SAndroid Build Coastguard Worker } 154*d57664e9SAndroid Build Coastguard Worker} 155*d57664e9SAndroid Build Coastguard Worker``` 156*d57664e9SAndroid Build Coastguard Worker 157*d57664e9SAndroid Build Coastguard Worker### Injecting scenes 158*d57664e9SAndroid Build Coastguard Worker 159*d57664e9SAndroid Build Coastguard WorkerScenes are injected into the Dagger dependency graph from the 160*d57664e9SAndroid Build Coastguard Worker[`SceneModule`](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/ui/composable/SceneModule.kt;l=35-50;drc=564f233d5b597aedf06961c76e582464eebe8ba6). 161*d57664e9SAndroid Build Coastguard Worker 162*d57664e9SAndroid Build Coastguard Worker## Scene navigation 163*d57664e9SAndroid Build Coastguard Worker 164*d57664e9SAndroid Build Coastguard WorkerAs seen above, each scene is responsible for providing an observable `Flow` of a 165*d57664e9SAndroid Build Coastguard Worker`Map` that connects `UserAction` (for example: swipe down, swipe up, back 166*d57664e9SAndroid Build Coastguard Workerbutton/gesture, etc.) keys to `SceneModel` destinations. This is how the scene 167*d57664e9SAndroid Build Coastguard Workernavigation graph is defined. 168*d57664e9SAndroid Build Coastguard Worker 169*d57664e9SAndroid Build Coastguard WorkerNOTE: this controls *only* user-input based navigation. To learn about the other 170*d57664e9SAndroid Build Coastguard Workertype of scene navigation, please see the 171*d57664e9SAndroid Build Coastguard Worker[Automatic scene transitions](#Automatic-scene-transitions) section. 172*d57664e9SAndroid Build Coastguard Worker 173*d57664e9SAndroid Build Coastguard WorkerBecause this is a `Flow`, scene implemetations should feel free to emit new 174*d57664e9SAndroid Build Coastguard Workervalues over time. For example, the `Lockscreen` scene ties the "swipe up" user 175*d57664e9SAndroid Build Coastguard Workeraction to go to the `Bouncer` scene if the device is still locked or to go to 176*d57664e9SAndroid Build Coastguard Workerthe `Gone` scene if the device is unlocked, allowing the user to dismiss the 177*d57664e9SAndroid Build Coastguard Workerlockscreen UI when not locked. 178*d57664e9SAndroid Build Coastguard Worker 179*d57664e9SAndroid Build Coastguard Worker## Scene transition animations 180*d57664e9SAndroid Build Coastguard Worker 181*d57664e9SAndroid Build Coastguard WorkerThe Scene Framework separates transition animations from content UI declaration 182*d57664e9SAndroid Build Coastguard Workerby placing the definition of the former in a different location. This way, 183*d57664e9SAndroid Build Coastguard Workerthere's no longer a need to contaminate the content UI declaration with 184*d57664e9SAndroid Build Coastguard Workeranimation logic, a practice that becomes unscalable over time. 185*d57664e9SAndroid Build Coastguard Worker 186*d57664e9SAndroid Build Coastguard WorkerUnder the hood, the Scene Framework uses 187*d57664e9SAndroid Build Coastguard Worker[`SceneTransitionLayout`](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SceneTransitionLayout.kt), 188*d57664e9SAndroid Build Coastguard Workera `@Composable` function designed with scene graph and transitions in mind. In 189*d57664e9SAndroid Build Coastguard Workerfact, the Scene Framework is merely a shallow wrapper around 190*d57664e9SAndroid Build Coastguard Worker`SceneTransitionLayout`. 191*d57664e9SAndroid Build Coastguard Worker 192*d57664e9SAndroid Build Coastguard WorkerThe `SceneTransitionLayout` API requires the transitions to be passed-in 193*d57664e9SAndroid Build Coastguard Workerseparately from the scenes themselves. In System UI, the transitions can be 194*d57664e9SAndroid Build Coastguard Workerfound in 195*d57664e9SAndroid Build Coastguard Worker[`SceneContainerTransitions`](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt). 196*d57664e9SAndroid Build Coastguard WorkerAs you can see, each possible scene-to-scene transition has its own builder, 197*d57664e9SAndroid Build Coastguard Workerhere's one example: 198*d57664e9SAndroid Build Coastguard Worker 199*d57664e9SAndroid Build Coastguard Worker```kotlin 200*d57664e9SAndroid Build Coastguard Workerfun TransitionBuilder.lockscreenToShadeTransition() { 201*d57664e9SAndroid Build Coastguard Worker spec = tween(durationMillis = 500) 202*d57664e9SAndroid Build Coastguard Worker 203*d57664e9SAndroid Build Coastguard Worker punchHole(Shade.Elements.QuickSettings, bounds = Shade.Elements.Scrim, Shade.Shapes.Scrim) 204*d57664e9SAndroid Build Coastguard Worker translate(Shade.Elements.Scrim, Edge.Top, startsOutsideLayoutBounds = false) 205*d57664e9SAndroid Build Coastguard Worker fractionRange(end = 0.5f) { 206*d57664e9SAndroid Build Coastguard Worker fade(Shade.Elements.ScrimBackground) 207*d57664e9SAndroid Build Coastguard Worker translate( 208*d57664e9SAndroid Build Coastguard Worker QuickSettings.Elements.CollapsedGrid, 209*d57664e9SAndroid Build Coastguard Worker Edge.Top, 210*d57664e9SAndroid Build Coastguard Worker startsOutsideLayoutBounds = false, 211*d57664e9SAndroid Build Coastguard Worker ) 212*d57664e9SAndroid Build Coastguard Worker } 213*d57664e9SAndroid Build Coastguard Worker fractionRange(start = 0.5f) { fade(Notifications.Elements.Notifications) } 214*d57664e9SAndroid Build Coastguard Worker} 215*d57664e9SAndroid Build Coastguard Worker``` 216*d57664e9SAndroid Build Coastguard Worker 217*d57664e9SAndroid Build Coastguard WorkerGoing through the example code: 218*d57664e9SAndroid Build Coastguard Worker 219*d57664e9SAndroid Build Coastguard Worker* The `spec` is the animation that should be invoked, in the example above, we use a `tween` 220*d57664e9SAndroid Build Coastguard Workeranimation with a duration of 500 milliseconds 221*d57664e9SAndroid Build Coastguard Worker* Then there's a series of function calls: `punchHole` applies a clip mask to the `Scrim` 222*d57664e9SAndroid Build Coastguard Workerelement in the destination scene (in this case it's the `Shade` scene) which has the 223*d57664e9SAndroid Build Coastguard Workerposition and size determined by the `bounds` parameter and the shape passed into the `shape` 224*d57664e9SAndroid Build Coastguard Workerparameter. This lets the `Lockscreen` scene render "through" the `Shade` scene 225*d57664e9SAndroid Build Coastguard Worker* The `translate` call shifts the `Scrim` element to/from the `Top` edge of the scene container 226*d57664e9SAndroid Build Coastguard Worker* The first `fractionRange` wrapper tells the system to apply its contained functions 227*d57664e9SAndroid Build Coastguard Workeronly during the first half of the transition. Inside of it, we see a `fade` of 228*d57664e9SAndroid Build Coastguard Workerthe `ScrimBackground` element and a `translate` o the `CollpasedGrid` element 229*d57664e9SAndroid Build Coastguard Workerto/from the `Top` edge 230*d57664e9SAndroid Build Coastguard Worker* The second `fractionRange` only starts at the second half of the transition (e.g. when 231*d57664e9SAndroid Build Coastguard Workerthe previous one ends) and applies a `fade` on the `Notifications` element 232*d57664e9SAndroid Build Coastguard Worker 233*d57664e9SAndroid Build Coastguard WorkerYou can find the actual documentation for this API 234*d57664e9SAndroid Build Coastguard Worker[here](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/TransitionDsl.kt). 235*d57664e9SAndroid Build Coastguard Worker 236*d57664e9SAndroid Build Coastguard Worker### Tagging elements 237*d57664e9SAndroid Build Coastguard Worker 238*d57664e9SAndroid Build Coastguard WorkerAs demonstrated above, elements within a scene can be addressed from transition 239*d57664e9SAndroid Build Coastguard Workerdefintions. In order to "tag" an element with a specific `ElementKey`, the 240*d57664e9SAndroid Build Coastguard Worker[`element` modifier](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SceneTransitionLayout.kt) 241*d57664e9SAndroid Build Coastguard Workermust be used on the composable that declared that element's UI: 242*d57664e9SAndroid Build Coastguard Worker 243*d57664e9SAndroid Build Coastguard Worker```kotlin 244*d57664e9SAndroid Build Coastguard WorkerText( 245*d57664e9SAndroid Build Coastguard Worker text = "Some text", 246*d57664e9SAndroid Build Coastguard Worker modifier = Modifier.element(MyElements.SomeText), 247*d57664e9SAndroid Build Coastguard Worker) 248*d57664e9SAndroid Build Coastguard Worker``` 249*d57664e9SAndroid Build Coastguard Worker 250*d57664e9SAndroid Build Coastguard WorkerIn addition to the ability to refer to a tagged element in transition 251*d57664e9SAndroid Build Coastguard Workerdefinitions, if the same `ElementKey` is used for one element in the current 252*d57664e9SAndroid Build Coastguard Workerscene and another element in the destination scene, the element is considered to 253*d57664e9SAndroid Build Coastguard Workerbe a **shared element**. As such, the framework automatically translates and 254*d57664e9SAndroid Build Coastguard Workerscales the bounds of the shared element from its current bounds in the source 255*d57664e9SAndroid Build Coastguard Workerscene to its final bounds in the destination scene. 256*d57664e9SAndroid Build Coastguard Worker 257*d57664e9SAndroid Build Coastguard Worker## Scene container 258*d57664e9SAndroid Build Coastguard Worker 259*d57664e9SAndroid Build Coastguard WorkerTo set up a scene framework instance, a scene container must be declared. This 260*d57664e9SAndroid Build Coastguard Workeris the root of an entire scene graph that puts together the scenes, their 261*d57664e9SAndroid Build Coastguard Workertransitions, and the configuration. The container is then added to a parent 262*d57664e9SAndroid Build Coastguard Worker`@Composable` or `View` so it can be displayed. 263*d57664e9SAndroid Build Coastguard Worker 264*d57664e9SAndroid Build Coastguard WorkerThe default scene container in System UI is defined in the 265*d57664e9SAndroid Build Coastguard Worker[`SceneContainer.kt` file](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt). 266*d57664e9SAndroid Build Coastguard Worker 267*d57664e9SAndroid Build Coastguard Worker### Scene container configuration 268*d57664e9SAndroid Build Coastguard Worker 269*d57664e9SAndroid Build Coastguard WorkerThe `SceneContainer` function is passed a few parameters including a view-model 270*d57664e9SAndroid Build Coastguard Workerand a set of scenes. The exact details of what gets passed in depends on the 271*d57664e9SAndroid Build Coastguard Worker[`SceneContainerConfig` object](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerConfig.kt) 272*d57664e9SAndroid Build Coastguard Workerwhich is injected into the Dagger dependency graph 273*d57664e9SAndroid Build Coastguard Worker[here](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerConfigModule.kt). 274*d57664e9SAndroid Build Coastguard Worker 275*d57664e9SAndroid Build Coastguard Worker## Automatic scene transitions 276*d57664e9SAndroid Build Coastguard Worker 277*d57664e9SAndroid Build Coastguard WorkerThe scene framework supports the ability for scenes to change automatically 278*d57664e9SAndroid Build Coastguard Workerbased on device state or events other than direct user input. For example: when 279*d57664e9SAndroid Build Coastguard Workerthe device is locked, there's an automatic scene transition to the `Lockscreen` 280*d57664e9SAndroid Build Coastguard Workerscene. 281*d57664e9SAndroid Build Coastguard Worker 282*d57664e9SAndroid Build Coastguard WorkerThis logic is contained within the 283*d57664e9SAndroid Build Coastguard Worker[`SceneContainerStartable`](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt) 284*d57664e9SAndroid Build Coastguard Workerclass. 285*d57664e9SAndroid Build Coastguard Worker 286*d57664e9SAndroid Build Coastguard Worker## Side-effects 287*d57664e9SAndroid Build Coastguard Worker 288*d57664e9SAndroid Build Coastguard WorkerSimilarly to [the above](#Automatic-scene-transitions), the 289*d57664e9SAndroid Build Coastguard Worker`SceneContainerStartable` also handles side-effects by updating other parts of 290*d57664e9SAndroid Build Coastguard Workerthe System UI codebase whenever internal scene framework state changes. As an 291*d57664e9SAndroid Build Coastguard Workerexample: the visibility of the `View` that contains our 292*d57664e9SAndroid Build Coastguard Worker[scene container](#Scene-container) is updated every time there's a transition 293*d57664e9SAndroid Build Coastguard Workerto or from the `Gone` scene. 294*d57664e9SAndroid Build Coastguard Worker 295*d57664e9SAndroid Build Coastguard Worker## Observing scene transition state 296*d57664e9SAndroid Build Coastguard Worker 297*d57664e9SAndroid Build Coastguard WorkerThere are a couple of ways to observe the transition state: 298*d57664e9SAndroid Build Coastguard Worker 299*d57664e9SAndroid Build Coastguard Worker1. [Easiest] using the `SceneScope` of the scene container, simply use the 300*d57664e9SAndroid Build Coastguard Worker `animateSharedXAsState` API, the full list is 301*d57664e9SAndroid Build Coastguard Worker [here](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/AnimateSharedAsState.kt). 302*d57664e9SAndroid Build Coastguard Worker2. [Harder] if outside the `SceneScope` of the scene container, observe 303*d57664e9SAndroid Build Coastguard Worker [`SceneInteractor.transitionState`](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt;l=88;drc=af57d5e49431c6728e7cf192bada88e0541ebf0c). 304*d57664e9SAndroid Build Coastguard Worker 305*d57664e9SAndroid Build Coastguard Worker## Dependency Injection 306*d57664e9SAndroid Build Coastguard Worker 307*d57664e9SAndroid Build Coastguard WorkerThe entire framework is provided into the Dagger dependency graph from the 308*d57664e9SAndroid Build Coastguard Workertop-level Dagger module at 309*d57664e9SAndroid Build Coastguard Worker[`SceneContainerFrameworkModule`](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt) 310*d57664e9SAndroid Build Coastguard Workerthis puts together the scenes from `SceneModule`, the configuration from 311*d57664e9SAndroid Build Coastguard Worker`SceneContainerConfigModule`, and the startable from 312*d57664e9SAndroid Build Coastguard Worker`SceneContainerStartableModule`. 313*d57664e9SAndroid Build Coastguard Worker 314*d57664e9SAndroid Build Coastguard Worker## Integration Notes 315*d57664e9SAndroid Build Coastguard Worker 316*d57664e9SAndroid Build Coastguard Worker### Relationship to Jetpack Compose 317*d57664e9SAndroid Build Coastguard Worker 318*d57664e9SAndroid Build Coastguard WorkerThe scene framework depends on Jetpack Compose; therefore, compiling System UI with 319*d57664e9SAndroid Build Coastguard WorkerJetpack Compose is required. However, because Jetpack Compose and Android Views 320*d57664e9SAndroid Build Coastguard Worker[interoperate](https://developer.android.com/jetpack/compose/migrate/interoperability-apis/views-in-compose), 321*d57664e9SAndroid Build Coastguard Workerthe UI in each scene doesn't necessarily need to be a pure hierarchy of `@Composable` 322*d57664e9SAndroid Build Coastguard Workerfunctions; instead, it's acceptable to use an `AndroidView` somewhere in the 323*d57664e9SAndroid Build Coastguard Workerhierarchy of composable functions to include a `View` or `ViewGroup` subtree. 324*d57664e9SAndroid Build Coastguard Worker 325*d57664e9SAndroid Build Coastguard Worker#### Interoperability with Views 326*d57664e9SAndroid Build Coastguard WorkerThe scene framework comes with built-in functionality to animate the entire scene and/or 327*d57664e9SAndroid Build Coastguard Workerelements within the scene in-tandem with the actual scene transition progress. 328*d57664e9SAndroid Build Coastguard Worker 329*d57664e9SAndroid Build Coastguard WorkerFor example, as the user drags their finger down rom the top of the lockscreen, 330*d57664e9SAndroid Build Coastguard Workerthe shade scene becomes visible and gradually expands, the amount of expansion tracks 331*d57664e9SAndroid Build Coastguard Workerthe movement of the finger. 332*d57664e9SAndroid Build Coastguard Worker 333*d57664e9SAndroid Build Coastguard WorkerThat feature of the framework uses a custom `element(ElementKey)` Jetpack Compose 334*d57664e9SAndroid Build Coastguard Worker`Modifier` to refer to elements within a scene. 335*d57664e9SAndroid Build Coastguard WorkerThe transition builders then use the same `ElementKey` objects to refer to those elements 336*d57664e9SAndroid Build Coastguard Workerand describe how they animate in-tandem with scene transitions. Because this is a 337*d57664e9SAndroid Build Coastguard WorkerJetpack Compose `Modifier`, it means that, in order for an element in a scene to be 338*d57664e9SAndroid Build Coastguard Workeranimated automatically by the framework, that element must be nested within a pure 339*d57664e9SAndroid Build Coastguard Worker`@Composable` hierarchy. The element itself is allowed to be a classic Android `View` 340*d57664e9SAndroid Build Coastguard Worker(nested within a Jetpack Compose `AndroidView`) but all ancestors must be `@Composable` 341*d57664e9SAndroid Build Coastguard Workerfunctions. 342*d57664e9SAndroid Build Coastguard Worker 343*d57664e9SAndroid Build Coastguard Worker### Notifications 344*d57664e9SAndroid Build Coastguard Worker 345*d57664e9SAndroid Build Coastguard WorkerAs of January 2024, the integration of notifications and heads-up notifications (HUNs) 346*d57664e9SAndroid Build Coastguard Workerinto the scene framework follows an unusual pattern. We chose this pattern due to migration 347*d57664e9SAndroid Build Coastguard Workerrisk and performance concerns but will eventually replace it with the more common element 348*d57664e9SAndroid Build Coastguard Workerplacement pattern that all other elements are following. 349*d57664e9SAndroid Build Coastguard Worker 350*d57664e9SAndroid Build Coastguard WorkerThe special pattern for notifications is that, instead of the notification list 351*d57664e9SAndroid Build Coastguard Worker(`NotificationStackScrollLayout` or "NSSL", which also displays HUNs) being placed in the element 352*d57664e9SAndroid Build Coastguard Workerhierarchy within the scenes that display notifications, the NSSL (which continues to be an Android View) 353*d57664e9SAndroid Build Coastguard Worker"floats" above the scene container, rendering on top of everything. This is very similar to 354*d57664e9SAndroid Build Coastguard Workerhow NSSL is integrated with the legacy shade, prior to the scene framework. 355*d57664e9SAndroid Build Coastguard Worker 356*d57664e9SAndroid Build Coastguard WorkerIn order to render the NSSL as if it's part of the organic hierarchy of elements within its 357*d57664e9SAndroid Build Coastguard Workerscenes, we control the NSSL's self-imposed effective bounds (e.g. position offsets, clip path, 358*d57664e9SAndroid Build Coastguard Workersize) from `@Composable` elements within the normal scene hierarchy. These special 359*d57664e9SAndroid Build Coastguard Worker"placeholder" elements can be found 360*d57664e9SAndroid Build Coastguard Worker[here](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt). 361*d57664e9SAndroid Build Coastguard Worker 362