[kairos] Add logging to facilitate debugging
Flag: EXEMPT unused
Test: atest kairos-tests
Change-Id: I3858504a44fe4357c8cc7c1aa4997945eb35573e
diff --git a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/FrpNetwork.kt b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/FrpNetwork.kt
index b688eaf..97252b4 100644
--- a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/FrpNetwork.kt
+++ b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/FrpNetwork.kt
@@ -137,7 +137,7 @@
override suspend fun <R> transact(block: suspend FrpTransactionScope.() -> R): R {
val result = CompletableDeferred<R>(coroutineContext[Job])
@Suppress("DeferredResultUnused")
- network.transaction {
+ network.transaction("FrpNetwork.transact") {
val buildScope =
BuildScopeImpl(
stateScope = StateScopeImpl(evalScope = this, endSignal = endSignal),
@@ -151,7 +151,7 @@
override suspend fun activateSpec(spec: FrpSpec<*>) {
val job =
network
- .transaction {
+ .transaction("FrpNetwork.activateSpec") {
val buildScope =
BuildScopeImpl(
stateScope = StateScopeImpl(evalScope = this, endSignal = endSignal),
@@ -166,7 +166,8 @@
override fun <In, Out> coalescingMutableTFlow(
coalesce: (old: Out, new: In) -> Out,
getInitialValue: () -> Out,
- ): CoalescingMutableTFlow<In, Out> = CoalescingMutableTFlow(coalesce, network, getInitialValue)
+ ): CoalescingMutableTFlow<In, Out> =
+ CoalescingMutableTFlow(null, coalesce, network, getInitialValue)
override fun <T> mutableTFlow(): MutableTFlow<T> = MutableTFlow(network)
diff --git a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/TFlow.kt b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/TFlow.kt
index c773d9c..a175e2e 100644
--- a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/TFlow.kt
+++ b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/TFlow.kt
@@ -467,12 +467,12 @@
@ExperimentalFrpApi
class CoalescingMutableTFlow<In, Out>
internal constructor(
+ internal val name: String?,
internal val coalesce: (old: Out, new: In) -> Out,
internal val network: Network,
private val getInitialValue: () -> Out,
internal val impl: InputNode<Out> = InputNode(),
) : TFlow<Out>() {
- internal val name: String? = null
internal val storage = AtomicReference(false to getInitialValue())
override fun toString(): String = "${this::class.simpleName}@$hashString"
@@ -490,7 +490,7 @@
val (scheduled, _) = storage.getAndUpdate { (_, old) -> true to coalesce(old, value) }
if (!scheduled) {
@Suppress("DeferredResultUnused")
- network.transaction {
+ network.transaction("CoalescingMutableTFlow${name?.let { "($name)" }.orEmpty()}.emit") {
impl.visit(this, storage.getAndSet(false to getInitialValue()).second)
}
}
@@ -524,7 +524,9 @@
val newEmit =
async(start = CoroutineStart.LAZY) {
jobOrNull?.join()
- network.transaction { impl.visit(this, value) }.await()
+ network
+ .transaction("MutableTFlow($name).emit") { impl.visit(this, value) }
+ .await()
}
jobOrNull = storage.getAndSet(newEmit)
newEmit.await()
diff --git a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/TState.kt b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/TState.kt
index 982d6c3..34bd509 100644
--- a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/TState.kt
+++ b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/TState.kt
@@ -457,6 +457,7 @@
private val input: CoalescingMutableTFlow<Deferred<T>, Deferred<T>?> =
CoalescingMutableTFlow(
+ name = null,
coalesce = { _, new -> new },
network = network,
getInitialValue = { null },
@@ -474,7 +475,7 @@
.cached()
state = TStateSource(name, operatorName, initialValue, calm)
@Suppress("DeferredResultUnused")
- network.transaction {
+ network.transaction("MutableTState.init") {
calm.activate(evalScope = this, downstream = Schedulable.S(state))?.let {
(connection, needsEval) ->
state.upstreamConnection = connection
diff --git a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/BuildScopeImpl.kt b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/BuildScopeImpl.kt
index 86f35f7..7e63849 100644
--- a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/BuildScopeImpl.kt
+++ b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/BuildScopeImpl.kt
@@ -85,7 +85,7 @@
builder: suspend S.() -> Unit,
): TFlow<A> {
var job: Job? = null
- val stopEmitter = newStopEmitter()
+ val stopEmitter = newStopEmitter("buildTFlow")
// Create a child scope that will be kept alive beyond the end of this transaction.
val childScope = coroutineScope.childScope()
lateinit var emitter: Pair<T, S>
@@ -131,7 +131,8 @@
): TFlow<Out> =
buildTFlow(
constructFlow = { inputNode ->
- val flow = CoalescingMutableTFlow(coalesce, network, getInitialValue, inputNode)
+ val flow =
+ CoalescingMutableTFlow(null, coalesce, network, getInitialValue, inputNode)
flow to
object : FrpCoalescingProducerScope<In> {
override fun emit(value: In) {
@@ -165,7 +166,9 @@
subRef.getAndSet(None)?.let { output ->
if (output is Just) {
@Suppress("DeferredResultUnused")
- network.transaction { scheduleDeactivation(output.value) }
+ network.transaction("observeEffect cancelled") {
+ scheduleDeactivation(output.value)
+ }
}
}
}
@@ -266,8 +269,9 @@
return changes to FrpDeferredValue(initOut)
}
- private fun newStopEmitter(): CoalescingMutableTFlow<Unit, Unit> =
+ private fun newStopEmitter(name: String): CoalescingMutableTFlow<Unit, Unit> =
CoalescingMutableTFlow(
+ name = name,
coalesce = { _, _: Unit -> },
network = network,
getInitialValue = {},
@@ -293,7 +297,7 @@
}
private fun mutableChildBuildScope(): BuildScopeImpl {
- val stopEmitter = newStopEmitter()
+ val stopEmitter = newStopEmitter("mutableChildBuildScope")
val childScope = coroutineScope.childScope()
childScope.coroutineContext.job.invokeOnCompletion { stopEmitter.emit(Unit) }
// Ensure that once this transaction is done, the new child scope enters the completing
diff --git a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/Network.kt b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/Network.kt
index f466113..599b186 100644
--- a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/Network.kt
+++ b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/Network.kt
@@ -118,12 +118,12 @@
}
/** Evaluates [block] inside of a new transaction when the network is ready. */
- fun <R> transaction(block: suspend EvalScope.() -> R): Deferred<R> =
+ fun <R> transaction(reason: String, block: suspend EvalScope.() -> R): Deferred<R> =
CompletableDeferred<R>(parent = coroutineScope.coroutineContext.job).also { onResult ->
val job =
coroutineScope.launch {
inputScheduleChan.send(
- ScheduledAction(onStartTransaction = block, onResult = onResult)
+ ScheduledAction(reason, onStartTransaction = block, onResult = onResult)
)
}
onResult.invokeOnCompletion { job.cancel() }
@@ -222,6 +222,7 @@
}
internal class ScheduledAction<T>(
+ val reason: String,
private val onResult: CompletableDeferred<T>? = null,
private val onStartTransaction: suspend EvalScope.() -> T,
) {