// Copyright 2018 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.

#include "biod/cros_fp_device.h"

#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>

#include <algorithm>

#include <base/bind.h>
#include <base/callback_helpers.h>
#include <base/check.h>
#include <base/logging.h>
#include <base/optional.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/stringprintf.h>
#include <chromeos/ec/cros_ec_dev.h>
#include <libec/ec_command.h>
#include <libec/ec_command_async.h>
#include <libec/fingerprint/fp_context_command_factory.h>
#include <libec/fingerprint/fp_frame_command.h>
#include <libec/versions_command.h>

using ec::EcCmdVersionSupportStatus;
using ec::EcCommand;
using ec::EcCommandAsync;
using ec::EmptyParam;
using ec::FpFlashProtectCommand;
using ec::FpMode;
using ec::FpSensorErrors;
using ec::VersionsCommand;

namespace {

std::string FourCC(const uint32_t a) {
  return base::StringPrintf(
      "%c%c%c%c", static_cast<char>(a), static_cast<char>(a >> 8),
      static_cast<char>(a >> 16), static_cast<char>(a >> 24));
}

}  // namespace

namespace biod {

constexpr char CrosFpDevice::kCrosFpPath[];

CrosFpDevice::~CrosFpDevice() {
  // Current session is gone, clean-up temporary state in the FP MCU.
  if (cros_fd_.is_valid())
    ResetContext();
}

base::Optional<CrosFpDevice::EcProtocolInfo> CrosFpDevice::EcProtoInfo() {
  /* read max request / response size from the MCU for protocol v3+ */
  EcCommand<EmptyParam, struct ec_response_get_protocol_info> cmd(
      EC_CMD_GET_PROTOCOL_INFO);
  // We retry this command because it is known to occasionally fail
  // with ETIMEDOUT on first attempt.
  if (!cmd.RunWithMultipleAttempts(cros_fd_.get(), kMaxIoAttempts)) {
    return base::nullopt;
  }

  uint16_t max_read =
      cmd.Resp()->max_response_packet_size - sizeof(struct ec_host_response);
  // TODO(vpalatin): workaround for b/78544921, can be removed if MCU is fixed.
  uint16_t max_write =
      cmd.Resp()->max_request_packet_size - sizeof(struct ec_host_request) - 4;

  return EcProtocolInfo{
      .max_read = max_read,
      .max_write = max_write,
  };
}

base::Optional<std::string> CrosFpDevice::ReadVersion() {
  // TODO(b/131438292): Remove the hardcoded size for the version buffer.
  std::array<uint8_t, 80> version_buf;
  for (int retry = 0; retry < kMaxIoAttempts; retry++) {
    ssize_t bytes_read =
        read(cros_fd_.get(), version_buf.data(), version_buf.size());
    if (bytes_read >= 0) {
      LOG_IF(INFO, retry > 0)
          << "FPMCU read cros_fp device succeeded on attempt " << retry + 1
          << "/" << kMaxIoAttempts << ".";
      // Ignore the last character read, since it should be a NUL.
      auto str = std::string(version_buf.cbegin(),
                             version_buf.cbegin() + bytes_read - 1);

      size_t newline_pos = str.find_first_of('\n');
      if (newline_pos == std::string::npos) {
        return base::nullopt;
      }

      return str.substr(0, newline_pos);
    }
    if (errno != ETIMEDOUT) {
      PLOG(ERROR) << "FPMCU failed to read cros_fp device on attempt "
                  << retry + 1 << "/" << kMaxIoAttempts
                  << ", retry is not allowed for error";
      return base::nullopt;
    }
    PLOG(ERROR) << "FPMCU failed to read cros_fp device on attempt "
                << retry + 1 << "/" << kMaxIoAttempts;
  }

  return base::nullopt;
}

bool CrosFpDevice::EcDevInit() {
  // This is a special read (before events are enabled) that can fail due
  // to ETIMEDOUT. This is because the first read with events disabled
  // triggers a get_version request to the FPMCU, which can timeout.
  base::Optional<std::string> version = ReadVersion();
  if (!version) {
    LOG(ERROR) << "Failed to read cros_fp device version.";
    return false;
  }
  LOG(INFO) << "cros_fp device version: " << *version;
  if (version != CROS_EC_DEV_VERSION) {
    LOG(ERROR) << "Invalid device version";
    return false;
  }

  base::Optional<EcProtocolInfo> info = EcProtoInfo();
  if (!info) {
    LOG(ERROR) << "Failed to get cros_fp protocol info.";
    return false;
  }

  ec_protocol_info_ = *info;

  unsigned long mask = 1 << EC_MKBP_EVENT_FINGERPRINT;  // NOLINT(runtime/int)
  if (ioctl(cros_fd_.get(), CROS_EC_DEV_IOCEVENTMASK_V2, mask) < 0) {
    LOG(ERROR) << "Fail to request fingerprint events";
    return false;
  }

  return true;
}

void CrosFpDevice::OnEventReadable() {
  struct ec_response_get_next_event evt;
  ssize_t sz = read(cros_fd_.get(), &evt, sizeof(evt));

  // We are interested only in fingerprint events, discard the other ones.
  if (evt.event_type != EC_MKBP_EVENT_FINGERPRINT ||
      sz < sizeof(evt.event_type) + sizeof(evt.data.fp_events))
    return;

  // Properly aligned event value.
  uint32_t events;
  memcpy(&events, &evt.data.fp_events, sizeof(events));
  mkbp_event_.Run(events);
}

bool CrosFpDevice::SetFpMode(const FpMode& mode) {
  EcCommand<struct ec_params_fp_mode, struct ec_response_fp_mode> cmd(
      EC_CMD_FP_MODE, ec::kVersionZero, {.mode = mode.RawVal()});
  bool ret = cmd.Run(cros_fd_.get());
  if (ret) {
    return true;
  }

  // In some cases the EC Command might go through, but the AP suspends
  // before the EC can ACK it. When the AP wakes up, it considers the
  // EC command to have timed out. Since this seems to happen during mode
  // setting, check the mode in case of a failure.
  FpMode cur_mode = GetFpMode();
  if (cur_mode == FpMode(FpMode::Mode::kModeInvalid)) {
    LOG(ERROR) << "Failed to get FP mode to verify mode was set in the MCU.";
    return false;
  }
  if (cur_mode == mode) {
    LOG(WARNING)
        << "EC Command to set mode failed, but mode was set successfully.";
    return true;
  } else {
    LOG(ERROR) << "EC command to set FP mode: " << mode
               << " failed; current FP mode: " << cur_mode;
  }
  return false;
}

FpMode CrosFpDevice::GetFpMode() {
  EcCommand<struct ec_params_fp_mode, struct ec_response_fp_mode> cmd(
      EC_CMD_FP_MODE, ec::kVersionZero,
      {.mode = static_cast<uint32_t>(FP_MODE_DONT_CHANGE)});
  if (!cmd.Run(cros_fd_.get())) {
    LOG(ERROR) << "Failed to get FP mode from MCU.";
    return FpMode(FpMode::Mode::kModeInvalid);
  }

  return FpMode(cmd.Resp()->mode);
}

EcCmdVersionSupportStatus CrosFpDevice::EcCmdVersionSupported(uint16_t cmd_code,
                                                              uint32_t ver) {
  VersionsCommand versions_cmd(cmd_code);
  versions_cmd.RunWithMultipleAttempts(cros_fd_.get(), kMaxIoAttempts);
  return versions_cmd.IsVersionSupported(ver);
}

bool CrosFpDevice::SupportsPositiveMatchSecret() {
  switch (EcCmdVersionSupported(EC_CMD_FP_READ_MATCH_SECRET, 0)) {
    case EcCmdVersionSupportStatus::SUPPORTED:
      LOG(INFO) << "Positive match secret is supported.";
      return true;
    case EcCmdVersionSupportStatus::UNSUPPORTED:
      LOG(INFO) << "Positive match secret is not supported.";
      return false;
    case EcCmdVersionSupportStatus::UNKNOWN:
      LOG(WARNING) << "Failed to check support for positive match secret. "
                      "Defaulting to not supporting.";
      return false;
  }
}

base::Optional<brillo::SecureVector> CrosFpDevice::FpReadMatchSecret(
    uint16_t index) {
  EcCommand<struct ec_params_fp_read_match_secret,
            struct ec_response_fp_read_match_secret>
      cmd(EC_CMD_FP_READ_MATCH_SECRET, 0, {.fgr = index});

  if (!cmd.Run(cros_fd_.get()) &&
      cmd.Result() == ec::kEcCommandUninitializedResult) {
    LOG(ERROR) << "Failed to run EC_CMD_FP_READ_MATCH_SECRET command.";
    return base::nullopt;
  }
  if (cmd.Result() != EC_RES_SUCCESS) {
    LOG(ERROR) << "Failed to read positive match secret, result: "
               << cmd.Result() << ".";
    return base::nullopt;
  }
  brillo::SecureVector secret(sizeof(cmd.Resp()->positive_match_secret));
  std::copy(cmd.Resp()->positive_match_secret,
            cmd.Resp()->positive_match_secret +
                sizeof(cmd.Resp()->positive_match_secret),
            secret.begin());
  brillo::SecureClearContainer(cmd.Resp()->positive_match_secret);
  return secret;
}

bool CrosFpDevice::UpdateFpInfo() {
  info_ = ec_command_factory_->FpInfoCommand();

  if (!info_->Run(cros_fd_.get())) {
    LOG(ERROR) << "Failed to get FP information.";
    return false;
  }

  return true;
}

base::Optional<CrosFpDeviceInterface::FpStats> CrosFpDevice::GetFpStats() {
  EcCommand<EmptyParam, struct ec_response_fp_stats> cmd(EC_CMD_FP_STATS);
  if (!cmd.Run(cros_fd_.get())) {
    return base::nullopt;
  }

  uint8_t inval = cmd.Resp()->timestamps_invalid;
  if (inval & (FPSTATS_CAPTURE_INV | FPSTATS_MATCHING_INV)) {
    return base::nullopt;
  }

  FpStats stats = {
      .capture_ms = cmd.Resp()->capture_time_us / 1000,
      .matcher_ms = cmd.Resp()->matching_time_us / 1000,
      .overall_ms = cmd.Resp()->overall_time_us / 1000,
  };

  return stats;
}

// static
bool CrosFpDevice::WaitOnEcBoot(const base::ScopedFD& cros_fp_fd,
                                ec_current_image expected_image) {
  int tries = 50;
  ec_current_image image = EC_IMAGE_UNKNOWN;

  while (tries) {
    tries--;
    // Check the EC has the right image.
    EcCommand<EmptyParam, struct ec_response_get_version> cmd(
        EC_CMD_GET_VERSION);
    if (!cmd.Run(cros_fp_fd.get())) {
      LOG(ERROR) << "Failed to retrieve cros_fp firmware version.";
      base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(500));
      continue;
    }
    image = static_cast<ec_current_image>(cmd.Resp()->current_image);
    if (image == expected_image) {
      LOG(INFO) << "EC image is " << (image == EC_IMAGE_RO ? "RO" : "RW")
                << ".";
      return true;
    }
    base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
  }
  LOG(ERROR) << "EC rebooted to incorrect image " << image;
  return false;
}

// static
base::Optional<CrosFpDeviceInterface::EcVersion> CrosFpDevice::GetVersion(
    const base::ScopedFD& cros_fp_fd) {
  EcCommand<EmptyParam, struct ec_response_get_version> cmd(EC_CMD_GET_VERSION);
  if (!cmd.Run(cros_fp_fd.get())) {
    LOG(ERROR) << "Failed to fetch cros_fp firmware version.";
    return base::nullopt;
  }

  // buffers should already be null terminated -- this is a safeguard
  cmd.Resp()->version_string_ro[sizeof(cmd.Resp()->version_string_ro) - 1] =
      '\0';
  cmd.Resp()->version_string_rw[sizeof(cmd.Resp()->version_string_rw) - 1] =
      '\0';

  return EcVersion{
      .ro_version = std::string(cmd.Resp()->version_string_ro),
      .rw_version = std::string(cmd.Resp()->version_string_rw),
      .current_image = static_cast<ec_current_image>(cmd.Resp()->current_image),
  };
}

bool CrosFpDevice::EcReboot(ec_current_image to_image) {
  DCHECK(to_image == EC_IMAGE_RO || to_image == EC_IMAGE_RW);

  EcCommand<EmptyParam, EmptyParam> cmd_reboot(EC_CMD_REBOOT);
  // Don't expect a return code, cros_fp has rebooted.
  cmd_reboot.Run(cros_fd_.get());

  if (!WaitOnEcBoot(cros_fd_, EC_IMAGE_RO)) {
    LOG(ERROR) << "EC did not come back up after reboot.";
    return false;
  }

  if (to_image == EC_IMAGE_RO) {
    // Tell the EC to remain in RO.
    EcCommand<struct ec_params_rwsig_action, EmptyParam> cmd_rwsig(
        EC_CMD_RWSIG_ACTION);
    cmd_rwsig.SetReq({.action = RWSIG_ACTION_ABORT});
    if (!cmd_rwsig.Run(cros_fd_.get())) {
      LOG(ERROR) << "Failed to keep cros_fp in RO.";
      return false;
    }
  }

  // EC jumps to RW after 1 second. Wait enough time in case we want to reboot
  // to RW. In case we wanted to remain in RO, wait anyway to ensure that the EC
  // received the instructions.
  base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(3));

  if (!WaitOnEcBoot(cros_fd_, to_image)) {
    LOG(ERROR) << "EC did not load the right image.";
    return false;
  }

  return true;
}

bool CrosFpDevice::AddEntropy(bool reset) {
  // Create the secret.
  EcCommandAsync<struct ec_params_rollback_add_entropy, EmptyParam>
      cmd_add_entropy(EC_CMD_ADD_ENTROPY, ADD_ENTROPY_GET_RESULT,
                      {.poll_for_result_num_attempts = 20,
                       .poll_interval = base::TimeDelta::FromMilliseconds(100),
                       // The EC temporarily stops responding to EC commands
                       // when this command is run, so we will keep trying until
                       // we get success (or time out).
                       .validate_poll_result = false});
  if (reset) {
    cmd_add_entropy.SetReq({.action = ADD_ENTROPY_RESET_ASYNC});
  } else {
    cmd_add_entropy.SetReq({.action = ADD_ENTROPY_ASYNC});
  }

  if (cmd_add_entropy.Run(cros_fd_.get())) {
    LOG(INFO) << "Entropy has been successfully added.";
    return true;
  }
  LOG(ERROR) << "Failed to check status of entropy command.";
  return false;
}

base::Optional<int32_t> CrosFpDevice::GetRollBackInfoId() {
  EcCommand<EmptyParam, struct ec_response_rollback_info> cmd_rb_info(
      EC_CMD_ROLLBACK_INFO);
  if (!cmd_rb_info.Run(cros_fd_.get())) {
    return base::nullopt;
  }

  return cmd_rb_info.Resp()->id;
}

bool CrosFpDevice::InitEntropy(bool reset) {
  base::Optional<int32_t> block_id = GetRollBackInfoId();
  if (!block_id) {
    LOG(ERROR) << "Failed to read block ID from FPMCU.";
    return false;
  }

  if (!reset && *block_id != 0) {
    // Secret has been set.
    LOG(INFO) << "Entropy source had been initialized previously.";
    return true;
  }
  LOG(INFO) << "Entropy source has not been initialized yet.";

  bool success = UpdateEntropy(reset);
  if (!success) {
    LOG(INFO) << "Entropy addition failed.";
    return false;
  }
  LOG(INFO) << "Entropy has been successfully added.";
  return true;
}

bool CrosFpDevice::Init() {
  cros_fd_ = base::ScopedFD(open(kCrosFpPath, O_RDWR));
  if (cros_fd_.get() < 0) {
    LOG(ERROR) << "Failed to open " << kCrosFpPath;
    return false;
  }

  if (!EcDevInit())
    return false;

  if (!InitEntropy(false)) {
    return false;
  }

  // Clean MCU memory if anything is remaining from aborted sessions
  ResetContext();

  // Retrieve the sensor information / parameters.
  if (!UpdateFpInfo())
    return false;

  LOG(INFO) << "CROS FP Sensor Info ";
  LOG(INFO) << "  Vendor ID  : " << FourCC(info_->sensor_id()->vendor_id);
  LOG(INFO) << "  Product ID : " << info_->sensor_id()->product_id;
  LOG(INFO) << "  Model ID   : 0x" << std::hex << info_->sensor_id()->model_id;
  LOG(INFO) << "  Version    : " << info_->sensor_id()->version;
  std::string error_flags;
  if ((info_->GetFpSensorErrors() & FpSensorErrors::kNoIrq) !=
      FpSensorErrors::kNone)
    error_flags += "NO_IRQ ";
  if ((info_->GetFpSensorErrors() & FpSensorErrors::kSpiCommunication) !=
      FpSensorErrors::kNone)
    error_flags += "SPI_COMM ";
  if ((info_->GetFpSensorErrors() & FpSensorErrors::kBadHardwareID) !=
      FpSensorErrors::kNone)
    error_flags += "BAD_HWID ";
  if ((info_->GetFpSensorErrors() & FpSensorErrors::kInitializationFailure) !=
      FpSensorErrors::kNone)
    error_flags += "INIT_FAIL";
  LOG(INFO) << "  Errors     : " << error_flags;
  LOG(INFO) << "CROS FP Image Info ";
  // Prints the pixel format in FOURCC format.
  LOG(INFO) << "  Pixel Format     : "
            << FourCC(info_->sensor_image()->pixel_format);
  LOG(INFO) << "  Image Data Size  : " << info_->sensor_image()->frame_size;
  LOG(INFO) << "  Image Dimensions : " << info_->sensor_image()->width << "x"
            << info_->sensor_image()->height << " "
            << info_->sensor_image()->bpp << " bpp";
  LOG(INFO) << "CROS FP Finger Template Info ";
  LOG(INFO) << "  Template data format  : " << info_->template_info()->version;
  LOG(INFO) << "  Template Data Size    : " << info_->template_info()->size;
  LOG(INFO) << "  Max number of fingers : "
            << info_->template_info()->max_templates;

  auto fp_resp = GetFlashProtect();
  if (!fp_resp) {
    LOG(ERROR) << "Unable to read flash protect state";
  } else {
    LOG(INFO) << "Flash Protect Flags : 0x" << std::hex << fp_resp->flags
              << "\t: " << FpFlashProtectCommand::ParseFlags(fp_resp->flags);
    LOG(INFO) << "Valid Flags         : 0x" << std::hex << fp_resp->valid_flags
              << "\t: "
              << FpFlashProtectCommand::ParseFlags(fp_resp->valid_flags);
    LOG(INFO) << "writable flags      : 0x" << std::hex
              << fp_resp->writable_flags << "\t: "
              << FpFlashProtectCommand::ParseFlags(fp_resp->writable_flags);
  }

  watcher_ = base::FileDescriptorWatcher::WatchReadable(
      cros_fd_.get(), base::BindRepeating(&CrosFpDevice::OnEventReadable,
                                          base::Unretained(this)));
  if (!watcher_) {
    LOG(ERROR) << "Unable to watch MKBP events";
    return false;
  }

  if (!input_device_.Init()) {
    LOG(ERROR) << "Failed to create Uinput device";
    return false;
  }

  return true;
}

base::Optional<std::bitset<32>> CrosFpDevice::GetDirtyMap() {
  // Retrieve the up-to-date dirty bitmap from the MCU.
  if (!UpdateFpInfo()) {
    return base::nullopt;
  }

  return info_->template_info()->dirty;
}

base::Optional<int> CrosFpDevice::GetIndexOfLastTemplate() {
  if (!UpdateFpInfo()) {
    return base::nullopt;
  }
  int index = info_->template_info()->num_valid - 1;
  if (index < 0 || index >= MaxTemplateCount()) {
    LOG(ERROR) << "Invalid index of last template: " << index << ".";
    return base::nullopt;
  }
  return index;
}

base::Optional<brillo::SecureVector> CrosFpDevice::GetPositiveMatchSecret(
    int index) {
  auto opt_index = base::make_optional<int>(index);
  if (opt_index == kLastTemplate) {
    opt_index = GetIndexOfLastTemplate();
    if (!opt_index) {
      return base::nullopt;
    }
  }
  return FpReadMatchSecret(static_cast<uint16_t>(*opt_index));
}

std::unique_ptr<VendorTemplate> CrosFpDevice::GetTemplate(int index) {
  if (index == kLastTemplate) {
    auto opt_index = GetIndexOfLastTemplate();
    if (!opt_index) {
      return nullptr;
    }
    index = *opt_index;

    // Is the last one really a new created one ?
    const auto& dirty = info_->template_info()->dirty;
    if (index >= dirty.size() || !dirty.test(index)) {
      return nullptr;
    }
  }

  // In the EC_CMD_FP_FRAME host command, the templates are indexed starting
  // from 1 (aka FP_FRAME_INDEX_TEMPLATE), as 0 (aka FP_FRAME_INDEX_RAW_IMAGE)
  // is used for the finger image.
  auto fp_frame_cmd = ec_command_factory_->FpFrameCommand(
      index + FP_FRAME_INDEX_TEMPLATE, info_->template_info()->size,
      ec_protocol_info_.max_read);
  if (!fp_frame_cmd->Run(cros_fd_.get())) {
    LOG(ERROR) << "Failed to get frame, result: " << fp_frame_cmd->Result();
    return nullptr;
  }
  return fp_frame_cmd->frame();
}

bool CrosFpDevice::UploadTemplate(const VendorTemplate& tmpl) {
  union cmd_with_data {
    struct ec_params_fp_template req;
    uint8_t _fullsize[ec::kMaxPacketSize];
  };
  EcCommand<union cmd_with_data, EmptyParam> cmd(EC_CMD_FP_TEMPLATE);
  struct ec_params_fp_template* req = &cmd.Req()->req;

  size_t max_chunk = ec_protocol_info_.max_write -
                     offsetof(struct ec_params_fp_template, data);

  auto pos = tmpl.begin();
  while (pos < tmpl.end()) {
    size_t remaining = tmpl.end() - pos;
    uint32_t tlen = std::min(max_chunk, remaining);
    req->offset = pos - tmpl.begin();
    req->size = tlen | (remaining == tlen ? FP_TEMPLATE_COMMIT : 0);
    std::copy(pos, pos + tlen, req->data);
    cmd.SetReqSize(tlen + sizeof(struct ec_params_fp_template));
    if (!cmd.Run(cros_fd_.get())) {
      LOG(ERROR) << "Failed to run FP_TEMPLATE command";
      biod_metrics_->SendUploadTemplateResult(metrics::kCmdRunFailure);
      return false;
    }
    if (cmd.Result() != EC_RES_SUCCESS) {
      LOG(ERROR) << "FP_TEMPLATE command failed @ " << pos - tmpl.begin();
      biod_metrics_->SendUploadTemplateResult(cmd.Result());
      return false;
    }
    pos += tlen;
  }
  biod_metrics_->SendUploadTemplateResult(EC_RES_SUCCESS);
  return true;
}

std::unique_ptr<struct ec_response_flash_protect>
CrosFpDevice::GetFlashProtect() const {
  auto fp_cmd = ec_command_factory_->FpFlashProtectCommand(0, 0);

  if (!fp_cmd) {
    LOG(ERROR) << "Unable to create FP flash protect command";
    return nullptr;
  }

  bool success = fp_cmd->Run(cros_fd_.get());
  if (!success) {
    return nullptr;
  }

  auto ret = std::make_unique<struct ec_response_flash_protect>();
  memcpy(ret.get(), fp_cmd->Resp(), fp_cmd->RespSize());

  return ret;
}

bool CrosFpDevice::SetContext(std::string user_hex) {
  auto fp_context_cmd = ec_command_factory_->FpContextCommand(this, user_hex);

  if (!fp_context_cmd) {
    LOG(ERROR) << "Unable to create FP context command";
    biod_metrics_->SendSetContextSuccess(false);
    return false;
  }

  bool success = true;
  FpMode original_mode = GetFpMode();
  if (original_mode == FpMode(FpMode::Mode::kModeInvalid)) {
    LOG(ERROR) << "Unable to get FP Mode.";
    success = false;
  }

  // FPMCU does not allow resetting context when mode is not none, to prevent
  // interrupting sensor library and leaking memory. However, for removing
  // fingerprints, since the user is in the fingerprint list UI, FPMCU is in
  // match mode. In this case we have to exit match mode and re-enter after
  // setting context.
  if (original_mode == FpMode(FpMode::Mode::kMatch)) {
    LOG(INFO) << "Attempting to set context with match mode.";
    if (!SetFpMode(FpMode(FpMode::Mode::kNone))) {
      LOG(ERROR) << "Setting FPMCU context: failed to switch mode from match "
                 << "to none.";
      success = false;
    }
  } else if (original_mode != FpMode(FpMode::Mode::kNone)) {
    LOG(ERROR) << "Attempting to set context with mode: " << original_mode
               << ".";
    success = false;
  }
  biod_metrics_->SendSetContextMode(original_mode);

  success &= fp_context_cmd->Run(cros_fd_.get());

  if (original_mode == FpMode(FpMode::Mode::kMatch)) {
    if (!SetFpMode(original_mode)) {
      LOG(ERROR) << "Setting FPMCU context: failed to switch back to match "
                 << "mode after setting context.";
      success = false;
    }
  }

  biod_metrics_->SendSetContextSuccess(success);
  return success;
}

bool CrosFpDevice::ResetContext() {
  FpMode cur_mode = GetFpMode();
  if (cur_mode == FpMode(FpMode::Mode::kModeInvalid)) {
    LOG(ERROR) << "Unable to get FP Mode.";
  }

  // ResetContext is called when we no longer expect any session to be running
  // (such as when the user logs out or biod is starting/stopping). This check
  // exists to make sure that we have disabled any matching in the firmware
  // when this is called. See https://crbug.com/980614 for details.
  if (cur_mode != FpMode(FpMode::Mode::kNone)) {
    LOG(ERROR) << "Attempting to reset context with mode: " << cur_mode;
  }

  CHECK(biod_metrics_);
  biod_metrics_->SendResetContextMode(cur_mode);

  return SetContext(std::string());
}

bool CrosFpDevice::UpdateEntropy(bool reset) {
  // Stash the most recent block id.
  base::Optional<int32_t> block_id = GetRollBackInfoId();
  if (!block_id) {
    LOG(ERROR) << "Failed to block ID from FPMCU before entropy reset.";
    return false;
  }

  // Reboot the EC to RO.
  if (!EcReboot(EC_IMAGE_RO)) {
    LOG(ERROR) << "Failed to reboot cros_fp to initialise entropy.";
    return false;
  }

  // Initialize the secret.
  if (!AddEntropy(reset)) {
    LOG(ERROR) << "Failed to add entropy.";
    return false;
  }

  // Entropy added, reboot cros_fp to RW.
  if (!EcReboot(EC_IMAGE_RW)) {
    LOG(ERROR) << "Failed to reboot cros_fp after initializing entropy.";
    return false;
  }

  base::Optional<int32_t> new_block_id = GetRollBackInfoId();
  if (!new_block_id) {
    LOG(ERROR) << "Failed to block ID from FPMCU after entropy reset.";
    return false;
  }

  int32_t block_id_diff = 2;
  if (!reset) {
    block_id_diff = 1;
  }

  if (new_block_id != *block_id + block_id_diff) {
    LOG(ERROR) << "Entropy source has not been updated; old block_id: "
               << *block_id << ", new block_id: " << *new_block_id;
    return false;
  }
  return true;
}

int CrosFpDevice::MaxTemplateCount() {
  if (!info_ || !info_->template_info()) {
    UpdateFpInfo();
  }
  CHECK(info_);
  CHECK(info_->template_info());
  return info_->template_info()->max_templates;
}

int CrosFpDevice::TemplateVersion() {
  if (!info_ || !info_->template_info()) {
    UpdateFpInfo();
  }
  CHECK(info_);
  CHECK(info_->template_info());
  return info_->template_info()->version;
}

int CrosFpDevice::DeadPixelCount() {
  if (!info_ || !info_->template_info()) {
    UpdateFpInfo();
  }
  CHECK(info_);
  CHECK(info_->template_info());
  return info_->NumDeadPixels();
}

void CrosFpDevice::SetMkbpEventCallback(CrosFpDevice::MkbpCallback callback) {
  mkbp_event_ = callback;
}

}  // namespace biod
