• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2021 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 
17 package com.android.systemui.unfold
18 
19 import android.content.Context
20 import android.hardware.devicestate.DeviceStateManager
21 import android.os.SystemProperties
22 import com.android.internal.foldables.FoldLockSettingAvailabilityProvider
23 import com.android.systemui.CoreStartable
24 import com.android.systemui.Flags
25 import com.android.systemui.dagger.qualifiers.Application
26 import com.android.systemui.dagger.qualifiers.Main
27 import com.android.systemui.keyguard.LifecycleScreenStatusProvider
28 import com.android.systemui.unfold.config.UnfoldTransitionConfig
29 import com.android.systemui.unfold.dagger.UnfoldBgProgressFlag
30 import com.android.systemui.unfold.dagger.UnfoldMain
31 import com.android.systemui.unfold.data.repository.FoldStateRepository
32 import com.android.systemui.unfold.data.repository.FoldStateRepositoryImpl
33 import com.android.systemui.unfold.data.repository.UnfoldTransitionRepository
34 import com.android.systemui.unfold.data.repository.UnfoldTransitionRepositoryImpl
35 import com.android.systemui.unfold.system.SystemUnfoldSharedModule
36 import com.android.systemui.unfold.updates.FoldProvider
37 import com.android.systemui.unfold.updates.FoldStateProvider
38 import com.android.systemui.unfold.updates.RotationChangeProvider
39 import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
40 import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider
41 import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider
42 import com.android.systemui.unfold.util.UnfoldOnlyProgressProvider
43 import com.android.systemui.unfold.util.UnfoldTransitionATracePrefix
44 import com.android.systemui.util.time.SystemClockImpl
45 import com.android.wm.shell.unfold.ShellUnfoldProgressProvider
46 import dagger.Binds
47 import dagger.Lazy
48 import dagger.Module
49 import dagger.Provides
50 import dagger.multibindings.ClassKey
51 import dagger.multibindings.IntoMap
52 import java.util.Optional
53 import java.util.concurrent.Executor
54 import javax.inject.Named
55 import javax.inject.Provider
56 import javax.inject.Singleton
57 
58 @Module(
59     includes =
60         [
61             UnfoldSharedModule::class,
62             SystemUnfoldSharedModule::class,
63             UnfoldTransitionModule.Bindings::class
64         ]
65 )
66 class UnfoldTransitionModule {
67 
68     @Provides @UnfoldTransitionATracePrefix fun tracingTagPrefix() = "systemui"
69 
70     @Provides
71     @UnfoldBgProgressFlag
72     @Singleton
73     fun unfoldBgProgressFlag() = Flags.unfoldAnimationBackgroundProgress()
74 
75     /** A globally available FoldStateListener that allows one to query the fold state. */
76     @Provides
77     @Singleton
78     fun providesFoldStateListener(
79         deviceStateManager: DeviceStateManager,
80         @Application context: Context,
81         @Main executor: Executor
82     ): DeviceStateManager.FoldStateListener {
83         val listener = DeviceStateManager.FoldStateListener(context)
84         deviceStateManager.registerCallback(executor, listener)
85 
86         return listener
87     }
88 
89     @Provides
90     @Singleton
91     fun providesFoldStateLoggingProvider(
92         config: UnfoldTransitionConfig,
93         foldStateProvider: Lazy<FoldStateProvider>
94     ): Optional<FoldStateLoggingProvider> =
95         if (config.isHingeAngleEnabled) {
96             Optional.of(FoldStateLoggingProviderImpl(foldStateProvider.get(), SystemClockImpl()))
97         } else {
98             Optional.empty()
99         }
100 
101     @Provides
102     @Singleton
103     fun providesFoldStateLogger(
104         optionalFoldStateLoggingProvider: Optional<FoldStateLoggingProvider>
105     ): Optional<FoldStateLogger> =
106         optionalFoldStateLoggingProvider.map { FoldStateLoggingProvider ->
107             FoldStateLogger(FoldStateLoggingProvider)
108         }
109 
110     @Provides
111     @Singleton
112     fun provideNaturalRotationProgressProvider(
113         context: Context,
114         @UnfoldMain rotationChangeProvider: RotationChangeProvider,
115         unfoldTransitionProgressProvider: Optional<UnfoldTransitionProgressProvider>
116     ): Optional<NaturalRotationUnfoldProgressProvider> =
117         unfoldTransitionProgressProvider.map { provider ->
118             NaturalRotationUnfoldProgressProvider(context, rotationChangeProvider, provider)
119         }
120 
121     @Provides
122     @Singleton
123     @Named(UNFOLD_ONLY_PROVIDER)
124     fun provideUnfoldOnlyProvider(
125         foldProvider: FoldProvider,
126         @Main executor: Executor,
127         sourceProvider: Optional<UnfoldTransitionProgressProvider>
128     ): Optional<UnfoldTransitionProgressProvider> =
129         sourceProvider.map { provider ->
130             UnfoldOnlyProgressProvider(foldProvider, executor, provider)
131         }
132 
133     @Provides
134     @Named(UNFOLD_STATUS_BAR)
135     @Singleton
136     fun provideStatusBarScopedTransitionProvider(
137         source: Optional<NaturalRotationUnfoldProgressProvider>
138     ): Optional<ScopedUnfoldTransitionProgressProvider> =
139         source.map { provider -> ScopedUnfoldTransitionProgressProvider(provider) }
140 
141     @Provides
142     @Singleton
143     fun provideShellProgressProvider(
144         config: UnfoldTransitionConfig,
145         foldProvider: FoldProvider,
146         provider: Provider<Optional<UnfoldTransitionProgressProvider>>,
147         @Named(UNFOLD_ONLY_PROVIDER)
148         unfoldOnlyProvider: Provider<Optional<UnfoldTransitionProgressProvider>>
149     ): ShellUnfoldProgressProvider {
150         val resultingProvider =
151             if (config.isEnabled) {
152                 // Return unfold only provider to the shell if we don't want to animate tasks during
153                 // folding. Shell provider listeners are responsible for animating task bounds.
154                 if (ENABLE_FOLD_TASK_ANIMATIONS) {
155                     provider
156                 } else {
157                     unfoldOnlyProvider
158                 }
159             } else {
160                 null
161             }
162 
163         return resultingProvider?.get()?.orElse(null)?.let { unfoldProgressProvider ->
164             UnfoldProgressProvider(unfoldProgressProvider, foldProvider)
165         }
166             ?: ShellUnfoldProgressProvider.NO_PROVIDER
167     }
168 
169     @Provides
170     fun screenStatusProvider(impl: LifecycleScreenStatusProvider): ScreenStatusProvider = impl
171 
172     @Provides
173     @Singleton
174     fun provideDisplaySwitchLatencyLogger(): DisplaySwitchLatencyLogger =
175         DisplaySwitchLatencyLogger()
176 
177     @Provides
178     @Singleton
179     fun provideFoldLockSettingAvailabilityProvider(
180         context: Context
181     ): FoldLockSettingAvailabilityProvider = FoldLockSettingAvailabilityProvider(context.resources)
182 
183     @Module
184     interface Bindings {
185         @Binds fun bindRepository(impl: UnfoldTransitionRepositoryImpl): UnfoldTransitionRepository
186 
187         @Binds fun bindFoldStateRepository(impl: FoldStateRepositoryImpl): FoldStateRepository
188     }
189 
190     @Module
191     interface Startables {
192         @Binds
193         @IntoMap
194         @ClassKey(UnfoldTraceLogger::class)
195         fun bindUnfoldTraceLogger(impl: UnfoldTraceLogger): CoreStartable
196     }
197 }
198 
199 const val UNFOLD_STATUS_BAR = "unfold_status_bar"
200 const val UNFOLD_ONLY_PROVIDER = "unfold_only_provider"
201 
202 // TODO: b/265764985 - tracking bug to clean-up the flag
203 // FeatureFlags are not accessible here because it's a global submodule (see GlobalModule.java)
204 private val ENABLE_FOLD_TASK_ANIMATIONS =
205     SystemProperties.getBoolean("persist.unfold.enable_fold_tasks_animation", false)
206