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

Commit a2c8f68c authored by Caitlin Shkuratov's avatar Caitlin Shkuratov
Browse files

[SB Refactor] Implement tinting in the new wifi view.

Bug: 238425913
Test: manual: Verify wifi icon updates to be the same color as all the
other status bar icons (e.g. light vs dark mode)
Test: atest MobileStatusBarWifiViewTest

Change-Id: I132cc62a8f8b69fc750c5f0b34750f5a1151be76
parent 80d7be59
Loading
Loading
Loading
Loading
+27 −1
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import kotlinx.coroutines.launch
 * view-model to be reused for multiple view/view-binder bindings.
 */
@OptIn(InternalCoroutinesApi::class)
@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
object WifiViewBinder {

    /**
@@ -59,6 +60,12 @@ object WifiViewBinder {

        /** Notifies that the visibility state has changed. */
        fun onVisibilityStateChanged(@StatusBarIconView.VisibleState state: Int)

        /** Notifies that the icon tint has been updated. */
        fun onIconTintChanged(newTint: Int)

        /** Notifies that the decor tint has been updated (used only for the dot). */
        fun onDecorTintChanged(newTint: Int)
    }

    /** Binds the view to the view-model, continuing to update the former based on the latter. */
@@ -82,6 +89,9 @@ object WifiViewBinder {
        @StatusBarIconView.VisibleState
        val visibilityState: MutableStateFlow<Int> = MutableStateFlow(STATE_HIDDEN)

        val iconTint: MutableStateFlow<Int> = MutableStateFlow(viewModel.defaultColor)
        val decorTint: MutableStateFlow<Int> = MutableStateFlow(viewModel.defaultColor)

        view.repeatWhenAttached {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                launch {
@@ -101,7 +111,7 @@ object WifiViewBinder {
                }

                launch {
                    viewModel.tint.collect { tint ->
                    iconTint.collect { tint ->
                        val tintList = ColorStateList.valueOf(tint)
                        iconView.imageTintList = tintList
                        activityInView.imageTintList = tintList
@@ -110,6 +120,8 @@ object WifiViewBinder {
                    }
                }

                launch { decorTint.collect { tint -> dotView.setDecorColor(tint) } }

                launch {
                    viewModel.isActivityInViewVisible.distinctUntilChanged().collect { visible ->
                        activityInView.isVisible = visible
@@ -144,6 +156,20 @@ object WifiViewBinder {
            override fun onVisibilityStateChanged(@StatusBarIconView.VisibleState state: Int) {
                visibilityState.value = state
            }

            override fun onIconTintChanged(newTint: Int) {
                if (viewModel.useDebugColoring) {
                    return
                }
                iconTint.value = newTint
            }

            override fun onDecorTintChanged(newTint: Int) {
                if (viewModel.useDebugColoring) {
                    return
                }
                decorTint.value = newTint
            }
        }
    }
}
+8 −5
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.util.AttributeSet
import android.view.Gravity
import android.view.LayoutInflater
import com.android.systemui.R
import com.android.systemui.plugins.DarkIconDispatcher
import com.android.systemui.statusbar.BaseStatusBarFrameLayout
import com.android.systemui.statusbar.StatusBarIconView
import com.android.systemui.statusbar.StatusBarIconView.STATE_DOT
@@ -51,18 +52,20 @@ class ModernStatusBarWifiView(
            binding.onVisibilityStateChanged(value)
        }

    override fun getSlot() = slot

    override fun onDarkChanged(areas: ArrayList<Rect>?, darkIntensity: Float, tint: Int) {
        // TODO(b/238425913)
        val newTint = DarkIconDispatcher.getTint(areas, this, tint)
        binding.onIconTintChanged(newTint)
        binding.onDecorTintChanged(newTint)
    }

    override fun getSlot() = slot

    override fun setStaticDrawableColor(color: Int) {
        // TODO(b/238425913)
        binding.onIconTintChanged(color)
    }

    override fun setDecorColor(color: Int) {
        // TODO(b/238425913)
        binding.onDecorTintChanged(color)
    }

    override fun setVisibleState(@StatusBarIconView.VisibleState state: Int, animate: Boolean) {
+8 −21
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
import com.android.systemui.statusbar.pipeline.wifi.ui.model.WifiIcon
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.flowOf

/**
 * A view model for a wifi icon in a specific location. This allows us to control parameters that
@@ -48,24 +47,12 @@ abstract class LocationBasedWifiViewModel(
    /** True if the airplane spacer view should be visible. */
    val isAirplaneSpacerVisible: Flow<Boolean>,
) {
    /** The color that should be used to tint the icon. */
    val tint: Flow<Int> =
        flowOf(
            if (statusBarPipelineFlags.useWifiDebugColoring()) {
    val useDebugColoring: Boolean = statusBarPipelineFlags.useWifiDebugColoring()

    val defaultColor: Int =
        if (useDebugColoring) {
            debugTint
        } else {
                DEFAULT_TINT
            }
        )

    companion object {
        /**
         * A default icon tint.
         *
         * TODO(b/238425913): The tint is actually controlled by
         * [com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager]. We
         * should use that logic instead of white as a default.
         */
        private const val DEFAULT_TINT = Color.WHITE
            Color.WHITE
        }
}
+37 −0
Original line number Diff line number Diff line
@@ -16,11 +16,14 @@

package com.android.systemui.statusbar.pipeline.wifi.ui.view

import android.content.res.ColorStateList
import android.graphics.Rect
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.testing.TestableLooper.RunWithLooper
import android.testing.ViewUtils
import android.view.View
import android.widget.ImageView
import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
@@ -44,6 +47,7 @@ import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiIntera
import com.android.systemui.statusbar.pipeline.wifi.shared.WifiConstants
import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.LocationBasedWifiViewModel
import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.WifiViewModel
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -229,10 +233,43 @@ class ModernStatusBarWifiViewTest : SysuiTestCase() {
        ViewUtils.detachView(view)
    }

    @Test
    fun onDarkChanged_iconHasNewColor() {
        whenever(statusBarPipelineFlags.useWifiDebugColoring()).thenReturn(false)
        val view = ModernStatusBarWifiView.constructAndBind(context, SLOT_NAME, viewModel)
        ViewUtils.attachView(view)
        testableLooper.processAllMessages()

        val areas = ArrayList(listOf(Rect(0, 0, 1000, 1000)))
        val color = 0x12345678
        view.onDarkChanged(areas, 1.0f, color)
        testableLooper.processAllMessages()

        assertThat(view.getIconView().imageTintList).isEqualTo(ColorStateList.valueOf(color))
    }

    @Test
    fun setStaticDrawableColor_iconHasNewColor() {
        whenever(statusBarPipelineFlags.useWifiDebugColoring()).thenReturn(false)
        val view = ModernStatusBarWifiView.constructAndBind(context, SLOT_NAME, viewModel)
        ViewUtils.attachView(view)
        testableLooper.processAllMessages()

        val color = 0x23456789
        view.setStaticDrawableColor(color)
        testableLooper.processAllMessages()

        assertThat(view.getIconView().imageTintList).isEqualTo(ColorStateList.valueOf(color))
    }

    private fun View.getIconGroupView(): View {
        return this.requireViewById(R.id.wifi_group)
    }

    private fun View.getIconView(): ImageView {
        return this.requireViewById(R.id.wifi_signal)
    }

    private fun View.getDotView(): View {
        return this.requireViewById(R.id.status_bar_dot)
    }