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/client_session_control.h"
13 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
14 #include "ui/events/event.h"
15 #include "ui/events/event_utils.h"
16 #include "ui/events/keycodes/keyboard_codes.h"
17 #include "ui/events/platform/platform_event_observer.h"
18 #include "ui/events/platform/platform_event_source.h"
24 class LocalInputMonitorChromeos
: public LocalInputMonitor
{
26 LocalInputMonitorChromeos(
27 scoped_refptr
<base::SingleThreadTaskRunner
> caller_task_runner
,
28 scoped_refptr
<base::SingleThreadTaskRunner
> input_task_runner
,
29 base::WeakPtr
<ClientSessionControl
> client_session_control
);
30 virtual ~LocalInputMonitorChromeos();
33 class Core
: ui::PlatformEventObserver
{
35 Core(scoped_refptr
<base::SingleThreadTaskRunner
> caller_task_runner
,
36 base::WeakPtr
<ClientSessionControl
> client_session_control
);
41 // ui::PlatformEventObserver interface.
42 void WillProcessEvent(const ui::PlatformEvent
& event
) override
;
43 void DidProcessEvent(const ui::PlatformEvent
& event
) override
;
46 void HandleMouseMove(const ui::PlatformEvent
& event
);
47 void HandleKeyPressed(const ui::PlatformEvent
& event
);
49 scoped_refptr
<base::SingleThreadTaskRunner
> caller_task_runner_
;
51 // Points to the object receiving mouse event notifications and session
52 // disconnect requests. Must be called on the |caller_task_runner_|.
53 base::WeakPtr
<ClientSessionControl
> client_session_control_
;
55 DISALLOW_COPY_AND_ASSIGN(Core
);
58 // Task runner on which ui::events are received.
59 scoped_refptr
<base::SingleThreadTaskRunner
> input_task_runner_
;
60 scoped_ptr
<Core
> core_
;
62 DISALLOW_COPY_AND_ASSIGN(LocalInputMonitorChromeos
);
65 LocalInputMonitorChromeos::LocalInputMonitorChromeos(
66 scoped_refptr
<base::SingleThreadTaskRunner
> caller_task_runner
,
67 scoped_refptr
<base::SingleThreadTaskRunner
> input_task_runner
,
68 base::WeakPtr
<ClientSessionControl
> client_session_control
)
69 : input_task_runner_(input_task_runner
),
70 core_(new Core(caller_task_runner
, client_session_control
)) {
71 input_task_runner_
->PostTask(
72 FROM_HERE
, base::Bind(&Core::Start
, base::Unretained(core_
.get())));
75 LocalInputMonitorChromeos::~LocalInputMonitorChromeos() {
76 input_task_runner_
->DeleteSoon(FROM_HERE
, core_
.release());
79 LocalInputMonitorChromeos::Core::Core(
80 scoped_refptr
<base::SingleThreadTaskRunner
> caller_task_runner
,
81 base::WeakPtr
<ClientSessionControl
> client_session_control
)
82 : caller_task_runner_(caller_task_runner
),
83 client_session_control_(client_session_control
) {
84 DCHECK(client_session_control_
.get());
87 void LocalInputMonitorChromeos::Core::Start() {
88 ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
91 LocalInputMonitorChromeos::Core::~Core() {
92 ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
95 void LocalInputMonitorChromeos::Core::WillProcessEvent(
96 const ui::PlatformEvent
& event
) {
97 // No need to handle this callback.
100 void LocalInputMonitorChromeos::Core::DidProcessEvent(
101 const ui::PlatformEvent
& event
) {
102 ui::EventType type
= ui::EventTypeFromNative(event
);
103 if (type
== ui::ET_MOUSE_MOVED
) {
104 HandleMouseMove(event
);
105 } else if (type
== ui::ET_KEY_PRESSED
) {
106 HandleKeyPressed(event
);
110 void LocalInputMonitorChromeos::Core::HandleMouseMove(
111 const ui::PlatformEvent
& event
) {
112 gfx::Point mouse_position
= ui::EventLocationFromNative(event
);
113 caller_task_runner_
->PostTask(
116 &ClientSessionControl::OnLocalMouseMoved
, client_session_control_
,
117 webrtc::DesktopVector(mouse_position
.x(), mouse_position
.y())));
120 void LocalInputMonitorChromeos::Core::HandleKeyPressed(
121 const ui::PlatformEvent
& event
) {
122 ui::KeyEvent
key_event(event
);
123 DCHECK(key_event
.is_char());
124 if (key_event
.IsControlDown() && key_event
.IsAltDown() &&
125 key_event
.key_code() == ui::VKEY_ESCAPE
) {
126 caller_task_runner_
->PostTask(
127 FROM_HERE
, base::Bind(&ClientSessionControl::DisconnectSession
,
128 client_session_control_
));
134 scoped_ptr
<LocalInputMonitor
> LocalInputMonitor::Create(
135 scoped_refptr
<base::SingleThreadTaskRunner
> caller_task_runner
,
136 scoped_refptr
<base::SingleThreadTaskRunner
> input_task_runner
,
137 scoped_refptr
<base::SingleThreadTaskRunner
> ui_task_runner
,
138 base::WeakPtr
<ClientSessionControl
> client_session_control
) {
139 return make_scoped_ptr(new LocalInputMonitorChromeos(
140 caller_task_runner
, input_task_runner
, client_session_control
));
143 } // namespace remoting