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

Commit d064e424 authored by Bryce Lee's avatar Bryce Lee Committed by Android (Google) Code Review
Browse files

Merge "Associate hardware sensor and debounce algorithm together." into main

parents d4a69c2a aa7b28f9
Loading
Loading
Loading
Loading
+14 −28
Original line number Diff line number Diff line
@@ -22,13 +22,11 @@ import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.hardware.SensorManager
import android.util.Log
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.lowlight.dagger.LowLightModule.Companion.LIGHT_SENSOR
import com.android.systemui.lowlight.dagger.AmbientLightModeModule.Companion.MONITOR_LIGHT_SENSOR
import com.android.systemui.lowlight.shared.model.LightSensor
import com.android.systemui.util.sensors.AsyncSensorManager
import java.util.Optional
import javax.inject.Inject
import javax.inject.Named
import javax.inject.Provider

interface AmbientLightModeMonitor {
    companion object {
@@ -76,13 +74,11 @@ interface AmbientLightModeMonitor {
 *   light mode.
 * @property sensorManager the sensor manager used to register sensor event updates.
 */
@SysUISingleton
class AmbientLightModeMonitorImpl
@Inject
constructor(
    private val algorithm: Optional<AmbientLightModeMonitor.DebounceAlgorithm>,
    private val sensorManager: AsyncSensorManager,
    @Named(LIGHT_SENSOR) private val lightSensor: Optional<Provider<Sensor>>,
    @Named(MONITOR_LIGHT_SENSOR) private val lightSensor: LightSensor,
) : AmbientLightModeMonitor {
    companion object {
        private const val TAG = "AmbientLightModeMonitor"
@@ -92,33 +88,25 @@ constructor(
    override fun start(callback: AmbientLightModeMonitor.Callback) {
        if (DEBUG) Log.d(TAG, "start monitoring ambient light mode")

        if (lightSensor.isEmpty || lightSensor.get().get() == null) {
            if (DEBUG) Log.w(TAG, "light sensor not available")
            return
        }

        if (algorithm.isEmpty) {
            if (DEBUG) Log.w(TAG, "debounce algorithm not available")
            return
        }

        algorithm.get().start(callback)
        lightSensor.apply {
            algorithm.start(callback)
            sensorManager.registerListener(
                mSensorEventListener,
            lightSensor.get().get(),
                sensor,
                SensorManager.SENSOR_DELAY_NORMAL,
            )
        }
    }

    /** Stop monitoring the current ambient light mode. */
    override fun stop() {
        if (DEBUG) Log.d(TAG, "stop monitoring ambient light mode")

        if (algorithm.isPresent) {
            algorithm.get().stop()
        }
        lightSensor.apply {
            algorithm.stop()
            sensorManager.unregisterListener(mSensorEventListener)
        }
    }

    private val mSensorEventListener: SensorEventListener =
        object : SensorEventListener {
@@ -128,9 +116,7 @@ constructor(
                    return
                }

                if (algorithm.isPresent) {
                    algorithm.get().onUpdateLightSensorEvent(event.values[0])
                }
                lightSensor.apply { algorithm.onUpdateLightSensorEvent(event.values[0]) }
            }

            override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {
+24 −20
Original line number Diff line number Diff line
@@ -25,6 +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.LowLightInteractor
import com.android.systemui.lowlight.domain.interactor.LowLightSettingsInteractor
import com.android.systemui.lowlight.shared.model.LowLightActionEntry
@@ -45,6 +46,7 @@ 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
@@ -73,7 +75,7 @@ constructor(
    private val userLockedInteractor: UserLockedInteractor,
    keyguardInteractor: KeyguardInteractor,
    powerInteractor: PowerInteractor,
    private val ambientLightModeMonitor: AmbientLightModeMonitor,
    @Named(LOW_LIGHT_MONITOR) private val ambientLightModeMonitor: AmbientLightModeMonitor?,
    private val uiEventLogger: UiEventLogger,
    private val lowLightBehaviorShellCommand: LowLightBehaviorShellCommand,
    private val lowLightShellCommand: LowLightShellCommand,
@@ -96,9 +98,10 @@ constructor(
    /** Whether the device is currently in a low-light environment. */
    private val isLowLightFromSensor =
        if (Flags.lowLightDreamBehavior()) {
            ambientLightModeMonitor?.let { monitor ->
                conflatedCallbackFlow {
                    ambientLightModeMonitor.start { lowLightMode: Int -> trySend(lowLightMode) }
                    awaitClose { ambientLightModeMonitor.stop() }
                        monitor.start { lowLightMode: Int -> trySend(lowLightMode) }
                        awaitClose { monitor.stop() }
                    }
                    .filterNot { it == AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_UNDECIDED }
                    .map { it == AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK }
@@ -116,6 +119,7 @@ constructor(
                        started = SharingStarted.WhileSubscribed(replayExpirationMillis = 0),
                        initialValue = false,
                    )
            } ?: MutableStateFlow(false)
        } else {
            MutableStateFlow(false)
        }
+36 −0
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.lowlight.dagger

import com.android.systemui.lowlight.AmbientLightModeMonitor
import com.android.systemui.lowlight.dagger.AmbientLightModeModule.Companion.MONITOR_LIGHT_SENSOR
import com.android.systemui.lowlight.shared.model.LightSensor
import dagger.BindsInstance
import dagger.Subcomponent
import javax.inject.Named

@Subcomponent(modules = [AmbientLightModeModule::class])
interface AmbientLightModeComponent {
    @Subcomponent.Factory
    interface Factory {
        fun create(
            @BindsInstance @Named(MONITOR_LIGHT_SENSOR) sensor: LightSensor
        ): AmbientLightModeComponent
    }

    fun getAmbientLightModeMonitor(): AmbientLightModeMonitor
}
+34 −0
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.lowlight.dagger

import com.android.systemui.lowlight.AmbientLightModeMonitor
import com.android.systemui.lowlight.AmbientLightModeMonitorImpl
import dagger.Binds
import dagger.Module

@Module
abstract class AmbientLightModeModule {
    companion object {
        const val MONITOR_LIGHT_SENSOR: String = "monitor_light_sensor"
    }

    @Binds
    abstract fun bindsAmbientLightModeMonitor(
        monitor: AmbientLightModeMonitorImpl
    ): AmbientLightModeMonitor
}
+20 −12
Original line number Diff line number Diff line
@@ -16,23 +16,27 @@

package com.android.systemui.lowlight.dagger

import android.hardware.Sensor
import com.android.systemui.CoreStartable
import com.android.systemui.lowlight.AmbientLightModeMonitor
import com.android.systemui.lowlight.AmbientLightModeMonitor.DebounceAlgorithm
import com.android.systemui.lowlight.AmbientLightModeMonitorImpl
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 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])
@Module(
    includes = [LowLightSettingsRepositoryModule::class, LowLightRepositoryModule::class],
    subcomponents = [AmbientLightModeComponent::class],
)
abstract class LowLightModule {
    @Binds
    @IntoMap
@@ -43,16 +47,20 @@ abstract class LowLightModule {

    @BindsOptionalOf abstract fun bindsLowLightDisplayController(): LowLightDisplayController

    @BindsOptionalOf abstract fun bindsDebounceAlgorithm(): DebounceAlgorithm

    @Binds
    abstract fun bindAmbientLightModeMonitor(
        impl: AmbientLightModeMonitorImpl
    ): AmbientLightModeMonitor

    @BindsOptionalOf @Named(LIGHT_SENSOR) abstract fun bindsLightSensor(): Sensor
    @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 if (sensor.isEmpty) null
            else factory.create(sensor.get().get()).getAmbientLightModeMonitor()
        }
    }
}
Loading