1 // Copyright 2014 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.
5 #include "remoting/host/local_input_monitor.h"
8 #include "base/callback.h"
9 #include "base/location.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/threading/non_thread_safe.h"
12 #include "remoting/host/chromeos/point_transformer.h"
13 #include "remoting/host/client_session_control.h"
14 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
15 #include "ui/events/event.h"
16 #include "ui/events/event_utils.h"
17 #include "ui/events/keycodes/keyboard_codes.h"
18 #include "ui/events/platform/platform_event_observer.h"
19 #include "ui/events/platform/platform_event_source.h"
25 class LocalInputMonitorChromeos
: public LocalInputMonitor
{
27 LocalInputMonitorChromeos(
28 scoped_refptr
<base::SingleThreadTaskRunner
> caller_task_runner
,
29 scoped_refptr
<base::SingleThreadTaskRunner
> input_task_runner
,
30 base::WeakPtr
<ClientSessionControl
> client_session_control
);
31 ~LocalInputMonitorChromeos() override
;
34 class Core
: ui::PlatformEventObserver
{
36 Core(scoped_refptr
<base::SingleThreadTaskRunner
> caller_task_runner
,
37 base::WeakPtr
<ClientSessionControl
> client_session_control
);
42 // ui::PlatformEventObserver interface.
43 void WillProcessEvent(const ui::PlatformEvent
& event
) override
;
44 void DidProcessEvent(const ui::PlatformEvent
& event
) override
;
47 void HandleMouseMove(const ui::PlatformEvent
& event
);
48 void HandleKeyPressed(const ui::PlatformEvent
& event
);
50 scoped_refptr
<base::SingleThreadTaskRunner
> caller_task_runner_
;
52 // Points to the object receiving mouse event notifications and session
53 // disconnect requests. Must be called on the |caller_task_runner_|.
54 base::WeakPtr
<ClientSessionControl
> client_session_control_
;
56 // Used to rotate the local mouse positions appropriately based on the
57 // current display rotation settings.
58 scoped_ptr
<PointTransformer
> point_transformer_
;
60 DISALLOW_COPY_AND_ASSIGN(Core
);
63 // Task runner on which ui::events are received.
64 scoped_refptr
<base::SingleThreadTaskRunner
> input_task_runner_
;
65 scoped_ptr
<Core
> core_
;
67 DISALLOW_COPY_AND_ASSIGN(LocalInputMonitorChromeos
);
70 LocalInputMonitorChromeos::LocalInputMonitorChromeos(
71 scoped_refptr
<base::SingleThreadTaskRunner
> caller_task_runner
,
72 scoped_refptr
<base::SingleThreadTaskRunner
> input_task_runner
,
73 base::WeakPtr
<ClientSessionControl
> client_session_control
)
74 : input_task_runner_(input_task_runner
),
75 core_(new Core(caller_task_runner
, client_session_control
)) {
76 input_task_runner_
->PostTask(
77 FROM_HERE
, base::Bind(&Core::Start
, base::Unretained(core_
.get())));
80 LocalInputMonitorChromeos::~LocalInputMonitorChromeos() {
81 input_task_runner_
->DeleteSoon(FROM_HERE
, core_
.release());
84 LocalInputMonitorChromeos::Core::Core(
85 scoped_refptr
<base::SingleThreadTaskRunner
> caller_task_runner
,
86 base::WeakPtr
<ClientSessionControl
> client_session_control
)
87 : caller_task_runner_(caller_task_runner
),
88 client_session_control_(client_session_control
) {
89 DCHECK(client_session_control_
.get());
92 void LocalInputMonitorChromeos::Core::Start() {
93 ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
94 point_transformer_
.reset(new PointTransformer());
97 LocalInputMonitorChromeos::Core::~Core() {
98 ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
101 void LocalInputMonitorChromeos::Core::WillProcessEvent(
102 const ui::PlatformEvent
& event
) {
103 // No need to handle this callback.
106 void LocalInputMonitorChromeos::Core::DidProcessEvent(
107 const ui::PlatformEvent
& event
) {
108 ui::EventType type
= ui::EventTypeFromNative(event
);
109 if (type
== ui::ET_MOUSE_MOVED
) {
110 HandleMouseMove(event
);
111 } else if (type
== ui::ET_KEY_PRESSED
) {
112 HandleKeyPressed(event
);
116 void LocalInputMonitorChromeos::Core::HandleMouseMove(
117 const ui::PlatformEvent
& event
) {
118 gfx::PointF mouse_position
= ui::EventLocationFromNative(event
);
119 mouse_position
= point_transformer_
->FromScreenCoordinates(mouse_position
);
121 caller_task_runner_
->PostTask(
124 &ClientSessionControl::OnLocalMouseMoved
, client_session_control_
,
125 webrtc::DesktopVector(mouse_position
.x(), mouse_position
.y())));
128 void LocalInputMonitorChromeos::Core::HandleKeyPressed(
129 const ui::PlatformEvent
& event
) {
130 ui::KeyEvent
key_event(event
);
131 DCHECK(key_event
.is_char());
132 if (key_event
.IsControlDown() && key_event
.IsAltDown() &&
133 key_event
.key_code() == ui::VKEY_ESCAPE
) {
134 caller_task_runner_
->PostTask(
135 FROM_HERE
, base::Bind(&ClientSessionControl::DisconnectSession
,
136 client_session_control_
));
142 scoped_ptr
<LocalInputMonitor
> LocalInputMonitor::Create(
143 scoped_refptr
<base::SingleThreadTaskRunner
> caller_task_runner
,
144 scoped_refptr
<base::SingleThreadTaskRunner
> input_task_runner
,
145 scoped_refptr
<base::SingleThreadTaskRunner
> ui_task_runner
,
146 base::WeakPtr
<ClientSessionControl
> client_session_control
) {
147 return make_scoped_ptr(new LocalInputMonitorChromeos(
148 caller_task_runner
, input_task_runner
, client_session_control
));
151 } // namespace remoting