Move lockout callbacks to ISessionCallback

Also fixes backward compatibility for AcquiredInfo and Error
constants.

For lockout-related changes:
1) If a session doesn't exist, it means the framework (or higher)
   doesn't care about its lockout state.
2) This allows the ISession#authenticate lifecycle to be clearer,
   e.g. no need for ILockoutCallback#onLockoutTimed followed by
   ISessionCallback#onError(LOCKOUT)

Bug: 168842956
Bug: 168843220

Test: make -j android.hardware.biometrics.fingerprint-update-api
Test: make -j
Test: make -j VtsHalBiometricsFingerprintTargetTest
Change-Id: I0b7e7ab3b89d0d1d7647535af07766c493a2067b
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
index 329a35d..df30dca 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
@@ -24,6 +24,6 @@
   SENSOR_DIRTY = 3,
   TOO_SLOW = 4,
   TOO_FAST = 5,
-  START = 6,
-  VENDOR = 7,
+  VENDOR = 6,
+  START = 7,
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl
index 0298c12..6bd71b2 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl
@@ -18,13 +18,11 @@
 package android.hardware.biometrics.fingerprint;
 @Backing(type="byte") @VintfStability
 enum Error {
-  HW_UNAVAILABLE = 0,
-  UNABLE_TO_PROCESS = 1,
-  TIMEOUT = 2,
-  NO_SPACE = 3,
-  CANCELED = 4,
-  UNABLE_TO_REMOVE = 5,
-  LOCKOUT = 6,
-  LOCKOUT_PERMANENT = 7,
+  HW_UNAVAILABLE = 1,
+  UNABLE_TO_PROCESS = 2,
+  TIMEOUT = 3,
+  NO_SPACE = 4,
+  CANCELED = 5,
+  UNABLE_TO_REMOVE = 6,
   VENDOR = 8,
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
index 9cbf343..6ca6d16 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
@@ -20,7 +20,6 @@
 interface IFingerprint {
   android.hardware.biometrics.fingerprint.SensorProps[] getSensorProps();
   android.hardware.biometrics.fingerprint.ISession createSession(in int sensorId, in int userId, in android.hardware.biometrics.fingerprint.ISessionCallback cb);
-  void setLockoutCallback(in android.hardware.biometrics.fingerprint.ILockoutCallback cb);
   void generateChallenge(in int sensorId, in int userId, in int timeoutSec, in android.hardware.biometrics.fingerprint.IGenerateChallengeCallback cb);
   void revokeChallenge(in int sensorId, in int userId, in long challenge, in android.hardware.biometrics.fingerprint.IRevokeChallengeCallback cb);
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl
deleted file mode 100644
index 88aabbf..0000000
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.biometrics.fingerprint;
-@VintfStability
-interface ILockoutCallback {
-  oneway void onLockoutTimed(in int sensorId, in int userId, in long durationMillis);
-  oneway void onLockoutPermanent(in int sensorId, in int userId);
-  oneway void onLockoutCleared(in int sensorId, in int userId);
-}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
index cbac890..74ec077 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
@@ -24,6 +24,9 @@
   void onEnrollmentProgress(in int enrollmentId, int remaining);
   void onAuthenticationSucceeded(in int enrollmentId, in android.hardware.keymaster.HardwareAuthToken hat);
   void onAuthenticationFailed();
+  void onLockoutTimed(in long durationMillis);
+  void onLockoutPermanent();
+  void onLockoutCleared();
   void onInteractionDetected();
   void onEnrollmentsEnumerated(in int[] enrollmentIds);
   void onEnrollmentsRemoved(in int[] enrollmentIds);
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
index a3259f6..adb1c78 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
@@ -50,6 +50,12 @@
     TOO_FAST,
 
     /**
+     * Vendor-specific acquisition message. See ISessionCallback#onAcquired vendorCode
+     * documentation.
+     */
+    VENDOR,
+
+    /**
      * This message represents the earliest message sent at the beginning of the authentication
      * pipeline. It is expected to be used to measure latency. For example, in a camera-based
      * authentication system it's expected to be sent prior to camera initialization. Note this
@@ -57,11 +63,5 @@
      * latency based on the time between the last START message and the onAuthenticated callback.
      */
     START,
-
-    /**
-     * Vendor-specific acquisition message. See ISessionCallback#onAcquired vendorCode
-     * documentation.
-     */
-    VENDOR
 }
 
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl
index da5ee18..014a4c0 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl
@@ -20,10 +20,15 @@
 @Backing(type="byte")
 enum Error {
     /**
+     * Used for testing, and to keep subsequent numbering consistent with older HIDLs.
+     */
+    // NO_ERROR = 0,
+
+    /**
      * A hardware error has occurred that cannot be resolved. For example, I2C failure or a broken
      * sensor.
      */
-    HW_UNAVAILABLE,
+    HW_UNAVAILABLE = 1,
 
     /**
      * The implementation is unable to process the request. For example, invalid arguments were
@@ -53,21 +58,19 @@
     UNABLE_TO_REMOVE,
 
     /**
-     * Authentication is locked out due to too many unsuccessful attempts. This is a rate-limiting
-     * lockout, and authentication can be restarted after a period of time. See the Android CDD for
-     * the full set of lockout and rate-limiting requirements.
+     * Reserved to maintain backwards compatibility. See ISessionCallback#onLockoutTimed instead.
      */
-    LOCKOUT,
-
-    /**
-     * Authenticatio nis disabled until the user unlocks with their device credential
-     * (PIN/Pattern/Password). See ISession#resetLockout.
-     */
-    LOCKOUT_PERMANENT,
+    // LOCKOUT = 7,
 
     /**
      * Used to enable vendor-specific error messages.
      */
-    VENDOR,
+    VENDOR = 8,
+
+    /**
+     * Reserved to maintain backwards compatibility. See ISessionCallback#onLockoutPermanent
+     * instead.
+     */
+    // LOCKOUT_PERMANENT = 9,
 }
 
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl
index 57319b2..0c8ebc5 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl
@@ -17,7 +17,6 @@
 package android.hardware.biometrics.fingerprint;
 
 import android.hardware.biometrics.fingerprint.IGenerateChallengeCallback;
-import android.hardware.biometrics.fingerprint.ILockoutCallback;
 import android.hardware.biometrics.fingerprint.IRevokeChallengeCallback;
 import android.hardware.biometrics.fingerprint.ISession;
 import android.hardware.biometrics.fingerprint.ISessionCallback;
@@ -73,36 +72,6 @@
     ISession createSession(in int sensorId, in int userId, in ISessionCallback cb);
 
     /**
-     * setLockoutCallback:
-     *
-     * Sets a callback to notify the framework lockout changes. Note
-     * that lockout is user AND sensor specific. In other words, there is a
-     * separate lockout state for each (user, sensor) pair. For example, the
-     * following is a valid state on a multi-sensor device:
-     * ------------------------------------------------------------------
-     * | SensorId | UserId | FailedAttempts | LockedOut | LockedUntil   |
-     * |----------|--------|----------------|-----------|---------------|
-     * | 0        | 0      | 1              | false     | x             |
-     * | 1        | 0      | 5              | true      | <future_time> |
-     * | 0        | 10     | 0              | false     | x             |
-     * | 1        | 10     | 0              | false     | x             |
-     * ------------------------------------------------------------------
-     *
-     * Lockout may be cleared in the following ways:
-     *   1) ISession#resetLockout
-     *   2) After a period of time, according to a rate-limiter.
-     *
-     * In addition, lockout states MUST persist after device reboots, HAL
-     * crashes, etc.
-     *
-     * See the Android CDD section 7.3.10 for the full set of lockout and
-     * rate-limiting requirements.
-     *
-     * @param cb Used to notify the framework of lockout changes.
-     */
-    void setLockoutCallback(in ILockoutCallback cb);
-
-    /**
      * generateChallenge:
      *
      * Begins a secure transaction request. Note that the challenge by itself
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl
deleted file mode 100644
index 43cb20f..0000000
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.biometrics.fingerprint;
-
-@VintfStability
-oneway interface ILockoutCallback {
-    /**
-     * Notifies the framework that the user has just entered the Error::LOCKOUT state. This must be
-     * sent in the following scenarios:
-     * 1) The user just attempted authentication and was rejected, resulting in a timed lockout.
-     * 2) The framework just created a session for a (sensorId, userId) pair that has not been
-     *    created since the HAL started (e.g. there is no active or idle session for this
-     *    (sensorId, userId) pair.
-     *
-     * @param sensorId Sensor for which the user is locked out.
-     * @param userId User for which the sensor is locked out.
-     * @param durationMillis Remaining duration of the lockout.
-     */
-    void onLockoutTimed(in int sensorId, in int userId, in long durationMillis);
-
-    /**
-     * Notifies the framework that the user has just entered the Error::LOCKOUT_PERMANENT state.
-     * This must be sent in the following scenarios:
-     * 1) The user just attempted authentication and was rejected, resulting in a permanent lockout.
-     * 2) The framework just created a session for a (sensorId, userId) pair that has not been
-     *    created since the HAL started (e.g. there is no active or idle session for this
-     *    (sensorId, userId) pair.
-     *
-     * @param sensorId Sensor for which the user is locked out.
-     * @param userId User for which the sensor is locked out.
-     */
-    void onLockoutPermanent(in int sensorId, in int userId);
-
-    /**
-     * Notifies the framework that lockout has been cleared for this (sensorId, userId) pair. This
-     * can happen in the following scenarios:
-     * 1) A timed lockout has ended (e.g. original durationMillis specified in #onLockoutTimed
-     *    has expired.
-     * 2) See ISession#resetLockout.
-     * 3) The (sensorId, userId) pair is not in any lockout state, and the user successfully
-     *    authenticated with a fingerprint.
-     *
-     * @param sensorId Sensor for which the user's lockout is cleared.
-     * @param userId User for the sensor's lockout is cleared.
-     */
-    void onLockoutCleared(in int sensorId, in int userId);
-}
-
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
index 946027b..d0f546a 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
@@ -95,55 +95,46 @@
      *
      * A request to start looking for fingerprints to authenticate.
      *
-     * Once the HAL is able to start processing the authentication request, it must
-     * notify framework via ISessionCallback#onStateChanged with
-     * SessionState::AUTHENTICATING.
+     * Once the HAL is able to start processing the authentication request, it must notify framework
+     * via ISessionCallback#onStateChanged with SessionState::AUTHENTICATING.
      *
-     * At any point during authentication, if a non-recoverable error occurs,
-     * the HAL must notify the framework via ISessionCallback#onError with
-     * the applicable authentication-specific error, and then send
-     * ISessionCallback#onStateChanged(cookie, SessionState::IDLING) if no
+     * At any point during authentication, if a non-recoverable error occurs, the HAL must notify
+     * the framework via ISessionCallback#onError with the applicable authentication-specific error,
+     * and then send ISessionCallback#onStateChanged(cookie, SessionState::IDLING) if no
      * subsequent operation is in the queue.
      *
-     * During authentication, the implementation may notify the framework
-     * via ISessionCallback#onAcquired with messages that may be used to guide
-     * the user. This callback can be invoked multiple times if necessary.
+     * During authentication, the implementation may notify the framework via
+     * ISessionCallback#onAcquired with messages that may be used to guide the user. This callback
+     * can be invoked multiple times if necessary.
      *
-     * The HAL must notify the framework of accepts/rejects via
-     * ISessionCallback#onAuthentication*.
+     * The HAL must notify the framework of accepts/rejects via ISessionCallback#onAuthentication*.
      *
      * The authentication lifecycle ends when either
-     *   1) A fingerprint is accepted, and ISessionCallback#onAuthenticationSucceeded
-     *      is invoked, or
-     *   2) Any non-recoverable error occurs (such as lockout). See the full
-     *      list of authentication-specific errors in the Error enum.
+     *   1) A fingerprint is accepted, and ISessionCallback#onAuthenticationSucceeded is invoked, or
+     *   2) Any non-recoverable error occurs (such as lockout). See the full list of
+     *      authentication-specific errors in the Error enum.
      *
-     * Note that it is now the HAL's responsibility to keep track of lockout
-     * states. See IFingerprint#setLockoutCallback and ISession#resetLockout.
+     * Note that upon successful authentication, the lockout counter for this (sensorId, userId)
+     * pair must be cleared.
      *
-     * Note that upon successful authentication, ONLY sensors configured as
-     * SensorStrength::STRONG are allowed to create and send a
-     * HardwareAuthToken to the framework. See the Android CDD for more
-     * details. For SensorStrength::STRONG sensors, the HardwareAuthToken's
-     * "challenge" field must be set with the operationId passed in during
-     * #authenticate. If the sensor is NOT SensorStrength::STRONG, the
-     * HardwareAuthToken MUST be null.
+     * Note that upon successful authentication, ONLY sensors configured as SensorStrength::STRONG
+     * are allowed to create and send a HardwareAuthToken to the framework. See the Android CDD for
+     * more details. For SensorStrength::STRONG sensors, the HardwareAuthToken's "challenge" field
+     * must be set with the operationId passed in during #authenticate. If the sensor is NOT
+     * SensorStrength::STRONG, the HardwareAuthToken MUST be null.
      *
-     * @param cookie An identifier used to track subsystem operations related
-     *               to this call path. The client must guarantee that it is
-     *               unique per ISession.
-     * @param operationId For sensors configured as SensorStrength::STRONG,
-     *                    this must be used ONLY upon successful authentication
-     *                    and wrapped in the HardwareAuthToken's "challenge"
-     *                    field and sent to the framework via
-     *                    ISessionCallback#onAuthenticated. The operationId is
-     *                    an opaque identifier created from a separate secure
-     *                    subsystem such as, but not limited to KeyStore/KeyMaster.
-     *                    The HardwareAuthToken can then be used as an attestation
-     *                    for the provided operation. For example, this is used
+     * @param cookie An identifier used to track subsystem operations related to this call path. The
+     *               client must guarantee that it is unique per ISession.
+     * @param operationId For sensors configured as SensorStrength::STRONG, this must be used ONLY
+     *                    upon successful authentication and wrapped in the HardwareAuthToken's
+     *                    "challenge" field and sent to the framework via
+     *                    ISessionCallback#onAuthenticated. The operationId is an opaque identifier
+     *                    created from a separate secure subsystem such as, but not limited to
+     *                    KeyStore/KeyMaster. The HardwareAuthToken can then be used as an
+     *                    attestation for the provided operation. For example, this is used
      *                    to unlock biometric-bound auth-per-use keys (see
-     *                    setUserAuthenticationParameters in
-     *                    KeyGenParameterSpec.Builder and KeyProtection.Builder.
+     *                    setUserAuthenticationParameters in KeyGenParameterSpec.Builder and
+     *                    KeyProtection.Builder.
      */
     ICancellationSignal authenticate(in int cookie, in long operationId);
 
@@ -300,17 +291,43 @@
     /**
      * resetLockout:
      *
-     * Requests the implementation to clear the lockout counter. Upon receiving
-     * this request, the implementation must perform the following:
+     * Requests the implementation to clear the lockout counter. Upon receiving this request, the
+     * implementation must perform the following:
      *   1) Verify the authenticity and integrity of the provided HAT
-     *   2) Verify that the timestamp provided within the HAT is relatively
-     *      recent (e.g. on the order of minutes, not hours).
-     * If either of the checks fail, the HAL must invoke ISessionCallback#onError
-     * with Error::UNABLE_TO_PROCESS and return to SessionState::IDLING
-     * if no subsequent work is in the queue.
+     *   2) Verify that the timestamp provided within the HAT is relatively recent (e.g. on the
+     *      order of minutes, not hours).
+     * If either of the checks fail, the HAL must invoke ISessionCallback#onError with
+     * Error::UNABLE_TO_PROCESS and return to SessionState::IDLING if no subsequent work is in the
+     * queue.
      *
-     * Upon successful verification, the HAL must clear the lockout counter
-     * and notify the framework via ILockoutCallback#onLockoutChanged(sensorId, userId, 0).
+     * Upon successful verification, the HAL must clear the lockout counter and notify the framework
+     * via ISessionCallback#onLockoutCleared.
+     *
+     * Note that lockout is user AND sensor specific. In other words, there is a separate lockout
+     * state for each (user, sensor) pair. For example, the following is a valid state on a
+     * multi-sensor device:
+     * ------------------------------------------------------------------
+     * | SensorId | UserId | FailedAttempts | LockedOut | LockedUntil   |
+     * |----------|--------|----------------|-----------|---------------|
+     * | 0        | 0      | 1              | false     | x             |
+     * | 1        | 0      | 5              | true      | <future_time> |
+     * | 0        | 10     | 0              | false     | x             |
+     * | 1        | 10     | 0              | false     | x             |
+     * ------------------------------------------------------------------
+     *
+     * Lockout may be cleared in the following ways:
+     *   1) ISession#resetLockout
+     *   2) After a period of time, according to a rate-limiter.
+     *
+     * Note that the "FailedAttempts" counter must be cleared upon successful fingerprint
+     * authentication. For example, if SensorId=0 UserId=0 FailedAttempts=1, and a successful
+     * fingerprint authentication occurs, the counter for that (SensorId, UserId) pair must be reset
+     * to 0.
+     *
+     * In addition, lockout states MUST persist after device reboots, HAL crashes, etc.
+     *
+     * See the Android CDD section 7.3.10 for the full set of lockout and rate-limiting
+     * requirements.
      *
      * @param cookie An identifier used to track subsystem operations related
      *               to this call path. The client must guarantee that it is
@@ -319,7 +336,6 @@
      */
     void resetLockout(in int cookie, in HardwareAuthToken hat);
 
-
     /**
      * Methods for notifying the under-display fingerprint sensor about external events.
      */
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
index 81a87a8..33a93e5 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
@@ -76,9 +76,8 @@
      * This method must only be used to notify the framework during SessionState::AUTHENTICATING.
      *
      * Used to notify the framework upon successful authentication. Note that the authentication
-     * lifecycle ends when either 1) a fingerprint is accepted, or 2) an error such as
-     * Error::LOCKOUT occurred. The authentication lifecycle does NOT end when a fingerprint is
-     * rejected.
+     * lifecycle ends when either 1) a fingerprint is accepted, or 2) an error occurred. The
+     * authentication lifecycle does NOT end when a fingerprint is rejected.
      *
      * @param enrollmentId Fingerprint that was accepted.
      * @param hat If the sensor is configured as SensorStrength::STRONG, a non-null attestation that
@@ -92,13 +91,51 @@
      * This method must only be used to notify the framework during SessionState::AUTHENTICATING.
      *
      * Used to notify the framework upon rejected attempts. Note that the authentication
-     * lifecycle ends when either 1) a fingerprint is accepted, or 2) an error such as
-     * Error::LOCKOUT occurred. The authentication lifecycle does NOT end when a fingerprint is
-     * rejected.
+     * lifecycle ends when either 1) a fingerprint is accepted, or 2) an occurred. The
+     * authentication lifecycle does NOT end when a fingerprint is rejected.
      */
     void onAuthenticationFailed();
 
     /**
+     * This method must only be used to notify the framework during SessionState::AUTHENTICATING.
+     *
+     * Authentication is locked out due to too many unsuccessful attempts. This is a rate-limiting
+     * lockout, and authentication can be restarted after a period of time. See
+     * ISession#resetLockout.
+     *
+     * @param sensorId Sensor for which the user is locked out.
+     * @param userId User for which the sensor is locked out.
+     * @param durationMillis Remaining duration of the lockout.
+     */
+    void onLockoutTimed(in long durationMillis);
+
+    /**
+     * This method must only be used to notify the framework during SessionState::AUTHENTICATING.
+     *
+     * Authentication is disabled until the user unlocks with their device credential
+     * (PIN/Pattern/Password). See ISession#resetLockout.
+     *
+     * @param sensorId Sensor for which the user is locked out.
+     * @param userId User for which the sensor is locked out.
+     */
+    void onLockoutPermanent();
+
+    /**
+     * Notifies the framework that lockout has been cleared for this (sensorId, userId) pair.
+     *
+     * Note that this method can be used to notify the framework during any state.
+     *
+     * Lockout can be cleared in the following scenarios:
+     * 1) A timed lockout has ended (e.g. durationMillis specified in previous #onLockoutTimed
+     *    has expired.
+     * 2) See ISession#resetLockout.
+     *
+     * @param sensorId Sensor for which the user's lockout is cleared.
+     * @param userId User for the sensor's lockout is cleared.
+     */
+    void onLockoutCleared();
+
+    /**
      * This method must only be used to notify the framework during
      * SessionState::DETECTING_INTERACTION
      *
diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp
index b3bd4e7..b907bf1 100644
--- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp
+++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp
@@ -61,11 +61,6 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Fingerprint::setLockoutCallback(
-        const std::shared_ptr<ILockoutCallback>& /*cb*/) {
-    return ndk::ScopedAStatus::ok();
-}
-
 ndk::ScopedAStatus Fingerprint::generateChallenge(
         int32_t /*sensorId*/, int32_t /*userId*/, int32_t /*timeoutSec*/,
         const std::shared_ptr<IGenerateChallengeCallback>& /*cb*/) {
diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.h b/biometrics/fingerprint/aidl/default/Fingerprint.h
index 463d07d..59cdd44 100644
--- a/biometrics/fingerprint/aidl/default/Fingerprint.h
+++ b/biometrics/fingerprint/aidl/default/Fingerprint.h
@@ -28,9 +28,6 @@
                                      const std::shared_ptr<ISessionCallback>& cb,
                                      std::shared_ptr<ISession>* _aidl_return) override;
 
-    ndk::ScopedAStatus setLockoutCallback(
-            const std::shared_ptr<ILockoutCallback>& cb) override;
-
     ndk::ScopedAStatus generateChallenge(
             int32_t sensorId, int32_t userId, int32_t timeoutSec,
             const std::shared_ptr<IGenerateChallengeCallback>& cb) override;
diff --git a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp
index 3011786..496badc 100644
--- a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp
+++ b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp
@@ -74,6 +74,18 @@
         return ndk::ScopedAStatus::ok();
     }
 
+    ndk::ScopedAStatus onLockoutTimed(int64_t /*durationMillis*/) override {
+        return ndk::ScopedAStatus::ok();
+    }
+
+    ndk::ScopedAStatus onLockoutPermanent() override {
+        return ndk::ScopedAStatus::ok();
+    }
+
+    ndk::ScopedAStatus onLockoutCleared() override {
+        return ndk::ScopedAStatus::ok();
+    }
+
     ndk::ScopedAStatus onInteractionDetected() override { return ndk::ScopedAStatus::ok(); }
 
     ndk::ScopedAStatus onEnrollmentsEnumerated(