Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/AODPromotedNotification.kt +105 −37 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading Loading @@ -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( Loading @@ -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() { Loading Loading @@ -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" packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java +1 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/AODPromotedNotification.kt +105 −37 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading Loading @@ -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( Loading @@ -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() { Loading Loading @@ -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"
packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java +1 −0 Original line number Diff line number Diff line Loading @@ -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); Loading