1 /* 2 * 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.view.layout.sections 19 20 import android.content.Context 21 import android.graphics.Point 22 import android.graphics.Rect 23 import android.util.DisplayMetrics 24 import android.view.WindowManager 25 import androidx.annotation.VisibleForTesting 26 import androidx.constraintlayout.widget.ConstraintSet 27 import com.android.keyguard.KeyguardUpdateMonitor 28 import com.android.systemui.R 29 import com.android.systemui.biometrics.AuthController 30 import com.android.systemui.keyguard.data.repository.KeyguardSection 31 import javax.inject.Inject 32 33 class DefaultLockIconSection 34 @Inject 35 constructor( 36 private val keyguardUpdateMonitor: KeyguardUpdateMonitor, 37 private val authController: AuthController, 38 private val windowManager: WindowManager, 39 private val context: Context, 40 ) : KeyguardSection { 41 private val lockIconViewId = R.id.lock_icon_view 42 43 override fun apply(constraintSet: ConstraintSet) { 44 val isUdfpsSupported = keyguardUpdateMonitor.isUdfpsSupported 45 val scaleFactor: Float = authController.scaleFactor 46 val mBottomPaddingPx = 47 context.resources.getDimensionPixelSize(R.dimen.lock_icon_margin_bottom) 48 val mDefaultPaddingPx = context.resources.getDimensionPixelSize(R.dimen.lock_icon_padding) 49 val scaledPadding: Int = (mDefaultPaddingPx * scaleFactor).toInt() 50 val bounds = windowManager.currentWindowMetrics.bounds 51 val widthPixels = bounds.right.toFloat() 52 val heightPixels = bounds.bottom.toFloat() 53 val defaultDensity = 54 DisplayMetrics.DENSITY_DEVICE_STABLE.toFloat() / 55 DisplayMetrics.DENSITY_DEFAULT.toFloat() 56 val lockIconRadiusPx = (defaultDensity * 36).toInt() 57 58 if (isUdfpsSupported) { 59 authController.udfpsLocation?.let { udfpsLocation -> 60 centerLockIcon( 61 udfpsLocation, 62 authController.udfpsRadius, 63 scaledPadding, 64 constraintSet 65 ) 66 } 67 } else { 68 centerLockIcon( 69 Point( 70 (widthPixels / 2).toInt(), 71 (heightPixels - ((mBottomPaddingPx + lockIconRadiusPx) * scaleFactor)).toInt() 72 ), 73 lockIconRadiusPx * scaleFactor, 74 scaledPadding, 75 constraintSet, 76 ) 77 } 78 } 79 80 @VisibleForTesting 81 internal fun centerLockIcon( 82 center: Point, 83 radius: Float, 84 drawablePadding: Int, 85 constraintSet: ConstraintSet 86 ) { 87 val sensorRect = 88 Rect().apply { 89 set( 90 center.x - radius.toInt(), 91 center.y - radius.toInt(), 92 center.x + radius.toInt(), 93 center.y + radius.toInt(), 94 ) 95 } 96 97 constraintSet.apply { 98 constrainWidth(lockIconViewId, sensorRect.right - sensorRect.left) 99 constrainHeight(lockIconViewId, sensorRect.bottom - sensorRect.top) 100 connect( 101 lockIconViewId, 102 ConstraintSet.TOP, 103 ConstraintSet.PARENT_ID, 104 ConstraintSet.TOP, 105 sensorRect.top 106 ) 107 connect( 108 lockIconViewId, 109 ConstraintSet.START, 110 ConstraintSet.PARENT_ID, 111 ConstraintSet.START, 112 sensorRect.left 113 ) 114 } 115 } 116 } 117