File: local_pointer_input_monitor_chromeos.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (175 lines) | stat: -rw-r--r-- 6,505 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
// Copyright 2018 The Chromium Authors
// 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_pointer_input_monitor.h"

#include <memory>
#include <utility>

#include "ash/shell.h"
#include "base/check_deref.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/location.h"
#include "base/task/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_constants.h"
#include "ui/events/event_target.h"
#include "ui/events/event_utils.h"
#include "ui/events/platform/platform_event_observer.h"
#include "ui/events/platform/platform_event_source.h"

namespace remoting {

namespace {

bool IsInjectedByCrd(const ui::PlatformEvent& event) {
  return event->source_device_id() == ui::ED_REMOTE_INPUT_DEVICE;
}

class LocalPointerInputMonitorChromeos : public LocalPointerInputMonitor {
 public:
  LocalPointerInputMonitorChromeos(
      scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
      scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
      LocalInputMonitor::PointerMoveCallback on_pointer_move);

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

  ~LocalPointerInputMonitorChromeos() override;

 private:
  class Core : ui::PlatformEventObserver {
   public:
    Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
         LocalInputMonitor::PointerMoveCallback on_pointer_move);

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

    ~Core() override;

    void Start();

    // ui::PlatformEventObserver interface.
    void WillProcessEvent(const ui::PlatformEvent& event) override;
    void DidProcessEvent(const ui::PlatformEvent& event) override;

   private:
    void HandlePointerMove(const ui::PlatformEvent& event, ui::EventType type);

    scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_;

    // Used to send pointer event notifications.
    // Must be called on the |caller_task_runner_|.
    LocalInputMonitor::PointerMoveCallback on_pointer_move_;
  };

  // Task runner on which ui::events are received.
  scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_;
  std::unique_ptr<Core> core_;
};

LocalPointerInputMonitorChromeos::LocalPointerInputMonitorChromeos(
    scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
    scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
    LocalInputMonitor::PointerMoveCallback on_pointer_move)
    : input_task_runner_(input_task_runner),
      core_(new Core(caller_task_runner, std::move(on_pointer_move))) {
  input_task_runner_->PostTask(
      FROM_HERE, base::BindOnce(&Core::Start, base::Unretained(core_.get())));
}

LocalPointerInputMonitorChromeos::~LocalPointerInputMonitorChromeos() {
  input_task_runner_->DeleteSoon(FROM_HERE, core_.release());
}

LocalPointerInputMonitorChromeos::Core::Core(
    scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
    LocalInputMonitor::PointerMoveCallback on_pointer_move)
    : caller_task_runner_(caller_task_runner),
      on_pointer_move_(std::move(on_pointer_move)) {}

void LocalPointerInputMonitorChromeos::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. (And if that doesn't work, maybe a PointerObserver.)
  if (ui::PlatformEventSource::GetInstance()) {
    ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
  }
}

LocalPointerInputMonitorChromeos::Core::~Core() {
  if (ui::PlatformEventSource::GetInstance()) {
    ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
  }
}

void LocalPointerInputMonitorChromeos::Core::WillProcessEvent(
    const ui::PlatformEvent& event) {
  // No need to handle this callback.
}

void LocalPointerInputMonitorChromeos::Core::DidProcessEvent(
    const ui::PlatformEvent& event) {
  // Do not pass on events remotely injected by CRD, as we're supposed to
  // monitor for local input only.
  if (IsInjectedByCrd(event)) {
    return;
  }

  ui::EventType type = ui::EventTypeFromNative(event);
  if (type == ui::EventType::kMouseMoved ||
      type == ui::EventType::kTouchMoved) {
    HandlePointerMove(event, type);
  }
}

void LocalPointerInputMonitorChromeos::Core::HandlePointerMove(
    const ui::PlatformEvent& event,
    ui::EventType type) {
  ui::LocatedEvent* located_event = event->AsLocatedEvent();
  // The event we received has the location of the mouse in pixels
  // *within the current display*. The event itself does not tell us what
  // display the mouse is on (so the top-left of every display has coordinates
  // 0x0 in the event).
  // Luckily the cursor manager remembers the display the mouse is on.
  const display::Display& current_display =
      ash::Shell::Get()->cursor_manager()->GetDisplay();
  const aura::Window& window = CHECK_DEREF(
      ash::Shell::Get()->GetRootWindowForDisplayId(current_display.id()));

  gfx::PointF location_in_window_in_pixels = located_event->location_f();

  gfx::PointF location_in_screen_in_dip =
      PointTransformer::ConvertWindowInPixelToScreenInDip(
          window, location_in_window_in_pixels);

  gfx::Point pointer_position = gfx::ToRoundedPoint(location_in_screen_in_dip);

  caller_task_runner_->PostTask(
      FROM_HERE, base::BindOnce(on_pointer_move_,
                                webrtc::DesktopVector(pointer_position.x(),
                                                      pointer_position.y()),
                                type));
}

}  // namespace

std::unique_ptr<LocalPointerInputMonitor> LocalPointerInputMonitor::Create(
    scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
    scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
    scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
    LocalInputMonitor::PointerMoveCallback on_pointer_move,
    base::OnceClosure disconnect_callback) {
  return std::make_unique<LocalPointerInputMonitorChromeos>(
      caller_task_runner, input_task_runner, std::move(on_pointer_move));
}

}  // namespace remoting