1 /* 2 * Copyright (C) 2020 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 package com.android.systemui.biometrics 17 18 import android.content.Context 19 import android.graphics.Canvas 20 import android.graphics.Color 21 import android.graphics.Paint 22 import android.graphics.Rect 23 import android.graphics.RectF 24 import android.util.AttributeSet 25 import android.util.Log 26 import android.view.MotionEvent 27 import android.widget.FrameLayout 28 import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams 29 import com.android.systemui.doze.DozeReceiver 30 31 private const val TAG = "UdfpsView" 32 33 /** 34 * The main view group containing all UDFPS animations. 35 */ 36 class UdfpsView( 37 context: Context, 38 attrs: AttributeSet? 39 ) : FrameLayout(context, attrs), DozeReceiver { 40 // sensorRect may be bigger than the sensor. True sensor dimensions are defined in 41 // overlayParams.sensorBounds 42 var sensorRect = Rect() 43 private var mUdfpsDisplayMode: UdfpsDisplayModeProvider? = null <lambda>null44 private val debugTextPaint = Paint().apply { 45 isAntiAlias = true 46 color = Color.BLUE 47 textSize = 32f 48 } 49 50 /** View controller (can be different for enrollment, BiometricPrompt, Keyguard, etc.). */ 51 var animationViewController: UdfpsAnimationViewController<*>? = null 52 53 /** Parameters that affect the position and size of the overlay. */ 54 var overlayParams = UdfpsOverlayParams() 55 56 /** Debug message. */ 57 var debugMessage: String? = null 58 set(value) { 59 field = value 60 postInvalidate() 61 } 62 63 /** True after the call to [configureDisplay] and before the call to [unconfigureDisplay]. */ 64 var isDisplayConfigured: Boolean = false 65 private set 66 setUdfpsDisplayModeProvidernull67 fun setUdfpsDisplayModeProvider(udfpsDisplayModeProvider: UdfpsDisplayModeProvider?) { 68 mUdfpsDisplayMode = udfpsDisplayModeProvider 69 } 70 71 // Don't propagate any touch events to the child views. onInterceptTouchEventnull72 override fun onInterceptTouchEvent(ev: MotionEvent): Boolean { 73 return (animationViewController == null || !animationViewController!!.shouldPauseAuth()) 74 } 75 dozeTimeTicknull76 override fun dozeTimeTick() { 77 animationViewController?.dozeTimeTick() 78 } 79 onLayoutnull80 override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) { 81 super.onLayout(changed, left, top, right, bottom) 82 83 // Updates sensor rect in relation to the overlay view 84 animationViewController?.onSensorRectUpdated(RectF(sensorRect)) 85 } 86 onAttachedToWindownull87 override fun onAttachedToWindow() { 88 super.onAttachedToWindow() 89 Log.v(TAG, "onAttachedToWindow") 90 } 91 onDetachedFromWindownull92 override fun onDetachedFromWindow() { 93 super.onDetachedFromWindow() 94 Log.v(TAG, "onDetachedFromWindow") 95 } 96 onDrawnull97 override fun onDraw(canvas: Canvas) { 98 super.onDraw(canvas) 99 if (!isDisplayConfigured) { 100 if (!debugMessage.isNullOrEmpty()) { 101 canvas.drawText(debugMessage!!, 0f, 160f, debugTextPaint) 102 } 103 } 104 } 105 configureDisplaynull106 fun configureDisplay(onDisplayConfigured: Runnable) { 107 isDisplayConfigured = true 108 animationViewController?.onDisplayConfiguring() 109 mUdfpsDisplayMode?.enable(onDisplayConfigured) 110 } 111 unconfigureDisplaynull112 fun unconfigureDisplay() { 113 isDisplayConfigured = false 114 animationViewController?.onDisplayUnconfigured() 115 mUdfpsDisplayMode?.disable(null /* onDisabled */) 116 } 117 } 118