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.composable.section 18 19 import android.widget.FrameLayout 20 import androidx.compose.foundation.layout.Column 21 import androidx.compose.foundation.layout.IntrinsicSize 22 import androidx.compose.foundation.layout.Row 23 import androidx.compose.foundation.layout.Spacer 24 import androidx.compose.foundation.layout.fillMaxWidth 25 import androidx.compose.foundation.layout.height 26 import androidx.compose.foundation.layout.padding 27 import androidx.compose.foundation.layout.width 28 import androidx.compose.runtime.Composable 29 import androidx.compose.runtime.getValue 30 import androidx.compose.ui.Alignment 31 import androidx.compose.ui.Modifier 32 import androidx.compose.ui.platform.LocalContext 33 import androidx.compose.ui.res.dimensionResource 34 import androidx.compose.ui.unit.dp 35 import androidx.compose.ui.viewinterop.AndroidView 36 import androidx.lifecycle.compose.collectAsStateWithLifecycle 37 import com.android.compose.animation.scene.SceneScope 38 import com.android.compose.modifiers.padding 39 import com.android.systemui.keyguard.KeyguardUnlockAnimationController 40 import com.android.systemui.keyguard.ui.composable.blueprint.ClockElementKeys 41 import com.android.systemui.keyguard.ui.composable.modifier.burnInAware 42 import com.android.systemui.keyguard.ui.composable.modifier.onTopPlacementChanged 43 import com.android.systemui.keyguard.ui.viewmodel.AodBurnInViewModel 44 import com.android.systemui.keyguard.ui.viewmodel.BurnInParameters 45 import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel 46 import com.android.systemui.keyguard.ui.viewmodel.LockscreenContentViewModel 47 import com.android.systemui.res.R 48 import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController 49 import javax.inject.Inject 50 51 class SmartSpaceSection 52 @Inject 53 constructor( 54 private val lockscreenSmartspaceController: LockscreenSmartspaceController, 55 private val keyguardUnlockAnimationController: KeyguardUnlockAnimationController, 56 private val keyguardSmartspaceViewModel: KeyguardSmartspaceViewModel, 57 private val aodBurnInViewModel: AodBurnInViewModel, 58 private val lockscreenContentViewModel: LockscreenContentViewModel, 59 ) { 60 @Composable 61 fun SceneScope.SmartSpace( 62 burnInParams: BurnInParameters, 63 onTopChanged: (top: Float?) -> Unit, 64 modifier: Modifier = Modifier, 65 ) { 66 val resources = LocalContext.current.resources 67 68 MovableElement(key = ClockElementKeys.smartspaceElementKey, modifier = modifier) { 69 Column( 70 modifier = 71 modifier 72 .onTopPlacementChanged(onTopChanged) 73 .padding( 74 top = { lockscreenContentViewModel.getSmartSpacePaddingTop(resources) }, 75 bottom = { 76 resources.getDimensionPixelSize( 77 R.dimen.keyguard_status_view_bottom_margin 78 ) 79 } 80 ) 81 ) { 82 if (!keyguardSmartspaceViewModel.isSmartspaceEnabled) { 83 return@Column 84 } 85 86 val paddingBelowClockStart = dimensionResource(R.dimen.below_clock_padding_start) 87 val paddingBelowClockEnd = dimensionResource(R.dimen.below_clock_padding_end) 88 89 if (keyguardSmartspaceViewModel.isDateWeatherDecoupled) { 90 Row( 91 verticalAlignment = Alignment.CenterVertically, 92 modifier = 93 Modifier.fillMaxWidth() 94 // All items will be constrained to be as tall as the shortest item. 95 .height(IntrinsicSize.Min) 96 .padding( 97 start = paddingBelowClockStart, 98 ), 99 ) { 100 Date( 101 modifier = 102 Modifier.burnInAware( 103 viewModel = aodBurnInViewModel, 104 params = burnInParams, 105 ), 106 ) 107 Spacer(modifier = Modifier.width(4.dp)) 108 Weather( 109 modifier = 110 Modifier.burnInAware( 111 viewModel = aodBurnInViewModel, 112 params = burnInParams, 113 ), 114 ) 115 } 116 } 117 118 Card( 119 modifier = 120 Modifier.fillMaxWidth() 121 .padding( 122 start = paddingBelowClockStart, 123 end = paddingBelowClockEnd, 124 ) 125 .burnInAware( 126 viewModel = aodBurnInViewModel, 127 params = burnInParams, 128 ), 129 ) 130 } 131 } 132 } 133 134 @Composable 135 private fun Card( 136 modifier: Modifier = Modifier, 137 ) { 138 AndroidView( 139 factory = { context -> 140 FrameLayout(context).apply { 141 addView( 142 lockscreenSmartspaceController.buildAndConnectView(this).apply { 143 layoutParams = 144 FrameLayout.LayoutParams( 145 FrameLayout.LayoutParams.MATCH_PARENT, 146 FrameLayout.LayoutParams.WRAP_CONTENT, 147 ) 148 149 keyguardUnlockAnimationController.lockscreenSmartspace = this 150 } 151 ) 152 } 153 }, 154 onRelease = { keyguardUnlockAnimationController.lockscreenSmartspace = null }, 155 modifier = modifier, 156 ) 157 } 158 159 @Composable 160 private fun Weather( 161 modifier: Modifier = Modifier, 162 ) { 163 val isVisible by keyguardSmartspaceViewModel.isWeatherVisible.collectAsStateWithLifecycle() 164 if (!isVisible) { 165 return 166 } 167 168 AndroidView( 169 factory = { context -> 170 FrameLayout(context).apply { 171 addView( 172 lockscreenSmartspaceController.buildAndConnectWeatherView(this).apply { 173 layoutParams = 174 FrameLayout.LayoutParams( 175 FrameLayout.LayoutParams.WRAP_CONTENT, 176 FrameLayout.LayoutParams.WRAP_CONTENT, 177 ) 178 } 179 ) 180 } 181 }, 182 modifier = modifier, 183 ) 184 } 185 186 @Composable 187 private fun Date( 188 modifier: Modifier = Modifier, 189 ) { 190 val isVisible by keyguardSmartspaceViewModel.isDateVisible.collectAsStateWithLifecycle() 191 if (!isVisible) { 192 return 193 } 194 195 AndroidView( 196 factory = { context -> 197 FrameLayout(context).apply { 198 addView( 199 lockscreenSmartspaceController.buildAndConnectDateView(this).apply { 200 layoutParams = 201 FrameLayout.LayoutParams( 202 FrameLayout.LayoutParams.WRAP_CONTENT, 203 FrameLayout.LayoutParams.WRAP_CONTENT, 204 ) 205 } 206 ) 207 } 208 }, 209 modifier = modifier, 210 ) 211 } 212 } 213