OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/host/win/session_event_executor.h" | 5 #include "remoting/host/win/session_input_injector.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/callback.h" | 11 #include "base/callback.h" |
12 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
13 #include "base/location.h" | 13 #include "base/location.h" |
14 #include "base/single_thread_task_runner.h" | 14 #include "base/single_thread_task_runner.h" |
15 #include "base/win/windows_version.h" | 15 #include "base/win/windows_version.h" |
(...skipping 20 matching lines...) Expand all Loading... |
36 } | 36 } |
37 | 37 |
38 } // namespace | 38 } // namespace |
39 | 39 |
40 namespace remoting { | 40 namespace remoting { |
41 | 41 |
42 using protocol::ClipboardEvent; | 42 using protocol::ClipboardEvent; |
43 using protocol::MouseEvent; | 43 using protocol::MouseEvent; |
44 using protocol::KeyEvent; | 44 using protocol::KeyEvent; |
45 | 45 |
46 class SessionEventExecutorWin::Core | 46 class SessionInputInjectorWin::Core |
47 : public base::RefCountedThreadSafe<SessionEventExecutorWin::Core>, | 47 : public base::RefCountedThreadSafe<SessionInputInjectorWin::Core>, |
48 public EventExecutor { | 48 public InputInjector { |
49 public: | 49 public: |
50 Core( | 50 Core( |
51 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, | 51 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, |
52 scoped_ptr<EventExecutor> nested_executor, | 52 scoped_ptr<InputInjector> nested_executor, |
53 scoped_refptr<base::SingleThreadTaskRunner> inject_sas_task_runner, | 53 scoped_refptr<base::SingleThreadTaskRunner> inject_sas_task_runner, |
54 const base::Closure& inject_sas); | 54 const base::Closure& inject_sas); |
55 | 55 |
56 // EventExecutor implementation. | 56 // InputInjector implementation. |
57 virtual void Start( | 57 virtual void Start( |
58 scoped_ptr<protocol::ClipboardStub> client_clipboard) OVERRIDE; | 58 scoped_ptr<protocol::ClipboardStub> client_clipboard) OVERRIDE; |
59 | 59 |
60 // protocol::ClipboardStub implementation. | 60 // protocol::ClipboardStub implementation. |
61 virtual void InjectClipboardEvent( | 61 virtual void InjectClipboardEvent( |
62 const protocol::ClipboardEvent& event) OVERRIDE; | 62 const protocol::ClipboardEvent& event) OVERRIDE; |
63 | 63 |
64 // protocol::InputStub implementation. | 64 // protocol::InputStub implementation. |
65 virtual void InjectKeyEvent(const protocol::KeyEvent& event) OVERRIDE; | 65 virtual void InjectKeyEvent(const protocol::KeyEvent& event) OVERRIDE; |
66 virtual void InjectMouseEvent(const protocol::MouseEvent& event) OVERRIDE; | 66 virtual void InjectMouseEvent(const protocol::MouseEvent& event) OVERRIDE; |
67 | 67 |
68 private: | 68 private: |
69 friend class base::RefCountedThreadSafe<Core>; | 69 friend class base::RefCountedThreadSafe<Core>; |
70 virtual ~Core(); | 70 virtual ~Core(); |
71 | 71 |
72 // Switches to the desktop receiving a user input if different from | 72 // Switches to the desktop receiving a user input if different from |
73 // the current one. | 73 // the current one. |
74 void SwitchToInputDesktop(); | 74 void SwitchToInputDesktop(); |
75 | 75 |
76 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_; | 76 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_; |
77 | 77 |
78 // Pointer to the next event executor. | 78 // Pointer to the next event executor. |
79 scoped_ptr<EventExecutor> nested_executor_; | 79 scoped_ptr<InputInjector> nested_executor_; |
80 | 80 |
81 scoped_refptr<base::SingleThreadTaskRunner> inject_sas_task_runner_; | 81 scoped_refptr<base::SingleThreadTaskRunner> inject_sas_task_runner_; |
82 | 82 |
83 media::ScopedThreadDesktop desktop_; | 83 media::ScopedThreadDesktop desktop_; |
84 | 84 |
85 // Used to inject Secure Attention Sequence on Vista+. | 85 // Used to inject Secure Attention Sequence on Vista+. |
86 base::Closure inject_sas_; | 86 base::Closure inject_sas_; |
87 | 87 |
88 // Used to inject Secure Attention Sequence on XP. | 88 // Used to inject Secure Attention Sequence on XP. |
89 scoped_ptr<SasInjector> sas_injector_; | 89 scoped_ptr<SasInjector> sas_injector_; |
90 | 90 |
91 // Keys currently pressed by the client, used to detect Ctrl-Alt-Del. | 91 // Keys currently pressed by the client, used to detect Ctrl-Alt-Del. |
92 std::set<uint32> pressed_keys_; | 92 std::set<uint32> pressed_keys_; |
93 | 93 |
94 DISALLOW_COPY_AND_ASSIGN(Core); | 94 DISALLOW_COPY_AND_ASSIGN(Core); |
95 }; | 95 }; |
96 | 96 |
97 SessionEventExecutorWin::Core::Core( | 97 SessionInputInjectorWin::Core::Core( |
98 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, | 98 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, |
99 scoped_ptr<EventExecutor> nested_executor, | 99 scoped_ptr<InputInjector> nested_executor, |
100 scoped_refptr<base::SingleThreadTaskRunner> inject_sas_task_runner, | 100 scoped_refptr<base::SingleThreadTaskRunner> inject_sas_task_runner, |
101 const base::Closure& inject_sas) | 101 const base::Closure& inject_sas) |
102 : input_task_runner_(input_task_runner), | 102 : input_task_runner_(input_task_runner), |
103 nested_executor_(nested_executor.Pass()), | 103 nested_executor_(nested_executor.Pass()), |
104 inject_sas_task_runner_(inject_sas_task_runner), | 104 inject_sas_task_runner_(inject_sas_task_runner), |
105 inject_sas_(inject_sas) { | 105 inject_sas_(inject_sas) { |
106 } | 106 } |
107 | 107 |
108 void SessionEventExecutorWin::Core::Start( | 108 void SessionInputInjectorWin::Core::Start( |
109 scoped_ptr<protocol::ClipboardStub> client_clipboard) { | 109 scoped_ptr<protocol::ClipboardStub> client_clipboard) { |
110 if (!input_task_runner_->BelongsToCurrentThread()) { | 110 if (!input_task_runner_->BelongsToCurrentThread()) { |
111 input_task_runner_->PostTask( | 111 input_task_runner_->PostTask( |
112 FROM_HERE, | 112 FROM_HERE, |
113 base::Bind(&Core::Start, this, base::Passed(&client_clipboard))); | 113 base::Bind(&Core::Start, this, base::Passed(&client_clipboard))); |
114 return; | 114 return; |
115 } | 115 } |
116 | 116 |
117 nested_executor_->Start(client_clipboard.Pass()); | 117 nested_executor_->Start(client_clipboard.Pass()); |
118 } | 118 } |
119 | 119 |
120 void SessionEventExecutorWin::Core::InjectClipboardEvent( | 120 void SessionInputInjectorWin::Core::InjectClipboardEvent( |
121 const ClipboardEvent& event) { | 121 const ClipboardEvent& event) { |
122 if (!input_task_runner_->BelongsToCurrentThread()) { | 122 if (!input_task_runner_->BelongsToCurrentThread()) { |
123 input_task_runner_->PostTask( | 123 input_task_runner_->PostTask( |
124 FROM_HERE, base::Bind(&Core::InjectClipboardEvent, this, event)); | 124 FROM_HERE, base::Bind(&Core::InjectClipboardEvent, this, event)); |
125 return; | 125 return; |
126 } | 126 } |
127 | 127 |
128 nested_executor_->InjectClipboardEvent(event); | 128 nested_executor_->InjectClipboardEvent(event); |
129 } | 129 } |
130 | 130 |
131 void SessionEventExecutorWin::Core::InjectKeyEvent(const KeyEvent& event) { | 131 void SessionInputInjectorWin::Core::InjectKeyEvent(const KeyEvent& event) { |
132 if (!input_task_runner_->BelongsToCurrentThread()) { | 132 if (!input_task_runner_->BelongsToCurrentThread()) { |
133 input_task_runner_->PostTask( | 133 input_task_runner_->PostTask( |
134 FROM_HERE, base::Bind(&Core::InjectKeyEvent, this, event)); | 134 FROM_HERE, base::Bind(&Core::InjectKeyEvent, this, event)); |
135 return; | 135 return; |
136 } | 136 } |
137 | 137 |
138 // HostEventDispatcher should drop events lacking the pressed field. | 138 // HostEventDispatcher should drop events lacking the pressed field. |
139 DCHECK(event.has_pressed()); | 139 DCHECK(event.has_pressed()); |
140 | 140 |
141 if (event.has_usb_keycode()) { | 141 if (event.has_usb_keycode()) { |
(...skipping 16 matching lines...) Expand all Loading... |
158 pressed_keys_.insert(event.usb_keycode()); | 158 pressed_keys_.insert(event.usb_keycode()); |
159 } else { | 159 } else { |
160 pressed_keys_.erase(event.usb_keycode()); | 160 pressed_keys_.erase(event.usb_keycode()); |
161 } | 161 } |
162 } | 162 } |
163 | 163 |
164 SwitchToInputDesktop(); | 164 SwitchToInputDesktop(); |
165 nested_executor_->InjectKeyEvent(event); | 165 nested_executor_->InjectKeyEvent(event); |
166 } | 166 } |
167 | 167 |
168 void SessionEventExecutorWin::Core::InjectMouseEvent(const MouseEvent& event) { | 168 void SessionInputInjectorWin::Core::InjectMouseEvent(const MouseEvent& event) { |
169 if (!input_task_runner_->BelongsToCurrentThread()) { | 169 if (!input_task_runner_->BelongsToCurrentThread()) { |
170 input_task_runner_->PostTask( | 170 input_task_runner_->PostTask( |
171 FROM_HERE, base::Bind(&Core::InjectMouseEvent, this, event)); | 171 FROM_HERE, base::Bind(&Core::InjectMouseEvent, this, event)); |
172 return; | 172 return; |
173 } | 173 } |
174 | 174 |
175 SwitchToInputDesktop(); | 175 SwitchToInputDesktop(); |
176 nested_executor_->InjectMouseEvent(event); | 176 nested_executor_->InjectMouseEvent(event); |
177 } | 177 } |
178 | 178 |
179 SessionEventExecutorWin::Core::~Core() { | 179 SessionInputInjectorWin::Core::~Core() { |
180 } | 180 } |
181 | 181 |
182 void SessionEventExecutorWin::Core::SwitchToInputDesktop() { | 182 void SessionInputInjectorWin::Core::SwitchToInputDesktop() { |
183 // Switch to the desktop receiving user input if different from the current | 183 // Switch to the desktop receiving user input if different from the current |
184 // one. | 184 // one. |
185 scoped_ptr<media::Desktop> input_desktop = media::Desktop::GetInputDesktop(); | 185 scoped_ptr<media::Desktop> input_desktop = media::Desktop::GetInputDesktop(); |
186 if (input_desktop.get() != NULL && !desktop_.IsSame(*input_desktop)) { | 186 if (input_desktop.get() != NULL && !desktop_.IsSame(*input_desktop)) { |
187 // If SetThreadDesktop() fails, the thread is still assigned a desktop. | 187 // If SetThreadDesktop() fails, the thread is still assigned a desktop. |
188 // So we can continue capture screen bits, just from a diffected desktop. | 188 // So we can continue capture screen bits, just from a diffected desktop. |
189 desktop_.SetThreadDesktop(input_desktop.Pass()); | 189 desktop_.SetThreadDesktop(input_desktop.Pass()); |
190 } | 190 } |
191 } | 191 } |
192 | 192 |
193 SessionEventExecutorWin::SessionEventExecutorWin( | 193 SessionInputInjectorWin::SessionInputInjectorWin( |
194 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, | 194 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, |
195 scoped_ptr<EventExecutor> nested_executor, | 195 scoped_ptr<InputInjector> nested_executor, |
196 scoped_refptr<base::SingleThreadTaskRunner> inject_sas_task_runner, | 196 scoped_refptr<base::SingleThreadTaskRunner> inject_sas_task_runner, |
197 const base::Closure& inject_sas) { | 197 const base::Closure& inject_sas) { |
198 core_ = new Core(input_task_runner, nested_executor.Pass(), | 198 core_ = new Core(input_task_runner, nested_executor.Pass(), |
199 inject_sas_task_runner, inject_sas); | 199 inject_sas_task_runner, inject_sas); |
200 } | 200 } |
201 | 201 |
202 SessionEventExecutorWin::~SessionEventExecutorWin() { | 202 SessionInputInjectorWin::~SessionInputInjectorWin() { |
203 } | 203 } |
204 | 204 |
205 void SessionEventExecutorWin::Start( | 205 void SessionInputInjectorWin::Start( |
206 scoped_ptr<protocol::ClipboardStub> client_clipboard) { | 206 scoped_ptr<protocol::ClipboardStub> client_clipboard) { |
207 core_->Start(client_clipboard.Pass()); | 207 core_->Start(client_clipboard.Pass()); |
208 } | 208 } |
209 | 209 |
210 void SessionEventExecutorWin::InjectClipboardEvent( | 210 void SessionInputInjectorWin::InjectClipboardEvent( |
211 const protocol::ClipboardEvent& event) { | 211 const protocol::ClipboardEvent& event) { |
212 core_->InjectClipboardEvent(event); | 212 core_->InjectClipboardEvent(event); |
213 } | 213 } |
214 | 214 |
215 void SessionEventExecutorWin::InjectKeyEvent(const protocol::KeyEvent& event) { | 215 void SessionInputInjectorWin::InjectKeyEvent(const protocol::KeyEvent& event) { |
216 core_->InjectKeyEvent(event); | 216 core_->InjectKeyEvent(event); |
217 } | 217 } |
218 | 218 |
219 void SessionEventExecutorWin::InjectMouseEvent( | 219 void SessionInputInjectorWin::InjectMouseEvent( |
220 const protocol::MouseEvent& event) { | 220 const protocol::MouseEvent& event) { |
221 core_->InjectMouseEvent(event); | 221 core_->InjectMouseEvent(event); |
222 } | 222 } |
223 | 223 |
224 } // namespace remoting | 224 } // namespace remoting |
OLD | NEW |