1 /* 2 * Copyright (C) 2025 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.systemui.lowlightclock.dagger 17 18 import android.content.res.Resources 19 import android.hardware.Sensor 20 import com.android.dream.lowlight.dagger.LowLightDreamModule 21 import com.android.systemui.CoreStartable 22 import com.android.systemui.communal.DeviceInactiveCondition 23 import com.android.systemui.dagger.SysUISingleton 24 import com.android.systemui.dagger.qualifiers.Main 25 import com.android.systemui.log.LogBuffer 26 import com.android.systemui.log.LogBufferFactory 27 import com.android.systemui.lowlightclock.AmbientLightModeMonitor.DebounceAlgorithm 28 import com.android.systemui.lowlightclock.DirectBootCondition 29 import com.android.systemui.lowlightclock.ForceLowLightCondition 30 import com.android.systemui.lowlightclock.LowLightCondition 31 import com.android.systemui.lowlightclock.LowLightDisplayController 32 import com.android.systemui.lowlightclock.LowLightMonitor 33 import com.android.systemui.lowlightclock.ScreenSaverEnabledCondition 34 import com.android.systemui.res.R 35 import com.android.systemui.shared.condition.Condition 36 import dagger.Binds 37 import dagger.BindsOptionalOf 38 import dagger.Module 39 import dagger.Provides 40 import dagger.multibindings.ClassKey 41 import dagger.multibindings.IntoMap 42 import dagger.multibindings.IntoSet 43 import javax.inject.Named 44 45 @Module(includes = [LowLightDreamModule::class]) 46 abstract class LowLightModule { 47 @Binds 48 @IntoSet 49 @Named(LOW_LIGHT_PRECONDITIONS) bindScreenSaverEnabledConditionnull50 abstract fun bindScreenSaverEnabledCondition(condition: ScreenSaverEnabledCondition): Condition 51 52 @Binds 53 @IntoSet 54 @Named(LOW_LIGHT_PRECONDITIONS) 55 abstract fun bindForceLowLightCondition(condition: ForceLowLightCondition): Condition 56 57 @Binds 58 @IntoSet 59 @Named(LOW_LIGHT_PRECONDITIONS) 60 abstract fun bindDeviceInactiveCondition(condition: DeviceInactiveCondition): Condition 61 62 @BindsOptionalOf abstract fun bindsLowLightDisplayController(): LowLightDisplayController 63 64 @BindsOptionalOf @Named(LIGHT_SENSOR) abstract fun bindsLightSensor(): Sensor 65 66 @BindsOptionalOf abstract fun bindsDebounceAlgorithm(): DebounceAlgorithm 67 68 /** Inject into LowLightMonitor. */ 69 @Binds 70 @IntoMap 71 @ClassKey(LowLightMonitor::class) 72 abstract fun bindLowLightMonitor(lowLightMonitor: LowLightMonitor): CoreStartable 73 74 companion object { 75 const val Y_TRANSLATION_ANIMATION_OFFSET: String = "y_translation_animation_offset" 76 const val Y_TRANSLATION_ANIMATION_DURATION_MILLIS: String = 77 "y_translation_animation_duration_millis" 78 const val ALPHA_ANIMATION_IN_START_DELAY_MILLIS: String = 79 "alpha_animation_in_start_delay_millis" 80 const val ALPHA_ANIMATION_DURATION_MILLIS: String = "alpha_animation_duration_millis" 81 const val LOW_LIGHT_PRECONDITIONS: String = "low_light_preconditions" 82 const val LIGHT_SENSOR: String = "low_light_monitor_light_sensor" 83 84 /** Provides a [LogBuffer] for logs related to low-light features. */ 85 @JvmStatic 86 @Provides 87 @SysUISingleton 88 @LowLightLog 89 fun provideLowLightLogBuffer(factory: LogBufferFactory): LogBuffer { 90 return factory.create("LowLightLog", 250) 91 } 92 93 @Provides 94 @IntoSet 95 @Named(LOW_LIGHT_PRECONDITIONS) 96 fun provideLowLightCondition( 97 lowLightCondition: LowLightCondition, 98 directBootCondition: DirectBootCondition, 99 ): Condition { 100 // Start lowlight if we are either in lowlight or in direct boot. The ordering of the 101 // conditions matters here since we don't want to start the lowlight condition if 102 // we are in direct boot mode. 103 return directBootCondition.or(lowLightCondition) 104 } 105 106 /** */ 107 @JvmStatic 108 @Provides 109 @Named(Y_TRANSLATION_ANIMATION_OFFSET) 110 fun providesAnimationInOffset(@Main resources: Resources): Int { 111 return resources.getDimensionPixelOffset( 112 R.dimen.low_light_clock_translate_animation_offset 113 ) 114 } 115 116 /** */ 117 @JvmStatic 118 @Provides 119 @Named(Y_TRANSLATION_ANIMATION_DURATION_MILLIS) 120 fun providesAnimationDurationMillis(@Main resources: Resources): Long { 121 return resources 122 .getInteger(R.integer.low_light_clock_translate_animation_duration_ms) 123 .toLong() 124 } 125 126 /** */ 127 @JvmStatic 128 @Provides 129 @Named(ALPHA_ANIMATION_IN_START_DELAY_MILLIS) 130 fun providesAlphaAnimationInStartDelayMillis(@Main resources: Resources): Long { 131 return resources 132 .getInteger(R.integer.low_light_clock_alpha_animation_in_start_delay_ms) 133 .toLong() 134 } 135 136 /** */ 137 @JvmStatic 138 @Provides 139 @Named(ALPHA_ANIMATION_DURATION_MILLIS) 140 fun providesAlphaAnimationDurationMillis(@Main resources: Resources): Long { 141 return resources 142 .getInteger(R.integer.low_light_clock_alpha_animation_duration_ms) 143 .toLong() 144 } 145 } 146 } 147