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

Commit e6a19d1e authored by Shawn Lee's avatar Shawn Lee Committed by Android (Google) Code Review
Browse files

Merge "[flexiglass] Send scroll from NSSL to flexiglass when bottom notif expands" into main

parents 6803757a 4bdceb3e
Loading
Loading
Loading
Loading
+22 −2
Original line number Original line Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.notifications.ui.composable


import android.util.Log
import android.util.Log
import androidx.compose.foundation.background
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.scrollBy
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsets
@@ -140,6 +141,8 @@ fun SceneScope.NotificationScrollingStack(
) {
) {
    val density = LocalDensity.current
    val density = LocalDensity.current
    val screenCornerRadius = LocalScreenCornerRadius.current
    val screenCornerRadius = LocalScreenCornerRadius.current
    val scrollState = rememberScrollState()
    val syntheticScroll = viewModel.syntheticScroll.collectAsState(0f)
    val expansionFraction by viewModel.expandFraction.collectAsState(0f)
    val expansionFraction by viewModel.expandFraction.collectAsState(0f)


    val navBarHeight =
    val navBarHeight =
@@ -180,11 +183,28 @@ fun SceneScope.NotificationScrollingStack(


    // if contentHeight drops below minimum visible scrim height while scrim is
    // if contentHeight drops below minimum visible scrim height while scrim is
    // expanded, reset scrim offset.
    // expanded, reset scrim offset.
    LaunchedEffect(contentHeight, screenHeight, maxScrimTop, scrimOffset) {
    LaunchedEffect(contentHeight, scrimOffset) {
        snapshotFlow { contentHeight.value < minVisibleScrimHeight() && scrimOffset.value < 0f }
        snapshotFlow { contentHeight.value < minVisibleScrimHeight() && scrimOffset.value < 0f }
            .collect { shouldCollapse -> if (shouldCollapse) scrimOffset.value = 0f }
            .collect { shouldCollapse -> if (shouldCollapse) scrimOffset.value = 0f }
    }
    }


    // if we receive scroll delta from NSSL, offset the scrim and placeholder accordingly.
    LaunchedEffect(syntheticScroll, scrimOffset, scrollState) {
        snapshotFlow { syntheticScroll.value }
            .collect { delta ->
                val minOffset = minScrimOffset()
                if (scrimOffset.value > minOffset) {
                    val remainingDelta = (minOffset - (scrimOffset.value - delta)).coerceAtLeast(0f)
                    scrimOffset.value = (scrimOffset.value - delta).coerceAtLeast(minOffset)
                    if (remainingDelta > 0f) {
                        scrollState.scrollBy(remainingDelta)
                    }
                } else {
                    scrollState.scrollTo(delta.roundToInt())
                }
            }
    }

    Box(
    Box(
        modifier =
        modifier =
            modifier
            modifier
@@ -260,7 +280,7 @@ fun SceneScope.NotificationScrollingStack(
                                )
                                )
                            }
                            }
                        )
                        )
                        .verticalScroll(rememberScrollState())
                        .verticalScroll(scrollState)
                        .fillMaxWidth()
                        .fillMaxWidth()
                        .height { (contentHeight.value + navBarHeight).roundToInt() },
                        .height { (contentHeight.value + navBarHeight).roundToInt() },
            )
            )
+10 −0
Original line number Original line Diff line number Diff line
@@ -4363,6 +4363,12 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
                    layoutEnd -= mShelf.getIntrinsicHeight() + mPaddingBetweenElements;
                    layoutEnd -= mShelf.getIntrinsicHeight() + mPaddingBetweenElements;
                }
                }
                if (endPosition > layoutEnd) {
                if (endPosition > layoutEnd) {
                    // if Scene Container is active, send bottom notification expansion delta
                    // to it so that it can scroll the stack and scrim accordingly.
                    if (SceneContainerFlag.isEnabled()) {
                        float diff = endPosition - layoutEnd;
                        mController.sendSyntheticScrollToSceneFramework(diff);
                    }
                    setOwnScrollY((int) (mOwnScrollY + endPosition - layoutEnd));
                    setOwnScrollY((int) (mOwnScrollY + endPosition - layoutEnd));
                    mDisallowScrollingInThisMotion = true;
                    mDisallowScrollingInThisMotion = true;
                }
                }
@@ -5081,6 +5087,10 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
    }
    }


    private void setOwnScrollY(int ownScrollY, boolean animateStackYChangeListener) {
    private void setOwnScrollY(int ownScrollY, boolean animateStackYChangeListener) {
        // If scene container is active, NSSL should not control its own scrolling.
        if (SceneContainerFlag.isEnabled()) {
            return;
        }
        // Avoid Flicking during clear all
        // Avoid Flicking during clear all
        // when the shade finishes closing, onExpansionStopped will call
        // when the shade finishes closing, onExpansionStopped will call
        // resetScrollPosition to setOwnScrollY to 0
        // resetScrollPosition to setOwnScrollY to 0
+5 −0
Original line number Original line Diff line number Diff line
@@ -1151,6 +1151,11 @@ public class NotificationStackScrollLayoutController implements Dumpable {
        }
        }
    }
    }


    /** Send internal notification expansion to the scene container framework. */
    public void sendSyntheticScrollToSceneFramework(Float delta) {
        mStackAppearanceInteractor.setSyntheticScroll(delta);
    }

    /** Get the y-coordinate of the top bound of the stack. */
    /** Get the y-coordinate of the top bound of the stack. */
    public float getPlaceholderTop() {
    public float getPlaceholderTop() {
        return mStackAppearanceInteractor.getStackBounds().getValue().getTop();
        return mStackAppearanceInteractor.getStackBounds().getValue().getTop();
+7 −0
Original line number Original line Diff line number Diff line
@@ -47,4 +47,11 @@ class NotificationStackAppearanceRepository @Inject constructor() {
     * further.
     * further.
     */
     */
    val scrolledToTop = MutableStateFlow(true)
    val scrolledToTop = MutableStateFlow(true)

    /**
     * The amount in px that the notification stack should scroll due to internal expansion. This
     * should only happen when a notification expansion hits the bottom of the screen, so it is
     * necessary to scroll up to keep expanding the notification.
     */
    val syntheticScroll = MutableStateFlow(0f)
}
}
+13 −0
Original line number Original line Diff line number Diff line
@@ -21,6 +21,7 @@ import com.android.systemui.common.shared.model.NotificationContainerBounds
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.notification.stack.data.repository.NotificationStackAppearanceRepository
import com.android.systemui.statusbar.notification.stack.data.repository.NotificationStackAppearanceRepository
import javax.inject.Inject
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.asStateFlow


@@ -50,6 +51,13 @@ constructor(
     */
     */
    val scrolledToTop: StateFlow<Boolean> = repository.scrolledToTop.asStateFlow()
    val scrolledToTop: StateFlow<Boolean> = repository.scrolledToTop.asStateFlow()


    /**
     * The amount in px that the notification stack should scroll due to internal expansion. This
     * should only happen when a notification expansion hits the bottom of the screen, so it is
     * necessary to scroll up to keep expanding the notification.
     */
    val syntheticScroll: Flow<Float> = repository.syntheticScroll.asStateFlow()

    /** Sets the position of the notification stack in the current scene. */
    /** Sets the position of the notification stack in the current scene. */
    fun setStackBounds(bounds: NotificationContainerBounds) {
    fun setStackBounds(bounds: NotificationContainerBounds) {
        check(bounds.top <= bounds.bottom) { "Invalid bounds: $bounds" }
        check(bounds.top <= bounds.bottom) { "Invalid bounds: $bounds" }
@@ -70,4 +78,9 @@ constructor(
    fun setScrolledToTop(scrolledToTop: Boolean) {
    fun setScrolledToTop(scrolledToTop: Boolean) {
        repository.scrolledToTop.value = scrolledToTop
        repository.scrolledToTop.value = scrolledToTop
    }
    }

    /** Sets the amount (px) that the notification stack should scroll due to internal expansion. */
    fun setSyntheticScroll(delta: Float) {
        repository.syntheticScroll.value = delta
    }
}
}
Loading