Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt +33 −51 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading Loading @@ -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) } } Loading @@ -119,17 +121,19 @@ object NotificationIconContainerViewBinder { configuration, configurationController, viewStore, ) } launch { viewModel.animationsEnabled.bindAnimationsEnabled(view) } launch { viewModel.isDozing.bindIsDozing(view, dozeParameters) } launch { ) { _, sbiv -> configuration .getColorAttr(R.attr.wallpaperTextColor, DEFAULT_AOD_ICON_COLOR) .bindIconColors(view) .collect { tint -> sbiv.staticDrawableColor = tint sbiv.setDecorColor(tint) } } } launch { viewModel.animationsEnabled.bindAnimationsEnabled(view) } launch { viewModel.isDozing.bindIsDozing(view, dozeParameters) } } } } /** Binds to [NotificationIconContainer.setAnimationsEnabled] */ Loading @@ -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, Loading Loading @@ -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( Loading Loading @@ -242,6 +228,7 @@ object NotificationIconContainerViewBinder { } } val iconBindings = mutableMapOf<String, Job>() var prevIcons = NotificationIconsViewData() sample(layoutParams, ::Pair).collect { (iconsData: NotificationIconsViewData, layoutParams: FrameLayout.LayoutParams), Loading @@ -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) Loading @@ -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, Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt +33 −51 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading Loading @@ -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) } } Loading @@ -119,17 +121,19 @@ object NotificationIconContainerViewBinder { configuration, configurationController, viewStore, ) } launch { viewModel.animationsEnabled.bindAnimationsEnabled(view) } launch { viewModel.isDozing.bindIsDozing(view, dozeParameters) } launch { ) { _, sbiv -> configuration .getColorAttr(R.attr.wallpaperTextColor, DEFAULT_AOD_ICON_COLOR) .bindIconColors(view) .collect { tint -> sbiv.staticDrawableColor = tint sbiv.setDecorColor(tint) } } } launch { viewModel.animationsEnabled.bindAnimationsEnabled(view) } launch { viewModel.isDozing.bindIsDozing(view, dozeParameters) } } } } /** Binds to [NotificationIconContainer.setAnimationsEnabled] */ Loading @@ -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, Loading Loading @@ -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( Loading Loading @@ -242,6 +228,7 @@ object NotificationIconContainerViewBinder { } } val iconBindings = mutableMapOf<String, Job>() var prevIcons = NotificationIconsViewData() sample(layoutParams, ::Pair).collect { (iconsData: NotificationIconsViewData, layoutParams: FrameLayout.LayoutParams), Loading @@ -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) Loading @@ -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, Loading