// Copyright 2013 The Chromium 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 "media/base/user_input_monitor.h"

#include <stddef.h>
#include <stdint.h>
#include <memory>

#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/lock.h"
#include "base/task/current_thread.h"
#include "base/win/message_window.h"
#include "third_party/skia/include/core/SkPoint.h"
#include "ui/events/keyboard_event_counter.h"
#include "ui/events/keycodes/keyboard_code_conversion_win.h"
#include "ui/events/win/keyboard_hook_monitor.h"
#include "ui/events/win/keyboard_hook_observer.h"

namespace media {
namespace {

// From the HID Usage Tables specification.
const USHORT kGenericDesktopPage = 1;
const USHORT kKeyboardUsage = 6;

std::unique_ptr<RAWINPUTDEVICE> GetRawInputDevices(HWND hwnd, DWORD flags) {
  std::unique_ptr<RAWINPUTDEVICE> device(new RAWINPUTDEVICE());
  device->dwFlags = flags;
  device->usUsagePage = kGenericDesktopPage;
  device->usUsage = kKeyboardUsage;
  device->hwndTarget = hwnd;
  return device;
}

// This is the actual implementation of event monitoring. It's separated from
// UserInputMonitorWin since it needs to be deleted on the UI thread.
class UserInputMonitorWinCore
    : public base::SupportsWeakPtr<UserInputMonitorWinCore>,
      public base::CurrentThread::DestructionObserver,
      public ui::KeyboardHookObserver {
 public:
  enum EventBitMask {
    MOUSE_EVENT_MASK = 1,
    KEYBOARD_EVENT_MASK = 2,
  };

  explicit UserInputMonitorWinCore(
      scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner);
  ~UserInputMonitorWinCore() override;

  // DestructionObserver overrides.
  void WillDestroyCurrentMessageLoop() override;

  // KeyboardHookObserver implementation.
  void OnHookRegistered() override;
  void OnHookUnregistered() override;

  uint32_t GetKeyPressCount() const;
  void StartMonitor();
  void StartMonitorWithMapping(base::WritableSharedMemoryMapping mapping);
  void StopMonitor();

 private:
  // Handles WM_INPUT messages.
  LRESULT OnInput(HRAWINPUT input_handle);
  // Handles messages received by |window_|.
  bool HandleMessage(UINT message,
                     WPARAM wparam,
                     LPARAM lparam,
                     LRESULT* result);

  void CreateRawInputWindow();
  void DestroyRawInputWindow();

  // Task runner on which |window_| is created.
  scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;

  // Used for sharing key press count value.
  std::unique_ptr<base::WritableSharedMemoryMapping> key_press_count_mapping_;

  // These members are only accessed on the UI thread.
  std::unique_ptr<base::win::MessageWindow> window_;
  ui::KeyboardEventCounter counter_;

  bool pause_monitoring_ = false;
  bool start_monitoring_after_hook_removed_ = false;

  DISALLOW_COPY_AND_ASSIGN(UserInputMonitorWinCore);
};

class UserInputMonitorWin : public UserInputMonitorBase {
 public:
  explicit UserInputMonitorWin(
      const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner);
  ~UserInputMonitorWin() override;

  // Public UserInputMonitor overrides.
  uint32_t GetKeyPressCount() const override;

 private:
  // Private UserInputMonitor overrides.
  void StartKeyboardMonitoring() override;
  void StartKeyboardMonitoring(
      base::WritableSharedMemoryMapping mapping) override;
  void StopKeyboardMonitoring() override;

  scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
  UserInputMonitorWinCore* core_;

  DISALLOW_COPY_AND_ASSIGN(UserInputMonitorWin);
};

UserInputMonitorWinCore::UserInputMonitorWinCore(
    scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner)
    : ui_task_runner_(ui_task_runner) {
  // Register this instance with the KeyboardHookMonitor to listen for changes
  // in the KeyboardHook registration state.  Since this instance may have been
  // constructed after a hook was registered, check the current state as well.
  ui::KeyboardHookMonitor::GetInstance()->AddObserver(this);
  pause_monitoring_ = ui::KeyboardHookMonitor::GetInstance()->IsActive();
}

UserInputMonitorWinCore::~UserInputMonitorWinCore() {
  DCHECK(!window_);
  ui::KeyboardHookMonitor::GetInstance()->RemoveObserver(this);
}

void UserInputMonitorWinCore::WillDestroyCurrentMessageLoop() {
  DCHECK(ui_task_runner_->BelongsToCurrentThread());
  StopMonitor();
}

uint32_t UserInputMonitorWinCore::GetKeyPressCount() const {
  return counter_.GetKeyPressCount();
}

void UserInputMonitorWinCore::StartMonitor() {
  DCHECK(ui_task_runner_->BelongsToCurrentThread());

  if (pause_monitoring_) {
    start_monitoring_after_hook_removed_ = true;
    return;
  }

  CreateRawInputWindow();
}

void UserInputMonitorWinCore::StartMonitorWithMapping(
    base::WritableSharedMemoryMapping mapping) {
  StartMonitor();
  key_press_count_mapping_ =
      std::make_unique<base::WritableSharedMemoryMapping>(std::move(mapping));
}

void UserInputMonitorWinCore::StopMonitor() {
  DCHECK(ui_task_runner_->BelongsToCurrentThread());

  DestroyRawInputWindow();
  start_monitoring_after_hook_removed_ = false;

  key_press_count_mapping_.reset();
}

void UserInputMonitorWinCore::OnHookRegistered() {
  DCHECK(ui_task_runner_->BelongsToCurrentThread());
  DCHECK(!pause_monitoring_);
  pause_monitoring_ = true;

  // Don't destroy |key_press_count_mapping_| as this is a temporary block and
  // we want to allow monitoring to continue using the same shared memory once
  // monitoring is unblocked.
  DestroyRawInputWindow();
}

void UserInputMonitorWinCore::OnHookUnregistered() {
  DCHECK(ui_task_runner_->BelongsToCurrentThread());
  DCHECK(pause_monitoring_);
  pause_monitoring_ = false;

  if (start_monitoring_after_hook_removed_) {
    start_monitoring_after_hook_removed_ = false;
    StartMonitor();
  }
}

void UserInputMonitorWinCore::CreateRawInputWindow() {
  DCHECK(ui_task_runner_->BelongsToCurrentThread());
  if (window_)
    return;

  std::unique_ptr<base::win::MessageWindow> window =
      std::make_unique<base::win::MessageWindow>();
  if (!window->Create(base::BindRepeating(
          &UserInputMonitorWinCore::HandleMessage, base::Unretained(this)))) {
    PLOG(ERROR) << "Failed to create the raw input window";
    return;
  }

  // Register to receive raw keyboard input.
  std::unique_ptr<RAWINPUTDEVICE> device(
      GetRawInputDevices(window->hwnd(), RIDEV_INPUTSINK));
  if (!RegisterRawInputDevices(device.get(), 1, sizeof(*device))) {
    PLOG(ERROR) << "RegisterRawInputDevices() failed for RIDEV_INPUTSINK";
    return;
  }

  window_ = std::move(window);
  // Start observing message loop destruction if we start monitoring the first
  // event.
  base::CurrentThread::Get()->AddDestructionObserver(this);
}

void UserInputMonitorWinCore::DestroyRawInputWindow() {
  DCHECK(ui_task_runner_->BelongsToCurrentThread());
  if (!window_)
    return;

  // Stop receiving raw input.
  std::unique_ptr<RAWINPUTDEVICE> device(
      GetRawInputDevices(nullptr, RIDEV_REMOVE));
  if (!RegisterRawInputDevices(device.get(), 1, sizeof(*device))) {
    PLOG(INFO) << "RegisterRawInputDevices() failed for RIDEV_REMOVE";
  }
  window_ = nullptr;

  // Stop observing message loop destruction if no event is being monitored.
  base::CurrentThread::Get()->RemoveDestructionObserver(this);
}

LRESULT UserInputMonitorWinCore::OnInput(HRAWINPUT input_handle) {
  DCHECK(ui_task_runner_->BelongsToCurrentThread());

  // Get the size of the input record.
  UINT size = 0;
  UINT result = GetRawInputData(
      input_handle, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER));
  if (result == static_cast<UINT>(-1)) {
    PLOG(ERROR) << "GetRawInputData() failed";
    return 0;
  }
  DCHECK_EQ(0u, result);

  // Retrieve the input record itself.
  std::unique_ptr<uint8_t[]> buffer(new uint8_t[size]);
  RAWINPUT* input = reinterpret_cast<RAWINPUT*>(buffer.get());
  result = GetRawInputData(
      input_handle, RID_INPUT, buffer.get(), &size, sizeof(RAWINPUTHEADER));
  if (result == static_cast<UINT>(-1)) {
    PLOG(ERROR) << "GetRawInputData() failed";
    return 0;
  }
  DCHECK_EQ(size, result);

  // Notify the observer about events generated locally.
  if (input->header.dwType == RIM_TYPEKEYBOARD &&
      input->header.hDevice != NULL) {
    ui::EventType event = (input->data.keyboard.Flags & RI_KEY_BREAK)
                              ? ui::ET_KEY_RELEASED
                              : ui::ET_KEY_PRESSED;
    ui::KeyboardCode key_code =
        ui::KeyboardCodeForWindowsKeyCode(input->data.keyboard.VKey);
    counter_.OnKeyboardEvent(event, key_code);

    // Update count value in shared memory.
    if (key_press_count_mapping_)
      WriteKeyPressMonitorCount(*key_press_count_mapping_, GetKeyPressCount());
  }

  return DefRawInputProc(&input, 1, sizeof(RAWINPUTHEADER));
}

bool UserInputMonitorWinCore::HandleMessage(UINT message,
                                            WPARAM wparam,
                                            LPARAM lparam,
                                            LRESULT* result) {
  DCHECK(ui_task_runner_->BelongsToCurrentThread());

  switch (message) {
    case WM_INPUT:
      *result = OnInput(reinterpret_cast<HRAWINPUT>(lparam));
      return true;

    default:
      return false;
  }
}

//
// Implementation of UserInputMonitorWin.
//

UserInputMonitorWin::UserInputMonitorWin(
    const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner)
    : ui_task_runner_(ui_task_runner),
      core_(new UserInputMonitorWinCore(ui_task_runner)) {}

UserInputMonitorWin::~UserInputMonitorWin() {
  if (!ui_task_runner_->DeleteSoon(FROM_HERE, core_))
    delete core_;
}

uint32_t UserInputMonitorWin::GetKeyPressCount() const {
  return core_->GetKeyPressCount();
}

void UserInputMonitorWin::StartKeyboardMonitoring() {
  ui_task_runner_->PostTask(
      FROM_HERE, base::BindOnce(&UserInputMonitorWinCore::StartMonitor,
                                core_->AsWeakPtr()));
}

void UserInputMonitorWin::StartKeyboardMonitoring(
    base::WritableSharedMemoryMapping mapping) {
  ui_task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(&UserInputMonitorWinCore::StartMonitorWithMapping,
                     core_->AsWeakPtr(), std::move(mapping)));
}

void UserInputMonitorWin::StopKeyboardMonitoring() {
  ui_task_runner_->PostTask(
      FROM_HERE, base::BindOnce(&UserInputMonitorWinCore::StopMonitor,
                                core_->AsWeakPtr()));
}

}  // namespace

std::unique_ptr<UserInputMonitor> UserInputMonitor::Create(
    scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
    scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) {
  return std::make_unique<UserInputMonitorWin>(ui_task_runner);
}

}  // namespace media
