diff --git a/keystore2/apc_compat/Android.bp b/keystore2/apc_compat/Android.bp
index df7521e..61697a8 100644
--- a/keystore2/apc_compat/Android.bp
+++ b/keystore2/apc_compat/Android.bp
@@ -27,7 +27,9 @@
         "apc_compat.cpp",
     ],
     shared_libs: [
+        "libbinder_ndk",
         "android.hardware.confirmationui@1.0",
+        "android.hardware.confirmationui-V1-ndk",
         "libbase",
         "libhidlbase",
         "libutils",
diff --git a/keystore2/apc_compat/apc_compat.cpp b/keystore2/apc_compat/apc_compat.cpp
index 08a8e45..9f60db2 100644
--- a/keystore2/apc_compat/apc_compat.cpp
+++ b/keystore2/apc_compat/apc_compat.cpp
@@ -19,6 +19,12 @@
 #include <android/hardware/confirmationui/1.0/IConfirmationUI.h>
 #include <hwbinder/IBinder.h>
 
+#include <aidl/android/hardware/confirmationui/BnConfirmationResultCallback.h>
+#include <aidl/android/hardware/confirmationui/IConfirmationResultCallback.h>
+#include <aidl/android/hardware/confirmationui/IConfirmationUI.h>
+#include <aidl/android/hardware/confirmationui/UIOption.h>
+#include <android/binder_manager.h>
+
 #include <memory>
 #include <string>
 #include <thread>
@@ -33,41 +39,52 @@
 using android::hardware::hidl_vec;
 using android::hardware::Return;
 using android::hardware::Status;
-using android::hardware::confirmationui::V1_0::IConfirmationResultCallback;
-using android::hardware::confirmationui::V1_0::IConfirmationUI;
+using HidlConfirmationResultCb =
+    android::hardware::confirmationui::V1_0::IConfirmationResultCallback;
+using HidlConfirmationUI = android::hardware::confirmationui::V1_0::IConfirmationUI;
 using android::hardware::confirmationui::V1_0::ResponseCode;
-using android::hardware::confirmationui::V1_0::UIOption;
+using HidlUIOptions = android::hardware::confirmationui::V1_0::UIOption;
 
-static uint32_t responseCode2Compat(ResponseCode rc) {
-    switch (rc) {
-    case ResponseCode::OK:
-        return APC_COMPAT_ERROR_OK;
-    case ResponseCode::Canceled:
-        return APC_COMPAT_ERROR_CANCELLED;
-    case ResponseCode::Aborted:
-        return APC_COMPAT_ERROR_ABORTED;
-    case ResponseCode::OperationPending:
-        return APC_COMPAT_ERROR_OPERATION_PENDING;
-    case ResponseCode::Ignored:
-        return APC_COMPAT_ERROR_IGNORED;
-    case ResponseCode::SystemError:
-    case ResponseCode::Unimplemented:
-    case ResponseCode::Unexpected:
-    case ResponseCode::UIError:
-    case ResponseCode::UIErrorMissingGlyph:
-    case ResponseCode::UIErrorMessageTooLong:
-    case ResponseCode::UIErrorMalformedUTF8Encoding:
-    default:
-        return APC_COMPAT_ERROR_SYSTEM_ERROR;
-    }
-}
+using AidlConfirmationUI = ::aidl::android::hardware::confirmationui::IConfirmationUI;
+using AidlBnConfirmationResultCb =
+    ::aidl::android::hardware::confirmationui::BnConfirmationResultCallback;
+using AidlUIOptions = ::aidl::android::hardware::confirmationui::UIOption;
 
-class ConfuiCompatSession : public IConfirmationResultCallback, public hidl_death_recipient {
+class CompatSessionCB {
   public:
-    static sp<ConfuiCompatSession>* tryGetService() {
-        sp<IConfirmationUI> service = IConfirmationUI::tryGetService();
+    void
+    finalize(uint32_t responseCode, ApcCompatCallback callback,
+             std::optional<std::reference_wrapper<const std::vector<uint8_t>>> dataConfirmed,
+             std::optional<std::reference_wrapper<const std::vector<uint8_t>>> confirmationToken) {
+        if (callback.result != nullptr) {
+            size_t dataConfirmedSize = 0;
+            const uint8_t* dataConfirmedPtr = nullptr;
+            size_t confirmationTokenSize = 0;
+            const uint8_t* confirmationTokenPtr = nullptr;
+            if (responseCode == APC_COMPAT_ERROR_OK) {
+                if (dataConfirmed) {
+                    dataConfirmedPtr = dataConfirmed->get().data();
+                    dataConfirmedSize = dataConfirmed->get().size();
+                }
+                if (confirmationToken) {
+                    confirmationTokenPtr = confirmationToken->get().data();
+                    confirmationTokenSize = confirmationToken->get().size();
+                }
+            }
+            callback.result(callback.data, responseCode, dataConfirmedPtr, dataConfirmedSize,
+                            confirmationTokenPtr, confirmationTokenSize);
+        }
+    }
+};
+
+class ConfuiHidlCompatSession : public HidlConfirmationResultCb,
+                                public hidl_death_recipient,
+                                public CompatSessionCB {
+  public:
+    static sp<ConfuiHidlCompatSession> tryGetService() {
+        sp<HidlConfirmationUI> service = HidlConfirmationUI::tryGetService();
         if (service) {
-            return new sp(new ConfuiCompatSession(std::move(service)));
+            return sp<ConfuiHidlCompatSession>(new ConfuiHidlCompatSession(std::move(service)));
         } else {
             return nullptr;
         }
@@ -78,13 +95,12 @@
                                     const char* locale, ApcCompatUiOptions ui_options) {
         std::string hidl_prompt(prompt_text);
         std::vector<uint8_t> hidl_extra(extra_data, extra_data + extra_data_size);
-        std::string hidl_locale(locale);
-        std::vector<UIOption> hidl_ui_options;
+        std::vector<HidlUIOptions> hidl_ui_options;
         if (ui_options.inverted) {
-            hidl_ui_options.push_back(UIOption::AccessibilityInverted);
+            hidl_ui_options.push_back(HidlUIOptions::AccessibilityInverted);
         }
         if (ui_options.magnified) {
-            hidl_ui_options.push_back(UIOption::AccessibilityMagnified);
+            hidl_ui_options.push_back(HidlUIOptions::AccessibilityMagnified);
         }
         auto lock = std::lock_guard(callback_lock_);
         if (callback_.result != nullptr) {
@@ -98,7 +114,7 @@
             return APC_COMPAT_ERROR_SYSTEM_ERROR;
         }
 
-        auto rc = service_->promptUserConfirmation(sp(this), hidl_prompt, hidl_extra, hidl_locale,
+        auto rc = service_->promptUserConfirmation(sp(this), hidl_prompt, hidl_extra, locale,
                                                    hidl_ui_options);
         if (!rc.isOk()) {
             LOG(ERROR) << "Communication error: promptUserConfirmation: " << rc.description();
@@ -111,10 +127,8 @@
 
     void abort() { service_->abort(); }
 
-    void
-    finalize(ResponseCode responseCode,
-             std::optional<std::reference_wrapper<const hidl_vec<uint8_t>>> dataConfirmed,
-             std::optional<std::reference_wrapper<const hidl_vec<uint8_t>>> confirmationToken) {
+    void finalize(ResponseCode responseCode, const hidl_vec<uint8_t>& dataConfirmed,
+                  const hidl_vec<uint8_t>& confirmationToken) {
         ApcCompatCallback callback;
         {
             auto lock = std::lock_guard(callback_lock_);
@@ -128,26 +142,14 @@
         if (callback.result != nullptr) {
             service_->unlinkToDeath(sp(this));
 
-            size_t dataConfirmedSize = 0;
-            const uint8_t* dataConfirmedPtr = nullptr;
-            size_t confirmationTokenSize = 0;
-            const uint8_t* confirmationTokenPtr = nullptr;
-            if (responseCode == ResponseCode::OK) {
-                if (dataConfirmed) {
-                    dataConfirmedPtr = dataConfirmed->get().data();
-                    dataConfirmedSize = dataConfirmed->get().size();
-                }
-                if (dataConfirmed) {
-                    confirmationTokenPtr = confirmationToken->get().data();
-                    confirmationTokenSize = confirmationToken->get().size();
-                }
-            }
-            callback.result(callback.data, responseCode2Compat(responseCode), dataConfirmedPtr,
-                            dataConfirmedSize, confirmationTokenPtr, confirmationTokenSize);
+            std::vector<uint8_t> data = dataConfirmed;
+            std::vector<uint8_t> token = confirmationToken;
+
+            CompatSessionCB::finalize(responseCode2Compat(responseCode), callback, data, token);
         }
     }
 
-    // IConfirmationResultCallback overrides:
+    // HidlConfirmationResultCb overrides:
     android::hardware::Return<void> result(ResponseCode responseCode,
                                            const hidl_vec<uint8_t>& dataConfirmed,
                                            const hidl_vec<uint8_t>& confirmationToken) override {
@@ -160,10 +162,34 @@
         finalize(ResponseCode::SystemError, {}, {});
     }
 
+    static uint32_t responseCode2Compat(ResponseCode rc) {
+        switch (rc) {
+        case ResponseCode::OK:
+            return APC_COMPAT_ERROR_OK;
+        case ResponseCode::Canceled:
+            return APC_COMPAT_ERROR_CANCELLED;
+        case ResponseCode::Aborted:
+            return APC_COMPAT_ERROR_ABORTED;
+        case ResponseCode::OperationPending:
+            return APC_COMPAT_ERROR_OPERATION_PENDING;
+        case ResponseCode::Ignored:
+            return APC_COMPAT_ERROR_IGNORED;
+        case ResponseCode::SystemError:
+        case ResponseCode::Unimplemented:
+        case ResponseCode::Unexpected:
+        case ResponseCode::UIError:
+        case ResponseCode::UIErrorMissingGlyph:
+        case ResponseCode::UIErrorMessageTooLong:
+        case ResponseCode::UIErrorMalformedUTF8Encoding:
+        default:
+            return APC_COMPAT_ERROR_SYSTEM_ERROR;
+        }
+    }
+
   private:
-    ConfuiCompatSession(sp<IConfirmationUI> service)
+    ConfuiHidlCompatSession(sp<HidlConfirmationUI> service)
         : service_(service), callback_{nullptr, nullptr} {}
-    sp<IConfirmationUI> service_;
+    sp<HidlConfirmationUI> service_;
 
     // The callback_lock_ protects the callback_ field against concurrent modification.
     // IMPORTANT: It must never be held while calling the call back.
@@ -171,34 +197,248 @@
     ApcCompatCallback callback_;
 };
 
+class ConfuiAidlCompatSession : public AidlBnConfirmationResultCb, public CompatSessionCB {
+  public:
+    static std::shared_ptr<ConfuiAidlCompatSession> tryGetService() {
+        constexpr const char confirmationUIServiceName[] =
+            "android.hardware.confirmationui.IConfirmationUI/default";
+        if (!AServiceManager_isDeclared(confirmationUIServiceName)) {
+            LOG(INFO) << confirmationUIServiceName << " is not declared in VINTF";
+            return nullptr;
+        }
+        std::shared_ptr<AidlConfirmationUI> aidlService = AidlConfirmationUI::fromBinder(
+            ndk::SpAIBinder(AServiceManager_waitForService(confirmationUIServiceName)));
+        if (aidlService) {
+            return ::ndk::SharedRefBase::make<ConfuiAidlCompatSession>(aidlService);
+        }
+
+        return nullptr;
+    }
+
+    uint32_t promptUserConfirmation(ApcCompatCallback callback, const char* prompt_text,
+                                    const uint8_t* extra_data, size_t extra_data_size,
+                                    const char* locale, ApcCompatUiOptions ui_options) {
+        std::vector<uint8_t> aidl_prompt(prompt_text, prompt_text + strlen(prompt_text));
+        std::vector<uint8_t> aidl_extra(extra_data, extra_data + extra_data_size);
+        std::vector<AidlUIOptions> aidl_ui_options;
+        if (ui_options.inverted) {
+            aidl_ui_options.push_back(AidlUIOptions::ACCESSIBILITY_INVERTED);
+        }
+        if (ui_options.magnified) {
+            aidl_ui_options.push_back(AidlUIOptions::ACCESSIBILITY_MAGNIFIED);
+        }
+        auto lock = std::lock_guard(callback_lock_);
+        if (callback_.result != nullptr) {
+            return APC_COMPAT_ERROR_OPERATION_PENDING;
+        }
+
+        if (!aidlService_) {
+            return APC_COMPAT_ERROR_SYSTEM_ERROR;
+        }
+        auto linkRet =
+            AIBinder_linkToDeath(aidlService_->asBinder().get(), death_recipient_.get(), this);
+        if (linkRet != STATUS_OK) {
+            LOG(ERROR) << "Communication error: promptUserConfirmation: "
+                          "Trying to register death recipient: ";
+            return APC_COMPAT_ERROR_SYSTEM_ERROR;
+        }
+
+        auto rc = aidlService_->promptUserConfirmation(ref<ConfuiAidlCompatSession>(), aidl_prompt,
+                                                       aidl_extra, locale, aidl_ui_options);
+        int ret = getReturnCode(rc);
+        if (ret == AidlConfirmationUI::OK) {
+            callback_ = callback;
+        } else {
+            LOG(ERROR) << "Communication error: promptUserConfirmation: " << rc.getDescription();
+        }
+        return responseCode2Compat(ret);
+    }
+
+    void abort() {
+        if (aidlService_) {
+            aidlService_->abort();
+        }
+    }
+
+    void
+    finalize(int32_t responseCode,
+             std::optional<std::reference_wrapper<const std::vector<uint8_t>>> dataConfirmed,
+             std::optional<std::reference_wrapper<const std::vector<uint8_t>>> confirmationToken) {
+        ApcCompatCallback callback;
+        {
+            auto lock = std::lock_guard(callback_lock_);
+            // Calling the callback consumes the callback data structure. We have to make
+            // sure that it can only be called once.
+            callback = callback_;
+            callback_ = {nullptr, nullptr};
+            // Unlock the callback_lock_ here. It must never be held while calling the callback.
+        }
+
+        if (callback.result != nullptr) {
+            if (aidlService_) {
+                AIBinder_unlinkToDeath(aidlService_->asBinder().get(), death_recipient_.get(),
+                                       this);
+            }
+            CompatSessionCB::finalize(responseCode2Compat(responseCode), callback, dataConfirmed,
+                                      confirmationToken);
+        }
+    }
+
+    // AidlBnConfirmationResultCb overrides:
+    ::ndk::ScopedAStatus result(int32_t responseCode, const std::vector<uint8_t>& dataConfirmed,
+                                const std::vector<uint8_t>& confirmationToken) override {
+        finalize(responseCode, dataConfirmed, confirmationToken);
+        return ::ndk::ScopedAStatus::ok();
+    };
+
+    void serviceDied() {
+        aidlService_.reset();
+        aidlService_ = nullptr;
+        finalize(AidlConfirmationUI::SYSTEM_ERROR, {}, {});
+    }
+
+    static void binderDiedCallbackAidl(void* ptr) {
+        LOG(ERROR) << __func__ << " : ConfuiAidlCompatSession Service died.";
+        auto aidlSession = static_cast<ConfuiAidlCompatSession*>(ptr);
+        if (aidlSession == nullptr) {
+            LOG(ERROR) << __func__ << ": Null ConfuiAidlCompatSession HAL died.";
+            return;
+        }
+        aidlSession->serviceDied();
+    }
+
+    int getReturnCode(const ::ndk::ScopedAStatus& result) {
+        if (result.isOk()) return AidlConfirmationUI::OK;
+
+        if (result.getExceptionCode() == EX_SERVICE_SPECIFIC) {
+            return static_cast<int>(result.getServiceSpecificError());
+        }
+        return result.getStatus();
+    }
+
+    uint32_t responseCode2Compat(int32_t rc) {
+        switch (rc) {
+        case AidlConfirmationUI::OK:
+            return APC_COMPAT_ERROR_OK;
+        case AidlConfirmationUI::CANCELED:
+            return APC_COMPAT_ERROR_CANCELLED;
+        case AidlConfirmationUI::ABORTED:
+            return APC_COMPAT_ERROR_ABORTED;
+        case AidlConfirmationUI::OPERATION_PENDING:
+            return APC_COMPAT_ERROR_OPERATION_PENDING;
+        case AidlConfirmationUI::IGNORED:
+            return APC_COMPAT_ERROR_IGNORED;
+        case AidlConfirmationUI::SYSTEM_ERROR:
+        case AidlConfirmationUI::UNIMPLEMENTED:
+        case AidlConfirmationUI::UNEXPECTED:
+        case AidlConfirmationUI::UI_ERROR:
+        case AidlConfirmationUI::UI_ERROR_MISSING_GLYPH:
+        case AidlConfirmationUI::UI_ERROR_MESSAGE_TOO_LONG:
+        case AidlConfirmationUI::UI_ERROR_MALFORMED_UTF8ENCODING:
+        default:
+            return APC_COMPAT_ERROR_SYSTEM_ERROR;
+        }
+    }
+
+    ConfuiAidlCompatSession(std::shared_ptr<AidlConfirmationUI> service)
+        : aidlService_(service), callback_{nullptr, nullptr} {
+        death_recipient_ = ::ndk::ScopedAIBinder_DeathRecipient(
+            AIBinder_DeathRecipient_new(binderDiedCallbackAidl));
+    }
+
+    virtual ~ConfuiAidlCompatSession() = default;
+    ConfuiAidlCompatSession(const ConfuiAidlCompatSession&) = delete;
+    ConfuiAidlCompatSession& operator=(const ConfuiAidlCompatSession&) = delete;
+
+  private:
+    std::shared_ptr<AidlConfirmationUI> aidlService_;
+
+    // The callback_lock_ protects the callback_ field against concurrent modification.
+    // IMPORTANT: It must never be held while calling the call back.
+    std::mutex callback_lock_;
+    ApcCompatCallback callback_;
+
+    ::ndk::ScopedAIBinder_DeathRecipient death_recipient_;
+};
+
+class ApcCompatSession {
+  public:
+    static ApcCompatServiceHandle getApcCompatSession() {
+        auto aidlCompatSession = ConfuiAidlCompatSession::tryGetService();
+        if (aidlCompatSession) {
+            return new ApcCompatSession(std::move(aidlCompatSession), nullptr);
+        }
+
+        sp<ConfuiHidlCompatSession> hidlCompatSession = ConfuiHidlCompatSession::tryGetService();
+        if (hidlCompatSession) {
+            return new ApcCompatSession(nullptr, std::move(hidlCompatSession));
+        }
+
+        LOG(ERROR) << "ConfirmationUI: Not found Service";
+        return nullptr;
+    }
+
+    uint32_t promptUserConfirmation(ApcCompatCallback callback, const char* prompt_text,
+                                    const uint8_t* extra_data, size_t extra_data_size,
+                                    char const* locale, ApcCompatUiOptions ui_options) {
+        if (aidlCompatSession_) {
+            return aidlCompatSession_->promptUserConfirmation(callback, prompt_text, extra_data,
+                                                              extra_data_size, locale, ui_options);
+        } else {
+            return hidlCompatSession_->promptUserConfirmation(callback, prompt_text, extra_data,
+                                                              extra_data_size, locale, ui_options);
+        }
+    }
+
+    void abortUserConfirmation() {
+        if (aidlCompatSession_) {
+            return aidlCompatSession_->abort();
+        } else {
+            return hidlCompatSession_->abort();
+        }
+    }
+
+    void closeUserConfirmationService() {
+        // Closing the handle implicitly aborts an ongoing sessions.
+        // Note that a resulting callback is still safely conducted, because we only delete a
+        // StrongPointer below. libhwbinder still owns another StrongPointer to this session.
+        abortUserConfirmation();
+    }
+
+    ApcCompatSession(std::shared_ptr<ConfuiAidlCompatSession> aidlCompatSession,
+                     sp<ConfuiHidlCompatSession> hidlCompatSession)
+        : aidlCompatSession_(aidlCompatSession), hidlCompatSession_(hidlCompatSession) {}
+
+  private:
+    std::shared_ptr<ConfuiAidlCompatSession> aidlCompatSession_;
+    sp<ConfuiHidlCompatSession> hidlCompatSession_;
+};
 }  // namespace keystore2
 
 using namespace keystore2;
 
 ApcCompatServiceHandle tryGetUserConfirmationService() {
-    return reinterpret_cast<ApcCompatServiceHandle>(ConfuiCompatSession::tryGetService());
+    return reinterpret_cast<ApcCompatServiceHandle>(ApcCompatSession::getApcCompatSession());
 }
 
 uint32_t promptUserConfirmation(ApcCompatServiceHandle handle, ApcCompatCallback callback,
                                 const char* prompt_text, const uint8_t* extra_data,
                                 size_t extra_data_size, char const* locale,
                                 ApcCompatUiOptions ui_options) {
-    auto session = reinterpret_cast<sp<ConfuiCompatSession>*>(handle);
-    return (*session)->promptUserConfirmation(callback, prompt_text, extra_data, extra_data_size,
-                                              locale, ui_options);
+    auto session = reinterpret_cast<ApcCompatSession*>(handle);
+    return session->promptUserConfirmation(callback, prompt_text, extra_data, extra_data_size,
+                                           locale, ui_options);
 }
 
 void abortUserConfirmation(ApcCompatServiceHandle handle) {
-    auto session = reinterpret_cast<sp<ConfuiCompatSession>*>(handle);
-    (*session)->abort();
+    auto session = reinterpret_cast<ApcCompatSession*>(handle);
+    session->abortUserConfirmation();
 }
 
 void closeUserConfirmationService(ApcCompatServiceHandle handle) {
-    // Closing the handle implicitly aborts an ongoing sessions.
-    // Note that a resulting callback is still safely conducted, because we only delete a
-    // StrongPointer below. libhwbinder still owns another StrongPointer to this session.
-    abortUserConfirmation(handle);
-    delete reinterpret_cast<sp<ConfuiCompatSession>*>(handle);
+    auto session = reinterpret_cast<ApcCompatSession*>(handle);
+    session->closeUserConfirmationService();
+    delete reinterpret_cast<ApcCompatSession*>(handle);
 }
 
 const ApcCompatServiceHandle INVALID_SERVICE_HANDLE = nullptr;
