1 /*
<lambda>null2  * Copyright (C) 2024 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.shade.domain.startable
18 
19 import android.content.Context
20 import com.android.systemui.CoreStartable
21 import com.android.systemui.common.ui.data.repository.ConfigurationRepository
22 import com.android.systemui.dagger.SysUISingleton
23 import com.android.systemui.dagger.qualifiers.Application
24 import com.android.systemui.log.LogBuffer
25 import com.android.systemui.log.dagger.ShadeTouchLog
26 import com.android.systemui.scene.domain.interactor.SceneInteractor
27 import com.android.systemui.scene.shared.flag.SceneContainerFlag
28 import com.android.systemui.shade.ShadeExpansionStateManager
29 import com.android.systemui.shade.TouchLogger.Companion.logTouchesTo
30 import com.android.systemui.shade.data.repository.ShadeRepository
31 import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor
32 import com.android.systemui.shade.shared.flag.DualShade
33 import com.android.systemui.shade.shared.model.ShadeMode
34 import com.android.systemui.shade.transition.ScrimShadeTransitionController
35 import com.android.systemui.statusbar.policy.SplitShadeStateController
36 import javax.inject.Inject
37 import javax.inject.Provider
38 import kotlinx.coroutines.CoroutineScope
39 import kotlinx.coroutines.flow.combine
40 import kotlinx.coroutines.flow.launchIn
41 import kotlinx.coroutines.flow.map
42 import kotlinx.coroutines.flow.onStart
43 import kotlinx.coroutines.launch
44 
45 @SysUISingleton
46 class ShadeStartable
47 @Inject
48 constructor(
49     @Application private val applicationScope: CoroutineScope,
50     @Application private val applicationContext: Context,
51     @ShadeTouchLog private val touchLog: LogBuffer,
52     private val configurationRepository: ConfigurationRepository,
53     private val shadeRepository: ShadeRepository,
54     private val splitShadeStateController: SplitShadeStateController,
55     private val scrimShadeTransitionController: ScrimShadeTransitionController,
56     private val sceneInteractorProvider: Provider<SceneInteractor>,
57     private val panelExpansionInteractorProvider: Provider<PanelExpansionInteractor>,
58     private val shadeExpansionStateManager: ShadeExpansionStateManager,
59 ) : CoreStartable {
60 
61     override fun start() {
62         hydrateShadeMode()
63         hydrateShadeExpansionStateManager()
64         logTouchesTo(touchLog)
65         scrimShadeTransitionController.init()
66     }
67 
68     private fun hydrateShadeExpansionStateManager() {
69         if (SceneContainerFlag.isEnabled) {
70             combine(
71                     panelExpansionInteractorProvider.get().legacyPanelExpansion,
72                     sceneInteractorProvider.get().isTransitionUserInputOngoing,
73                 ) { panelExpansion, tracking ->
74                     shadeExpansionStateManager.onPanelExpansionChanged(
75                         fraction = panelExpansion,
76                         expanded = panelExpansion > 0f,
77                         tracking = tracking,
78                     )
79                 }
80                 .launchIn(applicationScope)
81         }
82     }
83 
84     private fun hydrateShadeMode() {
85         if (DualShade.isEnabled) {
86             shadeRepository.setShadeMode(ShadeMode.Dual)
87             return
88         }
89         applicationScope.launch {
90             configurationRepository.onAnyConfigurationChange
91                 // Force initial collection.
92                 .onStart { emit(Unit) }
93                 .map { applicationContext.resources }
94                 .map { resources ->
95                     splitShadeStateController.shouldUseSplitNotificationShade(resources)
96                 }
97                 .collect { isSplitShade ->
98                     shadeRepository.setShadeMode(
99                         if (isSplitShade) ShadeMode.Split else ShadeMode.Single
100                     )
101                 }
102         }
103     }
104 }
105