1 /* 2 * Copyright (C) 2021 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.biometrics; 18 19 import android.annotation.Nullable; 20 import android.content.Context; 21 import android.graphics.RectF; 22 import android.util.AttributeSet; 23 import android.view.View; 24 import android.view.ViewGroup; 25 import android.widget.FrameLayout; 26 27 /** 28 * Base class for views containing UDFPS animations. Note that this is a FrameLayout so that we 29 * can support multiple child views drawing in the same region around the sensor location. 30 * 31 * - hides animation view when pausing auth 32 * - sends illumination events to fingerprint drawable 33 * - sends sensor rect updates to fingerprint drawable 34 * - optionally can override dozeTimeTick to adjust views for burn-in mitigation 35 */ 36 abstract class UdfpsAnimationView extends FrameLayout { 37 // mAlpha takes into consideration the status bar expansion amount to fade out icon when 38 // the status bar is expanded 39 private int mAlpha; 40 boolean mPauseAuth; 41 UdfpsAnimationView(Context context, @Nullable AttributeSet attrs)42 public UdfpsAnimationView(Context context, @Nullable AttributeSet attrs) { 43 super(context, attrs); 44 } 45 46 /** 47 * Fingerprint drawable 48 */ getDrawable()49 abstract UdfpsDrawable getDrawable(); 50 onSensorRectUpdated(RectF bounds)51 void onSensorRectUpdated(RectF bounds) { 52 getDrawable().onSensorRectUpdated(bounds); 53 } 54 onIlluminationStarting()55 void onIlluminationStarting() { 56 getDrawable().setIlluminationShowing(true); 57 getDrawable().invalidateSelf(); 58 } 59 onIlluminationStopped()60 void onIlluminationStopped() { 61 getDrawable().setIlluminationShowing(false); 62 getDrawable().invalidateSelf(); 63 } 64 65 /** 66 * @return true if changed 67 */ setPauseAuth(boolean pauseAuth)68 boolean setPauseAuth(boolean pauseAuth) { 69 if (pauseAuth != mPauseAuth) { 70 mPauseAuth = pauseAuth; 71 updateAlpha(); 72 return true; 73 } 74 return false; 75 } 76 77 /** 78 * @return current alpha 79 */ updateAlpha()80 protected int updateAlpha() { 81 int alpha = calculateAlpha(); 82 getDrawable().setAlpha(alpha); 83 84 // this is necessary so that touches won't be intercepted if udfps is paused: 85 if (mPauseAuth && alpha == 0 && getParent() != null) { 86 ((ViewGroup) getParent()).setVisibility(View.INVISIBLE); 87 } else { 88 ((ViewGroup) getParent()).setVisibility(View.VISIBLE); 89 } 90 91 return alpha; 92 } 93 calculateAlpha()94 int calculateAlpha() { 95 return mPauseAuth ? mAlpha : 255; 96 } 97 isPauseAuth()98 boolean isPauseAuth() { 99 return mPauseAuth; 100 } 101 expansionToAlpha(float expansion)102 private int expansionToAlpha(float expansion) { 103 // Fade to 0 opacity when reaching this expansion amount 104 final float maxExpansion = 0.4f; 105 106 if (expansion >= maxExpansion) { 107 return 0; // transparent 108 } 109 110 final float percent = expansion / maxExpansion; 111 return (int) ((1 - percent) * 255); 112 } 113 onExpansionChanged(float expansion, boolean expanded)114 public void onExpansionChanged(float expansion, boolean expanded) { 115 mAlpha = expansionToAlpha(expansion); 116 updateAlpha(); 117 } 118 119 /** 120 * @return true if handled 121 */ dozeTimeTick()122 boolean dozeTimeTick() { 123 return false; 124 } 125 } 126