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

Commit d7083acc authored by Julia Tuttle's avatar Julia Tuttle
Browse files

Clamp max height of AOD RONs

Bug: 402147649
Flag: com.android.systemui.aod_ui_rich_ongoing
Test: manual: Notify.apk, Big Text
Change-Id: I37808d7d976f217d9464d9fb5fc6a3b8d30cc78a
parent 19a953c5
Loading
Loading
Loading
Loading
+105 −37
Original line number Diff line number Diff line
@@ -19,19 +19,26 @@ package com.android.systemui.statusbar.notification.promoted
import android.app.Flags
import android.app.Flags.notificationsRedesignTemplates
import android.app.Notification
import android.content.Context
import android.graphics.PorterDuff
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.View.MeasureSpec.AT_MOST
import android.view.View.MeasureSpec.EXACTLY
import android.view.View.MeasureSpec.UNSPECIFIED
import android.view.View.MeasureSpec.makeMeasureSpec
import android.view.View.VISIBLE
import android.view.ViewGroup.MarginLayoutParams
import android.view.ViewStub
import android.widget.Chronometer
import android.widget.DateTimeView
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.ProgressBar
import android.widget.TextView
import androidx.annotation.DimenRes
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
@@ -42,7 +49,9 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.key
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.view.isVisible
@@ -88,24 +97,14 @@ fun AODPromotedNotification(
    }

    key(content.identity) {
        val sidePaddings = dimensionResource(systemuiR.dimen.notification_side_paddings)
        val sidePaddingValues = PaddingValues(horizontal = sidePaddings, vertical = 0.dp)

        val borderStroke = BorderStroke(1.dp, SecondaryText.brush)

        val borderRadius = dimensionResource(systemuiR.dimen.notification_corner_radius)
        val borderShape = RoundedCornerShape(borderRadius)

        Box(modifier = modifier.padding(sidePaddingValues)) {
        AODPromotedNotificationView(
            layoutResource = layoutResource,
            content = content,
            audiblyAlertedIconVisible = audiblyAlertedIconVisible,
                modifier = Modifier.border(borderStroke, borderShape),
            modifier = modifier,
        )
    }
}
}

@Composable
fun AODPromotedNotificationView(
@@ -114,28 +113,92 @@ fun AODPromotedNotificationView(
    audiblyAlertedIconVisible: Boolean,
    modifier: Modifier = Modifier,
) {
    val sidePaddings = dimensionResource(systemuiR.dimen.notification_side_paddings)
    val sidePaddingValues = PaddingValues(horizontal = sidePaddings, vertical = 0.dp)

    val boxModifier = modifier.padding(sidePaddingValues)

    val borderStroke = BorderStroke(1.dp, SecondaryText.brush)

    val borderRadius = dimensionResource(systemuiR.dimen.notification_corner_radius)
    val borderShape = RoundedCornerShape(borderRadius)

    val maxHeight =
        with(LocalDensity.current) {
                scaledFontHeight(systemuiR.dimen.notification_max_height_for_promoted_ongoing)
                    .toPx()
            }
            .toInt()

    val viewModifier = Modifier.border(borderStroke, borderShape)

    Box(modifier = boxModifier) {
        AndroidView(
            factory = { context ->
            val view =
                val notif =
                    traceSection("$TAG.inflate") {
                        LayoutInflater.from(context).inflate(layoutResource, /* root= */ null)
                    }

                val updater =
                traceSection("$TAG.findViews") { AODPromotedNotificationViewUpdater(view) }
                    traceSection("$TAG.findViews") { AODPromotedNotificationViewUpdater(notif) }

            view.setTag(viewUpdaterTagId, updater)
                val frame = FrameLayoutWithMaxHeight(maxHeight, context)
                frame.addView(notif)
                frame.setTag(viewUpdaterTagId, updater)

            view
                frame
            },
        update = { view ->
            val updater = view.getTag(viewUpdaterTagId) as AODPromotedNotificationViewUpdater
            update = { frame ->
                val updater = frame.getTag(viewUpdaterTagId) as AODPromotedNotificationViewUpdater

                traceSection("$TAG.update") { updater.update(content, audiblyAlertedIconVisible) }
                frame.maxHeight = maxHeight
            },
        modifier = modifier,
            modifier = viewModifier,
        )
    }
}

private class FrameLayoutWithMaxHeight(maxHeight: Int, context: Context) : FrameLayout(context) {
    var maxHeight = maxHeight
        set(value) {
            if (field != value) {
                field = value
                requestLayout()
            }
        }

    // This mirrors the logic in NotificationContentView.onMeasure.
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        if (childCount < 1) {
            return
        }

        val child = getChildAt(0)
        val childLayoutHeight = child.layoutParams.height
        val childHeightSpec =
            if (childLayoutHeight >= 0) {
                makeMeasureSpec(maxHeight.coerceAtMost(childLayoutHeight), EXACTLY)
            } else {
                makeMeasureSpec(maxHeight, AT_MOST)
            }
        measureChildWithMargins(child, widthMeasureSpec, 0, childHeightSpec, 0)
        val childMeasuredHeight = child.measuredHeight

        val ownHeightMode = MeasureSpec.getMode(heightMeasureSpec)
        val ownHeightSize = MeasureSpec.getSize(heightMeasureSpec)

        val ownMeasuredWidth = MeasureSpec.getSize(widthMeasureSpec)
        val ownMeasuredHeight =
            if (ownHeightMode != UNSPECIFIED) {
                childMeasuredHeight.coerceAtMost(ownHeightSize)
            } else {
                childMeasuredHeight
            }

        setMeasuredDimension(ownMeasuredWidth, ownMeasuredHeight)
    }
}

private val PromotedNotificationContentModel.layoutResource: Int?
    get() {
@@ -521,6 +584,11 @@ private enum class AodPromotedNotificationColor(val colorInt: Int) {
    val brush = SolidColor(androidx.compose.ui.graphics.Color(colorInt))
}

@Composable
private fun scaledFontHeight(@DimenRes dimenId: Int): Dp {
    return dimensionResource(dimenId) * LocalDensity.current.fontScale.coerceAtLeast(1f)
}

private val viewUpdaterTagId = systemuiR.id.aod_promoted_notification_view_updater_tag

private const val TAG = "AODPromotedNotification"
+1 −0
Original line number Diff line number Diff line
@@ -269,6 +269,7 @@ public class NotificationContentView extends FrameLayout implements Notification
        mNotificationMaxHeight = maxHeight;
    }

    // This logic is mirrored in FrameLayoutWithMaxHeight.onMeasure in AODPromotedNotification.kt.
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);