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.server.biometrics.sensors.fingerprint; 18 19 import static android.hardware.fingerprint.FingerprintStateListener.STATE_AUTH_OTHER; 20 import static android.hardware.fingerprint.FingerprintStateListener.STATE_BP_AUTH; 21 import static android.hardware.fingerprint.FingerprintStateListener.STATE_ENROLLING; 22 import static android.hardware.fingerprint.FingerprintStateListener.STATE_IDLE; 23 import static android.hardware.fingerprint.FingerprintStateListener.STATE_KEYGUARD_AUTH; 24 25 import android.annotation.NonNull; 26 import android.hardware.fingerprint.FingerprintStateListener; 27 import android.hardware.fingerprint.IFingerprintStateListener; 28 import android.os.RemoteException; 29 import android.util.Slog; 30 31 import com.android.server.biometrics.Utils; 32 import com.android.server.biometrics.sensors.AuthenticationClient; 33 import com.android.server.biometrics.sensors.BaseClientMonitor; 34 import com.android.server.biometrics.sensors.EnrollClient; 35 import com.android.server.biometrics.sensors.EnrollmentModifier; 36 37 import java.util.concurrent.CopyOnWriteArrayList; 38 39 /** 40 * A callback for receiving notifications about changes in fingerprint state. 41 */ 42 public class FingerprintStateCallback implements BaseClientMonitor.Callback { 43 44 @NonNull private final CopyOnWriteArrayList<IFingerprintStateListener> 45 mFingerprintStateListeners = new CopyOnWriteArrayList<>(); 46 47 private @FingerprintStateListener.State int mFingerprintState; 48 FingerprintStateCallback()49 public FingerprintStateCallback() { 50 mFingerprintState = STATE_IDLE; 51 } 52 getFingerprintState()53 public int getFingerprintState() { 54 return mFingerprintState; 55 } 56 57 @Override onClientStarted(@onNull BaseClientMonitor client)58 public void onClientStarted(@NonNull BaseClientMonitor client) { 59 final int previousFingerprintState = mFingerprintState; 60 61 if (client instanceof AuthenticationClient) { 62 final AuthenticationClient<?> authClient = (AuthenticationClient<?>) client; 63 if (authClient.isKeyguard()) { 64 mFingerprintState = STATE_KEYGUARD_AUTH; 65 } else if (authClient.isBiometricPrompt()) { 66 mFingerprintState = STATE_BP_AUTH; 67 } else { 68 mFingerprintState = STATE_AUTH_OTHER; 69 } 70 } else if (client instanceof EnrollClient) { 71 mFingerprintState = STATE_ENROLLING; 72 } else { 73 Slog.w(FingerprintService.TAG, 74 "Other authentication client: " + Utils.getClientName(client)); 75 mFingerprintState = STATE_IDLE; 76 } 77 78 Slog.d(FingerprintService.TAG, "Fps state updated from " + previousFingerprintState 79 + " to " + mFingerprintState + ", client " + client); 80 notifyFingerprintStateListeners(mFingerprintState); 81 } 82 83 @Override onClientFinished(@onNull BaseClientMonitor client, boolean success)84 public void onClientFinished(@NonNull BaseClientMonitor client, boolean success) { 85 mFingerprintState = STATE_IDLE; 86 Slog.d(FingerprintService.TAG, 87 "Client finished, fps state updated to " + mFingerprintState + ", client " 88 + client); 89 90 if (client instanceof EnrollmentModifier) { 91 EnrollmentModifier enrollmentModifier = (EnrollmentModifier) client; 92 final boolean enrollmentStateChanged = enrollmentModifier.hasEnrollmentStateChanged(); 93 Slog.d(FingerprintService.TAG, "Enrollment state changed: " + enrollmentStateChanged); 94 if (enrollmentStateChanged) { 95 notifyAllFingerprintEnrollmentStateChanged(client.getTargetUserId(), 96 client.getSensorId(), 97 enrollmentModifier.hasEnrollments()); 98 } 99 } 100 101 notifyFingerprintStateListeners(mFingerprintState); 102 } 103 notifyFingerprintStateListeners(@ingerprintStateListener.State int newState)104 private void notifyFingerprintStateListeners(@FingerprintStateListener.State int newState) { 105 for (IFingerprintStateListener listener : mFingerprintStateListeners) { 106 try { 107 listener.onStateChanged(newState); 108 } catch (RemoteException e) { 109 Slog.e(FingerprintService.TAG, "Remote exception in fingerprint state change", e); 110 } 111 } 112 } 113 114 /** 115 * This should be invoked when: 116 * 1) Enrolled --> None-enrolled 117 * 2) None-enrolled --> enrolled 118 * 3) HAL becomes ready 119 * 4) Listener is registered 120 */ notifyAllFingerprintEnrollmentStateChanged(int userId, int sensorId, boolean hasEnrollments)121 void notifyAllFingerprintEnrollmentStateChanged(int userId, int sensorId, 122 boolean hasEnrollments) { 123 for (IFingerprintStateListener listener : mFingerprintStateListeners) { 124 notifyFingerprintEnrollmentStateChanged(listener, userId, sensorId, hasEnrollments); 125 } 126 } 127 128 /** 129 * Notifies the listener of enrollment state changes. 130 */ notifyFingerprintEnrollmentStateChanged(@onNull IFingerprintStateListener listener, int userId, int sensorId, boolean hasEnrollments)131 void notifyFingerprintEnrollmentStateChanged(@NonNull IFingerprintStateListener listener, 132 int userId, int sensorId, boolean hasEnrollments) { 133 try { 134 listener.onEnrollmentsChanged(userId, sensorId, hasEnrollments); 135 } catch (RemoteException e) { 136 Slog.e(FingerprintService.TAG, "Remote exception", e); 137 } 138 } 139 140 /** 141 * Enables clients to register a FingerprintStateListener. Used by FingerprintService to forward 142 * updates in fingerprint sensor state to the SideFpNsEventHandler 143 * 144 * @param listener 145 */ registerFingerprintStateListener(@onNull IFingerprintStateListener listener)146 public void registerFingerprintStateListener(@NonNull IFingerprintStateListener listener) { 147 mFingerprintStateListeners.add(listener); 148 } 149 } 150