local_hotkey_input_monitor_chromeos.cc 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "remoting/host/input_monitor/local_hotkey_input_monitor.h"
  5. #include <utility>
  6. #include "base/bind.h"
  7. #include "base/callback.h"
  8. #include "base/location.h"
  9. #include "base/task/single_thread_task_runner.h"
  10. #include "ui/events/event.h"
  11. #include "ui/events/event_utils.h"
  12. #include "ui/events/keycodes/keyboard_codes.h"
  13. #include "ui/events/platform/platform_event_observer.h"
  14. #include "ui/events/platform/platform_event_source.h"
  15. namespace remoting {
  16. namespace {
  17. class LocalHotkeyInputMonitorChromeos : public LocalHotkeyInputMonitor {
  18. public:
  19. LocalHotkeyInputMonitorChromeos(
  20. scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
  21. scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
  22. base::OnceClosure disconnect_callback);
  23. LocalHotkeyInputMonitorChromeos(const LocalHotkeyInputMonitorChromeos&) =
  24. delete;
  25. LocalHotkeyInputMonitorChromeos& operator=(
  26. const LocalHotkeyInputMonitorChromeos&) = delete;
  27. ~LocalHotkeyInputMonitorChromeos() override;
  28. private:
  29. class Core : ui::PlatformEventObserver {
  30. public:
  31. Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
  32. base::OnceClosure disconnect_callback);
  33. Core(const Core&) = delete;
  34. Core& operator=(const Core&) = delete;
  35. ~Core() override;
  36. void Start();
  37. // ui::PlatformEventObserver interface.
  38. void WillProcessEvent(const ui::PlatformEvent& event) override;
  39. void DidProcessEvent(const ui::PlatformEvent& event) override;
  40. private:
  41. void HandleKeyPressed(const ui::PlatformEvent& event);
  42. scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_;
  43. // Must be called on |caller_task_runner_|.
  44. base::OnceClosure disconnect_callback_;
  45. };
  46. // Task runner on which ui::events are received.
  47. scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_;
  48. std::unique_ptr<Core> core_;
  49. };
  50. LocalHotkeyInputMonitorChromeos::LocalHotkeyInputMonitorChromeos(
  51. scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
  52. scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
  53. base::OnceClosure disconnect_callback)
  54. : input_task_runner_(input_task_runner),
  55. core_(new Core(caller_task_runner, std::move(disconnect_callback))) {
  56. input_task_runner_->PostTask(
  57. FROM_HERE, base::BindOnce(&Core::Start, base::Unretained(core_.get())));
  58. }
  59. LocalHotkeyInputMonitorChromeos::~LocalHotkeyInputMonitorChromeos() {
  60. input_task_runner_->DeleteSoon(FROM_HERE, core_.release());
  61. }
  62. LocalHotkeyInputMonitorChromeos::Core::Core(
  63. scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
  64. base::OnceClosure disconnect_callback)
  65. : caller_task_runner_(caller_task_runner),
  66. disconnect_callback_(std::move(disconnect_callback)) {
  67. DCHECK(disconnect_callback_);
  68. }
  69. void LocalHotkeyInputMonitorChromeos::Core::Start() {
  70. // TODO(erg): Need to handle the mus case where PlatformEventSource is null
  71. // because we are in mus. This class looks like it can be rewritten with mus
  72. // EventMatchers. (And if that doesn't work, maybe a PointerObserver.)
  73. if (ui::PlatformEventSource::GetInstance())
  74. ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
  75. }
  76. LocalHotkeyInputMonitorChromeos::Core::~Core() {
  77. if (ui::PlatformEventSource::GetInstance())
  78. ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
  79. }
  80. void LocalHotkeyInputMonitorChromeos::Core::WillProcessEvent(
  81. const ui::PlatformEvent& event) {
  82. // No need to handle this callback.
  83. }
  84. void LocalHotkeyInputMonitorChromeos::Core::DidProcessEvent(
  85. const ui::PlatformEvent& event) {
  86. ui::EventType type = ui::EventTypeFromNative(event);
  87. if (type == ui::ET_KEY_PRESSED) {
  88. HandleKeyPressed(event);
  89. }
  90. }
  91. void LocalHotkeyInputMonitorChromeos::Core::HandleKeyPressed(
  92. const ui::PlatformEvent& event) {
  93. // Ignore input if we've already initiated a disconnect.
  94. if (!disconnect_callback_) {
  95. return;
  96. }
  97. DCHECK(event->IsKeyEvent());
  98. ui::KeyEvent key_event(event);
  99. if (key_event.IsControlDown() && key_event.IsAltDown() &&
  100. key_event.key_code() == ui::VKEY_ESCAPE) {
  101. caller_task_runner_->PostTask(FROM_HERE, std::move(disconnect_callback_));
  102. }
  103. }
  104. } // namespace
  105. std::unique_ptr<LocalHotkeyInputMonitor> LocalHotkeyInputMonitor::Create(
  106. scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
  107. scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
  108. scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
  109. base::OnceClosure disconnect_callback) {
  110. return std::make_unique<LocalHotkeyInputMonitorChromeos>(
  111. caller_task_runner, input_task_runner, std::move(disconnect_callback));
  112. }
  113. } // namespace remoting