// 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 "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/weak_ptr.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();

  // DestructionObserver overrides.
  virtual 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<ObserverListThreadSafe<UserInputMonitor::MouseEventListener> >
      mouse_listeners_;

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

  DISALLOW_COPY_AND_ASSIGN(UserInputMonitorWinCore);
};

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

  // Public UserInputMonitor overrides.
  virtual size_t GetKeyPressCount() const OVERRIDE;

 private:
  // Private UserInputMonitor overrides.
  virtual void StartKeyboardMonitoring() OVERRIDE;
  virtual void StopKeyboardMonitoring() OVERRIDE;
  virtual void StartMouseMonitoring() OVERRIDE;
  virtual 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)))) {
      LOG_GETLASTERROR(ERROR) << "Failed to create the raw input window";
      window_.reset();
      return;
    }
  }

  // Register to receive raw mouse and/or keyboard input.
  scoped_ptr<RAWINPUTDEVICE> device(GetRawInputDevices(type, RIDEV_INPUTSINK));
  if (!RegisterRawInputDevices(device.get(), 1, sizeof(*device))) {
    LOG_GETLASTERROR(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_);
  scoped_ptr<RAWINPUTDEVICE> device(GetRawInputDevices(type, RIDEV_REMOVE));

  if (!RegisterRawInputDevices(device.get(), 1, sizeof(*device))) {
    LOG_GETLASTERROR(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 == -1) {
    LOG_GETLASTERROR(ERROR) << "GetRawInputData() failed";
    return 0;
  }
  DCHECK_EQ(0u, result);

  // Retrieve the input record itself.
  scoped_ptr<uint8[]> buffer(new uint8[size]);
  RAWINPUT* input = reinterpret_cast<RAWINPUT*>(buffer.get());
  result = GetRawInputData(
      input_handle, RID_INPUT, buffer.get(), &size, sizeof(RAWINPUTHEADER));
  if (result == -1) {
    LOG_GETLASTERROR(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(
        &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());

  scoped_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

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

}  // namespace media
