// 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/uinput_device.h"

#include <fcntl.h>
#include <linux/uinput.h>
#include <sys/ioctl.h>

#include <algorithm>
#include <cstring>

#include <base/check.h>
#include <base/logging.h>

namespace biod {

namespace {
// When creating a new uinput device, you must specify these parameters like
// with an actual, physical device. These are sane, safe values that we use
// when creating a uinput device. Note that powerd uses this name to identify
// Chrome OS fingerprint devices.
constexpr char kFpInputDeviceName[] = "cros_fp_input";
// This is the file handle on disk that you use to control the uinput module.
constexpr char kUinputControlPath[] = "/dev/uinput";

constexpr int kDummyProductID = 0xffff;
constexpr int kGoogleVendorID = 0x18d1;
constexpr int kVersionNumber = 1;
}  // namespace

UinputDevice::UinputDevice() {
  uinput_fd_ = base::ScopedFD(-1);
}

UinputDevice::~UinputDevice() {
  // Tell the OS to destroy the uinput device as this object is destructed.
  if (uinput_fd_.is_valid()) {
    int error = TEMP_FAILURE_RETRY(ioctl(uinput_fd_.get(), UI_DEV_DESTROY));
    if (error == -1) {
      PLOG(ERROR) << "Unable to destroy uinput device.";
    }
  }
}

bool UinputDevice::Init() {
  // Open a control file descriptor for creating a new uinput device.
  // This file descriptor is used with ioctls to configure the device and
  // receive the outgoing event information.
  if (uinput_fd_.is_valid()) {
    LOG(ERROR) << "Control FD already opened! (" << uinput_fd_.get() << ").";
    return false;
  }

  uinput_fd_ = base::ScopedFD(
      TEMP_FAILURE_RETRY(open(kUinputControlPath, O_WRONLY | O_NONBLOCK)));
  if (!uinput_fd_.is_valid()) {
    PLOG(ERROR) << "Unable to open " << kUinputControlPath << ".";
    return false;
  }
  LOG(INFO) << "Uinput control file descriptor opened (" << uinput_fd_.get()
            << ").";

  // Tell the kernel that this uinput device will report events of a
  // type |EV_KEY|. Individual event codes must still be
  // enabled individually, but their overarching types need to be enabled
  // first, which is done here.
  int error = TEMP_FAILURE_RETRY(ioctl(uinput_fd_.get(), UI_SET_EVBIT, EV_KEY));
  if (error == -1) {
    PLOG(ERROR) << "Unable to enable event type 0x" << std::hex << EV_KEY
                << ".";
    return false;
  }
  LOG(INFO) << "Enabled events of type 0x" << std::hex << EV_KEY << ".";

  // Tell the kernel that this uinput device will report |KEY_WAKEUP|
  // key event.
  error =
      TEMP_FAILURE_RETRY(ioctl(uinput_fd_.get(), UI_SET_KEYBIT, KEY_WAKEUP));
  if (error == -1) {
    PLOG(ERROR) << "Unable to enable EV_KEY 0x" << std::hex << KEY_WAKEUP
                << " events.";
    return false;
  }
  LOG(INFO) << "Enabled EV_KEY 0x" << std::hex << KEY_WAKEUP << " events.";

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

  return true;
}

bool UinputDevice::SendEvent(int value) const {
  // Send an input event to the kernel through this uinput device.
  struct input_event ev;
  ev.type = EV_KEY;
  ev.code = KEY_WAKEUP;
  ev.value = value;

  int bytes_written =
      TEMP_FAILURE_RETRY(write(uinput_fd_.get(), &ev, sizeof(ev)));
  if (bytes_written != sizeof(ev)) {
    LOG(ERROR) << "Failed to write() when sending an event. (" << bytes_written
               << ").";
    return false;
  }
  return true;
}

bool UinputDevice::FinalizeUinputCreation() const {
  struct uinput_setup device_info = {};
  DCHECK(strlen(kFpInputDeviceName) < UINPUT_MAX_NAME_SIZE);
  std::copy(kFpInputDeviceName, kFpInputDeviceName + strlen(kFpInputDeviceName),
            device_info.name);
  device_info.id = {.bustype = BUS_USB,
                    .vendor = kGoogleVendorID,
                    .product = kDummyProductID,
                    .version = kVersionNumber};
  int error =
      TEMP_FAILURE_RETRY(ioctl(uinput_fd_.get(), UI_DEV_SETUP, &device_info));
  if (error == -1) {
    PLOG(ERROR) << "uinput device setup ioctl failed.";
    return false;
  }

  // Finally request that a new uinput device is created to those specs.
  // After this step the device should be fully functional and ready to
  // send events.
  error = TEMP_FAILURE_RETRY(ioctl(uinput_fd_.get(), UI_DEV_CREATE));
  if (error == -1) {
    PLOG(ERROR) << "uinput device creation ioctl failed.";
    return false;
  }

  LOG(INFO) << "Successfully finalized uinput device creation.";
  return true;
}

}  // namespace biod
