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

Commit dbdba307 authored by Brad Hinegardner's avatar Brad Hinegardner
Browse files

Fall back to above large clock date weather if space is tight

When font and display sizes are large, there is
not much space below large clock to display
date and weather. We should fall back to the
prior behavior of date weather above large clock
in this case.

Additionally special-cased the metro and
number-overlap clocks because metro large clock
is quite tall, and number-overlap has a lot of
extra internal padding around it.

Wallpaper picker has been updated for these
scenarios.

Bug: 419171516
Bug: 419262872
Test: atest KeyguardClockViewModelTest.kt
Flag: com.android.systemui.shared.clock_reactive_smartspace_layout
Change-Id: Iada0345ce3d22728861143780231e3d38eaa23c3
parent 4c888ee9
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ class SmartspaceSectionTest : SysuiTestCase() {
    private val clockShouldBeCentered = MutableStateFlow(false)
    private val hasCustomWeatherDataDisplay = MutableStateFlow(false)
    private val shouldDateWeatherBeBelowSmallClock = MutableStateFlow(true)
    private val shouldDateWeatherBeBelowLargeClock = MutableStateFlow(true)
    private val isWeatherVisibleFlow = MutableStateFlow(false)
    private val isShadeLayoutWide = MutableStateFlow(false)
    private val isLargeClockVisible = MutableStateFlow(true)
@@ -100,6 +101,8 @@ class SmartspaceSectionTest : SysuiTestCase() {
        whenever(keyguardClockViewModel.isLargeClockVisible).thenReturn(isLargeClockVisible)
        whenever(keyguardClockViewModel.shouldDateWeatherBeBelowSmallClock)
            .thenReturn(shouldDateWeatherBeBelowSmallClock)
        whenever(keyguardClockViewModel.shouldDateWeatherBeBelowLargeClock)
            .thenReturn(shouldDateWeatherBeBelowLargeClock)
        whenever(keyguardClockViewModel.clockShouldBeCentered).thenReturn(clockShouldBeCentered)
        whenever(keyguardSmartspaceViewModel.isSmartspaceEnabled).thenReturn(true)
        whenever(keyguardSmartspaceViewModel.isWeatherVisible).thenReturn(isWeatherVisibleFlow)
+75 −0
Original line number Diff line number Diff line
@@ -284,6 +284,15 @@ class KeyguardClockViewModelTest(flags: FlagsParameterization) : SysuiTestCase()
            assertThat(result).isTrue()
        }

    @Test
    @DisableFlags(com.android.systemui.shared.Flags.FLAG_CLOCK_REACTIVE_SMARTSPACE_LAYOUT)
    fun dateWeatherBelowLargeClock_smartspacelayoutflag_off_false() =
        testScope.runTest {
            val result by collectLastValue(underTest.shouldDateWeatherBeBelowLargeClock)

            assertThat(result).isFalse()
        }

    @Test
    @EnableFlags(com.android.systemui.shared.Flags.FLAG_CLOCK_REACTIVE_SMARTSPACE_LAYOUT)
    fun dateWeatherBelowSmallClock_defaultFontAndDisplaySize_shadeLayoutNotWide_false() =
@@ -299,6 +308,72 @@ class KeyguardClockViewModelTest(flags: FlagsParameterization) : SysuiTestCase()
            assertThat(result).isFalse()
        }

    @Test
    @EnableFlags(com.android.systemui.shared.Flags.FLAG_CLOCK_REACTIVE_SMARTSPACE_LAYOUT)
    fun dateWeatherBelowLargeClock_variousFontAndDisplaySize_true() =
        testScope.runTest {
            mockConfiguration.fontScale = 1.0f
            mockConfiguration.screenWidthDp = 347
            val result1 by collectLastValue(underTest.shouldDateWeatherBeBelowLargeClock)
            assertThat(result1).isTrue()

            mockConfiguration.fontScale = 1.2f
            mockConfiguration.screenWidthDp = 347
            val result2 by collectLastValue(underTest.shouldDateWeatherBeBelowLargeClock)
            assertThat(result2).isTrue()

            mockConfiguration.fontScale = 1.7f
            mockConfiguration.screenWidthDp = 412
            val result3 by collectLastValue(underTest.shouldDateWeatherBeBelowLargeClock)
            assertThat(result3).isTrue()
        }

    @Test
    @EnableFlags(com.android.systemui.shared.Flags.FLAG_CLOCK_REACTIVE_SMARTSPACE_LAYOUT)
    fun dateWeatherBelowLargeClock_variousFontAndDisplaySize_false() =
        testScope.runTest {
            kosmos.shadeRepository.setShadeLayoutWide(false)
            mockConfiguration.fontScale = 1.0f
            mockConfiguration.screenWidthDp = 310
            val result1 by collectLastValue(underTest.shouldDateWeatherBeBelowLargeClock)
            assertThat(result1).isFalse()

            mockConfiguration.fontScale = 1.5f
            mockConfiguration.screenWidthDp = 347
            val result2 by collectLastValue(underTest.shouldDateWeatherBeBelowLargeClock)
            assertThat(result2).isFalse()

            mockConfiguration.fontScale = 2.0f
            mockConfiguration.screenWidthDp = 411
            val result3 by collectLastValue(underTest.shouldDateWeatherBeBelowLargeClock)
            assertThat(result3).isFalse()
        }

    @Test
    @EnableFlags(com.android.systemui.shared.Flags.FLAG_CLOCK_REACTIVE_SMARTSPACE_LAYOUT)
    fun dateWeatherBelowSmallClock_numberOverlapClock_variousFontAndDisplaySize_true() =
        testScope.runTest {
            config = ClockConfig("DIGITAL_CLOCK_NUMBEROVERLAP", "Test", "")
            kosmos.fakeKeyguardClockRepository.setCurrentClock(clockController)
            kosmos.shadeRepository.setShadeLayoutWide(false)
            mockConfiguration.fontScale = 0.85f
            mockConfiguration.screenWidthDp = 376
            val result3 by collectLastValue(underTest.shouldDateWeatherBeBelowSmallClock)
            assertThat(result3).isTrue()
        }

    @Test
    @EnableFlags(com.android.systemui.shared.Flags.FLAG_CLOCK_REACTIVE_SMARTSPACE_LAYOUT)
    fun dateWeatherBelowLargeClock_metroClock_variousFontAndDisplaySize_false() =
        testScope.runTest {
            config = ClockConfig("DIGITAL_CLOCK_METRO", "Test", "")
            kosmos.fakeKeyguardClockRepository.setCurrentClock(clockController)
            mockConfiguration.fontScale = 0.85f
            mockConfiguration.screenWidthDp = 375
            val result3 by collectLastValue(underTest.shouldDateWeatherBeBelowLargeClock)
            assertThat(result3).isFalse()
        }

    @Test
    @EnableFlags(com.android.systemui.shared.Flags.FLAG_CLOCK_REACTIVE_SMARTSPACE_LAYOUT)
    fun dateWeatherBelowSmallClock_variousFontAndDisplaySize_shadeLayoutNotWide_false() =
+12 −0
Original line number Diff line number Diff line
@@ -173,6 +173,18 @@ object KeyguardClockViewBinder {
                                )
                            }
                        }

                        launch("$TAG#clockViewModel.shouldDateWeatherBeBelowLargeClock") {
                            viewModel.shouldDateWeatherBeBelowLargeClock.collect {
                                blueprintInteractor.refreshBlueprint(
                                    Config(
                                        Type.SmartspaceVisibility,
                                        checkPriority = false,
                                        terminatePrevious = false,
                                    )
                                )
                            }
                        }
                    }
                }
            }
+137 −6
Original line number Diff line number Diff line
@@ -18,6 +18,12 @@
package com.android.systemui.keyguard.ui.binder

import android.view.View
import android.widget.LinearLayout
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
import androidx.constraintlayout.widget.ConstraintSet.START
import androidx.constraintlayout.widget.ConstraintSet.TOP
import androidx.core.view.isInvisible
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
@@ -25,8 +31,11 @@ import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.customization.clocks.ViewUtils.animateToAlpha
import com.android.systemui.keyguard.shared.model.ClockSizeSetting
import com.android.systemui.keyguard.ui.viewmodel.KeyguardPreviewSmartspaceViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardPreviewViewModel
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.plugins.clocks.ClockPreviewConfig
import com.android.systemui.plugins.clocks.ClockViewIds
import com.android.systemui.res.R
import kotlinx.coroutines.flow.combine

/** Binder for the small clock view, large clock view and smartspace. */
@@ -36,14 +45,20 @@ object KeyguardPreviewSmartspaceViewBinder {
    private var currentShowSmartspace: Boolean? = null

    @JvmStatic
    fun bind(parentView: View, viewModel: KeyguardPreviewSmartspaceViewModel) {
    fun bind(
        parentView: ConstraintLayout,
        viewModel: KeyguardPreviewSmartspaceViewModel,
        previewViewModel: KeyguardPreviewViewModel,
    ) {
        if (com.android.systemui.shared.Flags.clockReactiveSmartspaceLayout()) {
            val largeDateView =
                parentView.findViewById<View>(
                    com.android.systemui.shared.R.id.date_smartspace_view_large
                )
            val smallDateView =
                parentView.findViewById<View>(com.android.systemui.shared.R.id.date_smartspace_view)
                parentView.requireViewById<View>(
                    com.android.systemui.shared.R.id.date_smartspace_view
                )
            parentView.repeatWhenAttached {
                repeatOnLifecycle(Lifecycle.State.STARTED) {
                    launch("$TAG#viewModel.previewClockSize") {
@@ -54,7 +69,13 @@ object KeyguardPreviewSmartspaceViewBinder {
                                val largeDateViewVisibility =
                                    if (showSmartspace) {
                                        when (clockSize) {
                                            ClockSizeSetting.DYNAMIC -> View.VISIBLE
                                            ClockSizeSetting.DYNAMIC -> {
                                                if (viewModel.shouldDateWeatherBeBelowLargeClock) {
                                                    View.VISIBLE
                                                } else {
                                                    View.INVISIBLE
                                                }
                                            }
                                            ClockSizeSetting.SMALL -> View.INVISIBLE
                                        }
                                    } else {
@@ -63,7 +84,13 @@ object KeyguardPreviewSmartspaceViewBinder {
                                val smallDateViewVisibility =
                                    if (showSmartspace) {
                                        when (clockSize) {
                                            ClockSizeSetting.DYNAMIC -> View.INVISIBLE
                                            ClockSizeSetting.DYNAMIC -> {
                                                if (viewModel.shouldDateWeatherBeBelowLargeClock) {
                                                    View.INVISIBLE
                                                } else {
                                                    View.VISIBLE
                                                }
                                            }
                                            ClockSizeSetting.SMALL -> View.VISIBLE
                                        }
                                    } else {
@@ -75,7 +102,7 @@ object KeyguardPreviewSmartspaceViewBinder {
                                    }
                                    it.visibility = largeDateViewVisibility
                                }
                                smallDateView?.let {
                                smallDateView.let {
                                    if (shouldFadeIn && smallDateViewVisibility == View.VISIBLE) {
                                        it.alpha = 0F
                                    }
@@ -86,9 +113,113 @@ object KeyguardPreviewSmartspaceViewBinder {
                                        largeDateView?.animateToAlpha(1F)
                                    }
                                    if (smallDateViewVisibility == View.VISIBLE) {
                                        smallDateView?.animateToAlpha(1F)
                                        smallDateView.animateToAlpha(1F)
                                    }
                                }
                                val cs = ConstraintSet()
                                cs.clone(parentView)
                                cs.apply {
                                    val smallClockViewId = ClockViewIds.LOCKSCREEN_CLOCK_VIEW_SMALL
                                    val largeClockViewId = ClockViewIds.LOCKSCREEN_CLOCK_VIEW_LARGE
                                    when (clockSize) {
                                        ClockSizeSetting.DYNAMIC -> {
                                            if (viewModel.shouldDateWeatherBeBelowLargeClock) {
                                                largeDateView.also { view ->
                                                    constrainWidth(
                                                        view.id,
                                                        ConstraintSet.WRAP_CONTENT,
                                                    )
                                                    constrainHeight(
                                                        view.id,
                                                        ConstraintSet.WRAP_CONTENT,
                                                    )
                                                    connect(view.id, START, largeClockViewId, START)
                                                    connect(
                                                        view.id,
                                                        ConstraintSet.END,
                                                        largeClockViewId,
                                                        ConstraintSet.END,
                                                    )
                                                    connect(
                                                        view.id,
                                                        TOP,
                                                        largeClockViewId,
                                                        ConstraintSet.BOTTOM,
                                                        viewModel.getDateWeatherEndPadding(
                                                            view.context
                                                        ),
                                                    )
                                                }
                                            } else {
                                                smallDateView.also { view ->
                                                    constrainWidth(
                                                        view.id,
                                                        ConstraintSet.WRAP_CONTENT,
                                                    )
                                                    constrainHeight(
                                                        view.id,
                                                        ConstraintSet.WRAP_CONTENT,
                                                    )
                                                    (view as? LinearLayout)?.orientation =
                                                        LinearLayout.HORIZONTAL
                                                    connect(view.id, START, smallClockViewId, START)
                                                    clear(view.id, TOP)
                                                    connect(
                                                        view.id,
                                                        TOP,
                                                        PARENT_ID,
                                                        TOP,
                                                        viewModel.getLargeClockSmartspaceTopPadding(
                                                            parentView.context,
                                                            previewViewModel.buildPreviewConfig(),
                                                        ),
                                                    )
                                                }
                                            }
                                        }

                                        ClockSizeSetting.SMALL -> {
                                            smallDateView.also { view ->
                                                constrainWidth(view.id, ConstraintSet.WRAP_CONTENT)
                                                constrainHeight(view.id, ConstraintSet.WRAP_CONTENT)
                                                if (viewModel.shouldDateWeatherBeBelowSmallClock) {
                                                    (view as? LinearLayout)?.orientation =
                                                        LinearLayout.HORIZONTAL
                                                    connect(view.id, START, smallClockViewId, START)
                                                    connect(
                                                        view.id,
                                                        TOP,
                                                        smallClockViewId,
                                                        ConstraintSet.BOTTOM,
                                                        view.resources.getDimensionPixelSize(
                                                            R.dimen.smartspace_padding_vertical
                                                        ),
                                                    )
                                                } else {
                                                    (view as? LinearLayout)?.orientation =
                                                        LinearLayout.VERTICAL
                                                    connect(
                                                        view.id,
                                                        START,
                                                        smallClockViewId,
                                                        ConstraintSet.END,
                                                        view.resources.getDimensionPixelSize(
                                                            R.dimen.smartspace_padding_horizontal
                                                        ),
                                                    )
                                                    connect(view.id, TOP, smallClockViewId, TOP)
                                                    connect(
                                                        view.id,
                                                        ConstraintSet.BOTTOM,
                                                        smallClockViewId,
                                                        ConstraintSet.BOTTOM,
                                                    )
                                                }
                                            }
                                        }
                                    }
                                }
                                cs.applyTo(parentView)
                                currentShowSmartspace = showSmartspace
                            }
                    }
+2 −2
Original line number Diff line number Diff line
@@ -101,7 +101,7 @@ object KeyguardSmartspaceViewBinder {

                    launch("$TAG#smartspaceViewModel.isLargeClockVisible") {
                        clockViewModel.isLargeClockVisible.collect { isLargeClock ->
                            if (isLargeClock) {
                            if (isLargeClock && clockViewModel.shouldDateWeatherBeBelowLargeClock.value) {
                                // hide small clock date/weather
                                keyguardRootView.findViewById<View>(smallViewId)?.let {
                                    it.visibility = View.GONE
@@ -129,7 +129,7 @@ object KeyguardSmartspaceViewBinder {
                                ::Pair,
                            )
                            .collect { (isLargeClock, clockBounds) ->
                                val viewId = if (isLargeClock) smallViewId else largeViewId
                                val viewId = if (isLargeClock && clockViewModel.shouldDateWeatherBeBelowLargeClock.value) smallViewId else largeViewId
                                keyguardRootView.findViewById<View>(viewId)?.let {
                                    it.visibility = View.GONE
                                }
Loading