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

Commit c5ef3541 authored by Christian Go??llner's avatar Christian Go??llner Committed by Christian Göllner
Browse files

[StatusBar][Letterbox] Retrieve letterbox background info from WM

Before this change, we were assuming that the background was always
black.
Now we retrieve the actual values from WindowManager.

This is used to determine the color of the status bar icons that are
positioned on the background.

Fixes: 238607453
Test: Manually
Test: LetterboxBackgroundProviderTest.kt
Test: LetterboxAppearanceCalculatorTest.kt
Change-Id: I9dd9c95b35c5ca7ce20ee670e073cbad578ab5d9
parent 818d8099
Loading
Loading
Loading
Loading
+10 −6
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package com.android.systemui.statusbar.phone

import android.annotation.ColorInt
import android.graphics.Color
import android.graphics.Rect
import android.view.InsetsFlags
import android.view.ViewDebug
@@ -39,7 +38,13 @@ import javax.inject.Inject
class LetterboxAppearance(
    @Appearance val appearance: Int,
    val appearanceRegions: Array<AppearanceRegion>
)
) {
    override fun toString(): String {
        val appearanceString =
                ViewDebug.flagsToString(InsetsFlags::class.java, "appearance", appearance)
        return "LetterboxAppearance{$appearanceString, ${appearanceRegions.contentToString()}}"
    }
}

/**
 * Responsible for calculating the [Appearance] and [AppearanceRegion] for the status bar when apps
@@ -51,6 +56,7 @@ class LetterboxAppearanceCalculator
constructor(
    private val lightBarController: LightBarController,
    private val dumpManager: DumpManager,
    private val letterboxBackgroundProvider: LetterboxBackgroundProvider,
) : OnStatusBarViewInitializedListener, CentralSurfacesComponent.Startable {

    private var statusBarBoundsProvider: StatusBarBoundsProvider? = null
@@ -184,13 +190,11 @@ constructor(

    @ColorInt
    private fun outerLetterboxBackgroundColor(): Int {
        // TODO(b/238607453): retrieve this information from WindowManager.
        return Color.BLACK
        return letterboxBackgroundProvider.letterboxBackgroundColor
    }

    private fun isOuterLetterboxMultiColored(): Boolean {
        // TODO(b/238607453): retrieve this information from WindowManager.
        return false
        return letterboxBackgroundProvider.isLetterboxBackgroundMultiColored
    }

    private fun getEndSideIconsBounds(): Rect {
+74 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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

import android.annotation.ColorInt
import android.graphics.Color
import android.os.RemoteException
import android.view.IWindowManager
import com.android.systemui.Dumpable
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dump.DumpManager
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
import java.io.PrintWriter
import java.util.concurrent.Executor
import javax.inject.Inject

/** Responsible for providing information about the background of letterboxed apps. */
@CentralSurfacesScope
class LetterboxBackgroundProvider
@Inject
constructor(
    private val windowManager: IWindowManager,
    @Background private val backgroundExecutor: Executor,
    private val dumpManager: DumpManager,
) : CentralSurfacesComponent.Startable, Dumpable {

    @ColorInt
    var letterboxBackgroundColor: Int = Color.BLACK
        private set

    var isLetterboxBackgroundMultiColored: Boolean = false
        private set

    override fun start() {
        dumpManager.registerDumpable(javaClass.simpleName, this)

        // Using a background executor, as binder calls to IWindowManager are blocking
        backgroundExecutor.execute {
            try {
                isLetterboxBackgroundMultiColored = windowManager.isLetterboxBackgroundMultiColored
                letterboxBackgroundColor = windowManager.letterboxBackgroundColorInArgb
            } catch (e: RemoteException) {
                e.rethrowFromSystemServer()
            }
        }
    }

    override fun stop() {
        dumpManager.unregisterDumpable(javaClass.simpleName)
    }

    override fun dump(pw: PrintWriter, args: Array<out String>) {
        pw.println(
            """
           letterboxBackgroundColor: ${Color.valueOf(letterboxBackgroundColor)}
           isLetterboxBackgroundMultiColored: $isLetterboxBackgroundMultiColored
       """.trimIndent())
    }
}
+6 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.phone.dagger;

import com.android.systemui.statusbar.phone.LetterboxAppearanceCalculator;
import com.android.systemui.statusbar.phone.LetterboxBackgroundProvider;
import com.android.systemui.statusbar.phone.SystemBarAttributesListener;

import java.util.Set;
@@ -40,4 +41,9 @@ interface CentralSurfacesStartableModule {
    @IntoSet
    CentralSurfacesComponent.Startable sysBarAttrsListener(
            SystemBarAttributesListener systemBarAttributesListener);

    @Binds
    @IntoSet
    CentralSurfacesComponent.Startable letterboxBgProvider(
            LetterboxBackgroundProvider letterboxBackgroundProvider);
}
+25 −2
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.statusbar.phone

import android.graphics.Color
import android.graphics.Rect
import android.testing.AndroidTestingRunner
import android.view.WindowInsetsController
@@ -24,6 +25,7 @@ import androidx.test.filters.SmallTest
import com.android.internal.statusbar.LetterboxDetails
import com.android.internal.view.AppearanceRegion
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent
import com.google.common.truth.Expect
import com.google.common.truth.Truth.assertThat
@@ -33,7 +35,6 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.`when` as whenever
import com.android.systemui.dump.DumpManager
import org.mockito.MockitoAnnotations

@RunWith(AndroidTestingRunner::class)
@@ -56,6 +57,7 @@ class LetterboxAppearanceCalculatorTest : SysuiTestCase() {
    @Mock private lateinit var statusBarBoundsProvider: StatusBarBoundsProvider
    @Mock private lateinit var statusBarFragmentComponent: StatusBarFragmentComponent
    @Mock private lateinit var dumpManager: DumpManager
    @Mock private lateinit var letterboxBackgroundProvider: LetterboxBackgroundProvider

    private lateinit var calculator: LetterboxAppearanceCalculator

@@ -63,8 +65,12 @@ class LetterboxAppearanceCalculatorTest : SysuiTestCase() {
    fun setUp() {
        MockitoAnnotations.initMocks(this)
        whenever(statusBarFragmentComponent.boundsProvider).thenReturn(statusBarBoundsProvider)
        calculator = LetterboxAppearanceCalculator(lightBarController, dumpManager)
        calculator =
            LetterboxAppearanceCalculator(
                lightBarController, dumpManager, letterboxBackgroundProvider)
        calculator.onStatusBarViewInitialized(statusBarFragmentComponent)
        whenever(letterboxBackgroundProvider.letterboxBackgroundColor).thenReturn(Color.BLACK)
        whenever(letterboxBackgroundProvider.isLetterboxBackgroundMultiColored).thenReturn(false)
    }

    @Test
@@ -99,6 +105,23 @@ class LetterboxAppearanceCalculatorTest : SysuiTestCase() {
        expect.that(letterboxAppearance.appearanceRegions).isEqualTo(TEST_APPEARANCE_REGIONS)
    }

    @Test
    fun getLetterboxAppearance_noOverlap_BackgroundMultiColor_returnsAppearanceWithScrim() {
        whenever(letterboxBackgroundProvider.isLetterboxBackgroundMultiColored).thenReturn(true)
        whenever(statusBarBoundsProvider.visibleStartSideBounds).thenReturn(Rect(0, 0, 100, 100))
        whenever(statusBarBoundsProvider.visibleEndSideBounds).thenReturn(Rect(200, 0, 300, 100))
        val letterbox = letterboxWithInnerBounds(Rect(101, 0, 199, 100))

        val letterboxAppearance =
            calculator.getLetterboxAppearance(
                TEST_APPEARANCE, TEST_APPEARANCE_REGIONS, arrayOf(letterbox))

        expect
                .that(letterboxAppearance.appearance)
                .isEqualTo(TEST_APPEARANCE or APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS)
        expect.that(letterboxAppearance.appearanceRegions).isEqualTo(TEST_APPEARANCE_REGIONS)
    }

    @Test
    fun getLetterboxAppearance_noOverlap_returnsAppearanceWithoutScrim() {
        whenever(statusBarBoundsProvider.visibleStartSideBounds).thenReturn(Rect(0, 0, 100, 100))
+100 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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

import android.graphics.Color
import android.testing.AndroidTestingRunner
import android.view.IWindowManager
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations

@RunWith(AndroidTestingRunner::class)
@SmallTest
class LetterboxBackgroundProviderTest : SysuiTestCase() {

    private val fakeSystemClock = FakeSystemClock()
    private val fakeExecutor = FakeExecutor(fakeSystemClock)

    @Mock private lateinit var windowManager: IWindowManager
    @Mock private lateinit var dumpManager: DumpManager

    private lateinit var provider: LetterboxBackgroundProvider

    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)

        provider = LetterboxBackgroundProvider(windowManager, fakeExecutor, dumpManager)
    }

    @Test
    fun letterboxBackgroundColor_defaultValue_returnsBlack() {
        assertThat(provider.letterboxBackgroundColor).isEqualTo(Color.BLACK)
    }

    @Test
    fun letterboxBackgroundColor_afterOnStart_executorNotDone_returnsDefaultValue() {
        whenever(windowManager.letterboxBackgroundColorInArgb).thenReturn(Color.RED)

        provider.start()

        assertThat(provider.letterboxBackgroundColor).isEqualTo(Color.BLACK)
    }

    @Test
    fun letterboxBackgroundColor_afterOnStart_executorDone_returnsValueFromWindowManager() {
        whenever(windowManager.letterboxBackgroundColorInArgb).thenReturn(Color.RED)

        provider.start()
        fakeExecutor.runAllReady()

        assertThat(provider.letterboxBackgroundColor).isEqualTo(Color.RED)
    }

    @Test
    fun isLetterboxBackgroundMultiColored_defaultValue_returnsFalse() {
        assertThat(provider.isLetterboxBackgroundMultiColored).isEqualTo(false)
    }
    @Test
    fun isLetterboxBackgroundMultiColored_afterOnStart_executorNotDone_returnsDefaultValue() {
        whenever(windowManager.isLetterboxBackgroundMultiColored).thenReturn(true)

        provider.start()

        assertThat(provider.isLetterboxBackgroundMultiColored).isFalse()
    }

    @Test
    fun isBackgroundMultiColored_afterOnStart_executorDone_returnsValueFromWindowManager() {
        whenever(windowManager.isLetterboxBackgroundMultiColored).thenReturn(true)

        provider.start()
        fakeExecutor.runAllReady()

        assertThat(provider.isLetterboxBackgroundMultiColored).isTrue()
    }
}