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

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

Merge "[flexiglass] Send overscrolling touches from NSSL after expansion" into main

parents fe42feb5 a20f6cbf
Loading
Loading
Loading
Loading
+15 −5
Original line number Diff line number Diff line
@@ -30,11 +30,15 @@ import com.android.compose.nestedscroll.PriorityNestedScrollConnection
 */
fun NotificationScrimNestedScrollConnection(
    scrimOffset: () -> Float,
    onScrimOffsetChanged: (Float) -> Unit,
    snapScrimOffset: (Float) -> Unit,
    animateScrimOffset: (Float) -> Unit,
    minScrimOffset: () -> Float,
    maxScrimOffset: Float,
    contentHeight: () -> Float,
    minVisibleScrimHeight: () -> Float,
    isCurrentGestureOverscroll: () -> Boolean,
    onStart: (Float) -> Unit = {},
    onStop: (Float) -> Unit = {},
): PriorityNestedScrollConnection {
    return PriorityNestedScrollConnection(
        orientation = Orientation.Vertical,
@@ -49,7 +53,7 @@ fun NotificationScrimNestedScrollConnection(
        // scrolling down and content is done scrolling to top. After that, the scrim
        // needs to collapse; collapse the scrim until it is at the maxScrimOffset.
        canStartPostScroll = { offsetAvailable, _ ->
            offsetAvailable > 0 && scrimOffset() < maxScrimOffset
            offsetAvailable > 0 && (scrimOffset() < maxScrimOffset || isCurrentGestureOverscroll())
        },
        canStartPostFling = { false },
        canContinueScroll = {
@@ -57,7 +61,7 @@ fun NotificationScrimNestedScrollConnection(
            minScrimOffset() < currentHeight && currentHeight < maxScrimOffset
        },
        canScrollOnFling = true,
        onStart = { /* do nothing */},
        onStart = { offsetAvailable -> onStart(offsetAvailable) },
        onScroll = { offsetAvailable ->
            val currentHeight = scrimOffset()
            val amountConsumed =
@@ -68,10 +72,16 @@ fun NotificationScrimNestedScrollConnection(
                    val amountLeft = minScrimOffset() - currentHeight
                    offsetAvailable.coerceAtLeast(amountLeft)
                }
            onScrimOffsetChanged(currentHeight + amountConsumed)
            snapScrimOffset(currentHeight + amountConsumed)
            amountConsumed
        },
        // Don't consume the velocity on pre/post fling
        onStop = { 0f },
        onStop = { velocityAvailable ->
            onStop(velocityAvailable)
            if (scrimOffset() < minScrimOffset()) {
                animateScrimOffset(minScrimOffset())
            }
            0f
        },
    )
}
+19 −5
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
package com.android.systemui.notifications.ui.composable

import android.util.Log
import androidx.compose.animation.core.Animatable
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.scrollBy
import androidx.compose.foundation.layout.Box
@@ -39,8 +40,8 @@ import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -77,6 +78,7 @@ import com.android.systemui.statusbar.notification.stack.ui.viewmodel.Notificati
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationTransitionThresholds.EXPANSION_FOR_MAX_SCRIM_ALPHA
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel
import kotlin.math.roundToInt
import kotlinx.coroutines.launch

object Notifications {
    object Elements {
@@ -159,11 +161,13 @@ fun SceneScope.NotificationScrollingStack(
    shouldPunchHoleBehindScrim: Boolean,
    modifier: Modifier = Modifier,
) {
    val coroutineScope = rememberCoroutineScope()
    val density = LocalDensity.current
    val screenCornerRadius = LocalScreenCornerRadius.current
    val scrimCornerRadius = dimensionResource(R.dimen.notification_scrim_corner_radius)
    val scrollState = rememberScrollState()
    val syntheticScroll = viewModel.syntheticScroll.collectAsState(0f)
    val isCurrentGestureOverscroll = viewModel.isCurrentGestureOverscroll.collectAsState(false)
    val expansionFraction by viewModel.expandFraction.collectAsState(0f)

    val navBarHeight =
@@ -180,7 +184,7 @@ fun SceneScope.NotificationScrollingStack(
    // When fully expanded (scrimOffset = minScrimOffset), its top bound is at minScrimStartY,
    // which is equal to the height of the Shade Header. Thus, when the scrim is fully expanded, the
    // entire height of the scrim is visible on screen.
    val scrimOffset = remember { mutableStateOf(0f) }
    val scrimOffset = remember { Animatable(0f) }

    // set the bounds to null when the scrim disappears
    DisposableEffect(Unit) { onDispose { viewModel.onScrimBoundsChanged(null) } }
@@ -204,7 +208,7 @@ fun SceneScope.NotificationScrollingStack(
    // expanded, reset scrim offset.
    LaunchedEffect(stackHeight, scrimOffset) {
        snapshotFlow { stackHeight.value < minVisibleScrimHeight() && scrimOffset.value < 0f }
            .collect { shouldCollapse -> if (shouldCollapse) scrimOffset.value = 0f }
            .collect { shouldCollapse -> if (shouldCollapse) scrimOffset.snapTo(0f) }
    }

    // if we receive scroll delta from NSSL, offset the scrim and placeholder accordingly.
@@ -214,7 +218,7 @@ fun SceneScope.NotificationScrollingStack(
                val minOffset = minScrimOffset()
                if (scrimOffset.value > minOffset) {
                    val remainingDelta = (minOffset - (scrimOffset.value - delta)).coerceAtLeast(0f)
                    scrimOffset.value = (scrimOffset.value - delta).coerceAtLeast(minOffset)
                    scrimOffset.snapTo((scrimOffset.value - delta).coerceAtLeast(minOffset))
                    if (remainingDelta > 0f) {
                        scrollState.scrollBy(remainingDelta)
                    }
@@ -296,20 +300,30 @@ fun SceneScope.NotificationScrollingStack(
                modifier =
                    Modifier.verticalNestedScrollToScene(
                            topBehavior = NestedScrollBehavior.EdgeWithPreview,
                            isExternalOverscrollGesture = { isCurrentGestureOverscroll.value }
                        )
                        .nestedScroll(
                            remember(
                                scrimOffset,
                                maxScrimTop,
                                minScrimTop,
                                isCurrentGestureOverscroll,
                            ) {
                                NotificationScrimNestedScrollConnection(
                                    scrimOffset = { scrimOffset.value },
                                    onScrimOffsetChanged = { scrimOffset.value = it },
                                    snapScrimOffset = { value ->
                                        coroutineScope.launch { scrimOffset.snapTo(value) }
                                    },
                                    animateScrimOffset = { value ->
                                        coroutineScope.launch { scrimOffset.animateTo(value) }
                                    },
                                    minScrimOffset = minScrimOffset,
                                    maxScrimOffset = 0f,
                                    contentHeight = { stackHeight.value },
                                    minVisibleScrimHeight = minVisibleScrimHeight,
                                    isCurrentGestureOverscroll = {
                                        isCurrentGestureOverscroll.value
                                    },
                                )
                            }
                        )
+5 −2
Original line number Diff line number Diff line
@@ -877,6 +877,7 @@ internal class NestedScrollHandlerImpl(
    private val orientation: Orientation,
    private val topOrLeftBehavior: NestedScrollBehavior,
    private val bottomOrRightBehavior: NestedScrollBehavior,
    private val isExternalOverscrollGesture: () -> Boolean,
) {
    private val layoutState = layoutImpl.state
    private val draggableHandler = layoutImpl.draggableHandler(orientation)
@@ -932,7 +933,8 @@ internal class NestedScrollHandlerImpl(
        return PriorityNestedScrollConnection(
            orientation = orientation,
            canStartPreScroll = { offsetAvailable, offsetBeforeStart ->
                canChangeScene = offsetBeforeStart == 0f
                canChangeScene =
                    if (isExternalOverscrollGesture()) false else offsetBeforeStart == 0f

                val canInterceptSwipeTransition =
                    canChangeScene &&
@@ -962,7 +964,8 @@ internal class NestedScrollHandlerImpl(
                        else -> return@PriorityNestedScrollConnection false
                    }

                val isZeroOffset = offsetBeforeStart == 0f
                val isZeroOffset =
                    if (isExternalOverscrollGesture()) false else offsetBeforeStart == 0f

                val canStart =
                    when (behavior) {
+11 −0
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ internal fun Modifier.nestedScrollToScene(
    orientation: Orientation,
    topOrLeftBehavior: NestedScrollBehavior,
    bottomOrRightBehavior: NestedScrollBehavior,
    isExternalOverscrollGesture: () -> Boolean,
) =
    this then
        NestedScrollToSceneElement(
@@ -82,6 +83,7 @@ internal fun Modifier.nestedScrollToScene(
            orientation = orientation,
            topOrLeftBehavior = topOrLeftBehavior,
            bottomOrRightBehavior = bottomOrRightBehavior,
            isExternalOverscrollGesture = isExternalOverscrollGesture,
        )

private data class NestedScrollToSceneElement(
@@ -89,6 +91,7 @@ private data class NestedScrollToSceneElement(
    private val orientation: Orientation,
    private val topOrLeftBehavior: NestedScrollBehavior,
    private val bottomOrRightBehavior: NestedScrollBehavior,
    private val isExternalOverscrollGesture: () -> Boolean,
) : ModifierNodeElement<NestedScrollToSceneNode>() {
    override fun create() =
        NestedScrollToSceneNode(
@@ -96,6 +99,7 @@ private data class NestedScrollToSceneElement(
            orientation = orientation,
            topOrLeftBehavior = topOrLeftBehavior,
            bottomOrRightBehavior = bottomOrRightBehavior,
            isExternalOverscrollGesture = isExternalOverscrollGesture,
        )

    override fun update(node: NestedScrollToSceneNode) {
@@ -104,6 +108,7 @@ private data class NestedScrollToSceneElement(
            orientation = orientation,
            topOrLeftBehavior = topOrLeftBehavior,
            bottomOrRightBehavior = bottomOrRightBehavior,
            isExternalOverscrollGesture = isExternalOverscrollGesture,
        )
    }

@@ -121,6 +126,7 @@ private class NestedScrollToSceneNode(
    orientation: Orientation,
    topOrLeftBehavior: NestedScrollBehavior,
    bottomOrRightBehavior: NestedScrollBehavior,
    isExternalOverscrollGesture: () -> Boolean,
) : DelegatingNode() {
    private var priorityNestedScrollConnection: PriorityNestedScrollConnection =
        scenePriorityNestedScrollConnection(
@@ -128,6 +134,7 @@ private class NestedScrollToSceneNode(
            orientation = orientation,
            topOrLeftBehavior = topOrLeftBehavior,
            bottomOrRightBehavior = bottomOrRightBehavior,
            isExternalOverscrollGesture = isExternalOverscrollGesture,
        )

    private var nestedScrollNode: DelegatableNode =
@@ -150,6 +157,7 @@ private class NestedScrollToSceneNode(
        orientation: Orientation,
        topOrLeftBehavior: NestedScrollBehavior,
        bottomOrRightBehavior: NestedScrollBehavior,
        isExternalOverscrollGesture: () -> Boolean,
    ) {
        // Clean up the old nested scroll connection
        priorityNestedScrollConnection.reset()
@@ -162,6 +170,7 @@ private class NestedScrollToSceneNode(
                orientation = orientation,
                topOrLeftBehavior = topOrLeftBehavior,
                bottomOrRightBehavior = bottomOrRightBehavior,
                isExternalOverscrollGesture = isExternalOverscrollGesture,
            )
        nestedScrollNode =
            nestedScrollModifierNode(
@@ -177,11 +186,13 @@ private fun scenePriorityNestedScrollConnection(
    orientation: Orientation,
    topOrLeftBehavior: NestedScrollBehavior,
    bottomOrRightBehavior: NestedScrollBehavior,
    isExternalOverscrollGesture: () -> Boolean,
) =
    NestedScrollHandlerImpl(
            layoutImpl = layoutImpl,
            orientation = orientation,
            topOrLeftBehavior = topOrLeftBehavior,
            bottomOrRightBehavior = bottomOrRightBehavior,
            isExternalOverscrollGesture = isExternalOverscrollGesture,
        )
        .connection
+5 −1
Original line number Diff line number Diff line
@@ -141,23 +141,27 @@ internal class SceneScopeImpl(
    override fun Modifier.horizontalNestedScrollToScene(
        leftBehavior: NestedScrollBehavior,
        rightBehavior: NestedScrollBehavior,
        isExternalOverscrollGesture: () -> Boolean,
    ): Modifier =
        nestedScrollToScene(
            layoutImpl = layoutImpl,
            orientation = Orientation.Horizontal,
            topOrLeftBehavior = leftBehavior,
            bottomOrRightBehavior = rightBehavior,
            isExternalOverscrollGesture = isExternalOverscrollGesture,
        )

    override fun Modifier.verticalNestedScrollToScene(
        topBehavior: NestedScrollBehavior,
        bottomBehavior: NestedScrollBehavior
        bottomBehavior: NestedScrollBehavior,
        isExternalOverscrollGesture: () -> Boolean,
    ): Modifier =
        nestedScrollToScene(
            layoutImpl = layoutImpl,
            orientation = Orientation.Vertical,
            topOrLeftBehavior = topBehavior,
            bottomOrRightBehavior = bottomBehavior,
            isExternalOverscrollGesture = isExternalOverscrollGesture,
        )

    override fun Modifier.noResizeDuringTransitions(): Modifier {
Loading