// Copyright 2019 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CRYPTOHOME_PROXY_LEGACY_CRYPTOHOME_INTERFACE_ADAPTOR_H_
#define CRYPTOHOME_PROXY_LEGACY_CRYPTOHOME_INTERFACE_ADAPTOR_H_

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <attestation/proto_bindings/interface.pb.h>
#include <attestation-client/attestation/dbus-proxies.h>
#include <base/atomic_sequence_num.h>
#include <base/location.h>
#include <base/optional.h>
#include <brillo/dbus/dbus_object.h>
#include <dbus/cryptohome/dbus-constants.h>
#include <tpm_manager/proto_bindings/tpm_manager.pb.h>
#include <tpm_manager-client/tpm_manager/dbus-proxies.h>

#include "cryptohome/platform.h"
#include "cryptohome/rpc.pb.h"
#include "cryptohome/UserDataAuth.pb.h"
#include "dbus_adaptors/org.chromium.CryptohomeInterface.h"  // NOLINT(build/include_alpha)
#include "user_data_auth/dbus-proxies.h"
// The dbus_adaptor and proxy include must happen after the protobuf include

namespace cryptohome {

// This class is for holding a DBusMethodResponse in a std::shared_ptr, so that
// we can bind it to two separate callback.
template <typename... Types>
class SharedDBusMethodResponse {
 public:
  explicit SharedDBusMethodResponse(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<Types...>>
          response)
      : response_(std::move(response)) {}

  void ReplyWithError(const brillo::Error* error) {
    CHECK(response_) << "ReplyWithError() called after response has been sent";
    response_->ReplyWithError(error);
    response_.reset(nullptr);
  }

  void ReplyWithError(const base::Location& location,
                      const std::string& error_domain,
                      const std::string& error_code,
                      const std::string& error_message) {
    CHECK(response_) << "ReplyWithError() (4 parameter version) called after "
                        "response has been sent";
    response_->ReplyWithError(location, error_domain, error_code,
                              error_message);
    response_.reset(nullptr);
  }

  void Return(const Types&... return_values) {
    CHECK(response_) << "Return() called after response has been sent";
    response_->Return(return_values...);
    response_.reset(nullptr);
  }

 private:
  std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<Types...>> response_;
};

class LegacyCryptohomeInterfaceAdaptor
    : public org::chromium::CryptohomeInterfaceInterface,
      public org::chromium::CryptohomeInterfaceAdaptor {
 public:
  explicit LegacyCryptohomeInterfaceAdaptor(
      scoped_refptr<dbus::Bus> bus, brillo::dbus_utils::DBusObject* dbus_object)
      : org::chromium::CryptohomeInterfaceAdaptor(this),
        dbus_object_(dbus_object),
        default_attestation_proxy_(new org::chromium::AttestationProxy(bus)),
        attestation_proxy_(default_attestation_proxy_.get()),
        default_tpm_ownership_proxy_(new org::chromium::TpmOwnershipProxy(bus)),
        tpm_ownership_proxy_(default_tpm_ownership_proxy_.get()),
        default_tpm_nvram_proxy_(new org::chromium::TpmNvramProxy(bus)),
        tpm_nvram_proxy_(default_tpm_nvram_proxy_.get()),
        default_userdataauth_proxy_(
            new org::chromium::UserDataAuthInterfaceProxy(bus)),
        userdataauth_proxy_(default_userdataauth_proxy_.get()),
        default_arc_quota_proxy_(new org::chromium::ArcQuotaProxy(bus)),
        arc_quota_proxy_(default_arc_quota_proxy_.get()),
        default_pkcs11_proxy_(
            new org::chromium::CryptohomePkcs11InterfaceProxy(bus)),
        pkcs11_proxy_(default_pkcs11_proxy_.get()),
        default_install_attributes_proxy_(
            new org::chromium::InstallAttributesInterfaceProxy(bus)),
        install_attributes_proxy_(default_install_attributes_proxy_.get()),
        default_misc_proxy_(
            new org::chromium::CryptohomeMiscInterfaceProxy(bus)),
        misc_proxy_(default_misc_proxy_.get()),
        default_platform_(new Platform()),
        platform_(default_platform_.get()) {}

  void RegisterAsync();

  // The actual dbus methods
  void IsMounted(std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>>
                     response) override;
  void IsMountedForUser(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool, bool>>
          response,
      const std::string& in_username) override;
  void ListKeysEx(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::AccountIdentifier& in_account_id,
      const cryptohome::AuthorizationRequest& in_authorization_request,
      const cryptohome::ListKeysRequest& in_list_keys_request) override;
  void CheckKeyEx(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::AccountIdentifier& in_account_id,
      const cryptohome::AuthorizationRequest& in_authorization_request,
      const cryptohome::CheckKeyRequest& in_check_key_request) override;
  void RemoveKeyEx(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::AccountIdentifier& in_account_id,
      const cryptohome::AuthorizationRequest& in_authorization_request,
      const cryptohome::RemoveKeyRequest& in_remove_key_request) override;
  void MassRemoveKeys(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::AccountIdentifier& in_account_id,
      const cryptohome::AuthorizationRequest& in_authorization_request,
      const cryptohome::MassRemoveKeysRequest& in_mass_remove_keys_request)
      override;
  void GetKeyDataEx(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::AccountIdentifier& in_account_id,
      const cryptohome::AuthorizationRequest& in_authorization_request,
      const cryptohome::GetKeyDataRequest& in_get_key_data_request) override;
  void MigrateKeyEx(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::AccountIdentifier& in_account,
      const cryptohome::AuthorizationRequest& in_authorization_request,
      const cryptohome::MigrateKeyRequest& in_migrate_request) override;
  void AddKeyEx(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::AccountIdentifier& in_account_id,
      const cryptohome::AuthorizationRequest& in_authorization_request,
      const cryptohome::AddKeyRequest& in_add_key_request) override;
  void AddDataRestoreKey(std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
                             cryptohome::BaseReply>> response,
                         const cryptohome::AccountIdentifier& in_account_id,
                         const cryptohome::AuthorizationRequest&
                             in_authorization_request) override;
  void UpdateKeyEx(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::AccountIdentifier& in_account_id,
      const cryptohome::AuthorizationRequest& in_authorization_request,
      const cryptohome::UpdateKeyRequest& in_update_key_request) override;
  void RemoveEx(std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
                    cryptohome::BaseReply>> response,
                const cryptohome::AccountIdentifier& in_account) override;
  void GetSystemSalt(std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
                         std::vector<uint8_t>>> response) override;
  void GetSanitizedUsername(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<std::string>>
          response,
      const std::string& in_username) override;
  void MountEx(std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
                   cryptohome::BaseReply>> response,
               const cryptohome::AccountIdentifier& in_account_id,
               const cryptohome::AuthorizationRequest& in_authorization_request,
               const cryptohome::MountRequest& in_mount_request) override;
  void MountGuestEx(std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
                        cryptohome::BaseReply>> response,
                    const cryptohome::MountGuestRequest& in_request) override;
  void RenameCryptohome(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::AccountIdentifier& in_cryptohome_id_from,
      const cryptohome::AccountIdentifier& in_cryptohome_id_to) override;
  void GetAccountDiskUsage(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::AccountIdentifier& in_account_id) override;
  void UnmountEx(std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
                     cryptohome::BaseReply>> response,
                 const cryptohome::UnmountRequest& in_request) override;
  void UpdateCurrentUserActivityTimestamp(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<>> response,
      int32_t in_time_shift_sec) override;
  void TpmIsReady(std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>>
                      response) override;
  void TpmIsEnabled(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>> response)
      override;
  void TpmGetPassword(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<std::string>>
          response) override;
  void TpmIsOwned(std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>>
                      response) override;
  void TpmIsBeingOwned(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>> response)
      override;
  void TpmCanAttemptOwnership(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<>> response)
      override;
  void TpmClearStoredPassword(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<>> response)
      override;
  void TpmIsAttestationPrepared(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>> response)
      override;
  void TpmAttestationGetEnrollmentPreparationsEx(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::AttestationGetEnrollmentPreparationsRequest& in_request)
      override;
  void TpmVerifyAttestationData(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>> response,
      bool in_is_cros_core) override;
  void TpmVerifyEK(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>> response,
      bool in_is_cros_core) override;
  void TpmAttestationCreateEnrollRequest(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          std::vector<uint8_t>>> response,
      int32_t in_pca_type) override;
  void AsyncTpmAttestationCreateEnrollRequest(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<int32_t>> response,
      int32_t in_pca_type) override;
  void TpmAttestationEnroll(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>> response,
      int32_t in_pca_type,
      const std::vector<uint8_t>& in_pca_response) override;
  void AsyncTpmAttestationEnroll(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<int32_t>> response,
      int32_t in_pca_type,
      const std::vector<uint8_t>& in_pca_response) override;
  void TpmAttestationEnrollEx(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>> response,
      int32_t in_pca_type,
      bool in_forced) override;
  void AsyncTpmAttestationEnrollEx(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<int32_t>> response,
      int32_t in_pca_type,
      bool in_forced) override;
  void TpmAttestationCreateCertRequest(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          std::vector<uint8_t>>> response,
      int32_t in_pca_type,
      int32_t in_certificate_profile,
      const std::string& in_username,
      const std::string& in_request_origin) override;
  void AsyncTpmAttestationCreateCertRequest(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<int32_t>> response,
      int32_t in_pca_type,
      int32_t in_certificate_profile,
      const std::string& in_username,
      const std::string& in_request_origin) override;
  void TpmAttestationFinishCertRequest(
      std::unique_ptr<
          brillo::dbus_utils::DBusMethodResponse<std::vector<uint8_t>, bool>>
          response,
      const std::vector<uint8_t>& in_pca_response,
      bool in_is_user_specific,
      const std::string& in_username,
      const std::string& in_key_name) override;
  void AsyncTpmAttestationFinishCertRequest(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<int32_t>> response,
      const std::vector<uint8_t>& in_pca_response,
      bool in_is_user_specific,
      const std::string& in_username,
      const std::string& in_key_name) override;
  void TpmAttestationGetCertificateEx(
      std::unique_ptr<
          brillo::dbus_utils::DBusMethodResponse<std::vector<uint8_t>, bool>>
          response,
      int32_t in_certificate_profile,
      const std::string& in_username,
      const std::string& in_request_origin,
      int32_t in_pca_type,
      int32_t in_key_type,
      const std::string& in_key_name,
      bool in_forced,
      bool in_shall_trigger_enrollment) override;
  void AsyncTpmAttestationGetCertificateEx(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<int32_t>> response,
      int32_t in_certificate_profile,
      const std::string& in_username,
      const std::string& in_request_origin,
      int32_t in_pca_type,
      int32_t in_key_type,
      const std::string& in_key_name,
      bool in_forced,
      bool in_shall_trigger_enrollment) override;
  void TpmIsAttestationEnrolled(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>> response)
      override;
  void TpmAttestationDoesKeyExist(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>> response,
      bool in_is_user_specific,
      const std::string& in_username,
      const std::string& in_key_name) override;
  void TpmAttestationGetCertificate(
      std::unique_ptr<
          brillo::dbus_utils::DBusMethodResponse<std::vector<uint8_t>, bool>>
          response,
      bool in_is_user_specific,
      const std::string& in_username,
      const std::string& in_key_name) override;
  void TpmAttestationGetPublicKey(
      std::unique_ptr<
          brillo::dbus_utils::DBusMethodResponse<std::vector<uint8_t>, bool>>
          response,
      bool in_is_user_specific,
      const std::string& in_username,
      const std::string& in_key_name) override;
  void TpmAttestationGetEnrollmentId(
      std::unique_ptr<
          brillo::dbus_utils::DBusMethodResponse<std::vector<uint8_t>, bool>>
          response,
      bool in_ignore_cache) override;

  // NOTE: Despite its name, it's an async method that will emit signal when
  // finished.
  void TpmAttestationRegisterKey(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<int32_t>> response,
      bool in_is_user_specific,
      const std::string& in_username,
      const std::string& in_key_name) override;

  void TpmAttestationSignEnterpriseChallenge(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<int32_t>> response,
      bool in_is_user_specific,
      const std::string& in_username,
      const std::string& in_key_name,
      const std::string& in_domain,
      const std::vector<uint8_t>& in_device_id,
      bool in_include_signed_public_key,
      const std::vector<uint8_t>& in_challenge) override;
  void TpmAttestationSignEnterpriseVaChallenge(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<int32_t>> response,
      int32_t in_va_type,
      bool in_is_user_specific,
      const std::string& in_username,
      const std::string& in_key_name,
      const std::string& in_domain,
      const std::vector<uint8_t>& in_device_id,
      bool in_include_signed_public_key,
      const std::vector<uint8_t>& in_challenge) override;
  void TpmAttestationSignEnterpriseVaChallengeV2(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<int32_t>> response,
      int32_t in_va_type,
      bool in_is_user_specific,
      const std::string& in_username,
      const std::string& in_key_name,
      const std::string& in_domain,
      const std::vector<uint8_t>& in_device_id,
      bool in_include_signed_public_key,
      const std::vector<uint8_t>& in_challenge,
      const std::string& in_key_name_for_spkac) override;

  // Helper for reducing code duplication between
  // TpmAttestationSignEnterpriseVaChallengeV2,
  // TpmAttestationSignEnterpriseVaChallenge and
  // TpmAttestationSignEnterpriseChallenge.
  void TpmAttestationSignEnterpriseVaChallengeV2Actual(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<int32_t>> response,
      int32_t in_va_type,
      bool in_is_user_specific,
      const std::string& in_username,
      const std::string& in_key_name,
      const std::string& in_domain,
      const std::vector<uint8_t>& in_device_id,
      bool in_include_signed_public_key,
      const std::vector<uint8_t>& in_challenge,
      const base::Optional<std::string> in_key_name_for_spkac);

  void TpmAttestationSignSimpleChallenge(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<int32_t>> response,
      bool in_is_user_specific,
      const std::string& in_username,
      const std::string& in_key_name,
      const std::vector<uint8_t>& in_challenge) override;
  void TpmAttestationGetKeyPayload(
      std::unique_ptr<
          brillo::dbus_utils::DBusMethodResponse<std::vector<uint8_t>, bool>>
          response,
      bool in_is_user_specific,
      const std::string& in_username,
      const std::string& in_key_name) override;
  void TpmAttestationSetKeyPayload(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>> response,
      bool in_is_user_specific,
      const std::string& in_username,
      const std::string& in_key_name,
      const std::vector<uint8_t>& in_payload) override;
  void TpmAttestationDeleteKeys(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>> response,
      bool in_is_user_specific,
      const std::string& in_username,
      const std::string& in_key_prefix) override;
  void TpmAttestationDeleteKey(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>> response,
      bool in_is_user_specific,
      const std::string& in_username,
      const std::string& in_key_name) override;
  void TpmAttestationGetEK(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<std::string, bool>>
          response) override;
  void TpmAttestationResetIdentity(
      std::unique_ptr<
          brillo::dbus_utils::DBusMethodResponse<std::vector<uint8_t>, bool>>
          response,
      const std::string& in_reset_token) override;
  void TpmGetVersionStructured(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<uint32_t,
                                                             uint64_t,
                                                             uint32_t,
                                                             uint32_t,
                                                             uint64_t,
                                                             std::string>>
          response) override;
  void Pkcs11IsTpmTokenReady(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>> response)
      override;
  void Pkcs11GetTpmTokenInfo(
      std::unique_ptr<brillo::dbus_utils::
                          DBusMethodResponse<std::string, std::string, int32_t>>
          response) override;
  void Pkcs11GetTpmTokenInfoForUser(
      std::unique_ptr<brillo::dbus_utils::
                          DBusMethodResponse<std::string, std::string, int32_t>>
          response,
      const std::string& in_username) override;
  void Pkcs11Terminate(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<>> response,
      const std::string& in_username) override;
  void GetStatusString(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<std::string>>
          response) override;
  void InstallAttributesGet(
      std::unique_ptr<
          brillo::dbus_utils::DBusMethodResponse<std::vector<uint8_t>, bool>>
          response,
      const std::string& in_name) override;
  void InstallAttributesSet(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>> response,
      const std::string& in_name,
      const std::vector<uint8_t>& in_value) override;
  void InstallAttributesCount(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<int32_t>> response)
      override;
  void InstallAttributesFinalize(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>> response)
      override;
  void InstallAttributesIsReady(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>> response)
      override;
  void InstallAttributesIsSecure(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>> response)
      override;
  void InstallAttributesIsInvalid(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>> response)
      override;
  void InstallAttributesIsFirstInstall(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>> response)
      override;
  void SignBootLockbox(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::SignBootLockboxRequest& in_request) override;
  void VerifyBootLockbox(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::VerifyBootLockboxRequest& in_request) override;
  void FinalizeBootLockbox(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::FinalizeBootLockboxRequest& in_request) override;
  void GetBootAttribute(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::GetBootAttributeRequest& in_request) override;
  void SetBootAttribute(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::SetBootAttributeRequest& in_request) override;
  void FlushAndSignBootAttributes(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::FlushAndSignBootAttributesRequest& in_request) override;
  void GetLoginStatus(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::GetLoginStatusRequest& in_request) override;
  void GetTpmStatus(std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
                        cryptohome::BaseReply>> response,
                    const cryptohome::GetTpmStatusRequest& in_request) override;
  void GetEndorsementInfo(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::GetEndorsementInfoRequest& in_request) override;
  void InitializeCastKey(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::InitializeCastKeyRequest& in_request) override;
  void StartFingerprintAuthSession(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::AccountIdentifier& in_account_id,
      const cryptohome::StartFingerprintAuthSessionRequest& in_request)
      override;
  void EndFingerprintAuthSession(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::EndFingerprintAuthSessionRequest& in_request) override;
  void GetFirmwareManagementParameters(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::GetFirmwareManagementParametersRequest& in_request)
      override;
  void SetFirmwareManagementParameters(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::SetFirmwareManagementParametersRequest& in_request)
      override;
  void RemoveFirmwareManagementParameters(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::RemoveFirmwareManagementParametersRequest& in_request)
      override;
  void MigrateToDircrypto(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<>> response,
      const cryptohome::AccountIdentifier& in_account_id,
      const cryptohome::MigrateToDircryptoRequest& in_migrate_request) override;
  void NeedsDircryptoMigration(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>> response,
      const cryptohome::AccountIdentifier& in_account_id) override;
  void GetSupportedKeyPolicies(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::GetSupportedKeyPoliciesRequest& in_request) override;
  void IsQuotaSupported(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>> response)
      override;
  void GetCurrentSpaceForUid(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<int64_t>> response,
      uint32_t in_uid) override;
  void GetCurrentSpaceForGid(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<int64_t>> response,
      uint32_t in_gid) override;
  void LockToSingleUserMountUntilReboot(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::LockToSingleUserMountUntilRebootRequest& in_request)
      override;
  void GetRsuDeviceId(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
          cryptohome::BaseReply>> response,
      const cryptohome::GetRsuDeviceIdRequest& in_request) override;
  void CheckHealth(std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
                       cryptohome::BaseReply>> response,
                   const cryptohome::CheckHealthRequest& in_request) override;

  // This is a public version of OnDircryptoMigrationProgressSignal() that
  // simply calls the protected version. This is only used for testing because
  // the unit test cannot call the real protected version.
  void OnDircryptoMigrationProgressSignalForTestingOnly(
      const user_data_auth::DircryptoMigrationProgress& progress) {
    OnDircryptoMigrationProgressSignal(progress);
  }

  // This is a public version of OnLowDiskSpaceSignal() that simply calls the
  // protected version. This is only used for testing because the unit test
  // cannot call the real protected version.
  void OnLowDiskSpaceSignalForTestingOnly(
      const user_data_auth::LowDiskSpace& payload) {
    OnLowDiskSpaceSignal(payload);
  }

 protected:
  // This constructor is reserved only for testing.
  LegacyCryptohomeInterfaceAdaptor(
      org::chromium::AttestationProxyInterface* attestation_proxy,
      org::chromium::TpmOwnershipProxyInterface* tpm_ownership_proxy,
      org::chromium::TpmNvramProxyInterface* tpm_nvram_proxy,
      org::chromium::UserDataAuthInterfaceProxyInterface* userdataauth_proxy,
      org::chromium::ArcQuotaProxyInterface* arc_quota_proxy,
      org::chromium::CryptohomePkcs11InterfaceProxyInterface* pkcs11_proxy,
      org::chromium::InstallAttributesInterfaceProxyInterface*
          install_attributes_proxy,
      org::chromium::CryptohomeMiscInterfaceProxyInterface* misc_proxy,
      cryptohome::Platform* platform)
      : org::chromium::CryptohomeInterfaceAdaptor(this),
        dbus_object_(nullptr),
        attestation_proxy_(attestation_proxy),
        tpm_ownership_proxy_(tpm_ownership_proxy),
        tpm_nvram_proxy_(tpm_nvram_proxy),
        userdataauth_proxy_(userdataauth_proxy),
        arc_quota_proxy_(arc_quota_proxy),
        pkcs11_proxy_(pkcs11_proxy),
        install_attributes_proxy_(install_attributes_proxy),
        misc_proxy_(misc_proxy),
        platform_(platform) {}

  // This is used in testing to be able to mock SendAsyncCallStatusSignal.
  virtual void VirtualSendAsyncCallStatusSignal(int32_t in_async_id,
                                                bool in_return_status,
                                                int32_t in_return_code) {
    SendAsyncCallStatusSignal(in_async_id, in_return_status, in_return_code);
  }

  // This is used in testing to be able to mock
  // SendAsyncCallStatusWithDataSignal.
  virtual void VirtualSendAsyncCallStatusWithDataSignal(
      int32_t in_async_id,
      bool in_return_status,
      const std::vector<uint8_t>& in_data) {
    SendAsyncCallStatusWithDataSignal(in_async_id, in_return_status, in_data);
  }

  // This is used in testing to be able to mock
  // SendDircryptoMigrationProgressSignal
  virtual void VirtualSendDircryptoMigrationProgressSignal(
      int32_t in_status, uint64_t in_current_bytes, uint64_t in_total_bytes) {
    SendDircryptoMigrationProgressSignal(in_status, in_current_bytes,
                                         in_total_bytes);
  }

  // This is used in testing to be able to mock SendLowDiskSpaceSignal
  virtual void VirtualSendLowDiskSpaceSignal(uint64_t disk_free_bytes) {
    SendLowDiskSpaceSignal(disk_free_bytes);
  }

  // Signal forwarders

  // Forwards DircryptoMigrationProgress Signal
  void OnDircryptoMigrationProgressSignal(
      const user_data_auth::DircryptoMigrationProgress& progress);

  // Forwards LowDiskSpace Signal
  void OnLowDiskSpaceSignal(const user_data_auth::LowDiskSpace& payload);

  // Handles signal registration failure
  void OnSignalConnectedHandler(const std::string& interface,
                                const std::string& signal,
                                bool success);

 private:
  // Method used as callbacks once the call to the new interface returns
  // Note that OnSuccess in the method names below refers to a successful DBus
  // call, which may or may not be the same as the action being performed by the
  // underlying API is successful. Some of our APIs opt to reflect failure to
  // perform the action that the the API is supposed to do through protobuf
  // fields (such as using CryptohomeErrorCode).
  void IsMountedOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<bool>> response,
      const user_data_auth::IsMountedReply& reply);
  void IsMountedForUserOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<bool, bool>> response,
      const user_data_auth::IsMountedReply& reply);
  void ListKeysExOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<cryptohome::BaseReply>> response,
      const user_data_auth::ListKeysReply& reply);
  void GetKeyDataOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<cryptohome::BaseReply>> response,
      const user_data_auth::GetKeyDataReply& reply);
  void AddDataRestoreKeyOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<cryptohome::BaseReply>> response,
      const user_data_auth::AddDataRestoreKeyReply& reply);
  void GetSystemSaltOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<std::vector<uint8_t>>> response,
      const user_data_auth::GetSystemSaltReply& reply);
  void GetSanitizedUsernameOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<std::string>> response,
      const user_data_auth::GetSanitizedUsernameReply& reply);
  void MountExOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<cryptohome::BaseReply>> response,
      const user_data_auth::MountReply& reply);
  void GetAccountDiskUsageOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<cryptohome::BaseReply>> response,
      const user_data_auth::GetAccountDiskUsageReply& reply);
  void UpdateCurrentUserActivityTimestampOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<>> response,
      const user_data_auth::UpdateCurrentUserActivityTimestampReply& reply);
  void TpmIsReadyOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<bool>> response,
      const tpm_manager::GetTpmStatusReply& reply);
  void TpmIsEnabledOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<bool>> response,
      const tpm_manager::GetTpmStatusReply& reply);
  void TpmGetPasswordOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<std::string>> response,
      const tpm_manager::GetTpmStatusReply& reply);
  void TpmIsOwnedOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<bool>> response,
      const tpm_manager::GetTpmStatusReply& reply);
  void TpmCanAttemptOwnershipOnSuccess(
      const tpm_manager::TakeOwnershipReply& reply);
  void TpmCanAttemptOwnershipOnFailure(brillo::Error* err);
  void TpmClearStoredPasswordOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<>> response,
      const tpm_manager::ClearStoredOwnerPasswordReply& reply);
  void TpmIsAttestationPreparedOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<bool>> response_raw,
      const attestation::GetEnrollmentPreparationsReply& reply);
  void TpmAttestationGetEnrollmentPreparationsExOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<cryptohome::BaseReply>> response,
      const attestation::GetEnrollmentPreparationsReply& reply);
  void TpmVerifyAttestationDataOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<bool>> response,
      const attestation::VerifyReply& reply);
  void TpmVerifyEKOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<bool>> response,
      const attestation::VerifyReply& reply);
  void TpmAttestationCreateEnrollRequestOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<std::vector<uint8_t>>> response,
      const attestation::CreateEnrollRequestReply& reply);
  void TpmAttestationEnrollSuccess(
      std::shared_ptr<SharedDBusMethodResponse<bool>> response,
      const attestation::FinishEnrollReply& reply);
  void TpmAttestationCreateCertRequestOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<std::vector<uint8_t>>> response,
      const attestation::CreateCertificateRequestReply& reply);
  void TpmAttestationFinishCertRequestOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<std::vector<uint8_t>, bool>>
          response,
      const attestation::FinishCertificateRequestReply& reply);
  void TpmIsAttestationEnrolledOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<bool>> response,
      const attestation::GetStatusReply& reply);
  void TpmAttestationDoesKeyExistOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<bool>> response,
      const attestation::GetKeyInfoReply& reply);
  void TpmAttestationGetCertificateOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<std::vector<uint8_t>, bool>>
          response,
      const attestation::GetKeyInfoReply& reply);
  void TpmAttestationGetPublicKeyOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<std::vector<uint8_t>, bool>>
          response,
      const attestation::GetKeyInfoReply& reply);
  void TpmAttestationGetEnrollmentIdOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<std::vector<uint8_t>, bool>>
          response,
      const attestation::GetEnrollmentIdReply& reply);
  void TpmAttestationGetKeyPayloadOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<std::vector<uint8_t>, bool>>
          response,
      const attestation::GetKeyInfoReply& reply);
  void TpmAttestationSetKeyPayloadOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<bool>> response,
      const attestation::SetKeyPayloadReply& reply);
  void TpmAttestationDeleteKeysOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<bool>> response,
      const attestation::DeleteKeysReply& reply);
  void TpmAttestationDeleteKeyOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<bool>> response,
      const attestation::DeleteKeysReply& reply);
  void TpmAttestationGetEKOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<std::string, bool>> response,
      const attestation::GetEndorsementInfoReply& reply);
  void TpmAttestationResetIdentityOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<std::vector<uint8_t>, bool>>
          response,
      const attestation::ResetIdentityReply& reply);
  void TpmGetVersionStructuredOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<uint32_t,
                                               uint64_t,
                                               uint32_t,
                                               uint32_t,
                                               uint64_t,
                                               std::string>> response,
      const tpm_manager::GetVersionInfoReply& reply);
  void Pkcs11IsTpmTokenReadyOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<bool>> response,
      const user_data_auth::Pkcs11IsTpmTokenReadyReply& reply);
  void Pkcs11GetTpmTokenInfoOnSuccess(
      std::shared_ptr<
          SharedDBusMethodResponse<std::string, std::string, int32_t>> response,
      const user_data_auth::Pkcs11GetTpmTokenInfoReply& reply);
  void Pkcs11TerminateOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<>> response,
      const user_data_auth::Pkcs11TerminateReply& reply);
  void GetStatusStringOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<std::string>> response,
      const user_data_auth::GetStatusStringReply& reply);
  void InstallAttributesGetOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<std::vector<uint8_t>, bool>>
          response,
      const user_data_auth::InstallAttributesGetReply& reply);
  void InstallAttributesSetOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<bool>> response,
      const user_data_auth::InstallAttributesSetReply& reply);
  void InstallAttributesCountOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<int32_t>> response,
      const user_data_auth::InstallAttributesGetStatusReply& reply);
  void InstallAttributesFinalizeOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<bool>> response,
      const user_data_auth::InstallAttributesFinalizeReply& reply);
  void InstallAttributesIsReadyOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<bool>> response,
      const user_data_auth::InstallAttributesGetStatusReply& reply);
  void InstallAttributesIsSecureOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<bool>> response,
      const user_data_auth::InstallAttributesGetStatusReply& reply);
  void InstallAttributesIsInvalidOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<bool>> response,
      const user_data_auth::InstallAttributesGetStatusReply& reply);
  void InstallAttributesIsFirstInstallOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<bool>> response,
      const user_data_auth::InstallAttributesGetStatusReply& reply);
  void GetLoginStatusOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<cryptohome::BaseReply>> response,
      const user_data_auth::GetLoginStatusReply& reply);
  void GetTpmStatusOnStageOwnershipStatusDone(
      std::shared_ptr<SharedDBusMethodResponse<cryptohome::BaseReply>> response,
      const tpm_manager::GetTpmStatusReply& status_reply);
  void GetTpmStatusOnStageDictionaryAttackDone(
      std::shared_ptr<SharedDBusMethodResponse<cryptohome::BaseReply>> response,
      BaseReply reply,
      const tpm_manager::GetDictionaryAttackInfoReply& da_reply);
  void GetTpmStatusOnStageInstallAttributesDone(
      std::shared_ptr<SharedDBusMethodResponse<cryptohome::BaseReply>> response,
      BaseReply reply,
      const user_data_auth::InstallAttributesGetStatusReply&
          install_attr_reply);
  void GetTpmStatusOnStageAttestationDone(
      std::shared_ptr<SharedDBusMethodResponse<cryptohome::BaseReply>> response,
      BaseReply reply,
      const attestation::GetStatusReply& attestation_reply);
  void GetEndorsementInfoOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<cryptohome::BaseReply>> response,
      const attestation::GetEndorsementInfoReply& reply);
  void GetFirmwareManagementParametersOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<cryptohome::BaseReply>> response,
      const user_data_auth::GetFirmwareManagementParametersReply& reply);
  void MigrateToDircryptoOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<>> response,
      const user_data_auth::StartMigrateToDircryptoReply& reply);
  void NeedsDircryptoMigrationOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<bool>> response,
      const user_data_auth::NeedsDircryptoMigrationReply& reply);
  void GetSupportedKeyPoliciesOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<cryptohome::BaseReply>> response,
      const user_data_auth::GetSupportedKeyPoliciesReply& reply);
  void IsQuotaSupportedOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<bool>> response,
      const user_data_auth::GetArcDiskFeaturesReply& reply);
  void GetCurrentSpaceForUidOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<int64_t>> response,
      const user_data_auth::GetCurrentSpaceForArcUidReply& reply);
  void GetCurrentSpaceForGidOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<int64_t>> response,
      const user_data_auth::GetCurrentSpaceForArcGidReply& reply);
  void LockToSingleUserMountUntilRebootOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<cryptohome::BaseReply>> response,
      const user_data_auth::LockToSingleUserMountUntilRebootReply& reply);
  void GetRsuDeviceIdOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<cryptohome::BaseReply>> response,
      const user_data_auth::GetRsuDeviceIdReply& reply);
  void CheckHealthOnSuccess(
      std::shared_ptr<SharedDBusMethodResponse<cryptohome::BaseReply>> response,
      const user_data_auth::CheckHealthReply& reply);

  // This method forwards the error received from calling the new interface back
  // to the old interface
  template <typename... Types>
  void ForwardError(
      std::shared_ptr<SharedDBusMethodResponse<Types...>> response,
      brillo::Error* err) {
    response->ReplyWithError(err);
  }

  // Returns the next sequence ID for Async methods
  int NextSequence() {
    // AtomicSequenceNumber is zero-based, so increment so that the sequence
    // ids are one-based.
    return sequence_holder_.GetNext() + 1;
  }

  // This serves as the on_failure callback after calling the actual method
  // in attestationd.
  // Note that this is for the version of async call that have data result.
  template <typename ReplyProtoType>
  void AsyncForwardErrorWithData(const std::string& (ReplyProtoType::*func)()
                                     const,
                                 int async_id,
                                 brillo::Error* err) {
    // Error is ignored because there is no mechanism to forward the dbus
    // error through signal, and the current implementation in
    // service_distributed class handles the error by sending
    // STATUS_NOT_AVAILABLE instead, so we follow this behaviour.
    ReplyProtoType reply;
    reply.set_status(attestation::AttestationStatus::STATUS_NOT_AVAILABLE);
    AsyncReplyWithData(func, async_id, reply);
  }

  // This serves as the on_failure callback after calling the actual method
  // in attestationd
  // Note that this is for the version of async call that have no data result.
  template <typename ReplyProtoType>
  void AsyncForwardErrorWithNoData(int async_id, brillo::Error* err) {
    // Error is ignored because there is no mechanism to forward the dbus
    // error through signal, and the current implementation in
    // service_distributed class handles the error by sending
    // STATUS_NOT_AVAILABLE instead, so we follow this behaviour.
    ReplyProtoType reply;
    reply.set_status(attestation::AttestationStatus::STATUS_NOT_AVAILABLE);
    AsyncReplyWithNoData(async_id, reply);
  }

  // This serves as the on_success callback for async methods with data after
  // calling the actual method in attestationd.
  template <typename ReplyProtoType>
  void AsyncReplyWithData(const std::string& (ReplyProtoType::*func)() const,
                          int async_id,
                          const ReplyProtoType& reply) {
    std::string data_string = (reply.*func)();
    std::vector<uint8_t> data(data_string.begin(), data_string.end());
    bool return_status =
        reply.status() == attestation::AttestationStatus::STATUS_SUCCESS;
    VirtualSendAsyncCallStatusWithDataSignal(async_id, return_status, data);
  }

  // This serves as the on_success callback for async methods with no data after
  // calling the actual method in attestationd.
  template <typename ReplyProtoType>
  void AsyncReplyWithNoData(int async_id, const ReplyProtoType& reply) {
    bool return_status =
        reply.status() == attestation::AttestationStatus::STATUS_SUCCESS;
    VirtualSendAsyncCallStatusSignal(async_id, return_status, 0);
  }

  // This is a function that handles an async request received on the legacy
  // cryptohome interface. The code that calls this function resides in
  // the actual method handler, and it only needs to assemble the request
  // proto and pass it to this function, and this function will take care
  // of the rest.
  // Note that this version deals with async method calls that return byte array
  // data.
  template <typename RequestProtoType, typename ReplyProtoType>
  int HandleAsyncData(const std::string& (ReplyProtoType::*func)() const,
                      RequestProtoType request,
                      base::OnceCallback<void(
                          const RequestProtoType&,
                          const base::Callback<void(const ReplyProtoType&)>&,
                          const base::Callback<void(brillo::Error*)>&,
                          int)> target_method,
                      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) {
    int async_id = NextSequence();

    base::Callback<void(const ReplyProtoType&)> on_success = base::Bind(
        &LegacyCryptohomeInterfaceAdaptor::AsyncReplyWithData<ReplyProtoType>,
        base::Unretained(this), func, async_id);
    base::Callback<void(brillo::Error*)> on_failure =
        base::Bind(&LegacyCryptohomeInterfaceAdaptor::AsyncForwardErrorWithData<
                       ReplyProtoType>,
                   base::Unretained(this), func, async_id);
    std::move(target_method).Run(request, on_success, on_failure, timeout_ms);

    return async_id;
  }

  // This is a function that handles an async request received on the legacy
  // cryptohome interface. The code that calls this function resides in
  // the actual method handler, and it only needs to assemble the request
  // proto and pass it to this function, and this function will take care
  // of the rest.
  // Note that this version deals with async method calls that return only
  // status but not data.
  template <typename RequestProtoType, typename ReplyProtoType>
  int HandleAsyncStatus(RequestProtoType request,
                        base::OnceCallback<void(
                            const RequestProtoType&,
                            const base::Callback<void(const ReplyProtoType&)>&,
                            const base::Callback<void(brillo::Error*)>&,
                            int)> target_method) {
    int async_id = NextSequence();

    base::Callback<void(const ReplyProtoType&)> on_success = base::Bind(
        &LegacyCryptohomeInterfaceAdaptor::AsyncReplyWithNoData<ReplyProtoType>,
        base::Unretained(this), async_id);
    base::Callback<void(brillo::Error*)> on_failure = base::Bind(
        &LegacyCryptohomeInterfaceAdaptor::AsyncForwardErrorWithNoData<
            ReplyProtoType>,
        base::Unretained(this), async_id);
    std::move(target_method)
        .Run(request, on_success, on_failure,
             dbus::ObjectProxy::TIMEOUT_USE_DEFAULT);

    return async_id;
  }

  // This method is used when the handler for a successful DBus call to the new
  // API only needs to forward the error code in the new API's proto to a
  // BaseReply type on the legacy API.
  template <typename ReplyProtoType>
  static void ForwardBaseReplyErrorCode(
      std::shared_ptr<SharedDBusMethodResponse<cryptohome::BaseReply>> response,
      const ReplyProtoType& reply) {
    cryptohome::BaseReply base_reply;
    base_reply.set_error(
        static_cast<cryptohome::CryptohomeErrorCode>(reply.error()));
    ClearErrorIfNotSet(&base_reply);
    response->Return(base_reply);
  }

  // A helper function which maps an integer to a valid CertificateProfile.
  static attestation::CertificateProfile IntegerToCertificateProfile(
      int profile_value);

  // A helper function which maps an integer to a valid ACAType.
  static base::Optional<attestation::ACAType> IntegerToACAType(int type);

  // A helper function which maps an integer to a valid VAType.
  static base::Optional<attestation::VAType> IntegerToVAType(int type);

  // A helper function that clear |error| in a BaseReply if it's not set. This
  // is the default behaviour is the legacy interface and therefore should be
  // followed.
  static void ClearErrorIfNotSet(cryptohome::BaseReply* reply);

  // This is the DBus Object that this interface is registered to. Note that
  // this DBus Object is not owned by this class because multiple interfaces can
  // be associated with the same object.
  brillo::dbus_utils::DBusObject* dbus_object_;

  // Below are the DBus proxy objects that are used in this class. The default_*
  // versions are for holding an instance that is only used in actual,
  // non-testing setting. While the non default_* versions are the ones that's
  // actually used by the class. During testing, the non default_* versions will
  // be overridden with mocks for testing.
  // Note that this follows the convention in other cryptohome class such as
  // UserDataAuth class.
  std::unique_ptr<org::chromium::AttestationProxyInterface>
      default_attestation_proxy_;
  org::chromium::AttestationProxyInterface* attestation_proxy_;
  std::unique_ptr<org::chromium::TpmOwnershipProxyInterface>
      default_tpm_ownership_proxy_;
  org::chromium::TpmOwnershipProxyInterface* tpm_ownership_proxy_;
  std::unique_ptr<org::chromium::TpmNvramProxyInterface>
      default_tpm_nvram_proxy_;
  org::chromium::TpmNvramProxyInterface* tpm_nvram_proxy_;
  std::unique_ptr<org::chromium::UserDataAuthInterfaceProxyInterface>
      default_userdataauth_proxy_;
  org::chromium::UserDataAuthInterfaceProxyInterface* userdataauth_proxy_;
  std::unique_ptr<org::chromium::ArcQuotaProxyInterface>
      default_arc_quota_proxy_;
  org::chromium::ArcQuotaProxyInterface* arc_quota_proxy_;
  std::unique_ptr<org::chromium::CryptohomePkcs11InterfaceProxyInterface>
      default_pkcs11_proxy_;
  org::chromium::CryptohomePkcs11InterfaceProxyInterface* pkcs11_proxy_;
  std::unique_ptr<org::chromium::InstallAttributesInterfaceProxyInterface>
      default_install_attributes_proxy_;
  org::chromium::InstallAttributesInterfaceProxyInterface*
      install_attributes_proxy_;
  std::unique_ptr<org::chromium::CryptohomeMiscInterfaceProxyInterface>
      default_misc_proxy_;
  org::chromium::CryptohomeMiscInterfaceProxyInterface* misc_proxy_;

  // An atomic incrementing sequence for setting asynchronous call ids.
  base::AtomicSequenceNumber sequence_holder_;

  // The default platform object for accessing platform related functionalities
  std::unique_ptr<cryptohome::Platform> default_platform_;

  // The actual platform object used by this class, usually set to
  // default_platform_, but can be overridden for testing
  cryptohome::Platform* platform_;

  DISALLOW_COPY_AND_ASSIGN(LegacyCryptohomeInterfaceAdaptor);
};

}  // namespace cryptohome

#endif  // CRYPTOHOME_PROXY_LEGACY_CRYPTOHOME_INTERFACE_ADAPTOR_H_
