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

Commit b1ba1b9c authored by burakov's avatar burakov
Browse files

[Dual Shade] Refactor lockscreen viewmodels + fix placement of notifs.

This CL primarily achieves 3 things:

* Replaces state flows in lockscreen view-models to be hydrated states.

* Fixes the positioning of the notifications stack on the lock screen to
  be below the small clock (for Dual Shade wide layout).

* Removes a few unnecessary references to `isShadeLayoutWide`.

Bug: 395060439
Test: Manually tested by observing notification placement on lockscreen
 in both small and large clock configuration.
Test: Added and updated unit tests.
Test: Existing unit tests still pass.
Flag: com.android.systemui.scene_container
Change-Id: Id4b874797d924dae98637ae7d4c0f0719aa603f2
parent dfd02c67
Loading
Loading
Loading
Loading
+2 −8
Original line number Diff line number Diff line
@@ -20,11 +20,8 @@ import android.view.View
import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalView
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.compose.animation.scene.ContentScope
import com.android.internal.jank.Cuj
import com.android.internal.jank.Cuj.CujType
@@ -70,8 +67,7 @@ class LockscreenContent(
            rememberViewModel("LockscreenContent-scrimViewModel") {
                notificationScrimViewModelFactory.create()
            }
        val isContentVisible: Boolean by viewModel.isContentVisible.collectAsStateWithLifecycle()
        if (!isContentVisible) {
        if (!viewModel.isContentVisible) {
            // If the content isn't supposed to be visible, show a large empty box as it's needed
            // for scene transition animations (can't just skip rendering everything or shared
            // elements won't have correct final/initial bounds from animating in and out of the
@@ -80,15 +76,13 @@ class LockscreenContent(
            return
        }

        val coroutineScope = rememberCoroutineScope()
        val blueprintId by viewModel.blueprintId(coroutineScope).collectAsStateWithLifecycle()
        DisposableEffect(view) {
            clockInteractor.clockEventController.registerListeners(view)

            onDispose { clockInteractor.clockEventController.unregisterListeners() }
        }

        val blueprint = blueprintByBlueprintId[blueprintId] ?: return
        val blueprint = blueprintByBlueprintId[viewModel.blueprintId] ?: return
        with(blueprint) {
            Content(viewModel, modifier.sysuiResTag("keyguard_root_view"))
            NotificationLockscreenScrim(notificationLockscreenScrimViewModel)
+22 −19
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.graphicsLayer
@@ -32,7 +31,6 @@ import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntRect
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.compose.animation.scene.ContentScope
import com.android.compose.modifiers.padding
import com.android.systemui.compose.modifiers.sysuiResTag
@@ -45,6 +43,8 @@ import com.android.systemui.keyguard.ui.composable.section.SettingsMenuSection
import com.android.systemui.keyguard.ui.composable.section.StatusBarSection
import com.android.systemui.keyguard.ui.composable.section.TopAreaSection
import com.android.systemui.keyguard.ui.viewmodel.LockscreenContentViewModel
import com.android.systemui.keyguard.ui.viewmodel.LockscreenContentViewModel.NotificationsPlacement.BelowClock
import com.android.systemui.keyguard.ui.viewmodel.LockscreenContentViewModel.NotificationsPlacement.BesideClock
import com.android.systemui.res.R
import java.util.Optional
import javax.inject.Inject
@@ -71,11 +71,8 @@ constructor(
    @Composable
    override fun ContentScope.Content(viewModel: LockscreenContentViewModel, modifier: Modifier) {
        val isUdfpsVisible = viewModel.isUdfpsVisible
        val isShadeLayoutWide by viewModel.isShadeLayoutWide.collectAsStateWithLifecycle()
        val unfoldTranslations by viewModel.unfoldTranslations.collectAsStateWithLifecycle()
        val areNotificationsVisible by
            viewModel.areNotificationsVisible().collectAsStateWithLifecycle(initialValue = false)
        val isBypassEnabled by viewModel.isBypassEnabled.collectAsStateWithLifecycle()
        val isBypassEnabled = viewModel.isBypassEnabled
        val notificationsPlacement = viewModel.notificationsPlacement

        if (isBypassEnabled) {
            with(notificationSection) { HeadsUpNotifications() }
@@ -92,7 +89,9 @@ constructor(
                                modifier =
                                    Modifier.fillMaxWidth()
                                        .padding(
                                            horizontal = { unfoldTranslations.start.roundToInt() }
                                            horizontal = {
                                                viewModel.unfoldTranslations.start.roundToInt()
                                            }
                                        )
                            )
                        }
@@ -101,28 +100,28 @@ constructor(
                            with(topAreaSection) {
                                DefaultClockLayout(
                                    smartSpacePaddingTop = viewModel::getSmartSpacePaddingTop,
                                    isShadeLayoutWide = isShadeLayoutWide,
                                    modifier =
                                        Modifier.fillMaxWidth().graphicsLayer {
                                            translationX = unfoldTranslations.start
                                            translationX = viewModel.unfoldTranslations.start
                                        },
                                )
                            }
                            if (isShadeLayoutWide && !isBypassEnabled) {
                            if (notificationsPlacement is BesideClock && !isBypassEnabled) {
                                with(notificationSection) {
                                    Box(modifier = Modifier.fillMaxHeight()) {
                                        AodPromotedNotificationArea(
                                            modifier =
                                                Modifier.fillMaxWidth(0.5f)
                                                    .align(alignment = Alignment.TopEnd)
                                                    .align(notificationsPlacement.alignment)
                                        )
                                        Notifications(
                                            areNotificationsVisible = areNotificationsVisible,
                                            areNotificationsVisible =
                                                viewModel.areNotificationsVisible,
                                            burnInParams = null,
                                            modifier =
                                                Modifier.fillMaxWidth(0.5f)
                                                    .fillMaxHeight()
                                                    .align(alignment = Alignment.TopEnd)
                                                    .align(notificationsPlacement.alignment)
                                                    .padding(top = 12.dp),
                                        )
                                    }
@@ -138,7 +137,7 @@ constructor(
                            dimensionResource(R.dimen.below_clock_padding_start_icons)

                        with(notificationSection) {
                            if (!isShadeLayoutWide && !isBypassEnabled) {
                            if (notificationsPlacement is BelowClock && !isBypassEnabled) {
                                Box(modifier = Modifier.weight(weight = 1f)) {
                                    Column(Modifier.align(alignment = Alignment.TopStart)) {
                                        AodPromotedNotificationArea(
@@ -150,13 +149,13 @@ constructor(
                                        )
                                    }
                                    Notifications(
                                        areNotificationsVisible = areNotificationsVisible,
                                        areNotificationsVisible = viewModel.areNotificationsVisible,
                                        burnInParams = null,
                                    )
                                }
                            } else {
                                Column {
                                    if (!isShadeLayoutWide) {
                                    if (viewModel.notificationsPlacement is BelowClock) {
                                        AodPromotedNotificationArea(
                                            modifier =
                                                Modifier.padding(top = aodPromotedNotifTopPadding)
@@ -204,13 +203,17 @@ constructor(
                            isStart = true,
                            applyPadding = true,
                            modifier =
                                Modifier.graphicsLayer { translationX = unfoldTranslations.start },
                                Modifier.graphicsLayer {
                                    translationX = viewModel.unfoldTranslations.start
                                },
                        )
                        Shortcut(
                            isStart = false,
                            applyPadding = true,
                            modifier =
                                Modifier.graphicsLayer { translationX = unfoldTranslations.end },
                                Modifier.graphicsLayer {
                                    translationX = viewModel.unfoldTranslations.end
                                },
                        )
                    }
                    with(settingsMenuSection) { SettingsMenu(onSettingsMenuPlaced) }
+2 −5
Original line number Diff line number Diff line
@@ -41,16 +41,13 @@ constructor(
) {

    @Composable
    fun ContentScope.KeyguardMediaCarousel(
        isShadeLayoutWide: Boolean,
        modifier: Modifier = Modifier,
    ) {
    fun ContentScope.KeyguardMediaCarousel(modifier: Modifier = Modifier) {
        val viewModel =
            rememberViewModel(traceName = "KeyguardMediaCarousel") {
                keyguardMediaViewModelFactory.create()
            }
        val horizontalPadding =
            if (isShadeLayoutWide) {
            if (viewModel.isShadeLayoutWide) {
                dimensionResource(id = R.dimen.notification_side_paddings)
            } else {
                dimensionResource(id = R.dimen.notification_side_paddings) +
+1 −2
Original line number Diff line number Diff line
@@ -60,7 +60,6 @@ constructor(
    @Composable
    fun ContentScope.DefaultClockLayout(
        smartSpacePaddingTop: (Resources) -> Int,
        isShadeLayoutWide: Boolean,
        modifier: Modifier = Modifier,
    ) {
        val currentClockLayout by clockViewModel.currentClockLayout.collectAsStateWithLifecycle()
@@ -128,7 +127,7 @@ constructor(
                    )
                }
            }
            with(mediaCarouselSection) { KeyguardMediaCarousel(isShadeLayoutWide) }
            with(mediaCarouselSection) { KeyguardMediaCarousel() }
        }
    }

+0 −2
Original line number Diff line number Diff line
@@ -40,7 +40,6 @@ import com.android.systemui.keyguard.ui.view.layout.sections.DefaultStatusBarSec
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultUdfpsAccessibilityOverlaySection
import com.android.systemui.keyguard.ui.view.layout.sections.KeyguardSliceViewSection
import com.android.systemui.keyguard.ui.view.layout.sections.SmartspaceSection
import com.android.systemui.keyguard.ui.view.layout.sections.SplitShadeGuidelines
import com.android.systemui.util.mockito.whenever
import java.util.Optional
import org.junit.Before
@@ -66,7 +65,6 @@ class DefaultKeyguardBlueprintTest : SysuiTestCase() {
    @Mock private lateinit var defaultSettingsPopupMenuSection: DefaultSettingsPopupMenuSection
    @Mock private lateinit var defaultStatusBarViewSection: DefaultStatusBarSection
    @Mock private lateinit var defaultNSSLSection: DefaultNotificationStackScrollLayoutSection
    @Mock private lateinit var splitShadeGuidelines: SplitShadeGuidelines
    @Mock private lateinit var aodPromotedNotificationSection: AodPromotedNotificationSection
    @Mock private lateinit var aodNotificationIconsSection: AodNotificationIconsSection
    @Mock private lateinit var aodBurnInSection: AodBurnInSection
Loading