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 android.util.Log 21 import androidx.constraintlayout.widget.ConstraintLayout 22 import androidx.constraintlayout.widget.ConstraintSet 23 import androidx.lifecycle.Lifecycle 24 import androidx.lifecycle.repeatOnLifecycle 25 import com.android.app.tracing.coroutines.launch 26 import com.android.systemui.keyguard.KeyguardBottomAreaRefactor 27 import com.android.systemui.keyguard.shared.model.KeyguardBlueprint 28 import com.android.systemui.keyguard.ui.view.layout.blueprints.transitions.BaseBlueprintTransition 29 import com.android.systemui.keyguard.ui.view.layout.blueprints.transitions.IntraBlueprintTransition 30 import com.android.systemui.keyguard.ui.view.layout.blueprints.transitions.IntraBlueprintTransition.Config 31 import com.android.systemui.keyguard.ui.viewmodel.KeyguardBlueprintViewModel 32 import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel 33 import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel 34 import com.android.systemui.lifecycle.repeatWhenAttached 35 import com.android.systemui.res.R 36 import com.android.systemui.shared.R as sharedR 37 import com.android.systemui.util.kotlin.pairwise 38 39 object KeyguardBlueprintViewBinder { 40 @JvmStatic 41 fun bind( 42 constraintLayout: ConstraintLayout, 43 viewModel: KeyguardBlueprintViewModel, 44 clockViewModel: KeyguardClockViewModel, 45 smartspaceViewModel: KeyguardSmartspaceViewModel, 46 ) { 47 constraintLayout.repeatWhenAttached { 48 repeatOnLifecycle(Lifecycle.State.CREATED) { 49 launch("$TAG#viewModel.blueprint") { 50 viewModel.blueprint 51 .pairwise( 52 null as KeyguardBlueprint?, 53 ) 54 .collect { (prevBlueprint, blueprint) -> 55 val config = Config.DEFAULT 56 val transition = 57 if ( 58 !KeyguardBottomAreaRefactor.isEnabled && 59 prevBlueprint != null && 60 prevBlueprint != blueprint 61 ) { 62 BaseBlueprintTransition(clockViewModel) 63 .addTransition( 64 IntraBlueprintTransition( 65 config, 66 clockViewModel, 67 smartspaceViewModel 68 ) 69 ) 70 } else { 71 IntraBlueprintTransition( 72 config, 73 clockViewModel, 74 smartspaceViewModel 75 ) 76 } 77 78 viewModel.runTransition(constraintLayout, transition, config) { 79 // Replace sections from the previous blueprint with the new ones 80 blueprint.replaceViews( 81 constraintLayout, 82 prevBlueprint, 83 config.rebuildSections 84 ) 85 86 val cs = 87 ConstraintSet().apply { 88 clone(constraintLayout) 89 val emptyLayout = ConstraintSet.Layout() 90 knownIds.forEach { 91 getConstraint(it).layout.copyFrom(emptyLayout) 92 } 93 blueprint.applyConstraints(this) 94 } 95 96 logAlphaVisibilityOfAppliedConstraintSet(cs, clockViewModel) 97 cs.applyTo(constraintLayout) 98 } 99 } 100 } 101 102 launch("$TAG#viewModel.refreshTransition") { 103 viewModel.refreshTransition.collect { config -> 104 val blueprint = viewModel.blueprint.value 105 106 viewModel.runTransition( 107 constraintLayout, 108 IntraBlueprintTransition(config, clockViewModel, smartspaceViewModel), 109 config, 110 ) { 111 blueprint.rebuildViews(constraintLayout, config.rebuildSections) 112 113 val cs = 114 ConstraintSet().apply { 115 clone(constraintLayout) 116 blueprint.applyConstraints(this) 117 } 118 logAlphaVisibilityOfAppliedConstraintSet(cs, clockViewModel) 119 cs.applyTo(constraintLayout) 120 } 121 } 122 } 123 } 124 } 125 } 126 127 private fun logAlphaVisibilityOfAppliedConstraintSet( 128 cs: ConstraintSet, 129 viewModel: KeyguardClockViewModel 130 ) { 131 val currentClock = viewModel.currentClock.value 132 if (!DEBUG || currentClock == null) return 133 val smallClockViewId = R.id.lockscreen_clock_view 134 val largeClockViewId = currentClock.largeClock.layout.views[0].id 135 val smartspaceDateId = sharedR.id.date_smartspace_view 136 Log.i( 137 TAG, 138 "applyCsToSmallClock: vis=${cs.getVisibility(smallClockViewId)} " + 139 "alpha=${cs.getConstraint(smallClockViewId).propertySet.alpha}" 140 ) 141 Log.i( 142 TAG, 143 "applyCsToLargeClock: vis=${cs.getVisibility(largeClockViewId)} " + 144 "alpha=${cs.getConstraint(largeClockViewId).propertySet.alpha}" 145 ) 146 Log.i( 147 TAG, 148 "applyCsToSmartspaceDate: vis=${cs.getVisibility(smartspaceDateId)} " + 149 "alpha=${cs.getConstraint(smartspaceDateId).propertySet.alpha}" 150 ) 151 } 152 153 private const val TAG = "KeyguardBlueprintViewBinder" 154 private const val DEBUG = false 155 } 156