• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
18 package com.android.systemui.keyguard.ui.binder
19 
20 import androidx.constraintlayout.widget.ConstraintLayout
21 import androidx.constraintlayout.widget.ConstraintSet
22 import androidx.lifecycle.Lifecycle
23 import androidx.lifecycle.repeatOnLifecycle
24 import com.android.app.tracing.coroutines.launchTraced as launch
25 import com.android.systemui.Flags
26 import com.android.systemui.customization.R as customR
27 import com.android.systemui.keyguard.shared.model.KeyguardBlueprint
28 import com.android.systemui.keyguard.ui.view.layout.blueprints.transitions.IntraBlueprintTransition
29 import com.android.systemui.keyguard.ui.view.layout.blueprints.transitions.IntraBlueprintTransition.Config
30 import com.android.systemui.keyguard.ui.viewmodel.KeyguardBlueprintViewModel
31 import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel
32 import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel
33 import com.android.systemui.lifecycle.repeatWhenAttached
34 import com.android.systemui.log.LogBuffer
35 import com.android.systemui.log.core.Logger
36 import com.android.systemui.log.dagger.KeyguardBlueprintLog
37 import com.android.systemui.plugins.clocks.ClockLogger.Companion.getVisText
38 import com.android.systemui.shared.R as sharedR
39 import com.android.systemui.util.kotlin.pairwise
40 
41 object KeyguardBlueprintViewBinder {
42     @JvmStatic
43     fun bind(
44         constraintLayout: ConstraintLayout,
45         viewModel: KeyguardBlueprintViewModel,
46         clockViewModel: KeyguardClockViewModel,
47         smartspaceViewModel: KeyguardSmartspaceViewModel,
48         @KeyguardBlueprintLog log: LogBuffer,
49     ) {
50         val logger = Logger(log, TAG)
51         constraintLayout.repeatWhenAttached {
52             repeatOnLifecycle(Lifecycle.State.CREATED) {
53                 launch("$TAG#viewModel.blueprint") {
54                     viewModel.blueprint.pairwise(null as KeyguardBlueprint?).collect {
55                         (prevBlueprint, blueprint) ->
56                         val config = Config.DEFAULT
57                         val transition =
58                             IntraBlueprintTransition(
59                                 config,
60                                 clockViewModel,
61                                 smartspaceViewModel,
62                                 log,
63                             )
64 
65                         viewModel.runTransition(constraintLayout, transition, config) {
66                             // Replace sections from the previous blueprint with the new ones
67                             blueprint.replaceViews(
68                                 constraintLayout,
69                                 prevBlueprint,
70                                 config.rebuildSections,
71                             )
72 
73                             val cs =
74                                 ConstraintSet().apply {
75                                     clone(constraintLayout)
76                                     val emptyLayout = ConstraintSet.Layout()
77                                     knownIds.forEach {
78                                         getConstraint(it).layout.copyFrom(emptyLayout)
79                                     }
80                                     blueprint.applyConstraints(this)
81                                 }
82 
83                             logger.logConstraintSet(cs, clockViewModel)
84                             cs.applyTo(constraintLayout)
85                             if (com.android.systemui.shared.Flags.clockReactiveSmartspaceLayout()) {
86                                 manuallySetDateWeatherConstraintsOnConstraintLayout(
87                                     cs,
88                                     constraintLayout,
89                                 )
90                             }
91                         }
92                     }
93                 }
94 
95                 launch("$TAG#viewModel.refreshTransition") {
96                     viewModel.refreshTransition.collect { config ->
97                         val blueprint = viewModel.blueprint.value
98 
99                         viewModel.runTransition(
100                             constraintLayout,
101                             clockViewModel,
102                             smartspaceViewModel,
103                             config,
104                         ) {
105                             blueprint.rebuildViews(constraintLayout, config.rebuildSections)
106 
107                             val cs =
108                                 ConstraintSet().apply {
109                                     clone(constraintLayout)
110                                     blueprint.applyConstraints(this)
111                                 }
112                             logger.logConstraintSet(cs, clockViewModel)
113                             cs.applyTo(constraintLayout)
114                             if (com.android.systemui.shared.Flags.clockReactiveSmartspaceLayout()) {
115                                 manuallySetDateWeatherConstraintsOnConstraintLayout(
116                                     cs,
117                                     constraintLayout,
118                                 )
119                             }
120                         }
121                     }
122                 }
123             }
124         }
125     }
126 
127     private fun manuallySetDateWeatherConstraintsOnConstraintLayout(
128         cs: ConstraintSet,
129         constraintLayout: ConstraintLayout,
130     ) {
131         val ids = listOf(sharedR.id.date_smartspace_view, sharedR.id.date_smartspace_view_large)
132 
133         for (i in ids) {
134             constraintLayout.getViewById(i)?.visibility = cs.getVisibility(i)
135             constraintLayout.getViewById(i)?.alpha = cs.getConstraint(i).propertySet.alpha
136         }
137     }
138 
139     private fun Logger.logConstraintSet(cs: ConstraintSet, viewModel: KeyguardClockViewModel) {
140         val currentClock = viewModel.currentClock.value
141         if (currentClock == null) return
142 
143         this.i({ "applyCsToSmallClock: vis=${getVisText(int1)}; alpha=$str1; scale=$str2" }) {
144             val smallClockViewId = customR.id.lockscreen_clock_view
145             int1 = cs.getVisibility(smallClockViewId)
146             str1 = "${cs.getConstraint(smallClockViewId).propertySet.alpha}"
147             str2 = "${cs.getConstraint(smallClockViewId).transform.scaleX}"
148         }
149 
150         this.i({
151             "applyCsToLargeClock: vis=${getVisText(int1)}; alpha=$str1; scale=$str2; pivotX=$str3"
152         }) {
153             val largeClockViewId = currentClock.largeClock.layout.views[0].id
154             int1 = cs.getVisibility(largeClockViewId)
155             str1 = "${cs.getConstraint(largeClockViewId).propertySet.alpha}"
156             str2 = "${cs.getConstraint(largeClockViewId).transform.scaleX}"
157             str3 = "${cs.getConstraint(largeClockViewId).transform.transformPivotX}"
158         }
159 
160         this.i({ "applyCsToSmartspaceDate: vis=${getVisText(int1)}; alpha=$str1" }) {
161             val smartspaceDateId = sharedR.id.date_smartspace_view
162             int1 = cs.getVisibility(smartspaceDateId)
163             str1 = "${cs.getConstraint(smartspaceDateId).propertySet.alpha}"
164         }
165 
166         if (com.android.systemui.shared.Flags.clockReactiveSmartspaceLayout()) {
167             this.i({ "applyCsToSmartspaceWeather: vis=${getVisText(int1)}; alpha=$str1" }) {
168                 val smartspaceDateId = sharedR.id.weather_smartspace_view
169                 int1 = cs.getVisibility(smartspaceDateId)
170                 str1 = "${cs.getConstraint(smartspaceDateId).propertySet.alpha}"
171             }
172             this.i({ "applyCsToSmartspaceDateLarge: vis=${getVisText(int1)}; alpha=$str1" }) {
173                 val smartspaceDateId = sharedR.id.date_smartspace_view_large
174                 int1 = cs.getVisibility(smartspaceDateId)
175                 str1 = "${cs.getConstraint(smartspaceDateId).propertySet.alpha}"
176             }
177             this.i({ "applyCsToSmartspaceWeatherLarge: vis=${getVisText(int1)}; alpha=$str1" }) {
178                 val smartspaceDateId = sharedR.id.weather_smartspace_view_large
179                 int1 = cs.getVisibility(smartspaceDateId)
180                 str1 = "${cs.getConstraint(smartspaceDateId).propertySet.alpha}"
181             }
182         }
183     }
184 
185     private val TAG = "KeyguardBlueprintViewBinder"
186 }
187