// 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 "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/lock.h"
#include "base/win/message_window.h"
#include "media/base/keyboard_event_counter.h"
#include "third_party/skia/include/core/SkPoint.h"
#include "ui/events/keycodes/keyboard_code_conversion_win.h"

namespace media {
namespace {

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

// 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::MessageLoop::DestructionObserver {
 public:
  enum EventBitMask {
    MOUSE_EVENT_MASK = 1,
    KEYBOARD_EVENT_MASK = 2,
  };

  explicit UserInputMonitorWinCore(
      scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
      const scoped_refptr<UserInputMonitor::MouseListenerList>&
          mouse_listeners);
  ~UserInputMonitorWinCore() override;

  // DestructionObserver overrides.
  void WillDestroyCurrentMessageLoop() override;

  size_t GetKeyPressCount() const;
  void StartMonitor(EventBitMask type);
  void StopMonitor(EventBitMask type);

 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);
  RAWINPUTDEVICE* GetRawInputDevices(EventBitMask event, DWORD flags);

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

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

  DISALLOW_COPY_AND_ASSIGN(UserInputMonitorWinCore);
};

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

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

 private:
  // Private UserInputMonitor overrides.
  void StartKeyboardMonitoring() override;
  void StopKeyboardMonitoring() override;
  void StartMouseMonitoring() override;
  void StopMouseMonitoring() override;

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

  DISALLOW_COPY_AND_ASSIGN(UserInputMonitorWin);
};

UserInputMonitorWinCore::UserInputMonitorWinCore(
    scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
    const scoped_refptr<UserInputMonitor::MouseListenerList>& mouse_listeners)
    : ui_task_runner_(ui_task_runner),
      mouse_listeners_(mouse_listeners),
      events_monitored_(0) {}

UserInputMonitorWinCore::~UserInputMonitorWinCore() {
  DCHECK(!window_);
  DCHECK(!events_monitored_);
}

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

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

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

  if (events_monitored_ & type)
    return;

  if (type == KEYBOARD_EVENT_MASK)
    counter_.Reset();

  if (!window_) {
    window_.reset(new base::win::MessageWindow());
    if (!window_->Create(base::Bind(&UserInputMonitorWinCore::HandleMessage,
                                    base::Unretained(this)))) {
      PLOG(ERROR) << "Failed to create the raw input window";
      window_.reset();
      return;
    }
  }

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

  // Start observing message loop destruction if we start monitoring the first
  // event.
  if (!events_monitored_)
    base::MessageLoop::current()->AddDestructionObserver(this);

  events_monitored_ |= type;
}

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

  if (!(events_monitored_ & type))
    return;

  // Stop receiving raw input.
  DCHECK(window_);
  std::unique_ptr<RAWINPUTDEVICE> device(
      GetRawInputDevices(type, RIDEV_REMOVE));

  if (!RegisterRawInputDevices(device.get(), 1, sizeof(*device))) {
    PLOG(INFO) << "RegisterRawInputDevices() failed for RIDEV_REMOVE";
  }

  events_monitored_ &= ~type;
  if (events_monitored_ == 0) {
    window_.reset();

    // Stop observing message loop destruction if no event is being monitored.
    base::MessageLoop::current()->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_TYPEMOUSE && input->header.hDevice != NULL) {
    POINT position;
    if (!GetCursorPos(&position)) {
      position.x = 0;
      position.y = 0;
    }
    mouse_listeners_->Notify(
        FROM_HERE, &UserInputMonitor::MouseEventListener::OnMouseMoved,
        SkIPoint::Make(position.x, position.y));
  } else 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);
  }

  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;
  }
}

RAWINPUTDEVICE* UserInputMonitorWinCore::GetRawInputDevices(EventBitMask event,
                                                            DWORD flags) {
  DCHECK(ui_task_runner_->BelongsToCurrentThread());

  std::unique_ptr<RAWINPUTDEVICE> device(new RAWINPUTDEVICE());
  if (event == MOUSE_EVENT_MASK) {
    device->dwFlags = flags;
    device->usUsagePage = kGenericDesktopPage;
    device->usUsage = kMouseUsage;
    device->hwndTarget = window_->hwnd();
  } else {
    DCHECK_EQ(KEYBOARD_EVENT_MASK, event);
    device->dwFlags = flags;
    device->usUsagePage = kGenericDesktopPage;
    device->usUsage = kKeyboardUsage;
    device->hwndTarget = window_->hwnd();
  }
  return device.release();
}

//
// 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, mouse_listeners())) {}

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

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

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

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

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

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

}  // namespace

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

}  // namespace media
