// 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 <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
