diff options
| -rw-r--r-- | packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt | 84 |
1 files changed, 33 insertions, 51 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt index 65b798a14e0b..62c3e9e486b4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt @@ -18,7 +18,6 @@ package com.android.systemui.statusbar.notification.icon.ui.viewbinder import android.graphics.Color import android.graphics.Rect import android.view.View -import android.view.ViewGroup import android.widget.FrameLayout import androidx.annotation.ColorInt import androidx.collection.ArrayMap @@ -32,7 +31,6 @@ import com.android.systemui.statusbar.StatusBarIconView import com.android.systemui.statusbar.notification.NotificationUtils import com.android.systemui.statusbar.notification.collection.NotifCollection import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerViewBinder.IconViewStore -import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconColorLookup import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconColors import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerAlwaysOnDisplayViewModel import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerShelfViewModel @@ -52,6 +50,7 @@ import com.android.systemui.util.ui.stopAnimating import com.android.systemui.util.ui.value import javax.inject.Inject import kotlinx.coroutines.DisposableHandle +import kotlinx.coroutines.Job import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.StateFlow @@ -88,14 +87,17 @@ object NotificationIconContainerViewBinder { return view.repeatWhenAttached { lifecycleScope.run { launch { + val iconColors = + viewModel.iconColors.mapNotNull { it.iconColors(view.viewBounds) } viewModel.icons.bindIcons( view, configuration, configurationController, - viewStore - ) + viewStore, + ) { _, sbiv -> + iconColors.collect { sbiv.updateTintForIcon(it, contrastColorUtil) } + } } - launch { viewModel.iconColors.bindIconColors(view, contrastColorUtil) } launch { viewModel.bindIsolatedIcon(view, viewStore) } launch { viewModel.animationsEnabled.bindAnimationsEnabled(view) } } @@ -119,15 +121,17 @@ object NotificationIconContainerViewBinder { configuration, configurationController, viewStore, - ) + ) { _, sbiv -> + configuration + .getColorAttr(R.attr.wallpaperTextColor, DEFAULT_AOD_ICON_COLOR) + .collect { tint -> + sbiv.staticDrawableColor = tint + sbiv.setDecorColor(tint) + } + } } launch { viewModel.animationsEnabled.bindAnimationsEnabled(view) } launch { viewModel.isDozing.bindIsDozing(view, dozeParameters) } - launch { - configuration - .getColorAttr(R.attr.wallpaperTextColor, DEFAULT_AOD_ICON_COLOR) - .bindIconColors(view) - } } } } @@ -137,31 +141,6 @@ object NotificationIconContainerViewBinder { collect(view::setAnimationsEnabled) } - /** - * Binds to the [StatusBarIconView.setStaticDrawableColor] and [StatusBarIconView.setDecorColor] - * of the [children] of an [NotificationIconContainer]. - */ - private suspend fun Flow<NotificationIconColorLookup>.bindIconColors( - view: NotificationIconContainer, - contrastColorUtil: ContrastColorUtil, - ) { - mapNotNull { lookup -> lookup.iconColors(view.viewBounds) } - .collect { iconLookup -> view.applyTint(iconLookup, contrastColorUtil) } - } - - /** - * Binds to the [StatusBarIconView.setStaticDrawableColor] and [StatusBarIconView.setDecorColor] - * of the [children] of an [NotificationIconContainer]. - */ - private suspend fun Flow<Int>.bindIconColors(view: NotificationIconContainer) { - collect { tint -> - view.children.filterIsInstance<StatusBarIconView>().forEach { icon -> - icon.staticDrawableColor = tint - icon.setDecorColor(tint) - } - } - } - private suspend fun Flow<AnimatedValue<Boolean>>.bindIsDozing( view: NotificationIconContainer, dozeParameters: DozeParameters, @@ -208,12 +187,19 @@ object NotificationIconContainerViewBinder { } } - /** Binds [NotificationIconsViewData] to a [NotificationIconContainer]'s [children]. */ + /** + * Binds [NotificationIconsViewData] to a [NotificationIconContainer]'s [children]. + * + * [bindIcon] will be invoked to bind a child [StatusBarIconView] to an icon associated with the + * given `iconKey`. The parent [Job] of this coroutine will be cancelled automatically when the + * view is to be unbound. + */ private suspend fun Flow<NotificationIconsViewData>.bindIcons( view: NotificationIconContainer, configuration: ConfigurationState, configurationController: ConfigurationController, viewStore: IconViewStore, + bindIcon: suspend (iconKey: String, view: StatusBarIconView) -> Unit = { _, _ -> }, ): Unit = coroutineScope { val iconSizeFlow: Flow<Int> = configuration.getDimensionPixelSize( @@ -242,6 +228,7 @@ object NotificationIconContainerViewBinder { } } + val iconBindings = mutableMapOf<String, Job>() var prevIcons = NotificationIconsViewData() sample(layoutParams, ::Pair).collect { (iconsData: NotificationIconsViewData, layoutParams: FrameLayout.LayoutParams), @@ -261,15 +248,20 @@ object NotificationIconContainerViewBinder { } iconsDiff.removed - .mapNotNull { key -> childrenByNotifKey[key] } - .forEach { child -> view.removeView(child) } + .mapNotNull { key -> childrenByNotifKey[key]?.let { key to it } } + .forEach { (key, child) -> + view.removeView(child) + iconBindings.remove(key)?.cancel() + } - val toAdd = iconsDiff.added.map { viewStore.iconView(it.notifKey) } - for ((i, sbiv) in toAdd.withIndex()) { + val toAdd = iconsDiff.added.map { it.notifKey to viewStore.iconView(it.notifKey) } + for ((i, keyAndView) in toAdd.withIndex()) { + val (key, sbiv) = keyAndView // The view might still be transiently added if it was just removed // and added again view.removeTransientView(sbiv) view.addView(sbiv, i, layoutParams) + iconBindings[key] = launch { bindIcon(key, sbiv) } } view.setChangingViewPositions(true) @@ -292,16 +284,6 @@ object NotificationIconContainerViewBinder { // TODO(b/305739416): Once StatusBarIconView has its own Recommended Architecture stack, this // can be moved there and cleaned up. - private fun ViewGroup.applyTint( - iconColors: NotificationIconColors, - contrastColorUtil: ContrastColorUtil, - ) { - children - .filterIsInstance<StatusBarIconView>() - .filter { it.width != 0 } - .forEach { iv -> iv.updateTintForIcon(iconColors, contrastColorUtil) } - } - private fun StatusBarIconView.updateTintForIcon( iconColors: NotificationIconColors, contrastColorUtil: ContrastColorUtil, |