#include "ui/events/ozone/evdev/event_thread_evdev.h"
#include <memory>
#include <utility>
#include "base/allocator/partition_allocator/pointers/raw_ptr.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/message_loop/message_pump_type.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/thread.h"
#include "base/trace_event/trace_event.h"
#include "ui/events/ozone/evdev/cursor_delegate_evdev.h"
#include "ui/events/ozone/evdev/device_event_dispatcher_evdev.h"
#include "ui/events/ozone/evdev/input_controller_evdev.h"
#include "ui/events/ozone/evdev/input_device_factory_evdev.h"
#include "ui/events/ozone/evdev/input_device_factory_evdev_proxy.h"
#include "ui/events/ozone/evdev/input_device_opener_evdev.h"
namespace ui {
namespace {
class EvdevThread : public base::Thread {
public:
EvdevThread(std::unique_ptr<DeviceEventDispatcherEvdev> dispatcher,
CursorDelegateEvdev* cursor,
EventThreadStartCallback callback,
InputControllerEvdev* input_controller)
: base::Thread("evdev"),
dispatcher_(std::move(dispatcher)),
cursor_(cursor),
init_callback_(std::move(callback)),
init_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()),
input_controller_(input_controller) {}
~EvdevThread() override { Stop(); }
void Init() override {
TRACE_EVENT0("evdev", "EvdevThread::Init");
input_device_factory_ = std::make_unique<InputDeviceFactoryEvdev>(
std::move(dispatcher_), cursor_,
std::make_unique<InputDeviceOpenerEvdev>(), input_controller_);
auto proxy = std::make_unique<InputDeviceFactoryEvdevProxy>(
base::SingleThreadTaskRunner::GetCurrentDefault(),
input_device_factory_->GetWeakPtr());
if (cursor_)
cursor_->InitializeOnEvdev();
init_runner_->PostTask(
FROM_HERE, base::BindOnce(std::move(init_callback_), std::move(proxy)));
}
void CleanUp() override {
TRACE_EVENT0("evdev", "EvdevThread::CleanUp");
input_device_factory_.reset();
}
private:
std::unique_ptr<DeviceEventDispatcherEvdev> dispatcher_;
raw_ptr<CursorDelegateEvdev> cursor_;
EventThreadStartCallback init_callback_;
scoped_refptr<base::SingleThreadTaskRunner> init_runner_;
raw_ptr<InputControllerEvdev> input_controller_;
std::unique_ptr<InputDeviceFactoryEvdev> input_device_factory_;
};
}
EventThreadEvdev::EventThreadEvdev() {
}
EventThreadEvdev::~EventThreadEvdev() {
}
void EventThreadEvdev::Start(
std::unique_ptr<DeviceEventDispatcherEvdev> dispatcher,
CursorDelegateEvdev* cursor,
EventThreadStartCallback callback,
InputControllerEvdev* input_controller) {
TRACE_EVENT0("evdev", "EventThreadEvdev::Start");
thread_ = std::make_unique<EvdevThread>(
std::move(dispatcher), cursor, std::move(callback), input_controller);
base::Thread::Options thread_options;
thread_options.message_pump_type = base::MessagePumpType::UI;
thread_options.thread_type = base::ThreadType::kDisplayCritical;
if (!thread_->StartWithOptions(std::move(thread_options)))
LOG(FATAL) << "Failed to create input thread";
}
}