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

Commit 2f3581b9 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "[flexiglass] Fixes SysUiState related tests" into main

parents 075a2645 fedfbed5
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ class SceneContainerPluginTest : SysuiTestCase() {
    private val shadeDisplayRepository = kosmos.fakeShadeDisplaysRepository
    private val sceneDataSource = kosmos.fakeSceneDataSource

    private val underTest = kosmos.sceneContainerPlugin
    private val underTest: SceneContainerPlugin = kosmos.sceneContainerPluginImpl

    @Test
    @EnableFlags(Flags.FLAG_SHADE_WINDOW_GOES_AROUND)
+0 −165
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.model;


import static android.view.Display.DEFAULT_DISPLAY;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import android.view.Display;

import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;

import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.kosmos.KosmosJavaAdapter;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

@SmallTest
@RunWith(AndroidJUnit4.class)
public class SysUiStateTest extends SysuiTestCase {
    private static final int FLAG_1 = 1;
    private static final int FLAG_2 = 1 << 1;
    private static final int FLAG_3 = 1 << 2;
    private static final int FLAG_4 = 1 << 3;
    private static final int DISPLAY_ID = DEFAULT_DISPLAY;

    private KosmosJavaAdapter mKosmos;
    private SysUiState.SysUiStateCallback mCallback;
    private SysUiState mFlagsContainer;
    private SceneContainerPlugin mSceneContainerPlugin;
    private DumpManager mDumpManager;
    private SysUIStateDispatcher mSysUIStateDispatcher;

    private SysUiState createInstance(int displayId) {
        var sysuiState = new SysUiStateImpl(displayId, mSceneContainerPlugin, mDumpManager,
                mSysUIStateDispatcher);
        sysuiState.addCallback(mCallback);
        return sysuiState;
    }

    @Before
    public void setup() {
        mKosmos = new KosmosJavaAdapter(this);
        mFlagsContainer = mKosmos.getSysuiState();
        mSceneContainerPlugin = mKosmos.getSceneContainerPlugin();
        mCallback = mock(SysUiState.SysUiStateCallback.class);
        mDumpManager = mock(DumpManager.class);
        mSysUIStateDispatcher = mKosmos.getSysUIStateDispatcher();
        mFlagsContainer = createInstance(DEFAULT_DISPLAY);
    }

    @Test
    public void addSingle_setFlag() {
        setFlags(FLAG_1);

        verify(mCallback, times(1)).onSystemUiStateChanged(FLAG_1, DEFAULT_DISPLAY);
    }

    @Test
    public void addMultiple_setFlag() {
        setFlags(FLAG_1);
        setFlags(FLAG_2);

        verify(mCallback, times(1)).onSystemUiStateChanged(FLAG_1, DEFAULT_DISPLAY);
        verify(mCallback, times(1)).onSystemUiStateChanged(FLAG_1 | FLAG_2, DEFAULT_DISPLAY);
    }

    @Test
    public void addMultipleRemoveOne_setFlag() {
        setFlags(FLAG_1);
        setFlags(FLAG_2);
        mFlagsContainer.setFlag(FLAG_1, false).commitUpdate(DISPLAY_ID);

        verify(mCallback, times(1)).onSystemUiStateChanged(FLAG_1, DEFAULT_DISPLAY);
        verify(mCallback, times(1)).onSystemUiStateChanged(FLAG_1 | FLAG_2, DEFAULT_DISPLAY);
        verify(mCallback, times(1)).onSystemUiStateChanged(FLAG_2, DEFAULT_DISPLAY);
    }

    @Test
    public void addMultiple_setFlags() {
        setFlags(FLAG_1, FLAG_2, FLAG_3, FLAG_4);

        int expected = FLAG_1 | FLAG_2 | FLAG_3 | FLAG_4;
        verify(mCallback, times(1)).onSystemUiStateChanged(expected, DEFAULT_DISPLAY);
    }

    @Test
    public void addMultipleRemoveOne_setFlags() {
        setFlags(FLAG_1, FLAG_2, FLAG_3, FLAG_4);
        mFlagsContainer.setFlag(FLAG_2, false).commitUpdate(DISPLAY_ID);

        int expected1 = FLAG_1 | FLAG_2 | FLAG_3 | FLAG_4;
        verify(mCallback, times(1)).onSystemUiStateChanged(expected1, DEFAULT_DISPLAY);
        int expected2 = FLAG_1 | FLAG_3 | FLAG_4;
        verify(mCallback, times(1)).onSystemUiStateChanged(expected2, DEFAULT_DISPLAY);
    }

    @Test
    public void removeCallback() {
        mFlagsContainer.removeCallback(mCallback);
        setFlags(FLAG_1, FLAG_2, FLAG_3, FLAG_4);

        int expected = FLAG_1 | FLAG_2 | FLAG_3 | FLAG_4;
        verify(mCallback, times(0)).onSystemUiStateChanged(expected, DEFAULT_DISPLAY);
    }

    @Test
    public void setFlag_receivedForDefaultDisplay() {
        setFlags(FLAG_1);

        verify(mCallback, times(1)).onSystemUiStateChanged(FLAG_1, DEFAULT_DISPLAY);
    }


    @Test
    public void init_registersWithDumpManager() {
        mFlagsContainer.start();

        verify(mDumpManager).registerNormalDumpable(any(), eq(mFlagsContainer));
    }

    @Test
    public void destroy_unregistersWithDumpManager() {
        mFlagsContainer.destroy();

        verify(mDumpManager).unregisterDumpable(anyString());
    }

    private void setFlags(int... flags) {
        setFlags(mFlagsContainer, flags);
    }

    private void setFlags(SysUiState instance, int... flags) {
        for (int flag : flags) {
            instance.setFlag(flag, true);
        }
        instance.commitUpdate();
    }
}
+165 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.model

import android.view.Display
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.dumpManager
import com.android.systemui.kosmos.runTest
import com.android.systemui.model.SysUiState.SysUiStateCallback
import com.android.systemui.testKosmos
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyString
import org.mockito.kotlin.any
import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
import org.mockito.kotlin.times
import org.mockito.kotlin.verify

@SmallTest
@RunWith(AndroidJUnit4::class)
open class SysUiStateTest : SysuiTestCase() {

    private val kosmos = testKosmos()
    private val callback: SysUiStateCallback = mock()

    private lateinit var underTest: SysUiState

    @Before
    fun setup() {
        underTest = createInstance(Display.DEFAULT_DISPLAY)
    }

    @Test
    fun addSingle_setFlag() =
        kosmos.runTest {
            setFlags(FLAG_1)

            verify(callback, times(1)).onSystemUiStateChanged(FLAG_1, Display.DEFAULT_DISPLAY)
        }

    @Test
    fun addMultiple_setFlag() =
        kosmos.runTest {
            setFlags(FLAG_1)
            setFlags(FLAG_2)

            verify(callback, times(1)).onSystemUiStateChanged(FLAG_1, Display.DEFAULT_DISPLAY)
            verify(callback, times(1))
                .onSystemUiStateChanged((FLAG_1 or FLAG_2), Display.DEFAULT_DISPLAY)
        }

    @Test
    fun addMultipleRemoveOne_setFlag() =
        kosmos.runTest {
            setFlags(FLAG_1)
            setFlags(FLAG_2)
            underTest.setFlag(FLAG_1, false).commitUpdate(DISPLAY_ID)

            verify(callback, times(1)).onSystemUiStateChanged(FLAG_1, Display.DEFAULT_DISPLAY)
            verify(callback, times(1))
                .onSystemUiStateChanged((FLAG_1 or FLAG_2), Display.DEFAULT_DISPLAY)
            verify(callback, times(1)).onSystemUiStateChanged(FLAG_2, Display.DEFAULT_DISPLAY)
        }

    @Test
    fun addMultiple_setFlags() =
        kosmos.runTest {
            setFlags(FLAG_1, FLAG_2, FLAG_3, FLAG_4)

            val expected = FLAG_1 or FLAG_2 or FLAG_3 or FLAG_4
            verify(callback, times(1)).onSystemUiStateChanged(expected, Display.DEFAULT_DISPLAY)
        }

    @Test
    fun addMultipleRemoveOne_setFlags() =
        kosmos.runTest {
            setFlags(FLAG_1, FLAG_2, FLAG_3, FLAG_4)
            underTest.setFlag(FLAG_2, false).commitUpdate(DISPLAY_ID)

            val expected1 = FLAG_1 or FLAG_2 or FLAG_3 or FLAG_4
            verify(callback, times(1)).onSystemUiStateChanged(expected1, Display.DEFAULT_DISPLAY)
            val expected2 = FLAG_1 or FLAG_3 or FLAG_4
            verify(callback, times(1)).onSystemUiStateChanged(expected2, Display.DEFAULT_DISPLAY)
        }

    @Test
    fun removeCallback() =
        kosmos.runTest {
            underTest.removeCallback(callback)
            setFlags(FLAG_1, FLAG_2, FLAG_3, FLAG_4)

            val expected = FLAG_1 or FLAG_2 or FLAG_3 or FLAG_4
            verify(callback, times(0)).onSystemUiStateChanged(expected, Display.DEFAULT_DISPLAY)
        }

    @Test
    fun setFlag_receivedForDefaultDisplay() =
        kosmos.runTest {
            setFlags(FLAG_1)

            verify(callback, times(1)).onSystemUiStateChanged(FLAG_1, Display.DEFAULT_DISPLAY)
        }

    @Test
    fun init_registersWithDumpManager() =
        kosmos.runTest {
            underTest.start()

            verify(dumpManager).registerNormalDumpable(any(), eq(underTest))
        }

    @Test
    fun destroy_unregistersWithDumpManager() =
        kosmos.runTest {
            underTest.destroy()

            verify(dumpManager).unregisterDumpable(anyString())
        }

    private fun createInstance(displayId: Int): SysUiState {
        return SysUiStateImpl(
                displayId,
                kosmos.fakeSceneContainerPlugin,
                kosmos.dumpManager,
                kosmos.sysUIStateDispatcher,
            )
            .apply { addCallback(callback) }
    }

    private fun setFlags(vararg flags: Long) {
        setFlags(underTest, *flags)
    }

    private fun setFlags(instance: SysUiState, vararg flags: Long) {
        for (flag in flags) {
            instance.setFlag(flag, true)
        }
        instance.commitUpdate()
    }

    companion object {
        private const val FLAG_1 = 1L
        private const val FLAG_2 = 1L shl 1
        private const val FLAG_3 = 1L shl 2
        private const val FLAG_4 = 1L shl 3
        private const val DISPLAY_ID = Display.DEFAULT_DISPLAY
    }
}
+20 −11
Original line number Diff line number Diff line
@@ -21,9 +21,12 @@ import com.android.app.displaylib.PerDisplayInstanceRepositoryImpl
import com.android.app.displaylib.PerDisplayRepository
import com.android.systemui.display.data.repository.DisplayComponentRepository
import com.android.systemui.display.data.repository.PerDisplayCoroutineScopeRepositoryModule
import com.android.systemui.model.SceneContainerPlugin
import com.android.systemui.model.SceneContainerPluginImpl
import com.android.systemui.model.SysUIStateInstanceProvider
import com.android.systemui.model.SysUiState
import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround
import dagger.Binds
import dagger.Module
import dagger.Provides

@@ -31,8 +34,13 @@ import dagger.Provides
@Module(
    includes = [PerDisplayCoroutineScopeRepositoryModule::class, DisplayComponentRepository::class]
)
class PerDisplayRepositoriesModule {
interface PerDisplayRepositoriesModule {

    @Binds
    @SysUISingleton
    fun bindSceneContainerPlugin(impl: SceneContainerPluginImpl): SceneContainerPlugin

    companion object {
        @SysUISingleton
        @Provides
        fun provideSysUiStateRepository(
@@ -47,3 +55,4 @@ class PerDisplayRepositoriesModule {
            }
        }
    }
}
+20 −16
Original line number Diff line number Diff line
@@ -43,22 +43,33 @@ import kotlinx.coroutines.flow.StateFlow
 * A plugin for [SysUiState] that provides overrides for certain state flags that must be pulled
 * from the scene framework when that framework is enabled.
 */
interface SceneContainerPlugin {
    /**
     * Returns an override value for the given [flag] or `null` if the scene framework isn't enabled
     * or if the flag value doesn't need to be overridden.
     */
    fun flagValueOverride(@SystemUiStateFlags flag: Long, displayId: Int): Boolean?

    data class SceneContainerPluginState(
        val scene: SceneKey,
        val overlays: Set<OverlayKey>,
        val invisibleDueToOcclusion: Boolean,
        val isVisible: Boolean,
    )
}

@SysUISingleton
class SceneContainerPlugin
class SceneContainerPluginImpl
@Inject
constructor(
    private val sceneInteractor: Lazy<SceneInteractor>,
    private val occlusionInteractor: Lazy<SceneContainerOcclusionInteractor>,
    private val shadeDisplaysRepository: Lazy<ShadeDisplaysRepository>,
) {
) : SceneContainerPlugin {

    private val shadeDisplayId: StateFlow<Int> by lazy { shadeDisplaysRepository.get().displayId }

    /**
     * Returns an override value for the given [flag] or `null` if the scene framework isn't enabled
     * or if the flag value doesn't need to be overridden.
     */
    fun flagValueOverride(@SystemUiStateFlags flag: Long, displayId: Int): Boolean? {
    override fun flagValueOverride(@SystemUiStateFlags flag: Long, displayId: Int): Boolean? {
        if (!SceneContainerFlag.isEnabled) {
            return null
        }
@@ -76,7 +87,7 @@ constructor(
        val invisibleDueToOcclusion = occlusionInteractor.get().invisibleDueToOcclusion.value
        return idleTransitionStateOrNull?.let { idleState ->
            EvaluatorByFlag[flag]?.invoke(
                SceneContainerPluginState(
                SceneContainerPlugin.SceneContainerPluginState(
                    scene = idleState.currentScene,
                    overlays = idleState.currentOverlays,
                    isVisible = sceneInteractor.get().isVisible.value,
@@ -98,7 +109,7 @@ constructor(
         * to be overridden by the scene framework.
         */
        val EvaluatorByFlag =
            mapOf<Long, (SceneContainerPluginState) -> Boolean>(
            mapOf<Long, (SceneContainerPlugin.SceneContainerPluginState) -> Boolean>(
                SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE to
                    {
                        when {
@@ -139,11 +150,4 @@ constructor(
                SYSUI_STATE_COMMUNAL_HUB_SHOWING to { it.isVisible && it.scene == Scenes.Communal },
            )
    }

    data class SceneContainerPluginState(
        val scene: SceneKey,
        val overlays: Set<OverlayKey>,
        val invisibleDueToOcclusion: Boolean,
        val isVisible: Boolean,
    )
}
Loading