local_pointer_input_monitor_chromeos.cc 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  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_pointer_input_monitor.h"
  5. #include <memory>
  6. #include <utility>
  7. #include "ash/shell.h"
  8. #include "base/bind.h"
  9. #include "base/callback.h"
  10. #include "base/location.h"
  11. #include "base/task/single_thread_task_runner.h"
  12. #include "remoting/host/chromeos/point_transformer.h"
  13. #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
  14. #include "ui/events/event.h"
  15. #include "ui/events/event_constants.h"
  16. #include "ui/events/event_target.h"
  17. #include "ui/events/event_utils.h"
  18. #include "ui/events/platform/platform_event_observer.h"
  19. #include "ui/events/platform/platform_event_source.h"
  20. namespace remoting {
  21. namespace {
  22. bool IsInjectedByCrd(const ui::PlatformEvent& event) {
  23. return event->source_device_id() == ui::ED_REMOTE_INPUT_DEVICE;
  24. }
  25. class LocalPointerInputMonitorChromeos : public LocalPointerInputMonitor {
  26. public:
  27. LocalPointerInputMonitorChromeos(
  28. scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
  29. scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
  30. LocalInputMonitor::PointerMoveCallback on_pointer_move);
  31. LocalPointerInputMonitorChromeos(const LocalPointerInputMonitorChromeos&) =
  32. delete;
  33. LocalPointerInputMonitorChromeos& operator=(
  34. const LocalPointerInputMonitorChromeos&) = delete;
  35. ~LocalPointerInputMonitorChromeos() override;
  36. private:
  37. class Core : ui::PlatformEventObserver {
  38. public:
  39. Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
  40. LocalInputMonitor::PointerMoveCallback on_pointer_move);
  41. Core(const Core&) = delete;
  42. Core& operator=(const Core&) = delete;
  43. ~Core() override;
  44. void Start();
  45. // ui::PlatformEventObserver interface.
  46. void WillProcessEvent(const ui::PlatformEvent& event) override;
  47. void DidProcessEvent(const ui::PlatformEvent& event) override;
  48. private:
  49. void HandlePointerMove(const ui::PlatformEvent& event, ui::EventType type);
  50. scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_;
  51. // Used to send pointer event notifications.
  52. // Must be called on the |caller_task_runner_|.
  53. LocalInputMonitor::PointerMoveCallback on_pointer_move_;
  54. };
  55. // Task runner on which ui::events are received.
  56. scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_;
  57. std::unique_ptr<Core> core_;
  58. };
  59. LocalPointerInputMonitorChromeos::LocalPointerInputMonitorChromeos(
  60. scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
  61. scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
  62. LocalInputMonitor::PointerMoveCallback on_pointer_move)
  63. : input_task_runner_(input_task_runner),
  64. core_(new Core(caller_task_runner, std::move(on_pointer_move))) {
  65. input_task_runner_->PostTask(
  66. FROM_HERE, base::BindOnce(&Core::Start, base::Unretained(core_.get())));
  67. }
  68. LocalPointerInputMonitorChromeos::~LocalPointerInputMonitorChromeos() {
  69. input_task_runner_->DeleteSoon(FROM_HERE, core_.release());
  70. }
  71. LocalPointerInputMonitorChromeos::Core::Core(
  72. scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
  73. LocalInputMonitor::PointerMoveCallback on_pointer_move)
  74. : caller_task_runner_(caller_task_runner),
  75. on_pointer_move_(std::move(on_pointer_move)) {}
  76. void LocalPointerInputMonitorChromeos::Core::Start() {
  77. // TODO(erg): Need to handle the mus case where PlatformEventSource is null
  78. // because we are in mus. This class looks like it can be rewritten with mus
  79. // EventMatchers. (And if that doesn't work, maybe a PointerObserver.)
  80. if (ui::PlatformEventSource::GetInstance())
  81. ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
  82. }
  83. LocalPointerInputMonitorChromeos::Core::~Core() {
  84. if (ui::PlatformEventSource::GetInstance())
  85. ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
  86. }
  87. void LocalPointerInputMonitorChromeos::Core::WillProcessEvent(
  88. const ui::PlatformEvent& event) {
  89. // No need to handle this callback.
  90. }
  91. void LocalPointerInputMonitorChromeos::Core::DidProcessEvent(
  92. const ui::PlatformEvent& event) {
  93. // Do not pass on events remotely injected by CRD, as we're supposed to
  94. // monitor for local input only.
  95. if (IsInjectedByCrd(event))
  96. return;
  97. ui::EventType type = ui::EventTypeFromNative(event);
  98. if (type == ui::ET_MOUSE_MOVED || type == ui::ET_TOUCH_MOVED) {
  99. HandlePointerMove(event, type);
  100. }
  101. }
  102. void LocalPointerInputMonitorChromeos::Core::HandlePointerMove(
  103. const ui::PlatformEvent& event,
  104. ui::EventType type) {
  105. ui::LocatedEvent* located_event = event->AsLocatedEvent();
  106. // The event we received has the location of the mouse in pixels
  107. // *within the current display*. The event itself does not tell us what
  108. // display the mouse is on (so the top-left of every display has coordinates
  109. // 0x0 in the event).
  110. // Luckily the cursor manager remembers the display the mouse is on.
  111. const display::Display& current_display =
  112. ash::Shell::Get()->cursor_manager()->GetDisplay();
  113. const aura::Window* window =
  114. ash::Shell::Get()->GetRootWindowForDisplayId(current_display.id());
  115. gfx::PointF location_in_window_in_pixels = located_event->location_f();
  116. gfx::PointF location_in_screen_in_dip =
  117. PointTransformer::ConvertWindowInPixelToScreenInDip(
  118. window, location_in_window_in_pixels);
  119. gfx::Point pointer_position = gfx::ToRoundedPoint(location_in_screen_in_dip);
  120. caller_task_runner_->PostTask(
  121. FROM_HERE, base::BindOnce(on_pointer_move_,
  122. webrtc::DesktopVector(pointer_position.x(),
  123. pointer_position.y()),
  124. type));
  125. }
  126. } // namespace
  127. std::unique_ptr<LocalPointerInputMonitor> LocalPointerInputMonitor::Create(
  128. scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
  129. scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
  130. scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
  131. LocalInputMonitor::PointerMoveCallback on_pointer_move,
  132. base::OnceClosure disconnect_callback) {
  133. return std::make_unique<LocalPointerInputMonitorChromeos>(
  134. caller_task_runner, input_task_runner, std::move(on_pointer_move));
  135. }
  136. } // namespace remoting