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

Commit c040cfaa authored by Hawkwood Glazier's avatar Hawkwood Glazier
Browse files

Offset the keyguard notification placeholder bounds when they are reported

Bug: 327185849
Test: atest KeyguardInteractorTest
Flag: ACONFIG com.android.systemui.migrate_clocks_to_blueprint STAGING
Change-Id: I829714d2364df6599ef2f04164053bede7e04b98
parent 9120c0f5
Loading
Loading
Loading
Loading
+5 −0
Original line number Original line Diff line number Diff line
@@ -40,6 +40,7 @@ import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.data.repository.FakeShadeRepository
import com.android.systemui.shade.data.repository.FakeShadeRepository
import com.android.systemui.statusbar.notification.stack.domain.interactor.sharedNotificationContainerInteractor
import com.android.systemui.testKosmos
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -81,6 +82,10 @@ class KeyguardInteractorTest : SysuiTestCase() {
            keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor,
            keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor,
            sceneInteractorProvider = { sceneInteractor },
            sceneInteractorProvider = { sceneInteractor },
            fromGoneTransitionInteractor = { fromGoneTransitionInteractor },
            fromGoneTransitionInteractor = { fromGoneTransitionInteractor },
            sharedNotificationContainerInteractor = {
                kosmos.sharedNotificationContainerInteractor
            },
            applicationScope = testScope,
        )
        )
    }
    }


+20 −7
Original line number Original line Diff line number Diff line
@@ -16,15 +16,20 @@


package com.android.systemui.statusbar.notification.stack.ui.viewmodel
package com.android.systemui.statusbar.notification.stack.ui.viewmodel


import android.platform.test.annotations.DisableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.filters.SmallTest
import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.NotificationContainerBounds
import com.android.systemui.common.shared.model.NotificationContainerBounds
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.kosmos.testScope
import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationStackAppearanceInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationStackAppearanceInteractor
import com.android.systemui.statusbar.notification.stack.shared.model.StackBounds
import com.android.systemui.statusbar.notification.stack.shared.model.StackBounds
import com.android.systemui.testKosmos
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runner.RunWith


@@ -33,14 +38,22 @@ import org.junit.runner.RunWith
class NotificationsPlaceholderViewModelTest : SysuiTestCase() {
class NotificationsPlaceholderViewModelTest : SysuiTestCase() {
    private val kosmos = testKosmos()
    private val kosmos = testKosmos()
    private val underTest = kosmos.notificationsPlaceholderViewModel
    private val underTest = kosmos.notificationsPlaceholderViewModel

    @Test
    @Test
    fun onBoundsChanged_setsNotificationContainerBounds() {
    @DisableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT)
    fun onBoundsChanged_setsNotificationContainerBounds() =
        kosmos.testScope.runTest {
            underTest.onBoundsChanged(left = 5f, top = 5f, right = 5f, bottom = 5f)
            underTest.onBoundsChanged(left = 5f, top = 5f, right = 5f, bottom = 5f)
        assertThat(kosmos.keyguardInteractor.notificationContainerBounds.value)
            val containerBounds by
                collectLastValue(kosmos.keyguardInteractor.notificationContainerBounds)
            val stackBounds by
                collectLastValue(kosmos.notificationStackAppearanceInteractor.stackBounds)
            assertThat(containerBounds)
                .isEqualTo(NotificationContainerBounds(top = 5f, bottom = 5f))
                .isEqualTo(NotificationContainerBounds(top = 5f, bottom = 5f))
        assertThat(kosmos.notificationStackAppearanceInteractor.stackBounds.value)
            assertThat(stackBounds)
                .isEqualTo(StackBounds(left = 5f, top = 5f, right = 5f, bottom = 5f))
                .isEqualTo(StackBounds(left = 5f, top = 5f, right = 5f, bottom = 5f))
        }
        }

    @Test
    @Test
    fun onContentTopChanged_setsContentTop() {
    fun onContentTopChanged_setsContentTop() {
        underTest.onContentTopChanged(padding = 5f)
        underTest.onContentTopChanged(padding = 5f)
+2 −2
Original line number Original line Diff line number Diff line
@@ -493,7 +493,7 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() {
            showLockscreen()
            showLockscreen()


            keyguardInteractor.setNotificationContainerBounds(
            keyguardInteractor.setNotificationContainerBounds(
                NotificationContainerBounds(top = 1f, bottom = 2f)
                NotificationContainerBounds(top = 1f, bottom = 52f)
            )
            )
            runCurrent()
            runCurrent()


@@ -521,7 +521,7 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() {
            showLockscreen()
            showLockscreen()


            keyguardInteractor.setNotificationContainerBounds(
            keyguardInteractor.setNotificationContainerBounds(
                NotificationContainerBounds(top = 1f, bottom = 2f)
                NotificationContainerBounds(top = 1f, bottom = 52f)
            )
            )
            runCurrent()
            runCurrent()


+27 −4
Original line number Original line Diff line number Diff line
@@ -29,6 +29,8 @@ import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCall
import com.android.systemui.common.shared.model.NotificationContainerBounds
import com.android.systemui.common.shared.model.NotificationContainerBounds
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.MigrateClocksToBlueprint
import com.android.systemui.keyguard.data.repository.KeyguardRepository
import com.android.systemui.keyguard.data.repository.KeyguardRepository
import com.android.systemui.keyguard.shared.model.BiometricUnlockModel
import com.android.systemui.keyguard.shared.model.BiometricUnlockModel
import com.android.systemui.keyguard.shared.model.BiometricUnlockSource
import com.android.systemui.keyguard.shared.model.BiometricUnlockSource
@@ -46,14 +48,17 @@ import com.android.systemui.scene.shared.flag.SceneContainerFlags
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.data.repository.ShadeRepository
import com.android.systemui.shade.data.repository.ShadeRepository
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor
import com.android.systemui.util.kotlin.sample
import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
import javax.inject.Inject
import javax.inject.Provider
import javax.inject.Provider
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.delay
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.combine
@@ -66,6 +71,7 @@ import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn


/**
/**
 * Encapsulates business-logic related to the keyguard but not to a more specific part within it.
 * Encapsulates business-logic related to the keyguard but not to a more specific part within it.
@@ -84,16 +90,33 @@ constructor(
    keyguardTransitionInteractor: KeyguardTransitionInteractor,
    keyguardTransitionInteractor: KeyguardTransitionInteractor,
    sceneInteractorProvider: Provider<SceneInteractor>,
    sceneInteractorProvider: Provider<SceneInteractor>,
    private val fromGoneTransitionInteractor: Provider<FromGoneTransitionInteractor>,
    private val fromGoneTransitionInteractor: Provider<FromGoneTransitionInteractor>,
    sharedNotificationContainerInteractor: Provider<SharedNotificationContainerInteractor>,
    @Application applicationScope: CoroutineScope,
) {
) {
    // TODO(b/296118689): move to a repository
    // TODO(b/296118689): move to a repository
    private val _sharedNotificationContainerBounds = MutableStateFlow(NotificationContainerBounds())
    private val _notificationPlaceholderBounds = MutableStateFlow(NotificationContainerBounds())


    /** Bounds of the notification container. */
    /** Bounds of the notification container. */
    val notificationContainerBounds: StateFlow<NotificationContainerBounds> =
    val notificationContainerBounds: StateFlow<NotificationContainerBounds> by lazy {
        _sharedNotificationContainerBounds.asStateFlow()
        combine(
                _notificationPlaceholderBounds,
                sharedNotificationContainerInteractor.get().configurationBasedDimensions,
            ) { bounds, cfg ->
                // We offset the placeholder bounds by the configured top margin to account for
                // legacy placement behavior within notifications for splitshade.
                if (MigrateClocksToBlueprint.isEnabled && cfg.useSplitShade) {
                    bounds.copy(bottom = bounds.bottom - cfg.keyguardSplitShadeTopMargin)
                } else bounds
            }
            .stateIn(
                scope = applicationScope,
                started = SharingStarted.WhileSubscribed(),
                initialValue = NotificationContainerBounds(),
            )
    }


    fun setNotificationContainerBounds(position: NotificationContainerBounds) {
    fun setNotificationContainerBounds(position: NotificationContainerBounds) {
        _sharedNotificationContainerBounds.value = position
        _notificationPlaceholderBounds.value = position
    }
    }


    /**
    /**
+6 −10
Original line number Original line Diff line number Diff line
@@ -25,7 +25,6 @@ import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.constraintlayout.widget.ConstraintSet
import androidx.constraintlayout.widget.ConstraintSet.BOTTOM
import androidx.constraintlayout.widget.ConstraintSet.BOTTOM
import androidx.constraintlayout.widget.ConstraintSet.TOP
import androidx.constraintlayout.widget.ConstraintSet.TOP
import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor
import com.android.systemui.keyguard.MigrateClocksToBlueprint
import com.android.systemui.keyguard.MigrateClocksToBlueprint
import com.android.systemui.keyguard.shared.model.KeyguardSection
import com.android.systemui.keyguard.shared.model.KeyguardSection
import com.android.systemui.res.R
import com.android.systemui.res.R
@@ -51,21 +50,18 @@ constructor(
     * indication area, whichever is higher.
     * indication area, whichever is higher.
     */
     */
    protected fun addNotificationPlaceholderBarrier(constraintSet: ConstraintSet) {
    protected fun addNotificationPlaceholderBarrier(constraintSet: ConstraintSet) {
        val lockId =
            if (DeviceEntryUdfpsRefactor.isEnabled) {
                R.id.device_entry_icon_view
            } else {
                R.id.lock_icon_view
            }

        constraintSet.apply {
        constraintSet.apply {
            createBarrier(
            createBarrier(
                R.id.nssl_placeholder_barrier_bottom,
                R.id.nssl_placeholder_barrier_bottom,
                Barrier.TOP,
                Barrier.TOP,
                0,
                0,
                *intArrayOf(lockId, R.id.ambient_indication_container)
                *intArrayOf(
                    R.id.device_entry_icon_view,
                    R.id.lock_icon_view,
                    R.id.ambient_indication_container
                )
            )
            )
            connect(R.id.nssl_placeholder, BOTTOM, R.id.nssl_placeholder_barrier_bottom, TOP)
            connect(placeHolderId, BOTTOM, R.id.nssl_placeholder_barrier_bottom, TOP)
        }
        }
    }
    }


Loading