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

Commit 359d1fc8 authored by Ioana Alexandru's avatar Ioana Alexandru Committed by Android (Google) Code Review
Browse files

Merge changes I4ea40c3a,I40d005bc into main

* changes:
  Move cold notification flows to the bg thread.
  Perform footer inflation on a background thread.
parents bd0933e4 93436f99
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -31,8 +31,10 @@ import com.android.systemui.statusbar.policy.onThemeChanged
import com.android.systemui.util.kotlin.emitOnStart
import com.android.systemui.util.view.bindLatest
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.DisposableHandle
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge

@@ -95,7 +97,8 @@ constructor(
 * call [onInflate] on the resulting view each time. Disposes of the [DisposableHandle] returned by
 * [onInflate] when done.
 *
 * This never completes unless cancelled, it just suspends and waits for updates.
 * This never completes unless cancelled, it just suspends and waits for updates. It runs on a
 * background thread using [backgroundDispatcher].
 *
 * For parameters [resource], [root] and [attachToRoot], see [LayoutInflater.inflate].
 *
@@ -105,7 +108,7 @@ constructor(
 * ```
 * parentView.repeatWhenAttached {
 *     configurationState
 *         .reinflateOnChange(
 *         .reinflateAndBindLatest(
 *             R.layout.my_layout,
 *             parentView,
 *             attachToRoot = false,
@@ -124,7 +127,10 @@ suspend fun <T : View> ConfigurationState.reinflateAndBindLatest(
    @LayoutRes resource: Int,
    root: ViewGroup?,
    attachToRoot: Boolean,
    backgroundDispatcher: CoroutineDispatcher,
    onInflate: (T) -> DisposableHandle?,
) {
    inflateLayout<T>(resource, root, attachToRoot).bindLatest(onInflate)
    inflateLayout<T>(resource, root, attachToRoot)
        .flowOn(backgroundDispatcher)
        .bindLatest(onInflate)
}
+22 −10
Original line number Diff line number Diff line
@@ -15,37 +15,48 @@

package com.android.systemui.statusbar.notification.domain.interactor

import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.statusbar.notification.collection.render.NotifStats
import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository
import com.android.systemui.statusbar.notification.shared.ActiveNotificationGroupModel
import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map

class ActiveNotificationsInteractor
@Inject
constructor(
    private val repository: ActiveNotificationListRepository,
    @Background private val backgroundDispatcher: CoroutineDispatcher,
) {
    /** Notifications actively presented to the user in the notification stack, in order. */
    val topLevelRepresentativeNotifications: Flow<List<ActiveNotificationModel>> =
        repository.activeNotifications.map { store ->
        repository.activeNotifications
            .map { store ->
                store.renderList.map { key ->
                    val entry =
                        store[key]
                        ?: error("Could not find notification with key $key in active notif store.")
                            ?: error(
                                "Could not find notification with key $key in active notif store."
                            )
                    when (entry) {
                        is ActiveNotificationGroupModel -> entry.summary
                        is ActiveNotificationModel -> entry
                    }
                }
            }
            .flowOn(backgroundDispatcher)

    /** Are any notifications being actively presented in the notification stack? */
    val areAnyNotificationsPresent: Flow<Boolean> =
        repository.activeNotifications.map { it.renderList.isNotEmpty() }.distinctUntilChanged()
        repository.activeNotifications
            .map { it.renderList.isNotEmpty() }
            .distinctUntilChanged()
            .flowOn(backgroundDispatcher)

    /**
     * The same as [areAnyNotificationsPresent], but without flows, for easy access in synchronous
@@ -59,6 +70,7 @@ constructor(
        repository.notifStats
            .map { it.hasClearableAlertingNotifs || it.hasClearableSilentNotifs }
            .distinctUntilChanged()
            .flowOn(backgroundDispatcher)

    fun setNotifStats(notifStats: NotifStats) {
        repository.notifStats.value = notifStats
+7 −2
Original line number Diff line number Diff line
@@ -15,19 +15,24 @@
 */
package com.android.systemui.statusbar.notification.domain.interactor

import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.statusbar.notification.data.repository.NotificationsKeyguardViewStateRepository
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOn

/** Domain logic pertaining to notifications on the keyguard. */
class NotificationsKeyguardInteractor
@Inject
constructor(
    repository: NotificationsKeyguardViewStateRepository,
    @Background backgroundDispatcher: CoroutineDispatcher,
) {
    /** Is a pulse expansion occurring? */
    val isPulseExpanding: Flow<Boolean> = repository.isPulseExpanding
    val isPulseExpanding: Flow<Boolean> = repository.isPulseExpanding.flowOn(backgroundDispatcher)

    /** Are notifications fully hidden from view? */
    val areNotificationsFullyHidden: Flow<Boolean> = repository.areNotificationsFullyHidden
    val areNotificationsFullyHidden: Flow<Boolean> =
        repository.areNotificationsFullyHidden.flowOn(backgroundDispatcher)
}
+5 −1
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import com.android.internal.logging.nano.MetricsProto
import com.android.systemui.common.ui.ConfigurationState
import com.android.systemui.common.ui.reinflateAndBindLatest
import com.android.systemui.common.ui.view.setImportantForAccessibilityYesNo
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.res.R
@@ -41,6 +42,7 @@ import com.android.systemui.statusbar.notification.stack.ui.viewmodel.Notificati
import com.android.systemui.statusbar.phone.NotificationIconAreaController
import com.android.systemui.statusbar.policy.ConfigurationController
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch

@@ -49,12 +51,13 @@ class NotificationListViewBinder
@Inject
constructor(
    private val viewModel: NotificationListViewModel,
    private val metricsLogger: MetricsLogger,
    @Background private val backgroundDispatcher: CoroutineDispatcher,
    private val configuration: ConfigurationState,
    private val configurationController: ConfigurationController,
    private val falsingManager: FalsingManager,
    private val iconAreaController: NotificationIconAreaController,
    private val iconViewBindingFailureTracker: StatusBarIconViewBindingFailureTracker,
    private val metricsLogger: MetricsLogger,
    private val shelfIconViewStore: ShelfNotificationIconViewStore,
) {

@@ -105,6 +108,7 @@ constructor(
                    R.layout.status_bar_notification_footer,
                    parentView,
                    attachToRoot = false,
                    backgroundDispatcher,
                ) { footerView: FooterView ->
                    traceSection("bind FooterView") {
                        val disposableHandle =
+86 −74
Original line number Diff line number Diff line
@@ -30,6 +30,8 @@ import kotlinx.coroutines.DisposableHandle
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Test
@@ -44,17 +46,21 @@ class ConfigurationStateTest : SysuiTestCase() {

    private val configurationController: ConfigurationController = mock()
    private val layoutInflater = TestLayoutInflater()
    private val backgroundDispatcher = StandardTestDispatcher()
    private val testScope = TestScope(backgroundDispatcher)

    val underTest = ConfigurationState(configurationController, context, layoutInflater)

    @Test
    fun reinflateAndBindLatest_inflatesWithoutEmission() = runTest {
    fun reinflateAndBindLatest_inflatesWithoutEmission() =
        testScope.runTest {
            var callbackCount = 0
            backgroundScope.launch {
                underTest.reinflateAndBindLatest<View>(
                    resource = 0,
                    root = null,
                    attachToRoot = false,
                    backgroundDispatcher,
                ) {
                    callbackCount++
                    null
@@ -68,13 +74,15 @@ class ConfigurationStateTest : SysuiTestCase() {
        }

    @Test
    fun reinflateAndBindLatest_reinflatesOnThemeChanged() = runTest {
    fun reinflateAndBindLatest_reinflatesOnThemeChanged() =
        testScope.runTest {
            var callbackCount = 0
            backgroundScope.launch {
                underTest.reinflateAndBindLatest<View>(
                    resource = 0,
                    root = null,
                    attachToRoot = false,
                    backgroundDispatcher,
                ) {
                    callbackCount++
                    null
@@ -95,13 +103,15 @@ class ConfigurationStateTest : SysuiTestCase() {
        }

    @Test
    fun reinflateAndBindLatest_reinflatesOnDensityOrFontScaleChanged() = runTest {
    fun reinflateAndBindLatest_reinflatesOnDensityOrFontScaleChanged() =
        testScope.runTest {
            var callbackCount = 0
            backgroundScope.launch {
                underTest.reinflateAndBindLatest<View>(
                    resource = 0,
                    root = null,
                    attachToRoot = false,
                    backgroundDispatcher,
                ) {
                    callbackCount++
                    null
@@ -122,7 +132,8 @@ class ConfigurationStateTest : SysuiTestCase() {
        }

    @Test
    fun testReinflateAndBindLatest_disposesOnCancel() = runTest {
    fun testReinflateAndBindLatest_disposesOnCancel() =
        testScope.runTest {
            var callbackCount = 0
            var disposed = false
            val job = launch {
@@ -130,6 +141,7 @@ class ConfigurationStateTest : SysuiTestCase() {
                    resource = 0,
                    root = null,
                    attachToRoot = false,
                    backgroundDispatcher,
                ) {
                    callbackCount++
                    DisposableHandle { disposed = true }
Loading