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

Commit 912d3d38 authored by András Kurucz's avatar András Kurucz Committed by Android (Google) Code Review
Browse files

Merge "[Flexiglass] Set the top HUN height on the HeadsUpPlaceholder" into main

parents 4af89e2d e62b88a6
Loading
Loading
Loading
Loading
+87 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.notifications.ui.composable

import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.Measurable
import androidx.compose.ui.layout.MeasureResult
import androidx.compose.ui.layout.MeasureScope
import androidx.compose.ui.node.LayoutModifierNode
import androidx.compose.ui.node.ModifierNodeElement
import androidx.compose.ui.node.invalidateMeasurement
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.IntOffset
import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView

/**
 * Modify element, which updates the height to the height of current top heads up notification, or
 * to 0 if there is none.
 *
 * @param view Notification stack scroll view
 */
fun Modifier.notificationHeadsUpHeight(view: NotificationScrollView) =
    this then HeadsUpLayoutElement(view)

private data class HeadsUpLayoutElement(
    val view: NotificationScrollView,
) : ModifierNodeElement<HeadsUpLayoutNode>() {

    override fun create(): HeadsUpLayoutNode = HeadsUpLayoutNode(view)

    override fun update(node: HeadsUpLayoutNode) {
        check(view == node.view) { "Trying to reuse the node with a new View." }
    }
}

private class HeadsUpLayoutNode(val view: NotificationScrollView) :
    LayoutModifierNode, Modifier.Node() {

    private val headsUpHeightChangedListener = Runnable { invalidateMeasureIfAttached() }

    override fun onAttach() {
        super.onAttach()
        view.addHeadsUpHeightChangedListener(headsUpHeightChangedListener)
    }

    override fun onDetach() {
        super.onDetach()
        view.removeHeadsUpHeightChangedListener(headsUpHeightChangedListener)
    }

    override fun MeasureScope.measure(
        measurable: Measurable,
        constraints: Constraints
    ): MeasureResult {
        // TODO(b/339181697) make sure, that the row is already measured.
        val contentHeight = view.topHeadsUpHeight
        val placeable =
            measurable.measure(
                constraints.copy(minHeight = contentHeight, maxHeight = contentHeight)
            )
        return layout(placeable.width, placeable.height) { placeable.place(IntOffset.Zero) }
    }

    override fun toString(): String {
        return "HeadsUpLayoutNode(view=$view)"
    }

    fun invalidateMeasureIfAttached() {
        if (isAttached) {
            this.invalidateMeasurement()
        }
    }
}
+4 −5
Original line number Diff line number Diff line
@@ -67,7 +67,6 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.NestedScrollBehavior
import com.android.compose.animation.scene.SceneScope
import com.android.compose.modifiers.height
import com.android.compose.modifiers.thenIf
import com.android.systemui.common.ui.compose.windowinsets.LocalRawScreenHeight
import com.android.systemui.common.ui.compose.windowinsets.LocalScreenCornerRadius
@@ -108,18 +107,17 @@ object Notifications {
 */
@Composable
fun SceneScope.HeadsUpNotificationSpace(
    stackScrollView: NotificationScrollView,
    viewModel: NotificationsPlaceholderViewModel,
    modifier: Modifier = Modifier,
    isPeekFromBottom: Boolean = false,
) {
    val headsUpHeight = viewModel.headsUpHeight.collectAsStateWithLifecycle()

    Element(
        Notifications.Elements.HeadsUpNotificationPlaceholder,
        modifier =
            modifier
                .height { headsUpHeight.value.roundToInt() }
                .fillMaxWidth()
                .notificationHeadsUpHeight(stackScrollView)
                .debugBackground(viewModel, DEBUG_HUN_COLOR)
                .onGloballyPositioned { coordinates: LayoutCoordinates ->
                    val boundsInWindow = coordinates.boundsInWindow()
@@ -152,6 +150,7 @@ fun SceneScope.ConstrainedNotificationStack(
            modifier = Modifier.fillMaxSize(),
        )
        HeadsUpNotificationSpace(
            stackScrollView = stackScrollView,
            viewModel = viewModel,
            modifier = Modifier.align(Alignment.TopCenter),
        )
@@ -358,7 +357,7 @@ fun SceneScope.NotificationScrollingStack(
                        .onSizeChanged { size -> stackHeight.intValue = size.height },
            )
        }
        HeadsUpNotificationSpace(viewModel = viewModel)
        HeadsUpNotificationSpace(stackScrollView = stackScrollView, viewModel = viewModel)
    }
}

+4 −12
Original line number Diff line number Diff line
@@ -42,7 +42,6 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.rememberScrollState
@@ -60,7 +59,6 @@ import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.compose.animation.scene.SceneScope
@@ -79,14 +77,13 @@ import com.android.systemui.media.controls.ui.composable.MediaCarousel
import com.android.systemui.media.controls.ui.controller.MediaCarouselController
import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.media.dagger.MediaModule
import com.android.systemui.notifications.ui.composable.NotificationScrollingStack
import com.android.systemui.notifications.ui.composable.HeadsUpNotificationSpace
import com.android.systemui.qs.footer.ui.compose.FooterActionsWithAnimatedVisibility
import com.android.systemui.qs.ui.viewmodel.QuickSettingsSceneViewModel
import com.android.systemui.res.R
import com.android.systemui.scene.session.ui.composable.SaveableSession
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.ui.composable.ComposableScene
import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.shade.ui.composable.CollapsedShadeHeader
import com.android.systemui.shade.ui.composable.ExpandedShadeHeader
import com.android.systemui.shade.ui.composable.Shade
@@ -99,7 +96,6 @@ import com.android.systemui.statusbar.phone.ui.TintedIconManager
import dagger.Lazy
import javax.inject.Inject
import javax.inject.Named
import kotlin.math.roundToInt
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.stateIn
@@ -368,15 +364,11 @@ private fun SceneScope.QuickSettingsScene(
                    Modifier.align(Alignment.CenterHorizontally).sysuiResTag("qs_footer_actions"),
            )
        }
        NotificationScrollingStack(
        HeadsUpNotificationSpace(
            stackScrollView = notificationStackScrollView,
            viewModel = notificationsPlaceholderViewModel,
            shadeSession = shadeSession,
            maxScrimTop = { screenHeight },
            shouldPunchHoleBehindScrim = shouldPunchHoleBehindScrim,
            shadeMode = ShadeMode.Single,
            modifier =
                Modifier.fillMaxWidth().offset { IntOffset(x = 0, y = screenHeight.roundToInt()) },
            modifier = Modifier.align(Alignment.BottomCenter),
            isPeekFromBottom = true,
        )
    }
}
+1 −5
Original line number Diff line number Diff line
@@ -2843,14 +2843,10 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
        mIsSystemChildExpanded = expanded;
    }

    public void setLayoutListener(LayoutListener listener) {
    public void setLayoutListener(@Nullable LayoutListener listener) {
        mLayoutListener = listener;
    }

    public void removeListener() {
        mLayoutListener = null;
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        Trace.beginSection(appendTraceStyleTag("ExpNotRow#onLayout"));
+1 −1
Original line number Diff line number Diff line
@@ -242,7 +242,7 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl
    public void onLayout() {
        mIconsPlaced = false; // Force icons to be re-placed
        setMenuLocation();
        mParent.removeListener();
        mParent.setLayoutListener(null);
    }

    private void createMenuViews(boolean resetState) {
Loading