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

Commit 34e19259 authored by brycelee's avatar brycelee
Browse files

AmbientLightModeInteractor Introduction

This changelist introduces AmbientLightMonitorInteractor, which allows
for the current AmbientLightMonitor to be updated. This is useful for
applications where different AmbientLightMonitors might be used under
various conditions, such as lighting.

This change also makes the brightness sensors previously restricted to
Doze available to the rest of SystemUI.

Test: atest LowLightBehaviorCoreStartableTest
Bug: 432103856
Flag: EXEMPT bugfix
Change-Id: I07b4c77a19aed79f4c1f29720f41491eaeb11d4a
parent 371470ef
Loading
Loading
Loading
Loading
+20 −1
Original line number Diff line number Diff line
@@ -38,8 +38,10 @@ import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.lifecycle.FakeActivatable
import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.lowlight.data.repository.ambientLightModeMonitorRepository
import com.android.systemui.lowlight.data.repository.lowLightRepository
import com.android.systemui.lowlight.data.repository.lowLightSettingsRepository
import com.android.systemui.lowlight.domain.interactor.ambientLightModeInteractor
import com.android.systemui.lowlight.domain.interactor.lowLightInteractor
import com.android.systemui.lowlight.domain.interactor.lowLightSettingInteractor
import com.android.systemui.lowlight.shared.model.LowLightDisplayBehavior
@@ -63,7 +65,9 @@ import kotlinx.coroutines.runBlocking
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.any
import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever

@SmallTest
@@ -86,7 +90,7 @@ class LowLightBehaviorCoreStartableTest : SysuiTestCase() {
                userLockedInteractor = userLockedInteractor,
                keyguardInteractor = keyguardInteractor,
                powerInteractor = powerInteractor,
                ambientLightModeMonitor = ambientLightModeMonitor,
                ambientLightModeMonitorInteractor = ambientLightModeInteractor,
                uiEventLogger = mock(),
                lowLightBehaviorShellCommand = lowLightBehaviorShellCommand,
                lowLightShellCommand = lowLightShellCommand,
@@ -239,6 +243,21 @@ class LowLightBehaviorCoreStartableTest : SysuiTestCase() {
            assertThat(ambientLightModeMonitor.fake.started).isFalse()
        }

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

            setDisplayOn(true)
            assertThat(ambientLightModeMonitor.fake.started).isTrue()

            val secondMonitor: AmbientLightModeMonitor = mock()
            ambientLightModeMonitorRepository.setMonitor(secondMonitor)

            assertThat(ambientLightModeMonitor.fake.started).isFalse()
            verify(secondMonitor).start(any())
        }

    @Test
    fun testStopMonitorLowLightConditionsWhenDreamDisabled() =
        kosmos.runTest {
+2 −1
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.lowlight.AmbientLightModeMonitor
import com.android.systemui.lowlight.ambientLightModeMonitor
import com.android.systemui.lowlight.domain.interactor.ambientLightModeInteractor
import com.android.systemui.lowlight.fake
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
import com.android.systemui.power.domain.interactor.powerInteractor
@@ -101,7 +102,7 @@ class LowLightMonitorTest : SysuiTestCase() {
                userLockedInteractor = userLockedInteractor,
                keyguardInteractor = keyguardInteractor,
                powerInteractor = powerInteractor,
                ambientLightModeMonitor = ambientLightModeMonitor,
                ambientLightModeMonitorInteractor = ambientLightModeInteractor,
                uiEventLogger = mock(),
            )
        }
+2 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ import com.android.systemui.keyguard.dagger.KeyguardModule;
import com.android.systemui.keyguard.ui.composable.blueprint.DefaultBlueprintModule;
import com.android.systemui.keyguard.ui.view.layout.blueprints.KeyguardBlueprintModule;
import com.android.systemui.keyguard.ui.view.layout.sections.KeyguardSectionsModule;
import com.android.systemui.lowlight.dagger.NoopAmbientLightModeMonitorModule;
import com.android.systemui.media.dagger.MediaModule;
import com.android.systemui.media.muteawait.MediaMuteAwaitConnectionCli;
import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
@@ -166,6 +167,7 @@ import javax.inject.Provider;
        RecentsModule.class,
        ReferenceNotificationsModule.class,
        NoopPosturingModule.class,
        NoopAmbientLightModeMonitorModule.class,
        ReferenceScreenshotModule.class,
        RotationLockModule.class,
        RotationLockNewModule.class,
+25 −24
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@ import com.android.systemui.display.domain.interactor.DisplayStateInteractor
import com.android.systemui.dreams.domain.interactor.DreamSettingsInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.shared.model.DozeStateModel.Companion.isDozeOff
import com.android.systemui.lowlight.dagger.LowLightModule.Companion.LOW_LIGHT_MONITOR
import com.android.systemui.lowlight.domain.interactor.AmbientLowLightMonitorInteractor
import com.android.systemui.lowlight.domain.interactor.LowLightInteractor
import com.android.systemui.lowlight.domain.interactor.LowLightSettingsInteractor
import com.android.systemui.lowlight.shared.model.LowLightActionEntry
@@ -46,7 +46,6 @@ import com.android.systemui.util.kotlin.BooleanFlowOperators.not
import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated
import javax.inject.Inject
import javax.inject.Named
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
@@ -75,7 +74,7 @@ constructor(
    private val userLockedInteractor: UserLockedInteractor,
    keyguardInteractor: KeyguardInteractor,
    powerInteractor: PowerInteractor,
    @Named(LOW_LIGHT_MONITOR) private val ambientLightModeMonitor: AmbientLightModeMonitor?,
    ambientLightModeMonitorInteractor: AmbientLowLightMonitorInteractor,
    private val uiEventLogger: UiEventLogger,
    private val lowLightBehaviorShellCommand: LowLightBehaviorShellCommand,
    private val lowLightShellCommand: LowLightShellCommand,
@@ -98,10 +97,11 @@ constructor(
    /** Whether the device is currently in a low-light environment. */
    private val isLowLightFromSensor =
        if (Flags.lowLightDreamBehavior()) {
            ambientLightModeMonitor?.let { monitor ->
            ambientLightModeMonitorInteractor.currentMonitor.flatMapLatestConflated { monitor ->
                monitor?.let {
                    conflatedCallbackFlow {
                        monitor.start { lowLightMode: Int -> trySend(lowLightMode) }
                        awaitClose { monitor.stop() }
                            it.start { lowLightMode: Int -> trySend(lowLightMode) }
                            awaitClose { it.stop() }
                        }
                        .filterNot { it == AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_UNDECIDED }
                        .map { it == AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK }
@@ -112,14 +112,15 @@ constructor(
                                else LowLightDockEvent.AMBIENT_LIGHT_TO_LIGHT
                            )
                        }
                    // AmbientLightModeMonitor only supports a single callback, so ensure this is
                    // re-used if there are multiple subscribers.
                        // AmbientLightModeMonitor only supports a single callback, so ensure this
                        // is re-used if there are multiple subscribers.
                        .stateIn(
                            scope,
                            started = SharingStarted.WhileSubscribed(replayExpirationMillis = 0),
                            initialValue = false,
                        )
                } ?: MutableStateFlow(false)
            }
        } else {
            MutableStateFlow(false)
        }
+0 −25
Original line number Diff line number Diff line
@@ -17,22 +17,15 @@
package com.android.systemui.lowlight.dagger

import com.android.systemui.CoreStartable
import com.android.systemui.lowlight.AmbientLightModeMonitor
import com.android.systemui.lowlight.LowLightBehaviorCoreStartable
import com.android.systemui.lowlight.data.repository.dagger.LowLightRepositoryModule
import com.android.systemui.lowlight.data.repository.dagger.LowLightSettingsRepositoryModule
import com.android.systemui.lowlight.shared.model.LightSensor
import com.android.systemui.lowlightclock.LowLightDisplayController
import com.android.systemui.util.kotlin.getOrNull
import dagger.Binds
import dagger.BindsOptionalOf
import dagger.Module
import dagger.Provides
import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
import java.util.Optional
import javax.inject.Named
import javax.inject.Provider

@Module(
    includes = [LowLightSettingsRepositoryModule::class, LowLightRepositoryModule::class],
@@ -47,22 +40,4 @@ abstract class LowLightModule {
    ): CoreStartable

    @BindsOptionalOf abstract fun bindsLowLightDisplayController(): LowLightDisplayController

    @BindsOptionalOf @Named(LIGHT_SENSOR) abstract fun bindsLightSensor(): LightSensor

    companion object {
        const val LIGHT_SENSOR: String = "low_light_monitor_light_sensor"
        const val LOW_LIGHT_MONITOR: String = "low_light_monitor"

        @Provides
        @Named(LOW_LIGHT_MONITOR)
        fun providesLowLightMonitor(
            factory: AmbientLightModeComponent.Factory,
            @Named(LIGHT_SENSOR) sensor: Optional<Provider<LightSensor>>,
        ): AmbientLightModeMonitor? {
            return sensor.getOrNull()?.get()?.let {
                factory.create(it).getAmbientLightModeMonitor()
            }
        }
    }
}
Loading