1 /* 2 * Copyright (C) 2019 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 20 import android.content.Context; 21 import android.graphics.drawable.AnimatedVectorDrawable; 22 import android.graphics.drawable.Drawable; 23 import android.util.AttributeSet; 24 import android.util.Log; 25 26 import androidx.annotation.Nullable; 27 28 import com.android.systemui.R; 29 30 public class AuthBiometricFingerprintView extends AuthBiometricView { 31 32 private static final String TAG = "BiometricPrompt/AuthBiometricFingerprintView"; 33 AuthBiometricFingerprintView(Context context)34 public AuthBiometricFingerprintView(Context context) { 35 this(context, null); 36 } 37 AuthBiometricFingerprintView(Context context, AttributeSet attrs)38 public AuthBiometricFingerprintView(Context context, AttributeSet attrs) { 39 super(context, attrs); 40 } 41 42 @Override getDelayAfterAuthenticatedDurationMs()43 protected int getDelayAfterAuthenticatedDurationMs() { 44 return 0; 45 } 46 47 @Override getStateForAfterError()48 protected int getStateForAfterError() { 49 return STATE_AUTHENTICATING; 50 } 51 52 @Override handleResetAfterError()53 protected void handleResetAfterError() { 54 showTouchSensorString(); 55 } 56 57 @Override handleResetAfterHelp()58 protected void handleResetAfterHelp() { 59 showTouchSensorString(); 60 } 61 62 @Override supportsSmallDialog()63 protected boolean supportsSmallDialog() { 64 return false; 65 } 66 67 @Override updateState(@iometricState int newState)68 public void updateState(@BiometricState int newState) { 69 updateIcon(mState, newState); 70 71 // Do this last since the state variable gets updated. 72 super.updateState(newState); 73 } 74 75 @Override onAttachedToWindowInternal()76 void onAttachedToWindowInternal() { 77 super.onAttachedToWindowInternal(); 78 showTouchSensorString(); 79 } 80 showTouchSensorString()81 private void showTouchSensorString() { 82 mIndicatorView.setText(R.string.fingerprint_dialog_touch_sensor); 83 mIndicatorView.setTextColor(mTextColorHint); 84 } 85 updateIcon(int lastState, int newState)86 private void updateIcon(int lastState, int newState) { 87 final Drawable icon = getAnimationForTransition(lastState, newState); 88 if (icon == null) { 89 Log.e(TAG, "Animation not found, " + lastState + " -> " + newState); 90 return; 91 } 92 93 final AnimatedVectorDrawable animation = icon instanceof AnimatedVectorDrawable 94 ? (AnimatedVectorDrawable) icon 95 : null; 96 97 mIconView.setImageDrawable(icon); 98 99 final CharSequence iconContentDescription = getIconContentDescription(newState); 100 if (iconContentDescription != null) { 101 mIconView.setContentDescription(iconContentDescription); 102 } 103 104 if (animation != null && shouldAnimateForTransition(lastState, newState)) { 105 animation.forceAnimationOnUI(); 106 animation.start(); 107 } 108 } 109 110 @Nullable getIconContentDescription(int newState)111 private CharSequence getIconContentDescription(int newState) { 112 switch (newState) { 113 case STATE_IDLE: 114 case STATE_AUTHENTICATING_ANIMATING_IN: 115 case STATE_AUTHENTICATING: 116 case STATE_PENDING_CONFIRMATION: 117 case STATE_AUTHENTICATED: 118 return mContext.getString( 119 R.string.accessibility_fingerprint_dialog_fingerprint_icon); 120 121 case STATE_ERROR: 122 case STATE_HELP: 123 return mContext.getString(R.string.biometric_dialog_try_again); 124 125 default: 126 return null; 127 } 128 } 129 shouldAnimateForTransition(int oldState, int newState)130 private boolean shouldAnimateForTransition(int oldState, int newState) { 131 switch (newState) { 132 case STATE_HELP: 133 case STATE_ERROR: 134 return true; 135 case STATE_AUTHENTICATING_ANIMATING_IN: 136 case STATE_AUTHENTICATING: 137 if (oldState == STATE_ERROR || oldState == STATE_HELP) { 138 return true; 139 } else { 140 return false; 141 } 142 case STATE_AUTHENTICATED: 143 return false; 144 default: 145 return false; 146 } 147 } 148 getAnimationForTransition(int oldState, int newState)149 private Drawable getAnimationForTransition(int oldState, int newState) { 150 int iconRes; 151 152 switch (newState) { 153 case STATE_HELP: 154 case STATE_ERROR: 155 iconRes = R.drawable.fingerprint_dialog_fp_to_error; 156 break; 157 case STATE_AUTHENTICATING_ANIMATING_IN: 158 case STATE_AUTHENTICATING: 159 if (oldState == STATE_ERROR || oldState == STATE_HELP) { 160 iconRes = R.drawable.fingerprint_dialog_error_to_fp; 161 } else { 162 iconRes = R.drawable.fingerprint_dialog_fp_to_error; 163 } 164 break; 165 case STATE_AUTHENTICATED: 166 iconRes = R.drawable.fingerprint_dialog_fp_to_error; 167 break; 168 default: 169 return null; 170 } 171 172 return mContext.getDrawable(iconRes); 173 } 174 } 175