• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.systemui.util.composable.kairos
18 
19 import androidx.compose.runtime.Composable
20 import androidx.compose.runtime.LaunchedEffect
21 import androidx.compose.runtime.getValue
22 import androidx.compose.runtime.mutableStateOf
23 import androidx.compose.runtime.remember
24 import androidx.compose.runtime.setValue
25 import com.android.systemui.kairos.BuildSpec
26 import com.android.systemui.kairos.ExperimentalKairosApi
27 import com.android.systemui.kairos.KairosNetwork
28 import com.android.systemui.kairos.awaitClose
29 import com.android.systemui.kairos.launchEffect
30 
31 /**
32  * Activates the Kairos [buildSpec] within [kairosNetwork], bound to the current composition.
33  *
34  * [block] will be invoked with the result of activating the [buildSpec]. [buildSpec] will be
35  * deactivated automatically when [ActivatedKairosSpec] leaves the composition.
36  */
37 @ExperimentalKairosApi
38 @Composable
ActivatedKairosSpecnull39 fun <T> ActivatedKairosSpec(
40     buildSpec: BuildSpec<T>,
41     kairosNetwork: KairosNetwork,
42     block: @Composable (T) -> Unit,
43 ) {
44     val uninit = Any()
45     var state by remember { mutableStateOf<Any?>(uninit) }
46     LaunchedEffect(key1 = Unit) {
47         kairosNetwork.activateSpec {
48             val v = buildSpec.applySpec()
49             launchEffect {
50                 state = v
51                 awaitClose { state = uninit }
52             }
53         }
54     }
55     state.let {
56         if (it !== uninit) {
57             @Suppress("UNCHECKED_CAST") block(it as T)
58         }
59     }
60 }
61