Merge "[flexiglass] Update NSSL clipping based on Composable placeholder" into main
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt
index c49c197..12f1b30 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt
@@ -27,11 +27,13 @@
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.layout.LayoutCoordinates
import androidx.compose.ui.layout.boundsInWindow
import androidx.compose.ui.layout.onPlaced
@@ -89,13 +91,18 @@
isScrimVisible: Boolean,
modifier: Modifier = Modifier,
) {
+ val cornerRadius by viewModel.cornerRadiusDp.collectAsState()
+
Box(modifier = modifier) {
if (isScrimVisible) {
Box(
modifier =
Modifier.element(Notifications.Elements.NotificationScrim)
.fillMaxSize()
- .clip(RoundedCornerShape(32.dp))
+ .graphicsLayer {
+ shape = RoundedCornerShape(cornerRadius.dp)
+ clip = true
+ }
.background(MaterialTheme.colorScheme.surface)
)
}
@@ -167,7 +174,9 @@
}
val boundsInWindow = coordinates.boundsInWindow()
viewModel.onBoundsChanged(
+ left = boundsInWindow.left,
top = boundsInWindow.top,
+ right = boundsInWindow.right,
bottom = boundsInWindow.bottom,
)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt
index 28f3e93..4cdb08a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt
@@ -67,9 +67,24 @@
val bounds by collectLastValue(appearanceViewModel.stackBounds)
val top = 200f
+ val left = 0f
val bottom = 550f
- placeholderViewModel.onBoundsChanged(top, bottom)
- assertThat(bounds).isEqualTo(NotificationContainerBounds(top = top, bottom = bottom))
+ val right = 100f
+ placeholderViewModel.onBoundsChanged(
+ left = left,
+ top = top,
+ right = right,
+ bottom = bottom
+ )
+ assertThat(bounds)
+ .isEqualTo(
+ NotificationContainerBounds(
+ left = left,
+ top = top,
+ right = right,
+ bottom = bottom
+ )
+ )
}
@Test
diff --git a/packages/SystemUI/src/com/android/systemui/common/shared/model/NotificationContainerBounds.kt b/packages/SystemUI/src/com/android/systemui/common/shared/model/NotificationContainerBounds.kt
index fdd98bec..3063ebd 100644
--- a/packages/SystemUI/src/com/android/systemui/common/shared/model/NotificationContainerBounds.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/shared/model/NotificationContainerBounds.kt
@@ -18,8 +18,12 @@
/** Models the bounds of the notification container. */
data class NotificationContainerBounds(
+ /** The position of the left of the container in its window coordinate system, in pixels. */
+ val left: Float = 0f,
/** The position of the top of the container in its window coordinate system, in pixels. */
val top: Float = 0f,
+ /** The position of the right of the container in its window coordinate system, in pixels. */
+ val right: Float = 0f,
/** The position of the bottom of the container in its window coordinate system, in pixels. */
val bottom: Float = 0f,
/** Whether any modifications to top/bottom should be smoothly animated. */
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/NotificationStackScrollLayoutSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/NotificationStackScrollLayoutSection.kt
index a25471c..e88a975 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/NotificationStackScrollLayoutSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/NotificationStackScrollLayoutSection.kt
@@ -85,9 +85,9 @@
)
if (sceneContainerFlags.flexiNotifsEnabled()) {
NotificationStackAppearanceViewBinder.bind(
+ context,
sharedNotificationContainer,
notificationStackAppearanceViewModel,
- sceneContainerFlags,
ambientState,
controller,
)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
index 4588e02..d9697db 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
@@ -229,7 +229,9 @@
.distinctUntilChanged()
fun onNotificationContainerBoundsChanged(top: Float, bottom: Float) {
- keyguardInteractor.setNotificationContainerBounds(NotificationContainerBounds(top, bottom))
+ keyguardInteractor.setNotificationContainerBounds(
+ NotificationContainerBounds(top = top, bottom = bottom)
+ )
}
/** Is there an expanded pulse, are we animating in response? */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationStackAppearanceRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationStackAppearanceRepository.kt
index abf09ae..e78a694 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationStackAppearanceRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationStackAppearanceRepository.kt
@@ -26,5 +26,8 @@
@SysUISingleton
class NotificationStackAppearanceRepository @Inject constructor() {
/** The bounds of the notification stack in the current scene. */
- val stackBounds = MutableStateFlow(NotificationContainerBounds(0f, 0f))
+ val stackBounds = MutableStateFlow(NotificationContainerBounds())
+
+ /** The corner radius of the notification stack, in dp. */
+ val cornerRadiusDp = MutableStateFlow(32f)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractor.kt
index 32e4e89..61a4dfc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractor.kt
@@ -39,4 +39,7 @@
check(bounds.top <= bounds.bottom) { "Invalid bounds: $bounds" }
repository.stackBounds.value = bounds
}
+
+ /** The corner radius of the notification stack, in dp. */
+ val cornerRadiusDp: StateFlow<Float> = repository.cornerRadiusDp.asStateFlow()
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationStackAppearanceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationStackAppearanceViewBinder.kt
index fa7a8fd..a9b542d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationStackAppearanceViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationStackAppearanceViewBinder.kt
@@ -16,14 +16,16 @@
package com.android.systemui.statusbar.notification.stack.ui.viewbinder
+import android.content.Context
+import android.util.TypedValue
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.systemui.lifecycle.repeatWhenAttached
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
import com.android.systemui.statusbar.notification.stack.AmbientState
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationStackAppearanceViewModel
+import kotlin.math.roundToInt
import kotlinx.coroutines.launch
/** Binds the shared notification container to its view-model. */
@@ -31,9 +33,9 @@
@JvmStatic
fun bind(
+ context: Context,
view: SharedNotificationContainer,
viewModel: NotificationStackAppearanceViewModel,
- sceneContainerFlags: SceneContainerFlags,
ambientState: AmbientState,
controller: NotificationStackScrollLayoutController,
) {
@@ -45,6 +47,14 @@
bounds.top,
controller.isAddOrRemoveAnimationPending
)
+ controller.setRoundedClippingBounds(
+ it.left,
+ it.top,
+ it.right,
+ it.bottom,
+ viewModel.cornerRadiusDp.value.dpToPx(context),
+ viewModel.cornerRadiusDp.value.dpToPx(context),
+ )
}
}
launch {
@@ -56,4 +66,13 @@
}
}
}
+
+ private fun Float.dpToPx(context: Context): Int {
+ return TypedValue.applyDimension(
+ TypedValue.COMPLEX_UNIT_DIP,
+ this,
+ context.resources.displayMetrics
+ )
+ .roundToInt()
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationStackAppearanceViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationStackAppearanceViewModel.kt
index f4c0e92..834d3ff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationStackAppearanceViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationStackAppearanceViewModel.kt
@@ -23,6 +23,7 @@
import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.StateFlow
/** ViewModel which represents the state of the NSSL/Controller in the world of flexiglass */
@SysUISingleton
@@ -37,4 +38,7 @@
/** The bounds of the notification stack in the current scene. */
val stackBounds: Flow<NotificationContainerBounds> = stackAppearanceInteractor.stackBounds
+
+ /** The corner radius of the notification stack, in dp. */
+ val cornerRadiusDp: StateFlow<Float> = stackAppearanceInteractor.cornerRadiusDp
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt
index c6fd98e..9f22118 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt
@@ -24,6 +24,7 @@
import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor
import com.android.systemui.statusbar.notification.stack.shared.flexiNotifsEnabled
import javax.inject.Inject
+import kotlinx.coroutines.flow.StateFlow
/**
* ViewModel used by the Notification placeholders inside the scene container to update the
@@ -55,9 +56,14 @@
* pixels.
*/
fun onBoundsChanged(
+ left: Float,
top: Float,
+ right: Float,
bottom: Float,
) {
- interactor.setStackBounds(NotificationContainerBounds(top, bottom))
+ interactor.setStackBounds(NotificationContainerBounds(left, top, right, bottom))
}
+
+ /** The corner radius of the placeholder, in dp. */
+ val cornerRadiusDp: StateFlow<Float> = interactor.cornerRadiusDp
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
index 5b854e6..ffbc6ee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
@@ -178,7 +178,7 @@
.stateIn(
scope = applicationScope,
started = SharingStarted.WhileSubscribed(),
- initialValue = NotificationContainerBounds(0f, 0f),
+ initialValue = NotificationContainerBounds(),
)
val alpha: Flow<Float> =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
index 85b9392..f0205b3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
@@ -413,7 +413,7 @@
val top = 123f
val bottom = 456f
keyguardRootViewModel.onNotificationContainerBoundsChanged(top, bottom)
- assertThat(bounds).isEqualTo(NotificationContainerBounds(top, bottom))
+ assertThat(bounds).isEqualTo(NotificationContainerBounds(top = top, bottom = bottom))
}
@Test