1 /*
2  * Copyright (C) 2022 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 com.android.systemui.unfold.config.UnfoldTransitionConfig
20 import com.android.systemui.unfold.progress.FixedTimingTransitionProgressProvider
21 import com.android.systemui.unfold.progress.PhysicsBasedUnfoldTransitionProgressProvider
22 import com.android.systemui.unfold.progress.UnfoldTransitionProgressForwarder
23 import com.android.systemui.unfold.updates.DeviceFoldStateProvider
24 import com.android.systemui.unfold.updates.FoldStateProvider
25 import com.android.systemui.unfold.updates.hinge.EmptyHingeAngleProvider
26 import com.android.systemui.unfold.updates.hinge.HingeAngleProvider
27 import com.android.systemui.unfold.updates.hinge.HingeSensorAngleProvider
28 import com.android.systemui.unfold.util.ATraceLoggerTransitionProgressListener
29 import com.android.systemui.unfold.util.ScaleAwareTransitionProgressProvider
30 import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityManager
31 import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityManagerImpl
32 import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityProvider
33 import dagger.Module
34 import dagger.Provides
35 import java.util.Optional
36 import javax.inject.Provider
37 import javax.inject.Singleton
38 
39 @Module(includes = [UnfoldSharedInternalModule::class])
40 class UnfoldSharedModule {
41     @Provides
42     @Singleton
43     fun provideFoldStateProvider(
44         deviceFoldStateProvider: DeviceFoldStateProvider
45     ): FoldStateProvider = deviceFoldStateProvider
46 
47     @Provides
48     @Singleton
49     fun unfoldKeyguardVisibilityProvider(
50         impl: UnfoldKeyguardVisibilityManagerImpl
51     ): UnfoldKeyguardVisibilityProvider = impl
52 
53     @Provides
54     @Singleton
55     fun unfoldKeyguardVisibilityManager(
56         impl: UnfoldKeyguardVisibilityManagerImpl
57     ): UnfoldKeyguardVisibilityManager = impl
58 }
59 
60 /**
61  * Needed as methods inside must be public, but their parameters can be internal (and, a public
62  * method can't have internal parameters). Making the module internal and included in a public one
63  * fixes the issue.
64  */
65 @Module
66 internal class UnfoldSharedInternalModule {
67     @Provides
68     @Singleton
69     fun unfoldTransitionProgressProvider(
70         config: UnfoldTransitionConfig,
71         scaleAwareProviderFactory: ScaleAwareTransitionProgressProvider.Factory,
72         tracingListener: ATraceLoggerTransitionProgressListener,
73         physicsBasedUnfoldTransitionProgressProvider:
74             Provider<PhysicsBasedUnfoldTransitionProgressProvider>,
75         fixedTimingTransitionProgressProvider: Provider<FixedTimingTransitionProgressProvider>,
76     ): Optional<UnfoldTransitionProgressProvider> {
77         if (!config.isEnabled) {
78             return Optional.empty()
79         }
80         val baseProgressProvider =
81             if (config.isHingeAngleEnabled) {
82                 physicsBasedUnfoldTransitionProgressProvider.get()
83             } else {
84                 fixedTimingTransitionProgressProvider.get()
85             }
86 
87         return Optional.of(
88             scaleAwareProviderFactory.wrap(baseProgressProvider).apply {
89                 // Always present callback that logs animation beginning and end.
90                 addCallback(tracingListener)
91             }
92         )
93     }
94 
95     @Provides
96     fun hingeAngleProvider(
97         config: UnfoldTransitionConfig,
98         hingeAngleSensorProvider: Provider<HingeSensorAngleProvider>
99     ): HingeAngleProvider {
100         return if (config.isHingeAngleEnabled) {
101             hingeAngleSensorProvider.get()
102         } else {
103             EmptyHingeAngleProvider
104         }
105     }
106 
107     @Provides
108     @Singleton
109     fun provideProgressForwarder(
110             config: UnfoldTransitionConfig,
111             progressForwarder: Provider<UnfoldTransitionProgressForwarder>
112     ): Optional<UnfoldTransitionProgressForwarder> {
113         if (!config.isEnabled) {
114             return Optional.empty()
115         }
116         return Optional.of(progressForwarder.get())
117     }
118 }
119