Merge "Update comments of RegState.REG_EM" into main-ims-dev
diff --git a/audio/aidl/Android.bp b/audio/aidl/Android.bp
index d6e6f50..4871058 100644
--- a/audio/aidl/Android.bp
+++ b/audio/aidl/Android.bp
@@ -100,6 +100,7 @@
         "android/hardware/audio/core/MmapBufferDescriptor.aidl",
         "android/hardware/audio/core/ModuleDebug.aidl",
         "android/hardware/audio/core/StreamDescriptor.aidl",
+        "android/hardware/audio/core/SurroundSoundConfig.aidl",
     ],
     imports: [
         "android.hardware.common-V2",
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IConfig.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IConfig.aidl
index fd80715..163b7a0 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IConfig.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IConfig.aidl
@@ -34,4 +34,5 @@
 package android.hardware.audio.core;
 @VintfStability
 interface IConfig {
+  android.hardware.audio.core.SurroundSoundConfig getSurroundSoundConfig();
 }
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/SurroundSoundConfig.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/SurroundSoundConfig.aidl
new file mode 100644
index 0000000..08a1537
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/SurroundSoundConfig.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file 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.audio.core;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable SurroundSoundConfig {
+  android.hardware.audio.core.SurroundSoundConfig.SurroundFormatFamily[] formatFamilies;
+  @VintfStability
+  parcelable SurroundFormatFamily {
+    android.media.audio.common.AudioFormatDescription primaryFormat;
+    android.media.audio.common.AudioFormatDescription[] subFormats;
+  }
+}
diff --git a/audio/aidl/android/hardware/audio/core/IConfig.aidl b/audio/aidl/android/hardware/audio/core/IConfig.aidl
index c7bb414..c8ba6be 100644
--- a/audio/aidl/android/hardware/audio/core/IConfig.aidl
+++ b/audio/aidl/android/hardware/audio/core/IConfig.aidl
@@ -16,9 +16,22 @@
 
 package android.hardware.audio.core;
 
+import android.hardware.audio.core.SurroundSoundConfig;
+
 /**
  * This interface provides system-wide configuration parameters for audio I/O
  * (by "system" here we mean the device running Android).
  */
 @VintfStability
-interface IConfig {}
+interface IConfig {
+    /**
+     * Returns the surround sound configuration used for the Audio Policy
+     * Manager initial configuration.
+     *
+     * This method will only be called during the initialization of the Audio
+     * Policy Manager, and must always return the same result.
+     *
+     * @return The surround sound configuration
+     */
+    SurroundSoundConfig getSurroundSoundConfig();
+}
diff --git a/audio/aidl/android/hardware/audio/core/SurroundSoundConfig.aidl b/audio/aidl/android/hardware/audio/core/SurroundSoundConfig.aidl
new file mode 100644
index 0000000..eeda12a
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/SurroundSoundConfig.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 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.audio.core;
+
+import android.media.audio.common.AudioFormatDescription;
+
+/**
+ * SurroundSoundConfig defines the multi-channel formats that can be enabled on
+ * (primarily TV) devices.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable SurroundSoundConfig {
+    @VintfStability
+    parcelable SurroundFormatFamily {
+        /**
+         * A primaryFormat shall get an entry in the Surround Settings dialog on TV
+         * devices. There must be a corresponding Java ENCODING_... constant
+         * defined in AudioFormat.java, and a display name defined in
+         * AudioFormat.toDisplayName.
+         */
+        AudioFormatDescription primaryFormat;
+        /**
+         * List of formats that shall be equivalent to the primaryFormat from the
+         * users' point of view and don't need a dedicated Surround Settings
+         * dialog entry.
+         */
+        AudioFormatDescription[] subFormats;
+    }
+    SurroundFormatFamily[] formatFamilies;
+}
diff --git a/audio/aidl/default/Config.cpp b/audio/aidl/default/Config.cpp
index 3f7a3d3..0fdd5b4 100644
--- a/audio/aidl/default/Config.cpp
+++ b/audio/aidl/default/Config.cpp
@@ -13,7 +13,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#define LOG_TAG "AHAL_Module"
+#include <android-base/logging.h>
 
 #include "core-impl/Config.h"
 
-namespace aidl::android::hardware::audio::core {}  // namespace aidl::android::hardware::audio::core
+namespace aidl::android::hardware::audio::core {
+ndk::ScopedAStatus Config::getSurroundSoundConfig(SurroundSoundConfig* _aidl_return) {
+    SurroundSoundConfig surroundSoundConfig;
+    // TODO: parse from XML; for now, use empty config as default
+    *_aidl_return = std::move(surroundSoundConfig);
+    LOG(DEBUG) << __func__ << ": returning " << _aidl_return->toString();
+    return ndk::ScopedAStatus::ok();
+}
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/Config.h b/audio/aidl/default/include/core-impl/Config.h
index b62a14b..4555efd 100644
--- a/audio/aidl/default/include/core-impl/Config.h
+++ b/audio/aidl/default/include/core-impl/Config.h
@@ -20,6 +20,8 @@
 
 namespace aidl::android::hardware::audio::core {
 
-class Config : public BnConfig {};
+class Config : public BnConfig {
+    ndk::ScopedAStatus getSurroundSoundConfig(SurroundSoundConfig* _aidl_return) override;
+};
 
 }  // namespace aidl::android::hardware::audio::core
diff --git a/automotive/remoteaccess/hal/default/Android.bp b/automotive/remoteaccess/hal/default/Android.bp
index 51be330..a2bf86c 100644
--- a/automotive/remoteaccess/hal/default/Android.bp
+++ b/automotive/remoteaccess/hal/default/Android.bp
@@ -47,7 +47,7 @@
 
 cc_library {
     name: "RemoteAccessService",
-    vendor: true,
+    vendor_available: true,
     local_include_dirs: ["include"],
     export_include_dirs: ["include"],
     srcs: [
@@ -74,3 +74,36 @@
         "-Wno-unused-parameter",
     ],
 }
+
+cc_fuzz {
+    name: "android.hardware.automotive.remoteaccess@V1-default-service.aidl_fuzzer",
+    srcs: ["fuzzer/fuzzer.cpp"],
+    whole_static_libs: [
+        "RemoteAccessService",
+    ],
+    static_libs: [
+        "libgtest",
+        "libgmock",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "liblog",
+        "libutils",
+        "libgrpc++",
+        "libprotobuf-cpp-full",
+    ],
+    defaults: [
+        "vhalclient_defaults",
+        "service_fuzzer_defaults",
+    ],
+    cflags: [
+        "-Wno-unused-parameter",
+        "-DGRPC_SERVICE_ADDRESS=\"localhost:50051\"",
+    ],
+    fuzz_config: {
+        cc: [
+            "shanyu@google.com",
+        ],
+    },
+}
diff --git a/automotive/remoteaccess/hal/default/fuzzer/fuzzer.cpp b/automotive/remoteaccess/hal/default/fuzzer/fuzzer.cpp
new file mode 100644
index 0000000..292c80e
--- /dev/null
+++ b/automotive/remoteaccess/hal/default/fuzzer/fuzzer.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#include <RemoteAccessService.h>
+#include <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <gmock/gmock.h>
+#include <grpcpp/test/mock_stream.h>
+#include <wakeup_client.grpc.pb.h>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace remoteaccess {
+
+using ::grpc::ClientAsyncReaderInterface;
+using ::grpc::ClientAsyncResponseReaderInterface;
+using ::grpc::ClientContext;
+using ::grpc::ClientReader;
+using ::grpc::ClientReaderInterface;
+using ::grpc::CompletionQueue;
+using ::grpc::Status;
+using ::grpc::testing::MockClientReader;
+using ::testing::_;
+using ::testing::Return;
+
+class MockGrpcClientStub : public WakeupClient::StubInterface {
+  public:
+    ClientReaderInterface<GetRemoteTasksResponse>* GetRemoteTasksRaw(
+            [[maybe_unused]] ClientContext* context,
+            [[maybe_unused]] const GetRemoteTasksRequest& request) override {
+        MockClientReader<GetRemoteTasksResponse>* mockClientReader =
+                new MockClientReader<GetRemoteTasksResponse>();
+        ON_CALL(*mockClientReader, Finish()).WillByDefault(Return(Status::OK));
+        ON_CALL(*mockClientReader, Read(_)).WillByDefault(Return(false));
+        return mockClientReader;
+    }
+
+    Status NotifyWakeupRequired([[maybe_unused]] ClientContext* context,
+                                [[maybe_unused]] const NotifyWakeupRequiredRequest& request,
+                                [[maybe_unused]] NotifyWakeupRequiredResponse* response) {
+        return Status::OK;
+    }
+
+    // Async methods which we do not care.
+    ClientAsyncReaderInterface<GetRemoteTasksResponse>* AsyncGetRemoteTasksRaw(
+            [[maybe_unused]] ClientContext* context,
+            [[maybe_unused]] const GetRemoteTasksRequest& request,
+            [[maybe_unused]] CompletionQueue* cq, [[maybe_unused]] void* tag) {
+        return nullptr;
+    }
+
+    ClientAsyncReaderInterface<GetRemoteTasksResponse>* PrepareAsyncGetRemoteTasksRaw(
+            [[maybe_unused]] ClientContext* context,
+            [[maybe_unused]] const GetRemoteTasksRequest& request,
+            [[maybe_unused]] CompletionQueue* cq) {
+        return nullptr;
+    }
+
+    ClientAsyncResponseReaderInterface<NotifyWakeupRequiredResponse>* AsyncNotifyWakeupRequiredRaw(
+            [[maybe_unused]] ClientContext* context,
+            [[maybe_unused]] const NotifyWakeupRequiredRequest& request,
+            [[maybe_unused]] CompletionQueue* cq) {
+        return nullptr;
+    }
+
+    ClientAsyncResponseReaderInterface<NotifyWakeupRequiredResponse>*
+    PrepareAsyncNotifyWakeupRequiredRaw([[maybe_unused]] ClientContext* context,
+                                        [[maybe_unused]] const NotifyWakeupRequiredRequest& request,
+                                        [[maybe_unused]] CompletionQueue* c) {
+        return nullptr;
+    }
+};
+
+}  // namespace remoteaccess
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    android::hardware::automotive::remoteaccess::MockGrpcClientStub stub;
+    std::shared_ptr<android::hardware::automotive::remoteaccess::RemoteAccessService> service =
+            ndk::SharedRefBase::make<
+                    android::hardware::automotive::remoteaccess::RemoteAccessService>(&stub);
+    android::fuzzService(service->asBinder().get(), FuzzedDataProvider(data, size));
+
+    return 0;
+}
diff --git a/automotive/remoteaccess/hal/default/proto/Android.bp b/automotive/remoteaccess/hal/default/proto/Android.bp
index 31b9d0e..3e0dba1 100644
--- a/automotive/remoteaccess/hal/default/proto/Android.bp
+++ b/automotive/remoteaccess/hal/default/proto/Android.bp
@@ -35,7 +35,6 @@
         "wakeup_client.pb.h",
         "wakeup_client.grpc.pb.h",
     ],
-    vendor: true,
 }
 
 genrule {
@@ -52,12 +51,11 @@
         "wakeup_client.pb.cc",
         "wakeup_client.grpc.pb.cc",
     ],
-    vendor: true,
 }
 
 cc_library_static {
     name: "wakeup_client_protos",
-    vendor: true,
+    vendor_available: true,
     host_supported: true,
     include_dirs: [
         "external/protobuf/src",
diff --git a/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
index 72f37d7..5cd58d3 100644
--- a/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
+++ b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
@@ -174,6 +174,7 @@
 }
 
 ScopedAStatus RemoteAccessService::getDeviceId(std::string* deviceId) {
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
     auto vhalClient = IVhalClient::tryCreate();
     if (vhalClient == nullptr) {
         ALOGE("Failed to connect to VHAL");
@@ -181,6 +182,10 @@
                 /*errorCode=*/0, "Failed to connect to VHAL to get device ID");
     }
     return getDeviceIdWithClient(*vhalClient.get(), deviceId);
+#else
+    // Don't use VHAL client in fuzzing since IPC is not allowed.
+    return ScopedAStatus::ok();
+#endif
 }
 
 ScopedAStatus RemoteAccessService::getDeviceIdWithClient(IVhalClient& vhalClient,
diff --git a/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp b/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
index 68a1f26..651c9dc 100644
--- a/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
+++ b/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
@@ -56,43 +56,58 @@
         return;
     }
 
-    if (FingerprintHalProperties::operation_enroll_fails().value_or(false)) {
-        LOG(ERROR) << "Fail: operation_enroll_fails";
-        cb->onError(Error::VENDOR, 0 /* vendorError */);
+    // Force error-out
+    auto err = FingerprintHalProperties::operation_enroll_error().value_or(0);
+    if (err != 0) {
+        LOG(ERROR) << "Fail: operation_enroll_error";
+        auto ec = convertError(err);
+        cb->onError(ec.first, ec.second);
         return;
     }
 
-    // format is "<id>:<progress_ms>,<progress_ms>,...:<result>
+    // Format is "<id>:<progress_ms-[acquiredInfo..]>,...:<result>
     auto nextEnroll = FingerprintHalProperties::next_enrollment().value_or("");
     auto parts = Util::split(nextEnroll, ":");
     if (parts.size() != 3) {
-        LOG(ERROR) << "Fail: invalid next_enrollment";
+        LOG(ERROR) << "Fail: invalid next_enrollment:" << nextEnroll;
         cb->onError(Error::VENDOR, 0 /* vendorError */);
         return;
     }
     auto enrollmentId = std::stoi(parts[0]);
-    auto progress = Util::split(parts[1], ",");
-    for (size_t i = 0; i < progress.size(); i++) {
-        auto left = progress.size() - i - 1;
-        SLEEP_MS(std::stoi(progress[i]));
+    auto progress = parseEnrollmentCapture(parts[1]);
+    for (size_t i = 0; i < progress.size(); i += 2) {
+        auto left = (progress.size() - i) / 2 - 1;
+        auto duration = progress[i][0];
+        auto acquired = progress[i + 1];
+        auto N = acquired.size();
 
-        if (shouldCancel(cancel)) {
-            LOG(ERROR) << "Fail: cancel";
-            cb->onError(Error::CANCELED, 0 /* vendorCode */);
-            return;
+        for (int j = 0; j < N; j++) {
+            SLEEP_MS(duration / N);
+
+            if (shouldCancel(cancel)) {
+                LOG(ERROR) << "Fail: cancel";
+                cb->onError(Error::CANCELED, 0 /* vendorCode */);
+                return;
+            }
+            auto ac = convertAcquiredInfo(acquired[j]);
+            cb->onAcquired(ac.first, ac.second);
         }
 
-        cb->onAcquired(AcquiredInfo::GOOD, 0 /* vendorCode */);
         if (left == 0 && !IS_TRUE(parts[2])) {  // end and failed
             LOG(ERROR) << "Fail: requested by caller: " << nextEnroll;
             FingerprintHalProperties::next_enrollment({});
             cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorCode */);
         } else {  // progress and update props if last time
+            LOG(INFO) << "onEnroll: " << enrollmentId << " left: " << left;
             if (left == 0) {
                 auto enrollments = FingerprintHalProperties::enrollments();
                 enrollments.emplace_back(enrollmentId);
                 FingerprintHalProperties::enrollments(enrollments);
                 FingerprintHalProperties::next_enrollment({});
+                // change authenticatorId after new enrollment
+                auto id = FingerprintHalProperties::authenticator_id().value_or(0);
+                auto newId = id + 1;
+                FingerprintHalProperties::authenticator_id(newId);
                 LOG(INFO) << "Enrolled: " << enrollmentId;
             }
             cb->onEnrollmentProgress(enrollmentId, left);
@@ -104,12 +119,31 @@
                                              const std::future<void>& cancel) {
     BEGIN_OP(FingerprintHalProperties::operation_authenticate_latency().value_or(DEFAULT_LATENCY));
 
-    auto now = Util::getSystemNanoTime();
-    int64_t duration = FingerprintHalProperties::operation_authenticate_duration().value_or(0);
+    int64_t now = Util::getSystemNanoTime();
+    int64_t duration = FingerprintHalProperties::operation_authenticate_duration().value_or(10);
+    auto acquired = FingerprintHalProperties::operation_authenticate_acquired().value_or("1");
+    auto acquiredInfos = parseIntSequence(acquired);
+    int N = acquiredInfos.size();
+
+    if (N == 0) {
+        LOG(ERROR) << "Fail to parse authentiate acquired info: " + acquired;
+        cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+        return;
+    }
+
+    int i = 0;
     do {
         if (FingerprintHalProperties::operation_authenticate_fails().value_or(false)) {
             LOG(ERROR) << "Fail: operation_authenticate_fails";
-            cb->onError(Error::VENDOR, 0 /* vendorError */);
+            cb->onAuthenticationFailed();
+            return;
+        }
+
+        auto err = FingerprintHalProperties::operation_authenticate_error().value_or(0);
+        if (err != 0) {
+            LOG(ERROR) << "Fail: operation_authenticate_error";
+            auto ec = convertError(err);
+            cb->onError(ec.first, ec.second);
             return;
         }
 
@@ -126,20 +160,25 @@
             return;
         }
 
-        auto id = FingerprintHalProperties::enrollment_hit().value_or(0);
-        auto enrolls = FingerprintHalProperties::enrollments();
-        auto isEnrolled = std::find(enrolls.begin(), enrolls.end(), id) != enrolls.end();
-        if (id > 0 && isEnrolled) {
-            cb->onAuthenticationSucceeded(id, {} /* hat */);
-            return;
+        if (i < N) {
+            auto ac = convertAcquiredInfo(acquiredInfos[i]);
+            cb->onAcquired(ac.first, ac.second);
+            i++;
         }
 
-        SLEEP_MS(100);
+        SLEEP_MS(duration / N);
     } while (!Util::hasElapsed(now, duration));
 
-    LOG(ERROR) << "Fail: not enrolled";
-    cb->onAuthenticationFailed();
-    cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+    auto id = FingerprintHalProperties::enrollment_hit().value_or(0);
+    auto enrolls = FingerprintHalProperties::enrollments();
+    auto isEnrolled = std::find(enrolls.begin(), enrolls.end(), id) != enrolls.end();
+    if (id > 0 && isEnrolled) {
+        cb->onAuthenticationSucceeded(id, {} /* hat */);
+        return;
+    } else {
+        LOG(ERROR) << "Fail: fingerprint not enrolled";
+        cb->onAuthenticationFailed();
+    }
 }
 
 void FakeFingerprintEngine::detectInteractionImpl(ISessionCallback* cb,
@@ -147,17 +186,42 @@
     BEGIN_OP(FingerprintHalProperties::operation_detect_interaction_latency().value_or(
             DEFAULT_LATENCY));
 
-    if (FingerprintHalProperties::operation_detect_interaction_fails().value_or(false)) {
-        LOG(ERROR) << "Fail: operation_detect_interaction_fails";
-        cb->onError(Error::VENDOR, 0 /* vendorError */);
+    int64_t duration =
+            FingerprintHalProperties::operation_detect_interaction_duration().value_or(10);
+    auto acquired = FingerprintHalProperties::operation_detect_interaction_acquired().value_or("1");
+    auto acquiredInfos = parseIntSequence(acquired);
+    int N = acquiredInfos.size();
+    int64_t now = Util::getSystemNanoTime();
+
+    if (N == 0) {
+        LOG(ERROR) << "Fail to parse detect interaction acquired info: " + acquired;
+        cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
         return;
     }
 
-    if (shouldCancel(cancel)) {
-        LOG(ERROR) << "Fail: cancel";
-        cb->onError(Error::CANCELED, 0 /* vendorCode */);
-        return;
-    }
+    int i = 0;
+    do {
+        auto err = FingerprintHalProperties::operation_detect_interaction_error().value_or(0);
+        if (err != 0) {
+            LOG(ERROR) << "Fail: operation_detect_interaction_error";
+            auto ec = convertError(err);
+            cb->onError(ec.first, ec.second);
+            return;
+        }
+
+        if (shouldCancel(cancel)) {
+            LOG(ERROR) << "Fail: cancel";
+            cb->onError(Error::CANCELED, 0 /* vendorCode */);
+            return;
+        }
+
+        if (i < N) {
+            auto ac = convertAcquiredInfo(acquiredInfos[i]);
+            cb->onAcquired(ac.first, ac.second);
+            i++;
+        }
+        SLEEP_MS(duration / N);
+    } while (!Util::hasElapsed(now, duration));
 
     auto id = FingerprintHalProperties::enrollment_hit().value_or(0);
     auto enrolls = FingerprintHalProperties::enrollments();
@@ -211,24 +275,37 @@
 
 void FakeFingerprintEngine::getAuthenticatorIdImpl(ISessionCallback* cb) {
     BEGIN_OP(0);
-    int64_t authenticatorId = FingerprintHalProperties::authenticator_id().value_or(0);
-    if (FingerprintHalProperties::enrollments().size() > 0 && authenticatorId == 0) {
-        authenticatorId = 99999999;  // default authenticatorId, TODO(b/230515082)
+    int64_t authenticatorId;
+    if (FingerprintHalProperties::enrollments().size() == 0) {
+        authenticatorId = 0;
+    } else {
+        authenticatorId = FingerprintHalProperties::authenticator_id().value_or(0);
+        if (authenticatorId == 0) authenticatorId = 1;
     }
     cb->onAuthenticatorIdRetrieved(authenticatorId);
 }
 
 void FakeFingerprintEngine::invalidateAuthenticatorIdImpl(ISessionCallback* cb) {
     BEGIN_OP(0);
-    auto id = FingerprintHalProperties::authenticator_id().value_or(0);
-    auto newId = id + 1;
+    int64_t newId;
+    if (FingerprintHalProperties::enrollments().size() == 0) {
+        newId = 0;
+    } else {
+        auto id = FingerprintHalProperties::authenticator_id().value_or(0);
+        newId = id + 1;
+    }
     FingerprintHalProperties::authenticator_id(newId);
     cb->onAuthenticatorIdInvalidated(newId);
 }
 
 void FakeFingerprintEngine::resetLockoutImpl(ISessionCallback* cb,
-                                             const keymaster::HardwareAuthToken& /*hat*/) {
+                                             const keymaster::HardwareAuthToken& hat) {
     BEGIN_OP(0);
+    if (hat.mac.empty()) {
+        LOG(ERROR) << "Fail: hat in resetLockout()";
+        cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+        return;
+    }
     FingerprintHalProperties::lockout(false);
     cb->onLockoutCleared();
 }
@@ -286,4 +363,96 @@
     return {0 /* displayId (not used) */, 0 /* sensorLocationX */, 0 /* sensorLocationY */,
             0 /* sensorRadius */, "" /* display */};
 }
+
+std::vector<int32_t> FakeFingerprintEngine::parseIntSequence(const std::string& str,
+                                                             const std::string& sep) {
+    std::vector<std::string> seqs = Util::split(str, sep);
+    std::vector<int32_t> res;
+
+    for (const auto& seq : seqs) {
+        int32_t val;
+        if (ParseInt(seq, &val)) {
+            res.push_back(val);
+        } else {
+            LOG(WARNING) << "Invalid int sequence:" + str;
+            res.clear();
+            break;
+        }
+    }
+
+    return res;
+}
+
+std::vector<std::vector<int32_t>> FakeFingerprintEngine::parseEnrollmentCapture(
+        const std::string& str) {
+    std::vector<int32_t> defaultAcquiredInfo = {(int32_t)AcquiredInfo::GOOD};
+    std::vector<std::vector<int32_t>> res;
+    int i = 0, N = str.length();
+    std::size_t found = 0;
+    bool aborted = true;
+
+    while (found != std::string::npos) {
+        std::string durationStr, acquiredStr;
+        found = str.find_first_of("-,", i);
+        if (found == std::string::npos) {
+            if (N - i < 1) break;
+            durationStr = str.substr(i, N - i);
+        } else {
+            durationStr = str.substr(i, found - i);
+            if (str[found] == '-') {
+                found = str.find_first_of('[', found + 1);
+                if (found == std::string::npos) break;
+                i = found + 1;
+                found = str.find_first_of(']', found + 1);
+                if (found == std::string::npos) break;
+                acquiredStr = str.substr(i, found - i);
+                found = str.find_first_of(',', found + 1);
+            }
+        }
+        std::vector<int32_t> duration{0};
+        if (!ParseInt(durationStr, &duration[0])) break;
+        res.push_back(duration);
+        if (!acquiredStr.empty()) {
+            std::vector<int32_t> acquiredInfo = parseIntSequence(acquiredStr);
+            if (acquiredInfo.empty()) break;
+            res.push_back(acquiredInfo);
+        } else
+            res.push_back(defaultAcquiredInfo);
+
+        i = found + 1;
+        if (found == std::string::npos || found == N - 1) aborted = false;
+    }
+
+    if (aborted) {
+        LOG(ERROR) << "Failed to parse enrollment captures:" + str;
+        res.clear();
+    }
+
+    return res;
+}
+
+std::pair<AcquiredInfo, int32_t> FakeFingerprintEngine::convertAcquiredInfo(int32_t code) {
+    std::pair<AcquiredInfo, int32_t> res;
+    if (code > FINGERPRINT_ACQUIRED_VENDOR_BASE) {
+        res.first = AcquiredInfo::VENDOR;
+        res.second = code - FINGERPRINT_ACQUIRED_VENDOR_BASE;
+    } else {
+        res.first = (AcquiredInfo)code;
+        res.second = 0;
+    }
+    return res;
+}
+
+std::pair<Error, int32_t> FakeFingerprintEngine::convertError(int32_t code) {
+    std::pair<Error, int32_t> res;
+    if (code > FINGERPRINT_ERROR_VENDOR_BASE) {
+        res.first = Error::VENDOR;
+        res.second = code - FINGERPRINT_ERROR_VENDOR_BASE;
+    } else {
+        res.first = (Error)code;
+        res.second = 0;
+    }
+    return res;
+}
+
 }  // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp
index 922781c..74e7caf 100644
--- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp
+++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp
@@ -65,8 +65,18 @@
             {SW_COMPONENT_ID, "" /* hardwareVersion */, "" /* firmwareVersion */,
              "" /* serialNumber */, SW_VERSION}};
 
-    common::CommonProps commonProps = {SENSOR_ID, SENSOR_STRENGTH, MAX_ENROLLMENTS_PER_USER,
-                                       componentInfo};
+    auto sensorId = FingerprintHalProperties::sensor_id().value_or(SENSOR_ID);
+    auto sensorStrength =
+            FingerprintHalProperties::sensor_strength().value_or((int)SENSOR_STRENGTH);
+    auto maxEnrollments =
+            FingerprintHalProperties::max_enrollments().value_or(MAX_ENROLLMENTS_PER_USER);
+    auto navigationGuesture = FingerprintHalProperties::navigation_guesture().value_or(false);
+    auto detectInteraction = FingerprintHalProperties::detect_interaction().value_or(false);
+    auto displayTouch = FingerprintHalProperties::display_touch().value_or(true);
+    auto controlIllumination = FingerprintHalProperties::control_illumination().value_or(false);
+
+    common::CommonProps commonProps = {sensorId, (common::SensorStrength)sensorStrength,
+                                       maxEnrollments, componentInfo};
 
     SensorLocation sensorLocation = mEngine->getSensorLocation();
 
@@ -75,8 +85,10 @@
     *out = {{commonProps,
              mSensorType,
              {sensorLocation},
-             SUPPORTS_NAVIGATION_GESTURES,
-             false /* supportsDetectInteraction */}};
+             navigationGuesture,
+             detectInteraction,
+             displayTouch,
+             controlIllumination}};
     return ndk::ScopedAStatus::ok();
 }
 
diff --git a/biometrics/fingerprint/aidl/default/README.md b/biometrics/fingerprint/aidl/default/README.md
index bb6bb48..ad471f7 100644
--- a/biometrics/fingerprint/aidl/default/README.md
+++ b/biometrics/fingerprint/aidl/default/README.md
@@ -65,7 +65,7 @@
       $ adb shell getprop persist.vendor.fingerprint.virtual.enrollments
       ```
 
-### Authenticate
+## Authenticate
 
 To authenticate successfully set the enrolled id that should succeed. Unset it
 or change the value to make authenticate operations fail:
@@ -74,7 +74,52 @@
 $ adb shell setprop vendor.fingerprint.virtual.enrollment_hit 1
 ````
 
-### View HAL State
+## Acquired Info Insertion
+
+Fingerprint image acquisition states at HAL are reported to framework via onAcquired() callback. The valid acquired state info for AIDL HAL include
+
+{UNKNOWN(0), GOOD(1), PARTIAL(2), INSUFFICIENT(3), SENSOR_DIRTY(4), TOO_SLOW(5), TOO_FAST(6), VENDOR(7), START(8), TOO_DARK(9), TOO_BRIGHT(10), IMMOBILE(11), RETRYING_CAPTURE(12)}
+
+Refer to [AcquiredInfo.aidl](../android/hardware/biometrics/fingerprint/AcquiredInfo.aidl) for details
+
+
+The states can be specified in sequence for the HAL operations involving fingerprint image captures, namely authenticate, enrollment and detectInteraction
+
+```shell
+$ adb shell setprop vendor.fingerprint.virtual.operation_authenticate_acquired 6,9,1
+$ adb shell setprop vendor.fingerprint.virtual.operation_detect_interaction_acquired 6,1
+$ adb shell setprop vendor.fingerprint.virtual.next_enrollment 2:1000-[5,1],500:true
+
+#next_enrollment format example:
+.---------------------- enrollment id (2)
+|   .------------------ the image capture 1 duration (1000ms)
+|   |   .--------------   acquired info first (TOO_SLOW)
+|   |   | .------------   acquired info second (GOOD)
+|   |   | |   .-------- the image capture 2 duration (500ms)
+|   |   | |   |   .---- enrollment end status (success)
+|   |   | |   |   |
+|   |   | |   |   |
+|   |   | |   |   |
+2:1000-[5,1],500:true
+```
+For vendor specific acquired info, acquiredInfo = 1000 + vendorAcquiredInfo
+
+## Error Insertion
+The valid error codes for AIDL HAL include
+
+{UNKNOWN(0), HW_UNAVAILABLE(1), UNABLE_TO_PROCESS(2), TIMEOUT(3), NO_SPACE(4), CANCELED(5), UNABLE_TO_REMOVE(6), VENDOR(7), BAD_CALIBRATION(8)}
+
+Refer to [Error.aidl](../android/hardware/biometrics/fingerprint/Error.aidl) for details
+
+
+There are many HAL operations which can result in errors, refer to [here](fingerprint.sysprop) file for details.
+
+```shell
+$ adb shell setprop vendor.fingerprint.virtual.operation_authenticate_error 8
+```
+For vendor specific error, errorCode = 1000 + vendorErrorCode
+
+## View HAL State
 
 To view all the properties of the HAL (see `fingerprint.sysprop` file for the API):
 
diff --git a/biometrics/fingerprint/aidl/default/api/android.hardware.biometrics.fingerprint.VirtualProps-current.txt b/biometrics/fingerprint/aidl/default/api/android.hardware.biometrics.fingerprint.VirtualProps-current.txt
index 9dfb74d..fa21663 100644
--- a/biometrics/fingerprint/aidl/default/api/android.hardware.biometrics.fingerprint.VirtualProps-current.txt
+++ b/biometrics/fingerprint/aidl/default/api/android.hardware.biometrics.fingerprint.VirtualProps-current.txt
@@ -5,7 +5,7 @@
     api_name: "authenticator_id"
     type: Long
     access: ReadWrite
-    prop_name: "vendor.fingerprint.virtual.authenticator_id"
+    prop_name: "persist.vendor.fingerprint.virtual.authenticator_id"
   }
   prop {
     api_name: "challenge"
@@ -14,6 +14,21 @@
     prop_name: "vendor.fingerprint.virtual.challenge"
   }
   prop {
+    api_name: "control_illumination"
+    access: ReadWrite
+    prop_name: "persist.vendor.fingerprint.virtual.udfps.control_illumination"
+  }
+  prop {
+    api_name: "detect_interaction"
+    access: ReadWrite
+    prop_name: "persist.vendor.fingerprint.virtual.detect_interaction"
+  }
+  prop {
+    api_name: "display_touch"
+    access: ReadWrite
+    prop_name: "persist.vendor.fingerprint.virtual.udfps.display_touch"
+  }
+  prop {
     api_name: "enrollment_hit"
     type: Integer
     access: ReadWrite
@@ -28,7 +43,18 @@
   prop {
     api_name: "lockout"
     access: ReadWrite
-    prop_name: "vendor.fingerprint.virtual.lockout"
+    prop_name: "persist.vendor.fingerprint.virtual.lockout"
+  }
+  prop {
+    api_name: "max_enrollments"
+    type: Integer
+    access: ReadWrite
+    prop_name: "persist.vendor.fingerprint.virtual.max_enrollments"
+  }
+  prop {
+    api_name: "navigation_guesture"
+    access: ReadWrite
+    prop_name: "persist.vendor.fingerprint.virtual.navigation_guesture"
   }
   prop {
     api_name: "next_enrollment"
@@ -37,12 +63,24 @@
     prop_name: "vendor.fingerprint.virtual.next_enrollment"
   }
   prop {
+    api_name: "operation_authenticate_acquired"
+    type: String
+    access: ReadWrite
+    prop_name: "vendor.fingerprint.virtual.operation_authenticate_acquired"
+  }
+  prop {
     api_name: "operation_authenticate_duration"
     type: Integer
     access: ReadWrite
     prop_name: "vendor.fingerprint.virtual.operation_authenticate_duration"
   }
   prop {
+    api_name: "operation_authenticate_error"
+    type: Integer
+    access: ReadWrite
+    prop_name: "vendor.fingerprint.virtual.operation_authenticate_error"
+  }
+  prop {
     api_name: "operation_authenticate_fails"
     access: ReadWrite
     prop_name: "vendor.fingerprint.virtual.operation_authenticate_fails"
@@ -54,9 +92,22 @@
     prop_name: "vendor.fingerprint.virtual.operation_authenticate_latency"
   }
   prop {
-    api_name: "operation_detect_interaction_fails"
+    api_name: "operation_detect_interaction_acquired"
+    type: String
     access: ReadWrite
-    prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_fails"
+    prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_acquired"
+  }
+  prop {
+    api_name: "operation_detect_interaction_duration"
+    type: Integer
+    access: ReadWrite
+    prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_duration"
+  }
+  prop {
+    api_name: "operation_detect_interaction_error"
+    type: Integer
+    access: ReadWrite
+    prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_error"
   }
   prop {
     api_name: "operation_detect_interaction_latency"
@@ -65,9 +116,10 @@
     prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_latency"
   }
   prop {
-    api_name: "operation_enroll_fails"
+    api_name: "operation_enroll_error"
+    type: Integer
     access: ReadWrite
-    prop_name: "vendor.fingerprint.virtual.operation_enroll_fails"
+    prop_name: "vendor.fingerprint.virtual.operation_enroll_error"
   }
   prop {
     api_name: "operation_enroll_latency"
@@ -76,12 +128,24 @@
     prop_name: "vendor.fingerprint.virtual.operation_enroll_latency"
   }
   prop {
+    api_name: "sensor_id"
+    type: Integer
+    access: ReadWrite
+    prop_name: "persist.vendor.fingerprint.virtual.sensor_id"
+  }
+  prop {
     api_name: "sensor_location"
     type: String
     access: ReadWrite
     prop_name: "persist.vendor.fingerprint.virtual.sensor_location"
   }
   prop {
+    api_name: "sensor_strength"
+    type: Integer
+    access: ReadWrite
+    prop_name: "persist.vendor.fingerprint.virtual.sensor_strength"
+  }
+  prop {
     api_name: "type"
     type: String
     access: ReadWrite
diff --git a/biometrics/fingerprint/aidl/default/fingerprint.sysprop b/biometrics/fingerprint/aidl/default/fingerprint.sysprop
index 85e93b0..9b8fada 100644
--- a/biometrics/fingerprint/aidl/default/fingerprint.sysprop
+++ b/biometrics/fingerprint/aidl/default/fingerprint.sysprop
@@ -32,8 +32,12 @@
     api_name: "enrollment_hit"
 }
 
-# the next enrollment in the format: "<id>:<delay>,<delay>,...:<result>"
-# for example: "2:0:true"
+# the next enrollment in the format of:
+# "<id>:<delay>,<delay>,...:<result>"
+# <delay> = <duration-[acquiredInfos]>
+# [acquiredInfos] = [acquiredInfo1, acquiredInfo2, ...]
+# (refer to README.md file for acquiredInfo values)
+# e.g. "2:100,20:true", "2:100-[5,1],20:true"
 # this property is reset after enroll completes
 prop {
     prop_name: "vendor.fingerprint.virtual.next_enrollment"
@@ -45,7 +49,7 @@
 
 # value for getAuthenticatorId or 0
 prop {
-    prop_name: "vendor.fingerprint.virtual.authenticator_id"
+    prop_name: "persist.vendor.fingerprint.virtual.authenticator_id"
     type: Long
     scope: Public
     access: ReadWrite
@@ -63,7 +67,7 @@
 
 # if locked out
 prop {
-    prop_name: "vendor.fingerprint.virtual.lockout"
+    prop_name: "persist.vendor.fingerprint.virtual.lockout"
     type: Boolean
     scope: Public
     access: ReadWrite
@@ -79,22 +83,26 @@
     api_name: "operation_authenticate_fails"
 }
 
-# force all detectInteraction operations to fail
+# force all detectInteraction operations to error out
+# error consists of errorCode and vendorErrorCode
+# valid errorCodes are listed in README.md file
+# vendorErrorCode = (error>1000) ? error-1000 : 0
+# e.g. error(1002) --> errorCode(7) and vendorErrorCode(2)
 prop {
-    prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_fails"
-    type: Boolean
+    prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_error"
+    type: Integer
     scope: Public
     access: ReadWrite
-    api_name: "operation_detect_interaction_fails"
+    api_name: "operation_detect_interaction_error"
 }
 
-# force all enroll operations to fail
+# force all enroll operations to result in error
 prop {
-    prop_name: "vendor.fingerprint.virtual.operation_enroll_fails"
-    type: Boolean
+    prop_name: "vendor.fingerprint.virtual.operation_enroll_error"
+    type: Integer
     scope: Public
     access: ReadWrite
-    api_name: "operation_enroll_fails"
+    api_name: "operation_enroll_error"
 }
 
 # add a latency to authentication operations
@@ -134,6 +142,15 @@
     api_name: "operation_authenticate_duration"
 }
 
+# insert error for authenticate operations
+prop {
+    prop_name: "vendor.fingerprint.virtual.operation_authenticate_error"
+    type: Integer
+    scope: Public
+    access: ReadWrite
+    api_name: "operation_authenticate_error"
+}
+
 # sensor location
 #    <x>:<y>:<radius> in pixel
 prop {
@@ -143,3 +160,99 @@
     access: ReadWrite
     api_name: "sensor_location"
 }
+
+# acquired info during authentication in format of sequence
+prop {
+    prop_name: "vendor.fingerprint.virtual.operation_authenticate_acquired"
+    type: String
+    scope: Public
+    access: ReadWrite
+    api_name: "operation_authenticate_acquired"
+}
+
+# millisecond duration for detect interaction operations
+# (waits for changes to enrollment_hit)
+prop {
+    prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_duration"
+    type: Integer
+    scope: Public
+    access: ReadWrite
+    api_name: "operation_detect_interaction_duration"
+}
+
+# acquired info during detect interaction operation in format of sequence
+# e.g. 5,6,1  (TOO_SLOW, TOO_FAST, GOOD)
+# onAcquired() callback will be invoked in sequence
+# vendorAcquiredCode = (acquired>1000) ? acquired-1000 : 0
+prop {
+    prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_acquired"
+    type: String
+    scope: Public
+    access: ReadWrite
+    api_name: "operation_detect_interaction_acquired"
+}
+
+# sensor id (default: 5)
+prop {
+    prop_name: "persist.vendor.fingerprint.virtual.sensor_id"
+    type: Integer
+    scope: Public
+    access: ReadWrite
+    api_name: "sensor_id"
+}
+
+# sensor strength (default: 2)
+# [0=CONVENECE, 1=WEAK, 2=STRONG]
+prop {
+    prop_name: "persist.vendor.fingerprint.virtual.sensor_strength"
+    type: Integer
+    scope: Public
+    access: ReadWrite
+    api_name: "sensor_strength"
+}
+
+# max enrollments per user (default: 5)
+#
+prop {
+    prop_name: "persist.vendor.fingerprint.virtual.max_enrollments"
+    type: Integer
+    scope: Public
+    access: ReadWrite
+    api_name: "max_enrollments"
+}
+
+# whether support navigation guestures (default: false)
+prop {
+    prop_name: "persist.vendor.fingerprint.virtual.navigation_guesture"
+    type: Boolean
+    scope: Public
+    access: ReadWrite
+    api_name: "navigation_guesture"
+}
+
+# whether support detect interaction (default: false)
+prop {
+    prop_name: "persist.vendor.fingerprint.virtual.detect_interaction"
+    type: Boolean
+    scope: Public
+    access: ReadWrite
+    api_name: "detect_interaction"
+}
+
+# whether support display touch by hal (default: true)
+prop {
+    prop_name: "persist.vendor.fingerprint.virtual.udfps.display_touch"
+    type: Boolean
+    scope: Public
+    access: ReadWrite
+    api_name: "display_touch"
+}
+
+# whether support illumination control  by hal (default: false)
+prop {
+    prop_name: "persist.vendor.fingerprint.virtual.udfps.control_illumination"
+    type: Boolean
+    scope: Public
+    access: ReadWrite
+    api_name: "control_illumination"
+}
diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
index d7df818..22b1744 100644
--- a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
+++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
@@ -59,7 +59,17 @@
 
     virtual SensorLocation defaultSensorLocation();
 
+    std::vector<int32_t> parseIntSequence(const std::string& str, const std::string& sep = ",");
+
+    std::vector<std::vector<int32_t>> parseEnrollmentCapture(const std::string& str);
+
     std::mt19937 mRandom;
+
+  private:
+    static constexpr int32_t FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000;
+    static constexpr int32_t FINGERPRINT_ERROR_VENDOR_BASE = 1000;
+    std::pair<AcquiredInfo, int32_t> convertAcquiredInfo(int32_t code);
+    std::pair<Error, int32_t> convertError(int32_t code);
 };
 
 }  // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp
index 8696d26..32d01f4 100644
--- a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp
+++ b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp
@@ -38,8 +38,9 @@
         mLastChallengeRevoked = challenge;
         return ndk::ScopedAStatus::ok();
     };
-    ::ndk::ScopedAStatus onError(fingerprint::Error error, int32_t) override {
+    ::ndk::ScopedAStatus onError(fingerprint::Error error, int32_t vendorCode) override {
         mError = error;
+        mErrorVendorCode = vendorCode;
         return ndk::ScopedAStatus::ok();
     };
     ::ndk::ScopedAStatus onEnrollmentProgress(int32_t enrollmentId, int32_t remaining) override {
@@ -62,7 +63,10 @@
         mInteractionDetectedCount++;
         return ndk::ScopedAStatus::ok();
     };
-    ndk::ScopedAStatus onAcquired(AcquiredInfo /*info*/, int32_t /*vendorCode*/) override {
+    ndk::ScopedAStatus onAcquired(AcquiredInfo info, int32_t vendorCode) override {
+        mLastAcquiredInfo = (int32_t)info;
+        mLastAcquiredVendorCode = vendorCode;
+        mLastAcquiredCount++;
         return ndk::ScopedAStatus::ok();
     }
     ::ndk::ScopedAStatus onEnrollmentsEnumerated(
@@ -94,6 +98,7 @@
     ndk::ScopedAStatus onSessionClosed() override { return ndk::ScopedAStatus::ok(); }
 
     Error mError = Error::UNKNOWN;
+    int32_t mErrorVendorCode = 0;
     int64_t mLastChallenge = -1;
     int64_t mLastChallengeRevoked = -1;
     int32_t mLastEnrolled = -1;
@@ -105,6 +110,9 @@
     bool mAuthenticatorIdInvalidated = false;
     bool mLockoutPermanent = false;
     int mInteractionDetectedCount = 0;
+    int32_t mLastAcquiredInfo = -1;
+    int32_t mLastAcquiredVendorCode = -1;
+    int32_t mLastAcquiredCount = 0;
 };
 
 class FakeFingerprintEngineTest : public ::testing::Test {
@@ -116,6 +124,12 @@
         mCallback = ndk::SharedRefBase::make<TestSessionCallback>();
     }
 
+    void TearDown() override {
+        FingerprintHalProperties::operation_authenticate_error(0);
+        FingerprintHalProperties::operation_detect_interaction_error(0);
+        FingerprintHalProperties::operation_authenticate_acquired("");
+    }
+
     FakeFingerprintEngine mEngine;
     std::shared_ptr<TestSessionCallback> mCallback;
     std::promise<void> mCancel;
@@ -135,11 +149,13 @@
 
 TEST_F(FakeFingerprintEngineTest, ResetLockout) {
     FingerprintHalProperties::lockout(true);
-    mEngine.resetLockoutImpl(mCallback.get(), {});
+    keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+    mEngine.resetLockoutImpl(mCallback.get(), hat);
     ASSERT_FALSE(FingerprintHalProperties::lockout().value_or(true));
 }
 
 TEST_F(FakeFingerprintEngineTest, AuthenticatorId) {
+    FingerprintHalProperties::enrollments({1});
     FingerprintHalProperties::authenticator_id(50);
     mEngine.getAuthenticatorIdImpl(mCallback.get());
     ASSERT_EQ(50, mCallback->mLastAuthenticatorId);
@@ -162,6 +178,7 @@
     ASSERT_EQ(1, FingerprintHalProperties::enrollments().size());
     ASSERT_EQ(4, FingerprintHalProperties::enrollments()[0].value());
     ASSERT_EQ(4, mCallback->mLastEnrolled);
+    ASSERT_EQ(1, mCallback->mLastAcquiredInfo);
 }
 
 TEST_F(FakeFingerprintEngineTest, EnrollCancel) {
@@ -189,12 +206,28 @@
     ASSERT_FALSE(FingerprintHalProperties::next_enrollment().has_value());
 }
 
+TEST_F(FakeFingerprintEngineTest, EnrollAcquired) {
+    FingerprintHalProperties::enrollments({});
+    FingerprintHalProperties::next_enrollment("4:0,5-[12,1013]:true");
+    keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+    int32_t prevCnt = mCallback->mLastAcquiredCount;
+    mEngine.enrollImpl(mCallback.get(), hat, mCancel.get_future());
+    ASSERT_FALSE(FingerprintHalProperties::next_enrollment().has_value());
+    ASSERT_EQ(1, FingerprintHalProperties::enrollments().size());
+    ASSERT_EQ(4, FingerprintHalProperties::enrollments()[0].value());
+    ASSERT_EQ(4, mCallback->mLastEnrolled);
+    ASSERT_EQ(prevCnt + 3, mCallback->mLastAcquiredCount);
+    ASSERT_EQ(7, mCallback->mLastAcquiredInfo);
+    ASSERT_EQ(13, mCallback->mLastAcquiredVendorCode);
+}
+
 TEST_F(FakeFingerprintEngineTest, Authenticate) {
     FingerprintHalProperties::enrollments({1, 2});
     FingerprintHalProperties::enrollment_hit(2);
     mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
     ASSERT_FALSE(mCallback->mAuthenticateFailed);
     ASSERT_EQ(2, mCallback->mLastAuthenticated);
+    ASSERT_EQ(1, mCallback->mLastAcquiredInfo);
 }
 
 TEST_F(FakeFingerprintEngineTest, AuthenticateCancel) {
@@ -211,7 +244,6 @@
     FingerprintHalProperties::enrollment_hit({});
     mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
     ASSERT_TRUE(mCallback->mAuthenticateFailed);
-    ASSERT_EQ(mCallback->mError, Error::UNABLE_TO_PROCESS);
 }
 
 TEST_F(FakeFingerprintEngineTest, AuthenticateNotEnrolled) {
@@ -219,7 +251,6 @@
     FingerprintHalProperties::enrollment_hit(3);
     mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
     ASSERT_TRUE(mCallback->mAuthenticateFailed);
-    ASSERT_EQ(mCallback->mError, Error::UNABLE_TO_PROCESS);
 }
 
 TEST_F(FakeFingerprintEngineTest, AuthenticateLockout) {
@@ -231,11 +262,41 @@
     ASSERT_NE(mCallback->mError, Error::UNKNOWN);
 }
 
+TEST_F(FakeFingerprintEngineTest, AuthenticateError8) {
+    FingerprintHalProperties::operation_authenticate_error(8);
+    mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+    ASSERT_EQ(mCallback->mError, (Error)8);
+    ASSERT_EQ(mCallback->mErrorVendorCode, 0);
+}
+
+TEST_F(FakeFingerprintEngineTest, AuthenticateError9) {
+    FingerprintHalProperties::operation_authenticate_error(1009);
+    mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+    ASSERT_EQ(mCallback->mError, (Error)7);
+    ASSERT_EQ(mCallback->mErrorVendorCode, 9);
+}
+
+TEST_F(FakeFingerprintEngineTest, AuthenticateAcquired) {
+    FingerprintHalProperties::lockout(false);
+    FingerprintHalProperties::enrollments({1, 2});
+    FingerprintHalProperties::enrollment_hit(2);
+    FingerprintHalProperties::operation_authenticate_acquired("4,1009");
+    int32_t prevCount = mCallback->mLastAcquiredCount;
+    mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+    ASSERT_FALSE(mCallback->mAuthenticateFailed);
+    ASSERT_EQ(2, mCallback->mLastAuthenticated);
+    ASSERT_EQ(prevCount + 2, mCallback->mLastAcquiredCount);
+    ASSERT_EQ(7, mCallback->mLastAcquiredInfo);
+    ASSERT_EQ(9, mCallback->mLastAcquiredVendorCode);
+}
+
 TEST_F(FakeFingerprintEngineTest, InteractionDetect) {
     FingerprintHalProperties::enrollments({1, 2});
     FingerprintHalProperties::enrollment_hit(2);
+    FingerprintHalProperties::operation_detect_interaction_acquired("");
     mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
     ASSERT_EQ(1, mCallback->mInteractionDetectedCount);
+    ASSERT_EQ(1, mCallback->mLastAcquiredInfo);
 }
 
 TEST_F(FakeFingerprintEngineTest, InteractionDetectCancel) {
@@ -261,6 +322,26 @@
     ASSERT_EQ(0, mCallback->mInteractionDetectedCount);
 }
 
+TEST_F(FakeFingerprintEngineTest, InteractionDetectError) {
+    FingerprintHalProperties::operation_detect_interaction_error(8);
+    mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
+    ASSERT_EQ(0, mCallback->mInteractionDetectedCount);
+    ASSERT_EQ(mCallback->mError, (Error)8);
+    ASSERT_EQ(mCallback->mErrorVendorCode, 0);
+}
+
+TEST_F(FakeFingerprintEngineTest, InteractionDetectAcquired) {
+    FingerprintHalProperties::enrollments({1, 2});
+    FingerprintHalProperties::enrollment_hit(2);
+    FingerprintHalProperties::operation_detect_interaction_acquired("4,1013");
+    int32_t prevCount = mCallback->mLastAcquiredCount;
+    mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
+    ASSERT_EQ(1, mCallback->mInteractionDetectedCount);
+    ASSERT_EQ(prevCount + 2, mCallback->mLastAcquiredCount);
+    ASSERT_EQ(7, mCallback->mLastAcquiredInfo);
+    ASSERT_EQ(13, mCallback->mLastAcquiredVendorCode);
+}
+
 TEST_F(FakeFingerprintEngineTest, EnumerateEnrolled) {
     FingerprintHalProperties::enrollments({2, 4, 8});
     mEngine.enumerateEnrollmentsImpl(mCallback.get());
@@ -290,6 +371,76 @@
     }
 }
 
+TEST_F(FakeFingerprintEngineTest, parseIntSequence) {
+    std::vector<int32_t> seqV;
+    seqV = mEngine.parseIntSequence("");
+    ASSERT_EQ(0, seqV.size());
+    seqV = mEngine.parseIntSequence("2");
+    ASSERT_EQ(1, seqV.size());
+    ASSERT_EQ(2, seqV[0]);
+    seqV = mEngine.parseIntSequence("2,3,4");
+    std::vector<int32_t> expV{2, 3, 4};
+    ASSERT_EQ(expV, seqV);
+    seqV = mEngine.parseIntSequence("2,3,a");
+    ASSERT_EQ(0, seqV.size());
+    seqV = mEngine.parseIntSequence("2, 3, 4");
+    ASSERT_EQ(expV, seqV);
+    seqV = mEngine.parseIntSequence("123,456");
+    ASSERT_EQ(2, seqV.size());
+    std::vector<int32_t> expV1{123, 456};
+    ASSERT_EQ(expV1, seqV);
+    seqV = mEngine.parseIntSequence("12f3,456");
+    ASSERT_EQ(0, seqV.size());
+}
+
+TEST_F(FakeFingerprintEngineTest, parseEnrollmentCaptureOk) {
+    std::vector<std::vector<int32_t>> ecV;
+    ecV = mEngine.parseEnrollmentCapture("100,200,300");
+    ASSERT_EQ(6, ecV.size());
+    std::vector<std::vector<int32_t>> expE{{100}, {200}, {300}};
+    std::vector<int32_t> defC{1};
+    for (int i = 0; i < ecV.size(); i += 2) {
+        ASSERT_EQ(expE[i / 2], ecV[i]);
+        ASSERT_EQ(defC, ecV[i + 1]);
+    }
+    ecV = mEngine.parseEnrollmentCapture("100");
+    ASSERT_EQ(2, ecV.size());
+    ASSERT_EQ(expE[0], ecV[0]);
+    ASSERT_EQ(defC, ecV[1]);
+
+    ecV = mEngine.parseEnrollmentCapture("100-[5,6,7]");
+    std::vector<int32_t> expC{5, 6, 7};
+    ASSERT_EQ(2, ecV.size());
+    for (int i = 0; i < ecV.size(); i += 2) {
+        ASSERT_EQ(expE[i / 2], ecV[i]);
+        ASSERT_EQ(expC, ecV[i + 1]);
+    }
+    ecV = mEngine.parseEnrollmentCapture("100-[5,6,7], 200, 300-[9,10]");
+    std::vector<std::vector<int32_t>> expC1{{5, 6, 7}, {1}, {9, 10}};
+    ASSERT_EQ(6, ecV.size());
+    for (int i = 0; i < ecV.size(); i += 2) {
+        ASSERT_EQ(expE[i / 2], ecV[i]);
+        ASSERT_EQ(expC1[i / 2], ecV[i + 1]);
+    }
+    ecV = mEngine.parseEnrollmentCapture("100-[5,6,7], 200-[2,1], 300-[9]");
+    std::vector<std::vector<int32_t>> expC2{{5, 6, 7}, {2, 1}, {9}};
+    ASSERT_EQ(ecV.size(), 6);
+    for (int i = 0; i < ecV.size(); i += 2) {
+        ASSERT_EQ(expE[i / 2], ecV[i]);
+        ASSERT_EQ(expC2[i / 2], ecV[i + 1]);
+    }
+}
+
+TEST_F(FakeFingerprintEngineTest, parseEnrollmentCaptureFail) {
+    std::vector<std::string> badStr{"10c",         "100-5",   "100-[5,6,7", "100-5,6,7]",
+                                    "100,2x0,300", "200-[f]", "a,b"};
+    std::vector<std::vector<int32_t>> ecV;
+    for (const auto s : badStr) {
+        ecV = mEngine.parseEnrollmentCapture(s);
+        ASSERT_EQ(ecV.size(), 0);
+    }
+}
+
 }  // namespace aidl::android::hardware::biometrics::fingerprint
 
 int main(int argc, char** argv) {
diff --git a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineUdfpsTest.cpp b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineUdfpsTest.cpp
index 485f401..7c0021f 100644
--- a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineUdfpsTest.cpp
+++ b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineUdfpsTest.cpp
@@ -47,14 +47,10 @@
             sc.sensorRadius == FakeFingerprintEngineUdfps::defaultSensorRadius && sc.display == "");
 }
 
-TEST_F(FakeFingerprintEngineUdfpsTest, getSensorLocation) {
-    FingerprintHalProperties::sensor_location("");
-    SensorLocation sc = mEngine.getSensorLocation();
-    ASSERT_TRUE(isDefaultLocation(sc));
-
+TEST_F(FakeFingerprintEngineUdfpsTest, getSensorLocationOk) {
     auto loc = "100:200:30";
     FingerprintHalProperties::sensor_location(loc);
-    sc = mEngine.getSensorLocation();
+    SensorLocation sc = mEngine.getSensorLocation();
     ASSERT_TRUE(sc.sensorLocationX == 100);
     ASSERT_TRUE(sc.sensorLocationY == 200);
     ASSERT_TRUE(sc.sensorRadius == 30);
@@ -66,8 +62,14 @@
     ASSERT_TRUE(sc.sensorLocationY == 200);
     ASSERT_TRUE(sc.sensorRadius == 30);
     ASSERT_TRUE(sc.display == "screen1");
+}
 
-    loc = "100";
+TEST_F(FakeFingerprintEngineUdfpsTest, getSensorLocationBad) {
+    FingerprintHalProperties::sensor_location("");
+    SensorLocation sc = mEngine.getSensorLocation();
+    ASSERT_TRUE(isDefaultLocation(sc));
+
+    auto loc = "100";
     FingerprintHalProperties::sensor_location(loc);
     sc = mEngine.getSensorLocation();
     ASSERT_TRUE(isDefaultLocation(sc));
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/DtmfParams.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/DtmfParams.aidl
index 659fa0b..5523fd8 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/DtmfParams.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/DtmfParams.aidl
@@ -34,6 +34,7 @@
 package android.hardware.radio.ims.media;
 @VintfStability
 parcelable DtmfParams {
-  byte payloadTypeNumber;
+  byte rxPayloadTypeNumber;
+  byte txPayloadTypeNumber;
   byte samplingRateKHz;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsDeregistrationReason.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsDeregistrationReason.aidl
index 330374e..b04e559 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsDeregistrationReason.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsDeregistrationReason.aidl
@@ -36,5 +36,5 @@
 enum ImsDeregistrationReason {
   REASON_SIM_REMOVED = 1,
   REASON_SIM_REFRESH = 2,
-  REASON_NETWORK_MODE_CHANGED = 3,
+  REASON_ALLOWED_NETWORK_TYPES_CHANGED = 3,
 }
diff --git a/radio/aidl/android/hardware/radio/ims/IRadioImsIndication.aidl b/radio/aidl/android/hardware/radio/ims/IRadioImsIndication.aidl
index ea286c4..82773f2 100644
--- a/radio/aidl/android/hardware/radio/ims/IRadioImsIndication.aidl
+++ b/radio/aidl/android/hardware/radio/ims/IRadioImsIndication.aidl
@@ -32,12 +32,12 @@
      * on cellular networks. IMS service shall call stopImsTraffic when receiving
      * this indication.
      *
-     * @param token The token of startImsTraffic() associated with this indication
      * @param type Type of radio indication
+     * @param token The token of startImsTraffic() associated with this indication
      * @param info Connection failure information
      */
-    void onConnectionSetupFailure(in RadioIndicationType type, in String token,
-            in ConnectionFailureInfo info);
+    void onConnectionSetupFailure(
+            in RadioIndicationType type, in String token, in ConnectionFailureInfo info);
 
     /**
      * Access Network Bitrate Recommendation (ANBR), see 3GPP TS 26.114.
@@ -49,19 +49,18 @@
      * @param bitsPerSecond The recommended bit rate for the UE
      * for a specific logical channel and a specific direction by NW
      */
-     void notifyAnbr(in RadioIndicationType type, in ImsStreamType mediaType,
+    void notifyAnbr(in RadioIndicationType type, in ImsStreamType mediaType,
             in ImsStreamDirection direction, int bitsPerSecond);
 
     /**
-     * Fired by radio when a graceful IMS deregistration needs to be performed by telephony
-     * prior to radio performing network detach. Example scenarios are SIM refresh or user
-     * mode preference change which would cause network detach. The radio waits for the
-     * IMS deregistration, which will be notified by telephony via
+     * Requests IMS stack to perform graceful IMS deregistration before radio performing
+     * network detach in the events of SIM remove, refresh or and so on. The radio waits for
+     * the IMS deregistration, which will be notified by telephony via
      * {@link IRadioIms#updateImsRegistrationInfo()}, or a certain timeout interval to start
      * the network detach procedure.
      *
      * @param type Type of radio indication
      * @param reason the reason why the deregistration is triggered
      */
-     void triggerImsDeregistration(in RadioIndicationType type, in ImsDeregistrationReason reason);
+    void triggerImsDeregistration(in RadioIndicationType type, in ImsDeregistrationReason reason);
 }
diff --git a/radio/aidl/android/hardware/radio/ims/ImsDeregistrationReason.aidl b/radio/aidl/android/hardware/radio/ims/ImsDeregistrationReason.aidl
index 83c0321..eac8db4 100644
--- a/radio/aidl/android/hardware/radio/ims/ImsDeregistrationReason.aidl
+++ b/radio/aidl/android/hardware/radio/ims/ImsDeregistrationReason.aidl
@@ -34,5 +34,5 @@
      * Radio shall send this reason to IMS stack to perform graceful de-registration
      * due to allowed network types bitmask changed that results in NAS detach.
      */
-    REASON_NETWORK_MODE_CHANGED = 3,
+    REASON_ALLOWED_NETWORK_TYPES_CHANGED = 3,
 }
diff --git a/radio/aidl/android/hardware/radio/ims/SuggestedAction.aidl b/radio/aidl/android/hardware/radio/ims/SuggestedAction.aidl
index a17b8a4..2d12ed6 100644
--- a/radio/aidl/android/hardware/radio/ims/SuggestedAction.aidl
+++ b/radio/aidl/android/hardware/radio/ims/SuggestedAction.aidl
@@ -21,17 +21,17 @@
 @Backing(type="int")
 enum SuggestedAction {
     /** Default value */
-    NONE = 0,
+    NONE,
     /**
      * Indicates that the IMS registration is failed with fatal error such as 403 or 404
      * on all P-CSCF addresses. The radio shall block the current PLMN or disable
      * the RAT as per the carrier requirements.
      */
-    TRIGGER_PLMN_BLOCK = 1 << 0,
+    TRIGGER_PLMN_BLOCK,
     /**
      * Indicates that the IMS registration on current PLMN failed multiple times.
      * The radio shall block the current PLMN or disable the RAT during EPS or 5GS mobility
      * management timer value as per the carrier requirements.
      */
-    TRIGGER_PLMN_BLOCK_WITH_TIMEOUT = 1 << 1,
+    TRIGGER_PLMN_BLOCK_WITH_TIMEOUT,
 }
diff --git a/radio/aidl/android/hardware/radio/ims/media/DtmfParams.aidl b/radio/aidl/android/hardware/radio/ims/media/DtmfParams.aidl
index ad920f2..a7dcb0d 100644
--- a/radio/aidl/android/hardware/radio/ims/media/DtmfParams.aidl
+++ b/radio/aidl/android/hardware/radio/ims/media/DtmfParams.aidl
@@ -19,11 +19,21 @@
 @VintfStability
 parcelable DtmfParams {
     /**
-     * Dynamic payload type number to be used for DTMF RTP packets. The values is
-     * in the range from 96 to 127 chosen during the session establishment. The PT
-     * value of the RTP header of all DTMF packets shall be set with this value.
+     * Dynamic payload type number to be used for DTMF RTP packets received.
+     * The values is in the range from 96 to 127 chosen during the session
+     * establishment. The PT  value of the RTP header of all DTMF packets shall be
+     * set with this value.
      */
-    byte payloadTypeNumber;
+    byte rxPayloadTypeNumber;
+
+    /**
+     * Dynamic payload type number to be used for DTMF RTP packets sent.
+     * The values is in the range from 96 to 127 chosen during the session
+     * establishment. The PT value of the RTP header of all DTMF packets shall be set
+     * with this value.
+     */
+    byte txPayloadTypeNumber;
+
     /** Sampling rate in kHz */
     byte samplingRateKHz;
 }
diff --git a/radio/aidl/vts/radio_ims_indication.cpp b/radio/aidl/vts/radio_ims_indication.cpp
index 8e98d85..f382de0 100644
--- a/radio/aidl/vts/radio_ims_indication.cpp
+++ b/radio/aidl/vts/radio_ims_indication.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/radio/aidl/vts/radio_ims_response.cpp b/radio/aidl/vts/radio_ims_response.cpp
index 62912ea..9d8db4a 100644
--- a/radio/aidl/vts/radio_ims_response.cpp
+++ b/radio/aidl/vts/radio_ims_response.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/radio/aidl/vts/radio_ims_test.cpp b/radio/aidl/vts/radio_ims_test.cpp
index 27cc8d9..e5cbeb4 100644
--- a/radio/aidl/vts/radio_ims_test.cpp
+++ b/radio/aidl/vts/radio_ims_test.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/radio/aidl/vts/radio_ims_utils.h b/radio/aidl/vts/radio_ims_utils.h
index 98fd3cb..c981ebc 100644
--- a/radio/aidl/vts/radio_ims_utils.h
+++ b/radio/aidl/vts/radio_ims_utils.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -43,7 +43,8 @@
     virtual ndk::ScopedAStatus updateImsRegistrationInfoResponse(
             const RadioResponseInfo& info) override;
 
-    virtual ndk::ScopedAStatus startImsTrafficResponse(const RadioResponseInfo& info,
+    virtual ndk::ScopedAStatus startImsTrafficResponse(
+            const RadioResponseInfo& info,
             const std::optional<ConnectionFailureInfo>& response) override;
 
     virtual ndk::ScopedAStatus stopImsTrafficResponse(const RadioResponseInfo& info) override;
diff --git a/security/keymint/RKP_CHANGELOG.md b/security/keymint/RKP_CHANGELOG.md
index dfcc938..243fc26 100644
--- a/security/keymint/RKP_CHANGELOG.md
+++ b/security/keymint/RKP_CHANGELOG.md
@@ -21,13 +21,13 @@
 ## IRemotelyProvisionedComponent 2 -> 3
 * ProtectedData has been removed.
 * DeviceInfo
-  * `cert_type` has been added, with values corresponding to `widevine` or `keymint`
   * `version` has moved to a top-level field within the CSR generated by the HAL
 * IRemotelyProvisionedComponent
   * The need for an EEK has been removed. There is no longer an encrypted portion of the CSR.
   * Test mode has been removed.
   * The schema for the CSR itself has been significantly simplified, please see
-    IRemotelyProvisionedComponent.aidl for more details.
-    * Notably, the chain of signing, MACing, and encryption operations has been replaced with a single
+    IRemotelyProvisionedComponent.aidl for more details. Notably,
+    * the chain of signing, MACing, and encryption operations has been replaced with a single
       COSE_Sign1 object.
+    * CertificateType has been added to identify the type of certificate being requested.
 
diff --git a/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl b/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl
index 6854851..f0af619 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl
@@ -49,16 +49,7 @@
      *         "security_level" : "tee" / "strongbox",
      *         "fused": 1 / 0,  ; 1 if secure boot is enforced for the processor that the IRPC
      *                          ; implementation is contained in. 0 otherwise.
-     *         "cert_type": CertificateType;
      *     }
-     *
-     *     ; A tstr identifying the type of certificate. The set of supported certificate types may
-     *     ; be extended without requiring a version bump of the HAL. Custom certificate types may
-     *     ; be used, but the provisioning server may reject the request for an unknown certificate
-     *     ; type. The currently defined certificate types are:
-     *     ;  - "widevine"
-     *     ;  - "keymint"
-     *     CertificateType = tstr
      */
     byte[] deviceInfo;
 }
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
index 77df99f..86c1717 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
@@ -315,38 +315,50 @@
      *
      * @return the following CBOR Certificate Signing Request (Csr) serialized into a byte array:
      *
-     * Csr = [
-     *    version: 3,              ; The CDDL Schema version.
-     *    UdsCerts,
-     *    DiceCertChain,
-     *    SignedData
-     * ]
+     * Csr = AuthenticatedMessage<CsrPayload>
      *
-     * ; COSE_Sign1 (untagged)
-     * SignedData = [
-     *     protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 },
-     *     unprotected: {},
-     *     payload: bstr .cbor SignedDataPayload,
-     *     signature: bstr            ; PureEd25519(CDI_Leaf_Priv, bstr .cbor SignedDataSigStruct) /
-     *                                ; ECDSA(CDI_Leaf_Priv, bstr .cbor SignedDataSigStruct)
-     * ]
-     *
-     * ; Sig_structure for SignedData
-     * SignedDataSigStruct = [
-     *     context: "Signature1",
-     *     protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 },
-     *     external_aad: bstr .size 0,
-     *     payload: bstr .cbor SignedDataPayload
-     * ]
-     *
-     * SignedDataPayload = [               ; CBOR Array defining the payload for SignedData
+     * CsrPayload = [                      ; CBOR Array defining the payload for Csr
+     *     version: 1,                     ; The CsrPayload CDDL Schema version.
+     *     CertificateType,                ; The type of certificate being requested.
      *     DeviceInfo,                     ; Defined in DeviceInfo.aidl
      *     challenge: bstr .size (32..64), ; Provided by the method parameters
      *     KeysToSign,                     ; Provided by the method parameters
      * ]
      *
+     *  ; A tstr identifying the type of certificate. The set of supported certificate types may
+     *  ; be extended without requiring a version bump of the HAL. Custom certificate types may
+     *  ; be used, but the provisioning server may reject the request for an unknown certificate
+     *  ; type. The currently defined certificate types are:
+     *  ;  - "widevine"
+     *  ;  - "keymint"
+     *  CertificateType = tstr
+     *
      * KeysToSign = [ * PublicKey ]   ; Please see MacedPublicKey.aidl for the PublicKey definition.
      *
+     * AuthenticatedMessage<T> = [
+     *    version: 3,              ; The AuthenticatedMessage CDDL Schema version.
+     *    UdsCerts,
+     *    DiceCertChain,
+     *    SignedData<T>,
+     * ]
+     *
+     * ; COSE_Sign1 (untagged)
+     * SignedData<T> = [
+     *     protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 },
+     *     unprotected: {},
+     *     payload: bstr .cbor T / nil,
+     *     signature: bstr         ; PureEd25519(CDI_Leaf_Priv, bstr .cbor SignedDataSigStruct<T>) /
+     *                             ; ECDSA(CDI_Leaf_Priv, bstr .cbor SignedDataSigStruct<T>)
+     * ]
+     *
+     * ; Sig_structure for SignedData
+     * SignedDataSigStruct<T> = [
+     *     context: "Signature1",
+     *     protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 },
+     *     external_aad: bstr .size 0,
+     *     payload: bstr .cbor T
+     * ]
+     *
      * ; UdsCerts allows the platform to provide additional certifications for the UDS_Pub. For
      * ; example, this could be provided by the hardware vendor, who certifies all of their chips.
      * ; The SignerName is a free-form string describing who generated the signature. The root