| // Copyright 2018 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 "remoting/host/input_monitor/local_keyboard_input_monitor.h" |
| |
| #include <utility> |
| |
| #include "base/bind.h" |
| #include "base/callback.h" |
| #include "base/location.h" |
| #include "base/macros.h" |
| #include "base/single_thread_task_runner.h" |
| #include "remoting/host/chromeos/point_transformer.h" |
| #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" |
| #include "ui/events/event.h" |
| #include "ui/events/event_utils.h" |
| #include "ui/events/keycodes/dom/keycode_converter.h" |
| #include "ui/events/platform/platform_event_observer.h" |
| #include "ui/events/platform/platform_event_source.h" |
| |
| namespace remoting { |
| |
| namespace { |
| |
| class LocalKeyboardInputMonitorChromeos : public LocalKeyboardInputMonitor { |
| public: |
| LocalKeyboardInputMonitorChromeos( |
| scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
| scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, |
| LocalInputMonitor::KeyPressedCallback key_pressed_callback); |
| ~LocalKeyboardInputMonitorChromeos() override; |
| |
| private: |
| class Core : ui::PlatformEventObserver { |
| public: |
| Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
| LocalInputMonitor::KeyPressedCallback on_key_event_callback); |
| ~Core() override; |
| |
| void Start(); |
| |
| // ui::PlatformEventObserver interface. |
| void WillProcessEvent(const ui::PlatformEvent& event) override; |
| void DidProcessEvent(const ui::PlatformEvent& event) override; |
| |
| private: |
| scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; |
| LocalInputMonitor::KeyPressedCallback key_pressed_callback_; |
| |
| DISALLOW_COPY_AND_ASSIGN(Core); |
| }; |
| |
| // Task runner on which ui::events are received. |
| scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_; |
| std::unique_ptr<Core> core_; |
| |
| DISALLOW_COPY_AND_ASSIGN(LocalKeyboardInputMonitorChromeos); |
| }; |
| |
| LocalKeyboardInputMonitorChromeos::LocalKeyboardInputMonitorChromeos( |
| scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
| scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, |
| LocalInputMonitor::KeyPressedCallback key_pressed_callback) |
| : input_task_runner_(input_task_runner), |
| core_(new Core(caller_task_runner, std::move(key_pressed_callback))) { |
| input_task_runner_->PostTask( |
| FROM_HERE, base::BindOnce(&Core::Start, base::Unretained(core_.get()))); |
| } |
| |
| LocalKeyboardInputMonitorChromeos::~LocalKeyboardInputMonitorChromeos() { |
| input_task_runner_->DeleteSoon(FROM_HERE, core_.release()); |
| } |
| |
| LocalKeyboardInputMonitorChromeos::Core::Core( |
| scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
| LocalInputMonitor::KeyPressedCallback key_pressed_callback) |
| : caller_task_runner_(caller_task_runner), |
| key_pressed_callback_(std::move(key_pressed_callback)) {} |
| |
| void LocalKeyboardInputMonitorChromeos::Core::Start() { |
| // TODO(erg): Need to handle the mus case where PlatformEventSource is null |
| // because we are in mus. This class looks like it can be rewritten with mus |
| // EventMatchers. |
| if (ui::PlatformEventSource::GetInstance()) { |
| ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this); |
| } |
| } |
| |
| LocalKeyboardInputMonitorChromeos::Core::~Core() { |
| if (ui::PlatformEventSource::GetInstance()) { |
| ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this); |
| } |
| } |
| |
| void LocalKeyboardInputMonitorChromeos::Core::WillProcessEvent( |
| const ui::PlatformEvent& event) { |
| // No need to handle this callback. |
| } |
| |
| void LocalKeyboardInputMonitorChromeos::Core::DidProcessEvent( |
| const ui::PlatformEvent& event) { |
| ui::EventType type = ui::EventTypeFromNative(event); |
| if (type == ui::ET_KEY_PRESSED) { |
| ui::DomCode dom_code = ui::CodeFromNative(event); |
| uint32_t usb_keycode = ui::KeycodeConverter::DomCodeToUsbKeycode(dom_code); |
| caller_task_runner_->PostTask( |
| FROM_HERE, base::BindOnce(key_pressed_callback_, usb_keycode)); |
| } |
| } |
| |
| } // namespace |
| |
| std::unique_ptr<LocalKeyboardInputMonitor> LocalKeyboardInputMonitor::Create( |
| scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
| scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, |
| scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, |
| LocalInputMonitor::KeyPressedCallback on_key_event_callback, |
| base::OnceClosure disconnect_callback) { |
| return std::make_unique<LocalKeyboardInputMonitorChromeos>( |
| caller_task_runner, input_task_runner, std::move(on_key_event_callback)); |
| } |
| |
| } // namespace remoting |