1 /*
<lambda>null2  * Copyright (C) 2023 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.keyguard.ui.binder
18 
19 import android.view.View
20 import androidx.constraintlayout.helper.widget.Layer
21 import androidx.constraintlayout.widget.ConstraintLayout
22 import androidx.lifecycle.Lifecycle
23 import androidx.lifecycle.repeatOnLifecycle
24 import com.android.app.tracing.coroutines.launch
25 import com.android.systemui.keyguard.MigrateClocksToBlueprint
26 import com.android.systemui.keyguard.domain.interactor.KeyguardBlueprintInteractor
27 import com.android.systemui.keyguard.ui.view.layout.blueprints.transitions.IntraBlueprintTransition.Config
28 import com.android.systemui.keyguard.ui.view.layout.blueprints.transitions.IntraBlueprintTransition.Type
29 import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel
30 import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel
31 import com.android.systemui.lifecycle.repeatWhenAttached
32 import com.android.systemui.res.R
33 import com.android.systemui.shared.R as sharedR
34 
35 object KeyguardSmartspaceViewBinder {
36     @JvmStatic
37     fun bind(
38         keyguardRootView: ConstraintLayout,
39         clockViewModel: KeyguardClockViewModel,
40         smartspaceViewModel: KeyguardSmartspaceViewModel,
41         blueprintInteractor: KeyguardBlueprintInteractor,
42     ) {
43         keyguardRootView.repeatWhenAttached {
44             repeatOnLifecycle(Lifecycle.State.CREATED) {
45                 launch("$TAG#clockViewModel.hasCustomWeatherDataDisplay") {
46                     if (!MigrateClocksToBlueprint.isEnabled) return@launch
47                     clockViewModel.hasCustomWeatherDataDisplay.collect { hasCustomWeatherDataDisplay
48                         ->
49                         updateDateWeatherToBurnInLayer(
50                             keyguardRootView,
51                             clockViewModel,
52                             smartspaceViewModel
53                         )
54                         blueprintInteractor.refreshBlueprint(
55                             Config(
56                                 Type.SmartspaceVisibility,
57                                 checkPriority = false,
58                                 terminatePrevious = false,
59                             )
60                         )
61                     }
62                 }
63 
64                 launch("$TAG#smartspaceViewModel.bcSmartspaceVisibility") {
65                     if (!MigrateClocksToBlueprint.isEnabled) return@launch
66                     smartspaceViewModel.bcSmartspaceVisibility.collect {
67                         updateBCSmartspaceInBurnInLayer(keyguardRootView, clockViewModel)
68                         blueprintInteractor.refreshBlueprint(
69                             Config(
70                                 Type.SmartspaceVisibility,
71                                 checkPriority = false,
72                                 terminatePrevious = false,
73                             )
74                         )
75                     }
76                 }
77             }
78         }
79     }
80 
81     private fun updateBCSmartspaceInBurnInLayer(
82         keyguardRootView: ConstraintLayout,
83         clockViewModel: KeyguardClockViewModel,
84     ) {
85         // Visibility is controlled by updateTargetVisibility in CardPagerAdapter
86         val burnInLayer = keyguardRootView.requireViewById<Layer>(R.id.burn_in_layer)
87         burnInLayer.apply {
88             val smartspaceView =
89                 keyguardRootView.requireViewById<View>(sharedR.id.bc_smartspace_view)
90             if (smartspaceView.visibility == View.VISIBLE) {
91                 addView(smartspaceView)
92             } else {
93                 removeView(smartspaceView)
94             }
95         }
96         clockViewModel.burnInLayer?.updatePostLayout(keyguardRootView)
97     }
98 
99     private fun updateDateWeatherToBurnInLayer(
100         keyguardRootView: ConstraintLayout,
101         clockViewModel: KeyguardClockViewModel,
102         smartspaceViewModel: KeyguardSmartspaceViewModel
103     ) {
104         if (clockViewModel.hasCustomWeatherDataDisplay.value) {
105             removeDateWeatherFromBurnInLayer(keyguardRootView, smartspaceViewModel)
106         } else {
107             addDateWeatherToBurnInLayer(keyguardRootView, smartspaceViewModel)
108         }
109         clockViewModel.burnInLayer?.updatePostLayout(keyguardRootView)
110     }
111 
112     private fun addDateWeatherToBurnInLayer(
113         constraintLayout: ConstraintLayout,
114         smartspaceViewModel: KeyguardSmartspaceViewModel
115     ) {
116         val burnInLayer = constraintLayout.requireViewById<Layer>(R.id.burn_in_layer)
117         burnInLayer.apply {
118             if (
119                 smartspaceViewModel.isSmartspaceEnabled &&
120                     smartspaceViewModel.isDateWeatherDecoupled
121             ) {
122                 val dateView =
123                     constraintLayout.requireViewById<View>(sharedR.id.date_smartspace_view)
124                 addView(dateView)
125             }
126         }
127     }
128 
129     private fun removeDateWeatherFromBurnInLayer(
130         constraintLayout: ConstraintLayout,
131         smartspaceViewModel: KeyguardSmartspaceViewModel
132     ) {
133         val burnInLayer = constraintLayout.requireViewById<Layer>(R.id.burn_in_layer)
134         burnInLayer.apply {
135             if (
136                 smartspaceViewModel.isSmartspaceEnabled &&
137                     smartspaceViewModel.isDateWeatherDecoupled
138             ) {
139                 val dateView =
140                     constraintLayout.requireViewById<View>(sharedR.id.date_smartspace_view)
141                 removeView(dateView)
142             }
143         }
144     }
145 
146     private const val TAG = "KeyguardSmartspaceViewBinder"
147 }
148