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
|
// Copyright 2014 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/local_input_monitor.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/non_thread_safe.h"
#include "remoting/host/chromeos/point_transformer.h"
#include "remoting/host/client_session_control.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/keyboard_codes.h"
#include "ui/events/platform/platform_event_observer.h"
#include "ui/events/platform/platform_event_source.h"
namespace remoting {
namespace {
class LocalInputMonitorChromeos : public LocalInputMonitor {
public:
LocalInputMonitorChromeos(
scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
base::WeakPtr<ClientSessionControl> client_session_control);
~LocalInputMonitorChromeos() override;
private:
class Core : ui::PlatformEventObserver {
public:
Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
base::WeakPtr<ClientSessionControl> client_session_control);
~Core() override;
void Start();
// ui::PlatformEventObserver interface.
void WillProcessEvent(const ui::PlatformEvent& event) override;
void DidProcessEvent(const ui::PlatformEvent& event) override;
private:
void HandleMouseMove(const ui::PlatformEvent& event);
void HandleKeyPressed(const ui::PlatformEvent& event);
scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_;
// Points to the object receiving mouse event notifications and session
// disconnect requests. Must be called on the |caller_task_runner_|.
base::WeakPtr<ClientSessionControl> client_session_control_;
// Used to rotate the local mouse positions appropriately based on the
// current display rotation settings.
std::unique_ptr<PointTransformer> point_transformer_;
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(LocalInputMonitorChromeos);
};
LocalInputMonitorChromeos::LocalInputMonitorChromeos(
scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
base::WeakPtr<ClientSessionControl> client_session_control)
: input_task_runner_(input_task_runner),
core_(new Core(caller_task_runner, client_session_control)) {
input_task_runner_->PostTask(
FROM_HERE, base::Bind(&Core::Start, base::Unretained(core_.get())));
}
LocalInputMonitorChromeos::~LocalInputMonitorChromeos() {
input_task_runner_->DeleteSoon(FROM_HERE, core_.release());
}
LocalInputMonitorChromeos::Core::Core(
scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
base::WeakPtr<ClientSessionControl> client_session_control)
: caller_task_runner_(caller_task_runner),
client_session_control_(client_session_control) {
DCHECK(client_session_control_.get());
}
void LocalInputMonitorChromeos::Core::Start() {
ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
point_transformer_.reset(new PointTransformer());
}
LocalInputMonitorChromeos::Core::~Core() {
ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
}
void LocalInputMonitorChromeos::Core::WillProcessEvent(
const ui::PlatformEvent& event) {
// No need to handle this callback.
}
void LocalInputMonitorChromeos::Core::DidProcessEvent(
const ui::PlatformEvent& event) {
ui::EventType type = ui::EventTypeFromNative(event);
if (type == ui::ET_MOUSE_MOVED) {
HandleMouseMove(event);
} else if (type == ui::ET_KEY_PRESSED) {
HandleKeyPressed(event);
}
}
void LocalInputMonitorChromeos::Core::HandleMouseMove(
const ui::PlatformEvent& event) {
auto mouse_position = gfx::PointF(ui::EventLocationFromNative(event));
mouse_position = point_transformer_->FromScreenCoordinates(mouse_position);
caller_task_runner_->PostTask(
FROM_HERE,
base::Bind(
&ClientSessionControl::OnLocalMouseMoved, client_session_control_,
webrtc::DesktopVector(mouse_position.x(), mouse_position.y())));
}
void LocalInputMonitorChromeos::Core::HandleKeyPressed(
const ui::PlatformEvent& event) {
ui::KeyEvent key_event(event);
DCHECK(key_event.is_char());
if (key_event.IsControlDown() && key_event.IsAltDown() &&
key_event.key_code() == ui::VKEY_ESCAPE) {
caller_task_runner_->PostTask(
FROM_HERE, base::Bind(&ClientSessionControl::DisconnectSession,
client_session_control_, protocol::OK));
}
}
} // namespace
std::unique_ptr<LocalInputMonitor> LocalInputMonitor::Create(
scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
base::WeakPtr<ClientSessionControl> client_session_control) {
return base::WrapUnique(new LocalInputMonitorChromeos(
caller_task_runner, input_task_runner, client_session_control));
}
} // namespace remoting
|