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 17 package com.android.server.biometrics; 18 19 import static android.hardware.biometrics.BiometricManager.Authenticators; 20 21 import android.annotation.IntDef; 22 import android.annotation.NonNull; 23 import android.content.Context; 24 import android.hardware.biometrics.BiometricConstants; 25 import android.hardware.biometrics.IBiometricAuthenticator; 26 import android.hardware.biometrics.IBiometricSensorReceiver; 27 import android.os.IBinder; 28 import android.os.RemoteException; 29 import android.util.Slog; 30 31 import java.lang.annotation.Retention; 32 import java.lang.annotation.RetentionPolicy; 33 34 /** 35 * Wraps IBiometricAuthenticator implementation and stores information about the authenticator, 36 * including its current state. 37 * TODO(b/141025588): Consider refactoring the tests to not rely on this implementation detail. 38 */ 39 public abstract class BiometricSensor { 40 private static final String TAG = "BiometricService/Sensor"; 41 42 // State is unknown. Usually this means we need the sensor but have not requested for 43 // it to be used yet (cookie not sent yet) 44 static final int STATE_UNKNOWN = 0; 45 // Cookie has been generated, and the relevant sensor service has been asked to prepare 46 // for authentication. Awaiting "ack" from the sensor. 47 static final int STATE_WAITING_FOR_COOKIE = 1; 48 // The appropriate sensor service has "acked" notifying us that it's ready to be 49 // started for authentication. 50 static final int STATE_COOKIE_RETURNED = 2; 51 // The sensor is being used for authentication. 52 static final int STATE_AUTHENTICATING = 3; 53 // Cancel has been requested, waiting for ERROR_CANCELED to be received from the HAL 54 static final int STATE_CANCELING = 4; 55 static final int STATE_STOPPED = 5; 56 57 @IntDef({STATE_UNKNOWN, 58 STATE_WAITING_FOR_COOKIE, 59 STATE_COOKIE_RETURNED, 60 STATE_AUTHENTICATING, 61 STATE_CANCELING, 62 STATE_STOPPED}) 63 @Retention(RetentionPolicy.SOURCE) 64 @interface SensorState {} 65 66 @NonNull private final Context mContext; 67 public final int id; 68 public final @Authenticators.Types int oemStrength; // strength as configured by the OEM 69 public final int modality; 70 public final IBiometricAuthenticator impl; 71 72 private @Authenticators.Types int mUpdatedStrength; // updated by BiometricStrengthController 73 private @SensorState int mSensorState; 74 private @BiometricConstants.Errors int mError; 75 76 private int mCookie; // invalid during STATE_UNKNOWN 77 78 /** 79 * @return true if the user's system settings specifies that this sensor always requires 80 * confirmation. 81 */ confirmationAlwaysRequired(int userId)82 abstract boolean confirmationAlwaysRequired(int userId); 83 84 /** 85 * @return true if confirmation is supported by this sensor. 86 */ confirmationSupported()87 abstract boolean confirmationSupported(); 88 BiometricSensor(@onNull Context context, int id, int modality, @Authenticators.Types int strength, IBiometricAuthenticator impl)89 BiometricSensor(@NonNull Context context, int id, int modality, 90 @Authenticators.Types int strength, IBiometricAuthenticator impl) { 91 this.mContext = context; 92 this.id = id; 93 this.modality = modality; 94 this.oemStrength = strength; 95 this.impl = impl; 96 97 mUpdatedStrength = strength; 98 goToStateUnknown(); 99 } 100 goToStateUnknown()101 void goToStateUnknown() { 102 mSensorState = STATE_UNKNOWN; 103 mCookie = 0; 104 mError = BiometricConstants.BIOMETRIC_SUCCESS; 105 } 106 goToStateWaitingForCookie(boolean requireConfirmation, IBinder token, long sessionId, int userId, IBiometricSensorReceiver sensorReceiver, String opPackageName, long requestId, int cookie, boolean allowBackgroundAuthentication, boolean isForLegacyFingerprintManager, boolean isMandatoryBiometrics)107 void goToStateWaitingForCookie(boolean requireConfirmation, IBinder token, long sessionId, 108 int userId, IBiometricSensorReceiver sensorReceiver, String opPackageName, 109 long requestId, int cookie, boolean allowBackgroundAuthentication, 110 boolean isForLegacyFingerprintManager, boolean isMandatoryBiometrics) 111 throws RemoteException { 112 mCookie = cookie; 113 impl.prepareForAuthentication(requireConfirmation, token, 114 sessionId, userId, sensorReceiver, opPackageName, requestId, mCookie, 115 allowBackgroundAuthentication, isForLegacyFingerprintManager, 116 isMandatoryBiometrics); 117 mSensorState = STATE_WAITING_FOR_COOKIE; 118 } 119 goToStateCookieReturnedIfCookieMatches(int cookie)120 void goToStateCookieReturnedIfCookieMatches(int cookie) { 121 if (cookie == mCookie) { 122 Slog.d(TAG, "Sensor(" + id + ") matched cookie: " + cookie); 123 mSensorState = STATE_COOKIE_RETURNED; 124 } 125 } 126 startSensor()127 void startSensor() throws RemoteException { 128 impl.startPreparedClient(mCookie); 129 mSensorState = STATE_AUTHENTICATING; 130 } 131 goToStateCancelling(IBinder token, String opPackageName, long requestId)132 void goToStateCancelling(IBinder token, String opPackageName, long requestId) 133 throws RemoteException { 134 if (mSensorState != STATE_CANCELING) { 135 impl.cancelAuthenticationFromService(token, opPackageName, requestId); 136 mSensorState = STATE_CANCELING; 137 } 138 } 139 goToStoppedStateIfCookieMatches(int cookie, int error)140 void goToStoppedStateIfCookieMatches(int cookie, int error) { 141 if (cookie == mCookie) { 142 Slog.d(TAG, "Sensor(" + id + ") now in STATE_STOPPED"); 143 mError = error; 144 mSensorState = STATE_STOPPED; 145 } 146 } 147 148 /** 149 * Returns the actual strength, taking any updated strengths into effect. Since more bits 150 * means lower strength, the resulting strength is never stronger than the OEM's configured 151 * strength. 152 * @return a bitfield, see {@link android.hardware.biometrics.BiometricManager.Authenticators} 153 */ getCurrentStrength()154 @Authenticators.Types int getCurrentStrength() { 155 return oemStrength | mUpdatedStrength; 156 } 157 getSensorState()158 @SensorState int getSensorState() { 159 return mSensorState; 160 } 161 getCookie()162 int getCookie() { 163 return mCookie; 164 } 165 166 /** 167 * Stores the updated strength, which takes effect whenever {@link #getCurrentStrength()} 168 * is checked. 169 * @param newStrength 170 */ updateStrength(@uthenticators.Types int newStrength)171 void updateStrength(@Authenticators.Types int newStrength) { 172 String log = "updateStrength: Before(" + this + ")"; 173 mUpdatedStrength = newStrength; 174 log += " After(" + this + ")"; 175 Slog.d(TAG, log); 176 } 177 178 @Override toString()179 public String toString() { 180 return "ID(" + id + ")" 181 + ", oemStrength: " + oemStrength 182 + ", updatedStrength: " + mUpdatedStrength 183 + ", modality " + modality 184 + ", state: " + mSensorState 185 + ", cookie: " + mCookie; 186 } 187 } 188