Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 72b23ed8 authored by Ale Nijamkin's avatar Ale Nijamkin
Browse files

rememberViewModel defaults to Dispatchers.Default

Bug: 421000550
Test: Ran on device, moved through UIs with Flexiglass on and off, no
crashes or weird behaviour observed
Flag: com.android.systemui.remember_view_model_off_main_thread

Change-Id: Ibd2112cb82e49cc1f3a726375f7233310f82f66b
parent 8c2e9bec
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -2050,3 +2050,14 @@ flag {
     purpose: PURPOSE_BUGFIX
   }
}

flag {
    name: "remember_view_model_off_main_thread"
    namespace: "systemui"
    description: "View-models are remembered off the main thread"
    bug: "421000550"
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.display.domain.interactor.displayWindowPropertiesInteractor
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
import com.android.systemui.lifecycle.activateIn
import com.android.systemui.statusbar.RankingBuilder
@@ -57,6 +58,7 @@ class ConnectedDisplaysStatusBarNotificationIconViewStoreTest : SysuiTestCase()
            kosmos.iconManager,
            kosmos.displayWindowPropertiesInteractor,
            kosmos.notifPipeline,
            kosmos.testDispatcher,
        )

    private val notifCollectionListeners = mutableListOf<NotifCollectionListener>()
+20 −2
Original line number Diff line number Diff line
@@ -20,9 +20,14 @@ import android.view.View
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.app.tracing.coroutines.launchTraced
import com.android.app.tracing.coroutines.traceCoroutine
import com.android.systemui.Flags.rememberViewModelOffMainThread
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlinx.coroutines.CoroutineScope
import com.android.app.tracing.coroutines.launchTraced as launch
import kotlinx.coroutines.Dispatchers

/**
 * Returns a remembered view-model of the type [T]. If the returned instance is also an
@@ -39,11 +44,24 @@ import com.android.app.tracing.coroutines.launchTraced as launch
fun <T> rememberViewModel(
    traceName: String,
    key: Any = Unit,
    context: CoroutineContext = EmptyCoroutineContext,
    factory: () -> T,
): T {
    val instance = remember(key) { factory() }
    if (instance is Activatable) {
        LaunchedEffect(instance) { traceCoroutine(traceName) { instance.activate() } }
        LaunchedEffect(instance) {
            launchTraced(
                spanName = traceName,
                context =
                    when {
                        context != EmptyCoroutineContext -> context
                        rememberViewModelOffMainThread() -> Dispatchers.Default
                        else -> coroutineContext
                    },
            ) {
                instance.activate()
            }
        }
    }
    return instance
}
+14 −5
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.notification.icon.ui.viewbinder

import android.util.Log
import com.android.dream.lowlight.dagger.qualifiers.Main
import com.android.systemui.display.domain.interactor.DisplayWindowPropertiesInteractor
import com.android.systemui.lifecycle.Activatable
import com.android.systemui.statusbar.StatusBarIconView
@@ -30,8 +31,10 @@ import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import java.util.concurrent.ConcurrentHashMap
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.withContext

/** [IconViewStore] for the status bar on multiple displays. */
class ConnectedDisplaysStatusBarNotificationIconViewStore
@@ -42,6 +45,7 @@ constructor(
    private val iconManager: IconManager,
    private val displayWindowPropertiesInteractor: DisplayWindowPropertiesInteractor,
    private val notifPipeline: NotifPipeline,
    @Main private val mainDispatcher: CoroutineDispatcher,
) : IconViewStore, Activatable {

    private val cachedIcons = ConcurrentHashMap<String, StatusBarIconView>()
@@ -79,6 +83,10 @@ constructor(
    }

    override suspend fun activate() = coroutineScope {
        // In case activate is being invoked off the main thread, make sure to switch to the main
        // thread to do the work here as some of the downstream calls assert they've been called on
        // the main thread.
        withContext(mainDispatcher) {
            start()
            try {
                awaitCancellation()
@@ -86,6 +94,7 @@ constructor(
                stop()
            }
        }
    }

    private fun start() {
        notifPipeline.addCollectionListener(notifCollectionListener)