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

Commit 3246cf07 authored by Steve Elliott's avatar Steve Elliott
Browse files

Reduce IconContainer view-model flow emissions

Flag: ACONFIG com.android.systemui.notifications_icon_container_refactor TRUNKFOOD
Bug: 322133256
Test: atest SystemUITests
Change-Id: I1471484511162efcec18ecec994e6d566e58d532
parent b0e5ec85
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@ import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart
@@ -56,6 +58,8 @@ constructor(
                panelTouchesEnabled && isKeyguardVisible
            }
            .flowOn(bgContext)
            .conflate()
            .distinctUntilChanged()

    /** Amount of a "white" tint to be applied to the icons. */
    val tintAlpha: Flow<Float> =
@@ -70,6 +74,8 @@ constructor(
                aodAmt + dozeAmt // If transitioning between them, they should sum to 1f
            }
            .flowOn(bgContext)
            .conflate()
            .distinctUntilChanged()

    /** Are notification icons animated (ex: animated gif)? */
    val areIconAnimationsEnabled: Flow<Boolean> =
@@ -78,8 +84,10 @@ constructor(
                // Don't animate icons when we're on AOD / dozing
                it != KeyguardState.AOD && it != KeyguardState.DOZING
            }
            .flowOn(bgContext)
            .onStart { emit(true) }
            .flowOn(bgContext)
            .conflate()
            .distinctUntilChanged()

    /** [NotificationIconsViewData] indicating which icons to display in the view. */
    val icons: Flow<NotificationIconsViewData> =
@@ -91,4 +99,6 @@ constructor(
                )
            }
            .flowOn(bgContext)
            .conflate()
            .distinctUntilChanged()
}
+4 −0
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@ import com.android.systemui.statusbar.notification.icon.ui.viewmodel.Notificatio
import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map

@@ -56,4 +58,6 @@ constructor(
                )
            }
            .flowOn(bgContext)
            .conflate()
            .distinctUntilChanged()
}
+12 −2
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flowOn
@@ -64,10 +65,13 @@ constructor(
                panelTouchesEnabled && !isKeyguardShowing
            }
            .flowOn(bgContext)
            .conflate()
            .distinctUntilChanged()

    /** The colors with which to display the notification icons. */
    val iconColors: Flow<NotificationIconColorLookup> =
        combine(darkIconInteractor.tintAreas, darkIconInteractor.tintColor) { areas, tint ->
        darkIconInteractor.darkState
            .map { (areas: Collection<Rect>, tint: Int) ->
                NotificationIconColorLookup { viewBounds: Rect ->
                    if (DarkIconDispatcher.isInAreas(areas, viewBounds)) {
                        IconColorsImpl(tint, areas)
@@ -77,6 +81,8 @@ constructor(
                }
            }
            .flowOn(bgContext)
            .conflate()
            .distinctUntilChanged()

    /** [NotificationIconsViewData] indicating which icons to display in the view. */
    val icons: Flow<NotificationIconsViewData> =
@@ -88,6 +94,8 @@ constructor(
                )
            }
            .flowOn(bgContext)
            .conflate()
            .distinctUntilChanged()

    /** An Icon to show "isolated" in the IconContainer. */
    val isolatedIcon: Flow<AnimatedValue<NotificationIconInfo?>> =
@@ -99,6 +107,8 @@ constructor(
            }
            .distinctUntilChanged()
            .flowOn(bgContext)
            .conflate()
            .distinctUntilChanged()
            .pairwise(initialValue = null)
            .sample(shadeInteractor.shadeExpansion) { (prev, iconInfo), shadeExpansion ->
                val animate =
@@ -113,7 +123,7 @@ constructor(

    /** Location to show an isolated icon, if there is one. */
    val isolatedIconLocation: Flow<Rect> =
        headsUpIconInteractor.isolatedIconLocation.filterNotNull()
        headsUpIconInteractor.isolatedIconLocation.filterNotNull().conflate().distinctUntilChanged()

    private class IconColorsImpl(
        override val tint: Int,
+3 −9
Original line number Diff line number Diff line
@@ -15,20 +15,14 @@
 */
package com.android.systemui.statusbar.phone.domain.interactor

import android.graphics.Rect
import com.android.systemui.statusbar.phone.data.repository.DarkIconRepository
import com.android.systemui.statusbar.phone.domain.model.DarkState
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map

/** States pertaining to calculating colors for icons in dark mode. */
class DarkIconInteractor @Inject constructor(repository: DarkIconRepository) {
    /** @see com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher.DarkChange.areas */
    val tintAreas: Flow<Collection<Rect>> = repository.darkState.map { it.areas }
    /**
     * @see com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher.DarkChange.darkIntensity
     */
    val darkIntensity: Flow<Float> = repository.darkState.map { it.darkIntensity }
    /** @see com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher.DarkChange.tint */
    val tintColor: Flow<Int> = repository.darkState.map { it.tint }
    /** Dark-mode state for tinting icons. */
    val darkState: Flow<DarkState> = repository.darkState.map { DarkState(it.areas, it.tint) }
}
+27 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.statusbar.phone.domain.model

import android.graphics.Rect

/** Dark mode visual states. */
data class DarkState(
    /** Areas on screen that require a dark-mode adjustment. */
    val areas: Collection<Rect>,
    /** Tint color to apply to UI elements that fall within [areas]. */
    val tint: Int,
)