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

Commit b90a66af authored by burakov's avatar burakov
Browse files

[Dual Shade] Change Dual Shade logic around screen width.

We've recently simplified our Dual Shade eligibility rules to be:

(1) The user can enable Single Shade on all non-wide* screens (handheld
    devices and folded foldables, in portrait).

(2) On all wide screens, including handhelds in landscape rotation, Dual
    Shade is enabled, regardless of user setting.

(3) This means we can get rid of the config-defined `isShadeLayoutWide`
    bit in `SceneContainer`. Instead, all code dependent on it will be
    gradually moved to perform the check in the `@Composable`, if
    possible.
    If not, it will use the newly-introduced `isWideScreen` instead of
    the legacy concept of `isShadeLayoutWide`, which was based on the
    config value `config_use_split_notification_shade` rather than the
    actual screen width.

* "Wide" is defined as >= 600dp.

In a follow-up CL, Split Shade will be deprecated in `SceneContainer`.

BONUS: This also replaces some incorrect references to `isLargeScreen`
with the newly introduced `isWideScreen`.

Fix: 391128665
Fix: 391379390
Fix: 391380435
Fix: 405379458
Bug: 354926927
Bug: 338033836
Bug: 405383415
Bug: 411365508
Bug: 411449027
Bug: 409594391
Bug: 408932746
Test: Added unit tests.
Test: Updated all affected unit tests.
Test: Manually tested by opening and closing both shades on both a
 folded and unfolded device, verifying the shade appears full width
 or partial width as expected.
Test: Manually tested by disabling Dual Shade, and verifying that
 Single Shade (folded) and Split Shade (unfolded) appear as expected.
Test: Manually tested by disabling scene_container and verifying that
 Single Shade (folded) and Split Shade (unfolded) appear as expected.
Flag: com.android.systemui.scene_container
Change-Id: I5a2c2119adc80bbdf1e7b0a3128c5ae452d81144
parent 9831f53b
Loading
Loading
Loading
Loading
+67 −5
Original line number Original line Diff line number Diff line
@@ -14,8 +14,10 @@
 * limitations under the License.
 * limitations under the License.
 */
 */


package com.android.systemui.keyguard.data.repository
package com.android.systemui.biometrics.data.repository


import android.content.res.Configuration
import android.util.DisplayMetrics
import android.util.Size
import android.util.Size
import android.view.Display
import android.view.Display
import android.view.Display.DEFAULT_DISPLAY
import android.view.Display.DEFAULT_DISPLAY
@@ -24,8 +26,6 @@ import android.view.Surface
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.data.repository.DisplayStateRepository
import com.android.systemui.biometrics.data.repository.DisplayStateRepositoryImpl
import com.android.systemui.biometrics.shared.model.DisplayRotation
import com.android.systemui.biometrics.shared.model.DisplayRotation
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.display.data.repository.DeviceStateRepository.DeviceState
import com.android.systemui.display.data.repository.DeviceStateRepository.DeviceState
@@ -35,6 +35,7 @@ import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runCurrent
@@ -44,13 +45,15 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runner.RunWith
import org.mockito.Mockito.spy
import org.mockito.Mockito.spy


@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@SmallTest
@RunWith(AndroidJUnit4::class)
@RunWith(AndroidJUnit4::class)
class DisplayStateRepositoryTest : SysuiTestCase() {
class DisplayStateRepositoryImplTest : SysuiTestCase() {
    private val display = mock<Display>()
    private val display = mock<Display>()
    private val testScope = TestScope(StandardTestDispatcher())
    private val testScope = TestScope(StandardTestDispatcher())
    private val fakeDeviceStateRepository = FakeDeviceStateRepository()
    private val fakeDeviceStateRepository = FakeDeviceStateRepository()
    private val fakeDisplayRepository = FakeDisplayRepository()
    private val fakeDisplayRepository = FakeDisplayRepository()
    private val configuration = Configuration()


    private lateinit var underTest: DisplayStateRepository
    private lateinit var underTest: DisplayStateRepository


@@ -58,11 +61,16 @@ class DisplayStateRepositoryTest : SysuiTestCase() {
    fun setUp() {
    fun setUp() {
        mContext.orCreateTestableResources.addOverride(
        mContext.orCreateTestableResources.addOverride(
            com.android.internal.R.bool.config_reverseDefaultRotation,
            com.android.internal.R.bool.config_reverseDefaultRotation,
            false
            false,
        )
        )


        // Set densityDpi such that pixels and DP are the same; Makes it easier to read and write
        // tests.
        configuration.densityDpi = DisplayMetrics.DENSITY_DEFAULT

        mContext = spy(mContext)
        mContext = spy(mContext)
        whenever(mContext.display).thenReturn(display)
        whenever(mContext.display).thenReturn(display)
        whenever(mContext.resources.configuration).thenReturn(configuration)


        underTest =
        underTest =
            DisplayStateRepositoryImpl(
            DisplayStateRepositoryImpl(
@@ -137,4 +145,58 @@ class DisplayStateRepositoryTest : SysuiTestCase() {
            fakeDisplayRepository.emitDisplayChangeEvent(DEFAULT_DISPLAY)
            fakeDisplayRepository.emitDisplayChangeEvent(DEFAULT_DISPLAY)
            assertThat(currentSize).isEqualTo(Size(200, 100))
            assertThat(currentSize).isEqualTo(Size(200, 100))
        }
        }

    @Test
    fun updatesIsLargeScreen_whenDisplayStateChanges() =
        testScope.runTest {
            val isLargeScreen by collectLastValue(underTest.isLargeScreen)
            runCurrent()

            whenever(display.getDisplayInfo(any())).then {
                val info = it.getArgument<DisplayInfo>(0)
                info.rotation = Surface.ROTATION_0
                info.logicalWidth = 100
                info.logicalHeight = 700
                return@then true
            }
            fakeDisplayRepository.emitDisplayChangeEvent(DEFAULT_DISPLAY)
            assertThat(isLargeScreen).isFalse()

            whenever(display.getDisplayInfo(any())).then {
                val info = it.getArgument<DisplayInfo>(0)
                info.rotation = Surface.ROTATION_0
                info.logicalWidth = 800
                info.logicalHeight = 700
                return@then true
            }
            fakeDisplayRepository.emitDisplayChangeEvent(DEFAULT_DISPLAY)
            assertThat(isLargeScreen).isTrue()
        }

    @Test
    fun updatesIsWideScreen_whenDisplayStateChanges() =
        testScope.runTest {
            val isWideScreen by collectLastValue(underTest.isWideScreen)
            runCurrent()

            whenever(display.getDisplayInfo(any())).then {
                val info = it.getArgument<DisplayInfo>(0)
                info.rotation = Surface.ROTATION_0
                info.logicalWidth = 200
                info.logicalHeight = 700
                return@then true
            }
            fakeDisplayRepository.emitDisplayChangeEvent(DEFAULT_DISPLAY)
            assertThat(isWideScreen).isFalse()

            whenever(display.getDisplayInfo(any())).then {
                val info = it.getArgument<DisplayInfo>(0)
                info.rotation = Surface.ROTATION_90
                info.logicalWidth = 700
                info.logicalHeight = 200
                return@then true
            }
            fakeDisplayRepository.emitDisplayChangeEvent(DEFAULT_DISPLAY)
            assertThat(isWideScreen).isTrue()
        }
}
}
+11 −8
Original line number Original line Diff line number Diff line
@@ -28,7 +28,6 @@ import com.android.systemui.biometrics.domain.interactor.displayStateInteractor
import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractorImpl
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractorImpl
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.display.data.repository.displayStateRepository
import com.android.systemui.dump.DumpManager
import com.android.systemui.dump.DumpManager
import com.android.systemui.kosmos.testCase
import com.android.systemui.kosmos.testCase
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testDispatcher
@@ -37,7 +36,9 @@ import com.android.systemui.qs.QSImpl
import com.android.systemui.qs.dagger.QSComponent
import com.android.systemui.qs.dagger.QSComponent
import com.android.systemui.qs.dagger.QSSceneComponent
import com.android.systemui.qs.dagger.QSSceneComponent
import com.android.systemui.settings.brightness.MirrorController
import com.android.systemui.settings.brightness.MirrorController
import com.android.systemui.shade.data.repository.fakeShadeRepository
import com.android.systemui.shade.domain.interactor.enableDualShade
import com.android.systemui.shade.domain.interactor.enableSingleShade
import com.android.systemui.shade.domain.interactor.enableSplitShade
import com.android.systemui.shade.domain.interactor.shadeModeInteractor
import com.android.systemui.shade.domain.interactor.shadeModeInteractor
import com.android.systemui.testKosmos
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.any
@@ -50,6 +51,7 @@ import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertThat
import java.util.Locale
import java.util.Locale
import javax.inject.Provider
import javax.inject.Provider
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.Test
@@ -61,6 +63,7 @@ import org.mockito.Mockito.inOrder
import org.mockito.Mockito.never
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.Mockito.verify


@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@SmallTest
@RunWith(AndroidJUnit4::class)
@RunWith(AndroidJUnit4::class)
class QSSceneAdapterImplTest : SysuiTestCase() {
class QSSceneAdapterImplTest : SysuiTestCase() {
@@ -550,16 +553,17 @@ class QSSceneAdapterImplTest : SysuiTestCase() {
    @Test
    @Test
    fun dispatchSplitShade() =
    fun dispatchSplitShade() =
        testScope.runTest {
        testScope.runTest {
            val shadeRepository = kosmos.fakeShadeRepository
            shadeRepository.setShadeLayoutWide(false)
            val qsImpl by collectLastValue(underTest.qsImpl)
            val qsImpl by collectLastValue(underTest.qsImpl)


            kosmos.enableSingleShade()
            runCurrent()

            underTest.inflate(context)
            underTest.inflate(context)
            runCurrent()
            runCurrent()


            verify(qsImpl!!).setInSplitShade(false)
            verify(qsImpl!!).setInSplitShade(false)


            shadeRepository.setShadeLayoutWide(true)
            kosmos.enableSplitShade()
            runCurrent()
            runCurrent()
            verify(qsImpl!!).setInSplitShade(true)
            verify(qsImpl!!).setInSplitShade(true)
        }
        }
@@ -581,11 +585,10 @@ class QSSceneAdapterImplTest : SysuiTestCase() {
        testScope.runTest {
        testScope.runTest {
            val qsImpl by collectLastValue(underTest.qsImpl)
            val qsImpl by collectLastValue(underTest.qsImpl)


            underTest.inflate(context)
            kosmos.enableDualShade(wideLayout = true)
            runCurrent()
            runCurrent()


            kosmos.displayStateRepository.setIsLargeScreen(true)
            underTest.inflate(context)
            runCurrent()


            verify(qsImpl!!).setIsNotificationPanelFullWidth(false)
            verify(qsImpl!!).setIsNotificationPanelFullWidth(false)


+1 −1
Original line number Original line Diff line number Diff line
@@ -214,7 +214,7 @@ class ShadeStartableTest(flags: FlagsParameterization) : SysuiTestCase() {
        testScope.runTest {
        testScope.runTest {
            underTest.start()
            underTest.start()


            kosmos.displayStateRepository.setIsLargeScreen(true)
            kosmos.displayStateRepository.setIsWideScreen(true)
            runCurrent()
            runCurrent()
            verify(kosmos.notificationStackScrollLayoutController).setIsFullWidth(false)
            verify(kosmos.notificationStackScrollLayoutController).setIsFullWidth(false)
            assertThat(kosmos.scrimController.clipQsScrim).isFalse()
            assertThat(kosmos.scrimController.clipQsScrim).isFalse()
+40 −34
Original line number Original line Diff line number Diff line
@@ -56,8 +56,19 @@ interface DisplayStateRepository {
    /** Provides the current display size */
    /** Provides the current display size */
    val currentDisplaySize: StateFlow<Size>
    val currentDisplaySize: StateFlow<Size>


    /** Provides whether the current display is large screen */
    /**
     * Provides whether the current display is a large screen (i.e. all edges are >= 600dp). This is
     * agnostic of display rotation.
     */
    val isLargeScreen: StateFlow<Boolean>
    val isLargeScreen: StateFlow<Boolean>

    /**
     * Provides whether the display's current horizontal width is large (>= 600dp).
     *
     * Note that unlike [isLargeScreen], which checks whether either one of the screen's width or
     * height is large, this flow's state is sensitive to the current display's orientation.
     */
    val isWideScreen: StateFlow<Boolean>
}
}


@SysUISingleton
@SysUISingleton
@@ -75,17 +86,7 @@ constructor(
    override val isInRearDisplayMode: StateFlow<Boolean> =
    override val isInRearDisplayMode: StateFlow<Boolean> =
        deviceStateRepository.state
        deviceStateRepository.state
            .map { it == REAR_DISPLAY }
            .map { it == REAR_DISPLAY }
            .stateIn(
            .stateIn(backgroundScope, started = SharingStarted.Eagerly, initialValue = false)
                backgroundScope,
                started = SharingStarted.Eagerly,
                initialValue = false,
            )

    private fun getDisplayInfo(): DisplayInfo {
        val cachedDisplayInfo = DisplayInfo()
        context.display?.getDisplayInfo(cachedDisplayInfo)
        return cachedDisplayInfo
    }


    private val currentDisplayInfo: StateFlow<DisplayInfo> =
    private val currentDisplayInfo: StateFlow<DisplayInfo> =
        displayRepository.displayChangeEvent
        displayRepository.displayChangeEvent
@@ -96,21 +97,13 @@ constructor(
                initialValue = getDisplayInfo(),
                initialValue = getDisplayInfo(),
            )
            )


    private fun rotationToDisplayRotation(rotation: Int): DisplayRotation {
        var adjustedRotation = rotation
        if (isReverseDefaultRotation) {
            adjustedRotation = (rotation + 1) % 4
        }
        return adjustedRotation.toDisplayRotation()
    }

    override val currentRotation: StateFlow<DisplayRotation> =
    override val currentRotation: StateFlow<DisplayRotation> =
        currentDisplayInfo
        currentDisplayInfo
            .map { rotationToDisplayRotation(it.rotation) }
            .map { rotationToDisplayRotation(it.rotation) }
            .stateIn(
            .stateIn(
                backgroundScope,
                backgroundScope,
                started = SharingStarted.WhileSubscribed(),
                started = SharingStarted.WhileSubscribed(),
                initialValue = rotationToDisplayRotation(currentDisplayInfo.value.rotation)
                initialValue = rotationToDisplayRotation(currentDisplayInfo.value.rotation),
            )
            )


    override val currentDisplaySize: StateFlow<Size> =
    override val currentDisplaySize: StateFlow<Size> =
@@ -122,7 +115,7 @@ constructor(
                initialValue =
                initialValue =
                    Size(
                    Size(
                        currentDisplayInfo.value.naturalWidth,
                        currentDisplayInfo.value.naturalWidth,
                        currentDisplayInfo.value.naturalHeight
                        currentDisplayInfo.value.naturalHeight,
                    ),
                    ),
            )
            )


@@ -130,22 +123,35 @@ constructor(
        currentDisplayInfo
        currentDisplayInfo
            .map {
            .map {
                // copied from systemui/shared/...Utilities.java
                // copied from systemui/shared/...Utilities.java
                val smallestWidth =
                val smallestWidth = min(it.logicalWidth, it.logicalHeight).toDpi()
                    dpiFromPx(
                        min(it.logicalWidth, it.logicalHeight).toFloat(),
                        context.resources.configuration.densityDpi
                    )
                smallestWidth >= LARGE_SCREEN_MIN_DPS
                smallestWidth >= LARGE_SCREEN_MIN_DPS
            }
            }
            .stateIn(
            .stateIn(backgroundScope, started = SharingStarted.Eagerly, initialValue = false)
                backgroundScope,

                started = SharingStarted.Eagerly,
    override val isWideScreen: StateFlow<Boolean> =
                initialValue = false,
        currentDisplayInfo
            )
            .map { it.logicalWidth.toDpi() >= LARGE_SCREEN_MIN_DPS }
            .stateIn(backgroundScope, started = SharingStarted.Eagerly, initialValue = false)

    private fun getDisplayInfo(): DisplayInfo {
        val cachedDisplayInfo = DisplayInfo()
        context.display.getDisplayInfo(cachedDisplayInfo)
        return cachedDisplayInfo
    }

    private fun rotationToDisplayRotation(rotation: Int): DisplayRotation {
        return if (isReverseDefaultRotation) {
                (rotation + 1) % 4
            } else {
                rotation
            }
            .toDisplayRotation()
    }


    private fun dpiFromPx(size: Float, densityDpi: Int): Float {
    private fun Int.toDpi(): Float {
        val densityDpi = context.resources.configuration.densityDpi
        val densityRatio = densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT
        val densityRatio = densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT
        return size / densityRatio
        return this / densityRatio
    }
    }


    companion object {
    companion object {
+26 −16
Original line number Original line Diff line number Diff line
@@ -21,12 +21,12 @@ import android.content.res.Configuration
import com.android.systemui.biometrics.data.repository.DisplayStateRepository
import com.android.systemui.biometrics.data.repository.DisplayStateRepository
import com.android.systemui.biometrics.shared.model.DisplayRotation
import com.android.systemui.biometrics.shared.model.DisplayRotation
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.display.data.repository.DisplayRepository
import com.android.systemui.display.data.repository.DisplayRepository
import com.android.systemui.unfold.compat.ScreenSizeFoldProvider
import com.android.systemui.unfold.compat.ScreenSizeFoldProvider
import com.android.systemui.unfold.updates.FoldProvider
import com.android.systemui.unfold.updates.FoldProvider
import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
import java.util.concurrent.Executor
import java.util.concurrent.Executor
import javax.inject.Inject
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineScope
@@ -37,6 +37,7 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.stateIn


/** Aggregates display state information. */
/** Aggregates display state information. */
// TODO(b/411335091): Move to com.android.systemui.display.domain.interactor.
interface DisplayStateInteractor {
interface DisplayStateInteractor {
    /** Whether the default display is currently off. */
    /** Whether the default display is currently off. */
    val isDefaultDisplayOff: Flow<Boolean>
    val isDefaultDisplayOff: Flow<Boolean>
@@ -65,8 +66,19 @@ interface DisplayStateInteractor {
    /** Called on configuration changes, used to keep the display state in sync */
    /** Called on configuration changes, used to keep the display state in sync */
    fun onConfigurationChanged(newConfig: Configuration)
    fun onConfigurationChanged(newConfig: Configuration)


    /** Provides whether the current display is large screen */
    /**
     * Provides whether the current display is a large screen (i.e. all edges are >= 600dp). This is
     * agnostic of display rotation.
     */
    val isLargeScreen: StateFlow<Boolean>
    val isLargeScreen: StateFlow<Boolean>

    /**
     * Provides whether the display's current horizontal width is large (>= 600dp).
     *
     * Note: Unlike [isLargeScreen], which checks whether either one of the screen's width or height
     * is large, this flow's state is sensitive to the current display's rotation.
     */
    val isWideScreen: StateFlow<Boolean>
}
}


/** Encapsulates logic for interacting with the display state. */
/** Encapsulates logic for interacting with the display state. */
@@ -81,10 +93,6 @@ constructor(
) : DisplayStateInteractor {
) : DisplayStateInteractor {
    private var screenSizeFoldProvider: ScreenSizeFoldProvider = ScreenSizeFoldProvider(context)
    private var screenSizeFoldProvider: ScreenSizeFoldProvider = ScreenSizeFoldProvider(context)


    fun setScreenSizeFoldProvider(foldProvider: ScreenSizeFoldProvider) {
        screenSizeFoldProvider = foldProvider
    }

    override val displayChanges = displayRepository.displayChangeEvent
    override val displayChanges = displayRepository.displayChangeEvent


    override val isFolded: Flow<Boolean> =
    override val isFolded: Flow<Boolean> =
@@ -93,7 +101,7 @@ constructor(
                    trySendWithFailureLogging(
                    trySendWithFailureLogging(
                        state,
                        state,
                        TAG,
                        TAG,
                        "Error sending fold state update to $state"
                        "Error sending fold state update to $state",
                    )
                    )
                }
                }


@@ -108,11 +116,7 @@ constructor(
                screenSizeFoldProvider.registerCallback(callback, mainExecutor)
                screenSizeFoldProvider.registerCallback(callback, mainExecutor)
                awaitClose { screenSizeFoldProvider.unregisterCallback(callback) }
                awaitClose { screenSizeFoldProvider.unregisterCallback(callback) }
            }
            }
            .stateIn(
            .stateIn(applicationScope, started = SharingStarted.Eagerly, initialValue = false)
                applicationScope,
                started = SharingStarted.Eagerly,
                initialValue = false,
            )


    override val isInRearDisplayMode: StateFlow<Boolean> =
    override val isInRearDisplayMode: StateFlow<Boolean> =
        displayStateRepository.isInRearDisplayMode
        displayStateRepository.isInRearDisplayMode
@@ -122,14 +126,20 @@ constructor(


    override val isReverseDefaultRotation: Boolean = displayStateRepository.isReverseDefaultRotation
    override val isReverseDefaultRotation: Boolean = displayStateRepository.isReverseDefaultRotation


    override fun onConfigurationChanged(newConfig: Configuration) {
        screenSizeFoldProvider.onConfigurationChange(newConfig)
    }

    override val isDefaultDisplayOff = displayRepository.defaultDisplayOff
    override val isDefaultDisplayOff = displayRepository.defaultDisplayOff


    override val isLargeScreen: StateFlow<Boolean> = displayStateRepository.isLargeScreen
    override val isLargeScreen: StateFlow<Boolean> = displayStateRepository.isLargeScreen


    override val isWideScreen: StateFlow<Boolean> = displayStateRepository.isWideScreen

    fun setScreenSizeFoldProvider(foldProvider: ScreenSizeFoldProvider) {
        screenSizeFoldProvider = foldProvider
    }

    override fun onConfigurationChanged(newConfig: Configuration) {
        screenSizeFoldProvider.onConfigurationChange(newConfig)
    }

    companion object {
    companion object {
        private const val TAG = "DisplayStateInteractor"
        private const val TAG = "DisplayStateInteractor"
    }
    }
Loading