xref: /aosp_15_r20/frameworks/base/packages/SystemUI/docs/scene.md (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
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    ![ribbon](imgs/ribbon.png)
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