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

Commit 844c3ece authored by Lucas Silva's avatar Lucas Silva
Browse files

Remove ScreenSaverEnabledCondition

Use DreamSettingsInteractor instead to determine if dreams are enabled.

Test: atest SystemUITests
Flag: EXEMPT refactor
Bug: 407633926
Change-Id: Ib0f689d52e339af94dac992e06b50ff66fd77f13
parent bc3901ff
Loading
Loading
Loading
Loading
+0 −81
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.lowlightclock

import android.content.res.Resources
import android.database.ContentObserver
import android.os.UserHandle
import android.provider.Settings
import android.util.Log
import com.android.internal.R
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.shared.condition.Condition
import com.android.systemui.util.settings.SecureSettings
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope

/** Condition for monitoring if the screensaver setting is enabled. */
class ScreenSaverEnabledCondition
@Inject
constructor(
    @Background scope: CoroutineScope,
    @Main resources: Resources,
    private val secureSettings: SecureSettings,
) : Condition(scope) {
    private val screenSaverEnabledByDefaultConfig =
        resources.getBoolean(R.bool.config_dreamsEnabledByDefault)

    private val screenSaverSettingObserver: ContentObserver =
        object : ContentObserver(null) {
            override fun onChange(selfChange: Boolean) {
                updateScreenSaverEnabledSetting()
            }
        }

    public override suspend fun start() {
        secureSettings.registerContentObserverForUserSync(
            Settings.Secure.SCREENSAVER_ENABLED,
            screenSaverSettingObserver,
            UserHandle.USER_CURRENT,
        )
        updateScreenSaverEnabledSetting()
    }

    override fun stop() {
        secureSettings.unregisterContentObserverSync(screenSaverSettingObserver)
    }

    override val startStrategy: Int
        get() = START_EAGERLY

    private fun updateScreenSaverEnabledSetting() {
        val enabled =
            secureSettings.getIntForUser(
                Settings.Secure.SCREENSAVER_ENABLED,
                if (screenSaverEnabledByDefaultConfig) 1 else 0,
                UserHandle.USER_CURRENT,
            ) != 0
        if (!enabled) {
            Log.i(TAG, "Disabling low-light clock because screen saver has been disabled")
        }
        updateCondition(enabled)
    }

    companion object {
        private val TAG: String = ScreenSaverEnabledCondition::class.java.simpleName
    }
}
+19 −6
Original line number Diff line number Diff line
@@ -21,7 +21,10 @@ import com.android.dream.lowlight.dagger.LowLightDreamModule
import com.android.systemui.CoreStartable
import com.android.systemui.communal.DeviceInactiveCondition
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dreams.domain.interactor.DreamSettingsInteractor
import com.android.systemui.dreams.shared.model.WhenToDream
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogBufferFactory
import com.android.systemui.lowlightclock.AmbientLightModeMonitor.DebounceAlgorithm
@@ -30,9 +33,10 @@ import com.android.systemui.lowlightclock.ForceLowLightCondition
import com.android.systemui.lowlightclock.LowLightCondition
import com.android.systemui.lowlightclock.LowLightDisplayController
import com.android.systemui.lowlightclock.LowLightMonitor
import com.android.systemui.lowlightclock.ScreenSaverEnabledCondition
import com.android.systemui.res.R
import com.android.systemui.shared.condition.Condition
import com.android.systemui.shared.condition.Condition.Companion.START_EAGERLY
import com.android.systemui.shared.condition.toCondition
import dagger.Binds
import dagger.BindsOptionalOf
import dagger.Module
@@ -41,14 +45,11 @@ import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
import dagger.multibindings.IntoSet
import javax.inject.Named
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.map

@Module(includes = [LowLightDreamModule::class])
abstract class LowLightModule {
    @Binds
    @IntoSet
    @Named(LOW_LIGHT_PRECONDITIONS)
    abstract fun bindScreenSaverEnabledCondition(condition: ScreenSaverEnabledCondition): Condition

    @Binds
    @IntoSet
    @Named(LOW_LIGHT_PRECONDITIONS)
@@ -81,6 +82,18 @@ abstract class LowLightModule {
        const val LOW_LIGHT_PRECONDITIONS: String = "low_light_preconditions"
        const val LIGHT_SENSOR: String = "low_light_monitor_light_sensor"

        @Provides
        @IntoSet
        @Named(LOW_LIGHT_PRECONDITIONS)
        fun provideDreamEnabledCondition(
            @Background scope: CoroutineScope,
            dreamSettingsInteractor: DreamSettingsInteractor,
        ): Condition {
            return dreamSettingsInteractor.whenToDream
                .map { it != WhenToDream.NEVER }
                .toCondition(scope = scope, strategy = START_EAGERLY, initialValue = false)
        }

        /** Provides a [LogBuffer] for logs related to low-light features. */
        @JvmStatic
        @Provides
+0 −115
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.lowlightclock

import android.content.res.Resources
import android.database.ContentObserver
import android.os.UserHandle
import android.provider.Settings
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.internal.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.condition.testStart
import com.android.systemui.kosmos.runCurrent
import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.testScope
import com.android.systemui.testKosmos
import com.android.systemui.util.settings.SecureSettings
import com.google.common.truth.Truth
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.any
import org.mockito.kotlin.argumentCaptor
import org.mockito.kotlin.eq
import org.mockito.kotlin.whenever

@SmallTest
@RunWith(AndroidTestingRunner::class)
class ScreenSaverEnabledConditionTest : SysuiTestCase() {
    private val kosmos = testKosmos()

    @Mock private lateinit var resources: Resources

    @Mock private lateinit var secureSettings: SecureSettings

    private val settingsObserverCaptor = argumentCaptor<ContentObserver>()
    private lateinit var condition: ScreenSaverEnabledCondition

    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)
        // Default dreams to enabled by default
        whenever(resources.getBoolean(R.bool.config_dreamsEnabledByDefault)).thenReturn(true)

        condition = ScreenSaverEnabledCondition(kosmos.testScope, resources, secureSettings)
    }

    @Test
    fun testScreenSaverInitiallyEnabled() =
        kosmos.runTest {
            setScreenSaverEnabled(true)
            testStart(condition)
            Truth.assertThat(condition.isConditionMet).isTrue()
        }

    @Test
    fun testScreenSaverInitiallyDisabled() =
        kosmos.runTest {
            setScreenSaverEnabled(false)
            testStart(condition)
            Truth.assertThat(condition.isConditionMet).isFalse()
        }

    @Test
    fun testScreenSaverStateChanges() =
        kosmos.runTest {
            setScreenSaverEnabled(false)
            testStart(condition)
            Truth.assertThat(condition.isConditionMet).isFalse()

            setScreenSaverEnabled(true)
            runCurrent()
            val observer = captureSettingsObserver()
            observer.onChange(/* selfChange= */ false)
            Truth.assertThat(condition.isConditionMet).isTrue()
        }

    private fun setScreenSaverEnabled(enabled: Boolean) {
        whenever(
                secureSettings.getIntForUser(
                    eq(Settings.Secure.SCREENSAVER_ENABLED),
                    any(),
                    eq(UserHandle.USER_CURRENT),
                )
            )
            .thenReturn(if (enabled) 1 else 0)
    }

    private fun captureSettingsObserver(): ContentObserver {
        Mockito.verify(secureSettings)
            .registerContentObserverForUserSync(
                eq(Settings.Secure.SCREENSAVER_ENABLED),
                settingsObserverCaptor.capture(),
                eq(UserHandle.USER_CURRENT),
            )
        return settingsObserverCaptor.lastValue
    }
}