1 /* <lambda>null2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 * except in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 * KIND, either express or implied. See the License for the specific language governing 12 * permissions and limitations under the License. 13 */ 14 package com.android.systemui.plugins.clocks 15 16 import android.util.DisplayMetrics 17 import android.view.View 18 import androidx.constraintlayout.widget.ConstraintSet 19 import androidx.constraintlayout.widget.ConstraintSet.BOTTOM 20 import androidx.constraintlayout.widget.ConstraintSet.END 21 import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID 22 import androidx.constraintlayout.widget.ConstraintSet.START 23 import androidx.constraintlayout.widget.ConstraintSet.TOP 24 import androidx.constraintlayout.widget.ConstraintSet.WRAP_CONTENT 25 import com.android.internal.policy.SystemBarUtils 26 import com.android.systemui.plugins.annotations.GeneratedImport 27 import com.android.systemui.plugins.annotations.ProtectedInterface 28 import com.android.systemui.plugins.annotations.ProtectedReturn 29 import com.android.systemui.plugins.clocks.ContextExt.getDimen 30 import com.android.systemui.plugins.clocks.ContextExt.getId 31 32 /** Specifies layout information for the clock face */ 33 @ProtectedInterface 34 @GeneratedImport("java.util.ArrayList") 35 @GeneratedImport("android.view.View") 36 interface ClockFaceLayout { 37 @get:ProtectedReturn("return new ArrayList<View>();") 38 /** All clock views to add to the root constraint layout before applying constraints. */ 39 val views: List<View> 40 41 @ProtectedReturn("return constraints;") 42 /** Custom constraints to apply to Lockscreen ConstraintLayout. */ 43 fun applyConstraints(constraints: ConstraintSet): ConstraintSet 44 45 @ProtectedReturn("return constraints;") 46 /** Custom constraints to apply to preview ConstraintLayout. */ 47 fun applyPreviewConstraints( 48 clockPreviewConfig: ClockPreviewConfig, 49 constraints: ConstraintSet, 50 ): ConstraintSet 51 52 /** Apply specified AOD BurnIn parameters to this layout */ 53 fun applyAodBurnIn(aodBurnInModel: AodClockBurnInModel) 54 } 55 56 /** Data class to contain AOD BurnIn information for correct aod rendering */ 57 data class AodClockBurnInModel( 58 /** Scale that the clock should render at to mitigate burnin */ 59 val scale: Float, 60 61 /** X-Translation for the clock to mitigate burnin */ 62 val translationX: Float, 63 64 /** Y-Translation for the clock to mitigate burnin */ 65 val translationY: Float, 66 ) 67 68 /** A ClockFaceLayout that applies the default lockscreen layout to a single view */ 69 class DefaultClockFaceLayout(val view: View) : ClockFaceLayout { 70 override val views = listOf(view) 71 applyConstraintsnull72 override fun applyConstraints(constraints: ConstraintSet): ConstraintSet { 73 if (views.size != 1) { 74 throw IllegalArgumentException( 75 "Should have only one container view when using DefaultClockFaceLayout" 76 ) 77 } 78 return constraints 79 } 80 applyPreviewConstraintsnull81 override fun applyPreviewConstraints( 82 clockPreviewConfig: ClockPreviewConfig, 83 constraints: ConstraintSet, 84 ): ConstraintSet { 85 return applyDefaultPreviewConstraints(clockPreviewConfig, constraints) 86 } 87 applyAodBurnInnull88 override fun applyAodBurnIn(aodBurnInModel: AodClockBurnInModel) { 89 // Default clock doesn't need detailed control of view 90 } 91 92 companion object { applyDefaultPreviewConstraintsnull93 fun applyDefaultPreviewConstraints( 94 clockPreviewConfig: ClockPreviewConfig, 95 constraints: ConstraintSet, 96 ): ConstraintSet { 97 constraints.apply { 98 val context = clockPreviewConfig.context 99 val lockscreenClockViewLargeId = context.getId("lockscreen_clock_view_large") 100 constrainWidth(lockscreenClockViewLargeId, WRAP_CONTENT) 101 constrainHeight(lockscreenClockViewLargeId, WRAP_CONTENT) 102 constrainMaxHeight(lockscreenClockViewLargeId, 0) 103 104 val largeClockTopMargin = 105 SystemBarUtils.getStatusBarHeight(context) + 106 context.getDimen("small_clock_padding_top") + 107 context.getDimen("keyguard_smartspace_top_offset") + 108 context.getDimen("date_weather_view_height") + 109 context.getDimen("enhanced_smartspace_height") 110 connect(lockscreenClockViewLargeId, TOP, PARENT_ID, TOP, largeClockTopMargin) 111 connect(lockscreenClockViewLargeId, START, PARENT_ID, START) 112 connect(lockscreenClockViewLargeId, END, PARENT_ID, END) 113 114 clockPreviewConfig.udfpsTop?.let { 115 val screenHeight = context.resources.displayMetrics.heightPixels 116 connect( 117 lockscreenClockViewLargeId, 118 BOTTOM, 119 PARENT_ID, 120 BOTTOM, 121 (screenHeight - it).toInt(), 122 ) 123 } 124 ?: run { 125 // Copied calculation codes from applyConstraints in 126 // DefaultDeviceEntrySection 127 clockPreviewConfig.lockId?.let { lockId -> 128 connect(lockscreenClockViewLargeId, BOTTOM, lockId, TOP) 129 } 130 ?: run { 131 val bottomPaddingPx = context.getDimen("lock_icon_margin_bottom") 132 val defaultDensity = 133 DisplayMetrics.DENSITY_DEVICE_STABLE.toFloat() / 134 DisplayMetrics.DENSITY_DEFAULT.toFloat() 135 val lockIconRadiusPx = (defaultDensity * 36).toInt() 136 val clockBottomMargin = bottomPaddingPx + 2 * lockIconRadiusPx 137 connect( 138 lockscreenClockViewLargeId, 139 BOTTOM, 140 PARENT_ID, 141 BOTTOM, 142 clockBottomMargin, 143 ) 144 } 145 } 146 147 val smallClockViewId = context.getId("lockscreen_clock_view") 148 constrainWidth(smallClockViewId, WRAP_CONTENT) 149 constrainHeight(smallClockViewId, context.getDimen("small_clock_height")) 150 connect( 151 smallClockViewId, 152 START, 153 PARENT_ID, 154 START, 155 context.getDimen("clock_padding_start") + 156 context.getDimen("status_view_margin_horizontal"), 157 ) 158 159 val smallClockTopMargin = clockPreviewConfig.getSmallClockTopPadding() 160 connect(smallClockViewId, TOP, PARENT_ID, TOP, smallClockTopMargin) 161 } 162 return constraints 163 } 164 } 165 } 166