123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- // 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_pointer_input_monitor.h"
- #include <memory>
- #include <utility>
- #include "ash/shell.h"
- #include "base/bind.h"
- #include "base/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::ET_MOUSE_MOVED || type == ui::ET_TOUCH_MOVED) {
- 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 =
- 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
|