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

Commit f420762d authored by Matt Pietal's avatar Matt Pietal
Browse files

Replace SharedFlow with StateFlow to fix notif height

When redacted notifications become visible by face unlock,
a flurry of change events are sent. The MutableSharedFlow
that was processing these events became overloaded and
it was dropping events necessary to process the change.
This resulted in the notifications overlapping the lock
icon.

Use a StateFlow for better performance and to prevent
dropped updates.

Fixes: 338602791
Test: atest SharedNotificationInteractorTest
Test: manual - race condition with redacted notifications,
unlock many times with face on keyguard
Flag: ACONFIG com.android.systemui.migrate_clocks_to_blueprint
TEAMFOOD

Change-Id: I3190881b81f68dc1e88b927ce62e64a9d7e12a6b
parent f57b481f
Loading
Loading
Loading
Loading
+0 −0

File moved.

+6 −2
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
@@ -654,7 +655,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) :
            var notificationCount = 10
            val calculateSpace = { space: Float, useExtraShelfSpace: Boolean -> notificationCount }
            val maxNotifications by collectLastValue(underTest.getMaxNotifications(calculateSpace))

            advanceTimeBy(50L)
            showLockscreen()

            overrideResource(R.bool.config_use_split_notification_shade, false)
@@ -668,12 +669,14 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) :
            // Also updates when directly requested (as it would from NotificationStackScrollLayout)
            notificationCount = 25
            sharedNotificationContainerInteractor.notificationStackChanged()
            advanceTimeBy(50L)
            assertThat(maxNotifications).isEqualTo(25)

            // Also ensure another collection starts with the same value. As an example, folding
            // then unfolding will restart the coroutine and it must get the last value immediately.
            val newMaxNotifications by
                collectLastValue(underTest.getMaxNotifications(calculateSpace))
            advanceTimeBy(50L)
            assertThat(newMaxNotifications).isEqualTo(25)
        }

@@ -683,7 +686,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) :
            var notificationCount = 10
            val calculateSpace = { space: Float, useExtraShelfSpace: Boolean -> notificationCount }
            val maxNotifications by collectLastValue(underTest.getMaxNotifications(calculateSpace))

            advanceTimeBy(50L)
            showLockscreen()

            overrideResource(R.bool.config_use_split_notification_shade, false)
@@ -718,6 +721,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization?) :
        testScope.runTest {
            val calculateSpace = { space: Float, useExtraShelfSpace: Boolean -> 10 }
            val maxNotifications by collectLastValue(underTest.getMaxNotifications(calculateSpace))
            advanceTimeBy(50L)

            // Show lockscreen with shade expanded
            showLockscreenWithShadeExpanded()
+4 −5
Original line number Diff line number Diff line
@@ -29,11 +29,10 @@ import com.android.systemui.statusbar.policy.SplitShadeStateController
import dagger.Lazy
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart
@@ -54,9 +53,9 @@ constructor(
    private val _topPosition = MutableStateFlow(0f)
    val topPosition = _topPosition.asStateFlow()

    private val _notificationStackChanged = MutableSharedFlow<Unit>(extraBufferCapacity = 1)
    private val _notificationStackChanged = MutableStateFlow(0L)
    /** An internal modification was made to notifications */
    val notificationStackChanged = _notificationStackChanged.asSharedFlow()
    val notificationStackChanged = _notificationStackChanged.debounce(20L)

    val configurationBasedDimensions: Flow<ConfigurationBasedDimensions> =
        configurationRepository.onAnyConfigurationChange
@@ -113,7 +112,7 @@ constructor(

    /** An internal modification was made to notifications */
    fun notificationStackChanged() {
        _notificationStackChanged.tryEmit(Unit)
        _notificationStackChanged.value = _notificationStackChanged.value + 1
    }

    data class ConfigurationBasedDimensions(
+1 −1
Original line number Diff line number Diff line
@@ -636,7 +636,7 @@ constructor(
                showUnlimitedNotifications,
                shadeInteractor.isUserInteracting,
                availableHeight,
                interactor.notificationStackChanged.onStart { emit(Unit) },
                interactor.notificationStackChanged,
                interactor.useExtraShelfSpace,
            ) { flows ->
                val showLimitedNotifications = flows[0] as Boolean