// 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 <sys/select.h>
#include <unistd.h>
#include <memory>

#include "base/bind.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/files/file_descriptor_watcher_posix.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/lock.h"
#include "base/task/current_thread.h"
#include "third_party/skia/include/core/SkPoint.h"
#include "ui/events/devices/x11/xinput_util.h"
#include "ui/events/keyboard_event_counter.h"
#include "ui/events/keycodes/keyboard_code_conversion_x.h"
#include "ui/gfx/x/xinput.h"

#if defined(USE_X11)
#include "ui/base/x/x11_user_input_monitor.h"  // nogncheck
#endif

#if defined(USE_OZONE)
#include "ui/base/ui_base_features.h"                     // nogncheck
#include "ui/ozone/public/ozone_platform.h"               // nogncheck
#include "ui/ozone/public/platform_user_input_monitor.h"  // nogncheck
#endif

namespace media {
namespace {

using WriteKeyPressCallback =
    base::RepeatingCallback<void(const base::WritableSharedMemoryMapping& shmem,
                                 uint32_t count)>;

// Provides a unified interface for using user input monitors of unrelated
// classes.
// TODO(crbug.com/1096425): remove this when non-Ozone path is deprecated.
class UserInputMonitorAdapter
    : public base::SupportsWeakPtr<UserInputMonitorAdapter> {
 public:
  UserInputMonitorAdapter() = default;
  UserInputMonitorAdapter(const UserInputMonitorAdapter&) = delete;
  UserInputMonitorAdapter& operator=(const UserInputMonitorAdapter&) = delete;
  virtual ~UserInputMonitorAdapter() = default;

  virtual uint32_t GetKeyPressCount() const = 0;
  virtual void StartMonitor(WriteKeyPressCallback callback) = 0;
  virtual void StartMonitorWithMapping(
      WriteKeyPressCallback callback,
      base::WritableSharedMemoryMapping mapping) = 0;
  virtual void StopMonitor() = 0;
};

// Wraps a specific user input monitor into UserInputMonitorAdapter interface.
template <typename Impl>
class UserInputMonitorLinuxCore : public UserInputMonitorAdapter {
 public:
  explicit UserInputMonitorLinuxCore(std::unique_ptr<Impl> user_input_monitor)
      : user_input_monitor_(std::move(user_input_monitor)) {}
  UserInputMonitorLinuxCore(const UserInputMonitorLinuxCore&) = delete;
  UserInputMonitorLinuxCore operator=(const UserInputMonitorLinuxCore&) =
      delete;
  ~UserInputMonitorLinuxCore() override = default;

  uint32_t GetKeyPressCount() const override {
    if (!user_input_monitor_)
      return 0;
    return user_input_monitor_->GetKeyPressCount();
  }
  void StartMonitor(WriteKeyPressCallback callback) override {
    if (!user_input_monitor_)
      return;
    user_input_monitor_->StartMonitor(callback);
  }
  void StartMonitorWithMapping(
      WriteKeyPressCallback callback,
      base::WritableSharedMemoryMapping mapping) override {
    if (!user_input_monitor_)
      return;
    user_input_monitor_->StartMonitorWithMapping(callback, std::move(mapping));
  }
  void StopMonitor() override {
    if (!user_input_monitor_)
      return;
    user_input_monitor_->StopMonitor();
  }

 private:
  std::unique_ptr<Impl> user_input_monitor_;
};

class UserInputMonitorLinux : public UserInputMonitorBase {
 public:
  explicit UserInputMonitorLinux(
      const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner);

  UserInputMonitorLinux(const UserInputMonitorLinux&) = delete;
  UserInputMonitorLinux& operator=(const UserInputMonitorLinux&) = delete;

  ~UserInputMonitorLinux() 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> io_task_runner_;
  UserInputMonitorAdapter* core_;
};

UserInputMonitorAdapter* CreateUserInputMonitor(
    const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) {
#if defined(USE_OZONE)
  if (features::IsUsingOzonePlatform()) {
    return new UserInputMonitorLinuxCore<ui::PlatformUserInputMonitor>(
        ui::OzonePlatform::GetInstance()->GetPlatformUserInputMonitor(
            io_task_runner));
  }
#endif
#if defined(USE_X11)
  return new UserInputMonitorLinuxCore<ui::XUserInputMonitor>(
      std::make_unique<ui::XUserInputMonitor>(io_task_runner));
#else
  NOTREACHED();
  return nullptr;
#endif
}

//
// Implementation of UserInputMonitorLinux.
//

UserInputMonitorLinux::UserInputMonitorLinux(
    const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
    : io_task_runner_(io_task_runner),
      core_(CreateUserInputMonitor(io_task_runner_)) {}

UserInputMonitorLinux::~UserInputMonitorLinux() {
  if (core_ && !io_task_runner_->DeleteSoon(FROM_HERE, core_))
    delete core_;
}

uint32_t UserInputMonitorLinux::GetKeyPressCount() const {
  if (!core_)
    return 0;
  return core_->GetKeyPressCount();
}

void UserInputMonitorLinux::StartKeyboardMonitoring() {
  if (!core_)
    return;
  io_task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(&UserInputMonitorAdapter::StartMonitor, core_->AsWeakPtr(),
                     base::BindRepeating(&WriteKeyPressMonitorCount)));
}

void UserInputMonitorLinux::StartKeyboardMonitoring(
    base::WritableSharedMemoryMapping mapping) {
  if (!core_)
    return;
  io_task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(
          &UserInputMonitorAdapter::StartMonitorWithMapping, core_->AsWeakPtr(),
          base::BindRepeating(&WriteKeyPressMonitorCount), std::move(mapping)));
}

void UserInputMonitorLinux::StopKeyboardMonitoring() {
  if (!core_)
    return;
  io_task_runner_->PostTask(
      FROM_HERE, base::BindOnce(&UserInputMonitorAdapter::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<UserInputMonitorLinux>(io_task_runner);
}

}  // namespace media
