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 package com.android.systemui.biometrics
17 
18 import android.content.Context
19 import android.hardware.biometrics.BiometricAuthenticator.Modality
20 import android.util.AttributeSet
21 
22 /** Face only view for BiometricPrompt. */
23 class AuthBiometricFaceView(
24     context: Context,
25     attrs: AttributeSet? = null
26 ) : AuthBiometricView(context, attrs) {
27 
28     override fun getDelayAfterAuthenticatedDurationMs() = HIDE_DELAY_MS
29 
30     override fun getStateForAfterError() = STATE_IDLE
31 
32     override fun handleResetAfterError() = resetErrorView()
33 
34     override fun handleResetAfterHelp() = resetErrorView()
35 
36     override fun supportsSmallDialog() = true
37 
38     override fun supportsManualRetry() = true
39 
40     override fun supportsRequireConfirmation() = true
41 
42     override fun createIconController(): AuthIconController =
43         AuthBiometricFaceIconController(mContext, mIconView)
44 
45     override fun updateState(@BiometricState newState: Int) {
46         if (newState == STATE_AUTHENTICATING_ANIMATING_IN ||
47             newState == STATE_AUTHENTICATING && size == AuthDialog.SIZE_MEDIUM) {
48             resetErrorView()
49         }
50 
51         // Do this last since the state variable gets updated.
52         super.updateState(newState)
53     }
54 
55     override fun onAuthenticationFailed(
56         @Modality modality: Int,
57         failureReason: String?
58     ) {
59         if (size == AuthDialog.SIZE_MEDIUM) {
60             if (supportsManualRetry()) {
61                 mTryAgainButton.visibility = VISIBLE
62                 mConfirmButton.visibility = GONE
63             }
64         }
65 
66         // Do this last since we want to know if the button is being animated (in the case of
67         // small -> medium dialog)
68         super.onAuthenticationFailed(modality, failureReason)
69     }
70 
71     private fun resetErrorView() {
72         mIndicatorView.setTextColor(mTextColorHint)
73         mIndicatorView.visibility = INVISIBLE
74     }
75 
76     companion object {
77         /** Delay before dismissing after being authenticated/confirmed. */
78         const val HIDE_DELAY_MS = 500
79     }
80 }
81