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

Commit 9fa90fda authored by Matt Pietal's avatar Matt Pietal Committed by Android (Google) Code Review
Browse files

Merge "Apply burn-in y translation to shared notif container" into main

parents 618ffc01 e799be90
Loading
Loading
Loading
Loading
+22 −1
Original line number Diff line number Diff line
@@ -18,9 +18,12 @@ package com.android.systemui.statusbar.notification.stack.ui.viewbinder

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.view.View
import android.view.WindowInsets
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyguard.ui.viewmodel.BurnInParameters
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.scene.shared.flag.SceneContainerFlags
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
@@ -30,6 +33,9 @@ import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificat
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.SharedNotificationContainerViewModel
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.DisposableHandle
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch

/** Binds the shared notification container to its view-model. */
@@ -65,6 +71,8 @@ object SharedNotificationContainerBinder {
                }
            }

        val burnInParams = MutableStateFlow(BurnInParameters())

        /*
         * For animation sensitive coroutines, immediately run just like applicationScope does
         * instead of doing a post() to the main thread. This extra delay can cause visible jitter.
@@ -122,7 +130,11 @@ object SharedNotificationContainerBinder {
                        }
                    }

                    launch { viewModel.translationY.collect { controller.setTranslationY(it) } }
                    launch {
                        burnInParams
                            .flatMapLatest { params -> viewModel.translationY(params) }
                            .collect { y -> controller.setTranslationY(y) }
                    }

                    launch {
                        viewModel.expansionAlpha.collect { controller.setMaxAlphaForExpansion(it) }
@@ -137,11 +149,20 @@ object SharedNotificationContainerBinder {

        controller.setOnHeightChangedRunnable(Runnable { viewModel.notificationStackChanged() })

        view.setOnApplyWindowInsetsListener { v: View, insets: WindowInsets ->
            val insetTypes = WindowInsets.Type.systemBars() or WindowInsets.Type.displayCutout()
            burnInParams.update { current ->
                current.copy(topInset = insets.getInsetsIgnoringVisibility(insetTypes).top)
            }
            insets
        }

        return object : DisposableHandle {
            override fun dispose() {
                disposableHandle.dispose()
                disposableHandleMainImmediate.dispose()
                controller.setOnHeightChangedRunnable(null)
                view.setOnApplyWindowInsetsListener(null)
            }
        }
    }
+11 −6
Original line number Diff line number Diff line
@@ -28,6 +28,8 @@ import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.StatusBarState.SHADE_LOCKED
import com.android.systemui.keyguard.shared.model.TransitionState.RUNNING
import com.android.systemui.keyguard.shared.model.TransitionState.STARTED
import com.android.systemui.keyguard.ui.viewmodel.AodBurnInViewModel
import com.android.systemui.keyguard.ui.viewmodel.BurnInParameters
import com.android.systemui.keyguard.ui.viewmodel.GlanceableHubToLockscreenTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.LockscreenToGlanceableHubTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.LockscreenToOccludedTransitionViewModel
@@ -65,10 +67,11 @@ constructor(
    keyguardTransitionInteractor: KeyguardTransitionInteractor,
    private val shadeInteractor: ShadeInteractor,
    communalInteractor: CommunalInteractor,
    occludedToLockscreenTransitionViewModel: OccludedToLockscreenTransitionViewModel,
    private val occludedToLockscreenTransitionViewModel: OccludedToLockscreenTransitionViewModel,
    lockscreenToOccludedTransitionViewModel: LockscreenToOccludedTransitionViewModel,
    glanceableHubToLockscreenTransitionViewModel: GlanceableHubToLockscreenTransitionViewModel,
    lockscreenToGlanceableHubTransitionViewModel: LockscreenToGlanceableHubTransitionViewModel
    lockscreenToGlanceableHubTransitionViewModel: LockscreenToGlanceableHubTransitionViewModel,
    private val aodBurnInViewModel: AodBurnInViewModel,
) {
    private val statesForConstrainedNotifications =
        setOf(
@@ -313,20 +316,22 @@ constructor(
     * Under certain scenarios, such as swiping up on the lockscreen, the container will need to be
     * translated as the keyguard fades out.
     */
    val translationY: Flow<Float> =
        combine(
    fun translationY(params: BurnInParameters): Flow<Float> {
        return combine(
            aodBurnInViewModel.translationY(params).onStart { emit(0f) },
            isOnLockscreenWithoutShade,
            merge(
                keyguardInteractor.keyguardTranslationY,
                occludedToLockscreenTransitionViewModel.lockscreenTranslationY,
            )
        ) { isOnLockscreenWithoutShade, translationY ->
        ) { burnInY, isOnLockscreenWithoutShade, translationY ->
            if (isOnLockscreenWithoutShade) {
                translationY
                burnInY + translationY
            } else {
                0f
            }
        }
    }

    /**
     * When on keyguard, there is limited space to display notifications so calculate how many could
+29 −3
Original line number Diff line number Diff line
@@ -38,6 +38,9 @@ import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.StatusBarState
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.keyguard.ui.viewmodel.AodBurnInViewModel
import com.android.systemui.keyguard.ui.viewmodel.BurnInParameters
import com.android.systemui.keyguard.ui.viewmodel.aodBurnInViewModel
import com.android.systemui.keyguard.ui.viewmodel.keyguardRootViewModel
import com.android.systemui.kosmos.testScope
import com.android.systemui.res.R
@@ -45,6 +48,7 @@ import com.android.systemui.shade.data.repository.shadeRepository
import com.android.systemui.shade.mockLargeScreenHeaderHelper
import com.android.systemui.statusbar.notification.stack.domain.interactor.sharedNotificationContainerInteractor
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -55,15 +59,22 @@ import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.mock

@SmallTest
@RunWith(AndroidJUnit4::class)
class SharedNotificationContainerViewModelTest : SysuiTestCase() {
    val aodBurnInViewModel = mock(AodBurnInViewModel::class.java)
    lateinit var translationYFlow: MutableStateFlow<Float>

    val kosmos =
        testKosmos().apply {
            fakeFeatureFlagsClassic.apply { set(Flags.FULL_SCREEN_USER_SWITCHER, false) }
        }

    init {
        kosmos.aodBurnInViewModel = aodBurnInViewModel
    }
    val testScope = kosmos.testScope
    val configurationRepository = kosmos.fakeConfigurationRepository
    val keyguardRepository = kosmos.fakeKeyguardRepository
@@ -75,11 +86,14 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() {
    val sharedNotificationContainerInteractor = kosmos.sharedNotificationContainerInteractor
    val largeScreenHeaderHelper = kosmos.mockLargeScreenHeaderHelper

    val underTest = kosmos.sharedNotificationContainerViewModel
    lateinit var underTest: SharedNotificationContainerViewModel

    @Before
    fun setUp() {
        overrideResource(R.bool.config_use_split_notification_shade, false)
        translationYFlow = MutableStateFlow(0f)
        whenever(aodBurnInViewModel.translationY(any())).thenReturn(translationYFlow)
        underTest = kosmos.sharedNotificationContainerViewModel
    }

    @Test
@@ -578,10 +592,22 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() {
            assertThat(maxNotifications).isEqualTo(-1)
        }

    @Test
    fun translationYUpdatesOnKeyguardForBurnIn() =
        testScope.runTest {
            val translationY by collectLastValue(underTest.translationY(BurnInParameters()))

            showLockscreen()
            assertThat(translationY).isEqualTo(0)

            translationYFlow.value = 150f
            assertThat(translationY).isEqualTo(150f)
        }

    @Test
    fun translationYUpdatesOnKeyguard() =
        testScope.runTest {
            val translationY by collectLastValue(underTest.translationY)
            val translationY by collectLastValue(underTest.translationY(BurnInParameters()))

            configurationRepository.setDimensionPixelSize(
                R.dimen.keyguard_translate_distance_on_swipe_up,
@@ -601,7 +627,7 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() {
    @Test
    fun translationYDoesNotUpdateWhenShadeIsExpanded() =
        testScope.runTest {
            val translationY by collectLastValue(underTest.translationY)
            val translationY by collectLastValue(underTest.translationY(BurnInParameters()))

            configurationRepository.setDimensionPixelSize(
                R.dimen.keyguard_translate_distance_on_swipe_up,
+1 −1
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import kotlinx.coroutines.ExperimentalCoroutinesApi

val Kosmos.aodBurnInViewModel by Fixture {
var Kosmos.aodBurnInViewModel by Fixture {
    AodBurnInViewModel(
        burnInInteractor = burnInInteractor,
        configurationInteractor = configurationInteractor,
+3 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.notification.stack.ui.viewmodel
import com.android.systemui.communal.domain.interactor.communalInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.keyguard.ui.viewmodel.aodBurnInViewModel
import com.android.systemui.keyguard.ui.viewmodel.glanceableHubToLockscreenTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.lockscreenToGlanceableHubTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.lockscreenToOccludedTransitionViewModel
@@ -40,6 +41,7 @@ val Kosmos.sharedNotificationContainerViewModel by Fixture {
        occludedToLockscreenTransitionViewModel = occludedToLockscreenTransitionViewModel,
        lockscreenToOccludedTransitionViewModel = lockscreenToOccludedTransitionViewModel,
        glanceableHubToLockscreenTransitionViewModel = glanceableHubToLockscreenTransitionViewModel,
        lockscreenToGlanceableHubTransitionViewModel = lockscreenToGlanceableHubTransitionViewModel
        lockscreenToGlanceableHubTransitionViewModel = lockscreenToGlanceableHubTransitionViewModel,
        aodBurnInViewModel = aodBurnInViewModel,
    )
}