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

Commit 0b0f6987 authored by Fabian Kozynski's avatar Fabian Kozynski
Browse files

Align footer actions with notif background

In split shade, align the bottom of the footer actions (circles) and the
security footer with the bottom of the notifications background.

Test: manual
Test: atest NotificationQSContainerControllerTest
Fixes: 220344583
Fixes: 221823497
Change-Id: I0b132d4f1b238b6ce14905dbf7eccfb9896577ba
parent fcd4e5e8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@
    android:layout_height="@dimen/footer_actions_height"
    android:elevation="@dimen/qs_panel_elevation"
    android:paddingTop="8dp"
    android:paddingBottom="4dp"
    android:paddingBottom="@dimen/qs_footer_actions_bottom_padding"
    android:background="@drawable/qs_footer_actions_background"
    android:gravity="center_vertical"
    android:layout_gravity="bottom"
+1 −0
Original line number Diff line number Diff line
@@ -340,6 +340,7 @@

    <!-- (48dp - 40dp) / 2 -->
    <dimen name="qs_footer_action_inset">4dp</dimen>
    <dimen name="qs_footer_actions_bottom_padding">4dp</dimen>
    <dimen name="qs_footer_action_inset_negative">-4dp</dimen>

    <!-- Margins on each side of QS Footer -->
+37 −23
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import com.android.systemui.util.ViewController
import com.android.systemui.util.concurrency.DelayableExecutor
import java.util.function.Consumer
import javax.inject.Inject
import kotlin.reflect.KMutableProperty0

@VisibleForTesting
internal const val INSET_DEBOUNCE_MILLIS = 500L
@@ -54,6 +55,7 @@ class NotificationsQSContainerController @Inject constructor(
    private var largeScreenShadeHeaderActive = false
    private var notificationsBottomMargin = 0
    private var scrimShadeBottomMargin = 0
    private var footerActionsOffset = 0
    private var bottomStableInsets = 0
    private var bottomCutoutInsets = 0
    private var panelMarginHorizontal = 0
@@ -132,18 +134,17 @@ class NotificationsQSContainerController @Inject constructor(
            resources.getDimensionPixelSize(R.dimen.notification_panel_margin_top)
        }
        updateConstraints()
        if (splitShadeEnabledChanged) {
            // Let's do it at the end when all margins/paddings were already applied.
            // We need to updateBottomSpacing() in case device configuration changed while showing
            // QS details/customizer
            updateBottomSpacing()
        }
        val previousScrimShadeBottomMargin = scrimShadeBottomMargin
        scrimShadeBottomMargin = resources.getDimensionPixelSize(
            R.dimen.split_shade_notifications_scrim_margin_bottom

        val scrimMarginChanged = ::scrimShadeBottomMargin.setAndReportChange(
            resources.getDimensionPixelSize(R.dimen.split_shade_notifications_scrim_margin_bottom)
        )
        val footerOffsetChanged = ::footerActionsOffset.setAndReportChange(
            resources.getDimensionPixelSize(R.dimen.qs_footer_action_inset) +
                resources.getDimensionPixelSize(R.dimen.qs_footer_actions_bottom_padding)
        )
        val dimensChanged = scrimMarginChanged || footerOffsetChanged

        if (previousScrimShadeBottomMargin != scrimShadeBottomMargin) {
        if (splitShadeEnabledChanged || dimensChanged) {
            updateBottomSpacing()
        }
    }
@@ -166,22 +167,13 @@ class NotificationsQSContainerController @Inject constructor(
    }

    private fun updateBottomSpacing() {
        val (containerPadding, notificationsMargin) = calculateBottomSpacing()
        var qsScrollPaddingBottom = 0
        if (!(isQSCustomizing || isQSDetailShowing)) {
            // With the new footer, we also want this padding in the bottom in these cases
            qsScrollPaddingBottom = if (splitShadeEnabled) {
                notificationsMargin - scrimShadeBottomMargin
            } else {
                bottomStableInsets
            }
        }
        val (containerPadding, notificationsMargin, qsContainerPadding) = calculateBottomSpacing()
        mView.setPadding(0, 0, 0, containerPadding)
        mView.setNotificationsMarginBottom(notificationsMargin)
        mView.setQSContainerPaddingBottom(qsScrollPaddingBottom)
        mView.setQSContainerPaddingBottom(qsContainerPadding)
    }

    private fun calculateBottomSpacing(): Pair<Int, Int> {
    private fun calculateBottomSpacing(): Paddings {
        val containerPadding: Int
        var stackScrollMargin = notificationsBottomMargin
        if (splitShadeEnabled) {
@@ -210,7 +202,17 @@ class NotificationsQSContainerController @Inject constructor(
                containerPadding = 0
            }
        }
        return containerPadding to stackScrollMargin
        val qsContainerPadding = if (!(isQSCustomizing || isQSDetailShowing)) {
            // We also want this padding in the bottom in these cases
            if (splitShadeEnabled) {
                stackScrollMargin - scrimShadeBottomMargin - footerActionsOffset
            } else {
                bottomStableInsets
            }
        } else {
            0
        }
        return Paddings(containerPadding, stackScrollMargin, qsContainerPadding)
    }

    fun updateConstraints() {
@@ -275,3 +277,15 @@ class NotificationsQSContainerController @Inject constructor(
        }
    }
}

private data class Paddings(
    val containerPadding: Int,
    val notificationsMargin: Int,
    val qsContainerPadding: Int
)

private fun KMutableProperty0<Int>.setAndReportChange(newValue: Int): Boolean {
    val oldValue = get()
    set(newValue)
    return oldValue != newValue
}
+13 −7
Original line number Diff line number Diff line
@@ -50,6 +50,10 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
        const val BUTTONS_NAVIGATION = WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON
        const val NOTIFICATIONS_MARGIN = 50
        const val SCRIM_MARGIN = 10
        const val FOOTER_ACTIONS_INSET = 2
        const val FOOTER_ACTIONS_PADDING = 2
        const val FOOTER_ACTIONS_OFFSET = FOOTER_ACTIONS_INSET + FOOTER_ACTIONS_PADDING
        const val QS_PADDING_OFFSET = SCRIM_MARGIN + FOOTER_ACTIONS_OFFSET
    }

    @Mock
@@ -95,6 +99,8 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
        overrideResource(R.dimen.split_shade_notifications_scrim_margin_bottom, SCRIM_MARGIN)
        overrideResource(R.dimen.notification_panel_margin_bottom, NOTIFICATIONS_MARGIN)
        overrideResource(R.bool.config_use_split_notification_shade, false)
        overrideResource(R.dimen.qs_footer_actions_bottom_padding, FOOTER_ACTIONS_PADDING)
        overrideResource(R.dimen.qs_footer_action_inset, FOOTER_ACTIONS_INSET)
        whenever(navigationModeController.addListener(navigationModeCaptor.capture()))
                .thenReturn(GESTURES_NAVIGATION)
        doNothing().`when`(overviewProxyService).addCallback(taskbarVisibilityCaptor.capture())
@@ -119,14 +125,14 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
                insets = windowInsets().withStableBottom())
        then(expectedContainerPadding = 0, // taskbar should disappear when shade is expanded
                expectedNotificationsMargin = NOTIFICATIONS_MARGIN,
                expectedQsPadding = NOTIFICATIONS_MARGIN - SCRIM_MARGIN)
                expectedQsPadding = NOTIFICATIONS_MARGIN - QS_PADDING_OFFSET)

        given(taskbarVisible = true,
                navigationMode = BUTTONS_NAVIGATION,
                insets = windowInsets().withStableBottom())
        then(expectedContainerPadding = STABLE_INSET_BOTTOM,
                expectedNotificationsMargin = NOTIFICATIONS_MARGIN,
                expectedQsPadding = NOTIFICATIONS_MARGIN - SCRIM_MARGIN)
                expectedQsPadding = NOTIFICATIONS_MARGIN - QS_PADDING_OFFSET)
    }

    @Test
@@ -138,14 +144,14 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
                navigationMode = GESTURES_NAVIGATION,
                insets = windowInsets().withStableBottom())
        then(expectedContainerPadding = 0,
                expectedQsPadding = NOTIFICATIONS_MARGIN - SCRIM_MARGIN)
                expectedQsPadding = NOTIFICATIONS_MARGIN - QS_PADDING_OFFSET)

        given(taskbarVisible = false,
                navigationMode = BUTTONS_NAVIGATION,
                insets = windowInsets().withStableBottom())
        then(expectedContainerPadding = 0, // qs goes full height as it's not obscuring nav buttons
                expectedNotificationsMargin = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN,
                expectedQsPadding = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN - SCRIM_MARGIN)
                expectedQsPadding = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN - QS_PADDING_OFFSET)
    }

    @Test
@@ -156,14 +162,14 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
                navigationMode = GESTURES_NAVIGATION,
                insets = windowInsets().withCutout())
        then(expectedContainerPadding = CUTOUT_HEIGHT,
            expectedQsPadding = NOTIFICATIONS_MARGIN - SCRIM_MARGIN)
            expectedQsPadding = NOTIFICATIONS_MARGIN - QS_PADDING_OFFSET)

        given(taskbarVisible = false,
                navigationMode = BUTTONS_NAVIGATION,
                insets = windowInsets().withCutout().withStableBottom())
        then(expectedContainerPadding = 0,
                expectedNotificationsMargin = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN,
                expectedQsPadding = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN - SCRIM_MARGIN)
                expectedQsPadding = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN - QS_PADDING_OFFSET)
    }

    @Test
@@ -365,7 +371,7 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
        container.addView(newViewWithId(View.NO_ID))
        val controller = NotificationsQSContainerController(container, navigationModeController,
                overviewProxyService, featureFlags, delayableExecutor)
        controller.updateResources()
        controller.updateConstraints()

        assertThat(container.getChildAt(0).id).isEqualTo(1)
        assertThat(container.getChildAt(1).id).isNotEqualTo(View.NO_ID)