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_input_injector.h" | 5 #include "remoting/host/win/session_input_injector.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <set> | 9 #include <set> |
10 #include <string> | 10 #include <string> |
(...skipping 16 matching lines...) Expand all Loading... |
27 | 27 |
28 bool CheckCtrlAndAltArePressed(const std::set<ui::DomCode>& pressed_keys) { | 28 bool CheckCtrlAndAltArePressed(const std::set<ui::DomCode>& pressed_keys) { |
29 size_t ctrl_keys = pressed_keys.count(ui::DomCode::CONTROL_LEFT) + | 29 size_t ctrl_keys = pressed_keys.count(ui::DomCode::CONTROL_LEFT) + |
30 pressed_keys.count(ui::DomCode::CONTROL_RIGHT); | 30 pressed_keys.count(ui::DomCode::CONTROL_RIGHT); |
31 size_t alt_keys = pressed_keys.count(ui::DomCode::ALT_LEFT) + | 31 size_t alt_keys = pressed_keys.count(ui::DomCode::ALT_LEFT) + |
32 pressed_keys.count(ui::DomCode::ALT_RIGHT); | 32 pressed_keys.count(ui::DomCode::ALT_RIGHT); |
33 return ctrl_keys != 0 && alt_keys != 0 && | 33 return ctrl_keys != 0 && alt_keys != 0 && |
34 (ctrl_keys + alt_keys == pressed_keys.size()); | 34 (ctrl_keys + alt_keys == pressed_keys.size()); |
35 } | 35 } |
36 | 36 |
| 37 bool IsWinKeyPressed(const std::set<ui::DomCode>& pressed_keys) { |
| 38 size_t win_keys = pressed_keys.count(ui::DomCode::META_LEFT) + |
| 39 pressed_keys.count(ui::DomCode::META_RIGHT); |
| 40 return win_keys != 0 && win_keys == pressed_keys.size(); |
| 41 } |
| 42 |
37 } // namespace | 43 } // namespace |
38 | 44 |
39 namespace remoting { | 45 namespace remoting { |
40 | 46 |
41 using protocol::ClipboardEvent; | 47 using protocol::ClipboardEvent; |
42 using protocol::KeyEvent; | 48 using protocol::KeyEvent; |
43 using protocol::MouseEvent; | 49 using protocol::MouseEvent; |
44 using protocol::TextEvent; | 50 using protocol::TextEvent; |
45 using protocol::TouchEvent; | 51 using protocol::TouchEvent; |
46 | 52 |
47 class SessionInputInjectorWin::Core | 53 class SessionInputInjectorWin::Core |
48 : public base::RefCountedThreadSafe<SessionInputInjectorWin::Core>, | 54 : public base::RefCountedThreadSafe<SessionInputInjectorWin::Core>, |
49 public InputInjector { | 55 public InputInjector { |
50 public: | 56 public: |
51 Core(scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, | 57 Core(scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, |
52 std::unique_ptr<InputInjector> nested_executor, | 58 std::unique_ptr<InputInjector> nested_executor, |
53 scoped_refptr<base::SingleThreadTaskRunner> inject_sas_task_runner, | 59 scoped_refptr<base::SingleThreadTaskRunner> inject_sas_task_runner, |
54 const base::Closure& inject_sas); | 60 const base::Closure& inject_sas, |
| 61 const base::Closure& lock_workstation); |
55 | 62 |
56 // InputInjector implementation. | 63 // InputInjector implementation. |
57 void Start(std::unique_ptr<ClipboardStub> client_clipboard) override; | 64 void Start(std::unique_ptr<ClipboardStub> client_clipboard) override; |
58 | 65 |
59 // protocol::ClipboardStub implementation. | 66 // protocol::ClipboardStub implementation. |
60 void InjectClipboardEvent(const ClipboardEvent& event) override; | 67 void InjectClipboardEvent(const ClipboardEvent& event) override; |
61 | 68 |
62 // protocol::InputStub implementation. | 69 // protocol::InputStub implementation. |
63 void InjectKeyEvent(const KeyEvent& event) override; | 70 void InjectKeyEvent(const KeyEvent& event) override; |
64 void InjectTextEvent(const TextEvent& event) override; | 71 void InjectTextEvent(const TextEvent& event) override; |
65 void InjectMouseEvent(const MouseEvent& event) override; | 72 void InjectMouseEvent(const MouseEvent& event) override; |
66 void InjectTouchEvent(const TouchEvent& event) override; | 73 void InjectTouchEvent(const TouchEvent& event) override; |
67 | 74 |
68 private: | 75 private: |
69 friend class base::RefCountedThreadSafe<Core>; | 76 friend class base::RefCountedThreadSafe<Core>; |
70 ~Core() override; | 77 ~Core() override; |
71 | 78 |
72 // Switches to the desktop receiving a user input if different from | 79 // Switches to the desktop receiving a user input if different from |
73 // the current one. | 80 // the current one. |
74 void SwitchToInputDesktop(); | 81 void SwitchToInputDesktop(); |
75 | 82 |
76 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_; | 83 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_; |
77 | 84 |
78 // Pointer to the next event executor. | 85 // Pointer to the next event executor. |
79 std::unique_ptr<InputInjector> nested_executor_; | 86 std::unique_ptr<InputInjector> nested_executor_; |
80 | 87 |
81 scoped_refptr<base::SingleThreadTaskRunner> inject_sas_task_runner_; | 88 scoped_refptr<base::SingleThreadTaskRunner> execute_action_task_runner_; |
82 | 89 |
83 webrtc::ScopedThreadDesktop desktop_; | 90 webrtc::ScopedThreadDesktop desktop_; |
84 | 91 |
85 // Used to inject Secure Attention Sequence on Vista+. | 92 // Used to inject Secure Attention Sequence on Vista+. |
86 base::Closure inject_sas_; | 93 base::Closure inject_sas_; |
87 | 94 |
| 95 // Used to lock the current session on non-home SKUs of Windows. |
| 96 base::Closure lock_workstation_; |
| 97 |
88 // Used to inject Secure Attention Sequence on XP. | 98 // Used to inject Secure Attention Sequence on XP. |
89 std::unique_ptr<SasInjector> sas_injector_; | 99 std::unique_ptr<SasInjector> sas_injector_; |
90 | 100 |
91 // Keys currently pressed by the client, used to detect Ctrl-Alt-Del. | 101 // Keys currently pressed by the client, used to detect key sequences. |
92 std::set<ui::DomCode> pressed_keys_; | 102 std::set<ui::DomCode> pressed_keys_; |
93 | 103 |
94 DISALLOW_COPY_AND_ASSIGN(Core); | 104 DISALLOW_COPY_AND_ASSIGN(Core); |
95 }; | 105 }; |
96 | 106 |
97 SessionInputInjectorWin::Core::Core( | 107 SessionInputInjectorWin::Core::Core( |
98 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, | 108 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, |
99 std::unique_ptr<InputInjector> nested_executor, | 109 std::unique_ptr<InputInjector> nested_executor, |
100 scoped_refptr<base::SingleThreadTaskRunner> inject_sas_task_runner, | 110 scoped_refptr<base::SingleThreadTaskRunner> execute_action_task_runner, |
101 const base::Closure& inject_sas) | 111 const base::Closure& inject_sas, |
| 112 const base::Closure& lock_workstation) |
102 : input_task_runner_(input_task_runner), | 113 : input_task_runner_(input_task_runner), |
103 nested_executor_(std::move(nested_executor)), | 114 nested_executor_(std::move(nested_executor)), |
104 inject_sas_task_runner_(inject_sas_task_runner), | 115 execute_action_task_runner_(execute_action_task_runner), |
105 inject_sas_(inject_sas) {} | 116 inject_sas_(inject_sas), |
| 117 lock_workstation_(lock_workstation) {} |
106 | 118 |
107 void SessionInputInjectorWin::Core::Start( | 119 void SessionInputInjectorWin::Core::Start( |
108 std::unique_ptr<protocol::ClipboardStub> client_clipboard) { | 120 std::unique_ptr<protocol::ClipboardStub> client_clipboard) { |
109 if (!input_task_runner_->BelongsToCurrentThread()) { | 121 if (!input_task_runner_->BelongsToCurrentThread()) { |
110 input_task_runner_->PostTask( | 122 input_task_runner_->PostTask( |
111 FROM_HERE, | 123 FROM_HERE, |
112 base::Bind(&Core::Start, this, base::Passed(&client_clipboard))); | 124 base::Bind(&Core::Start, this, base::Passed(&client_clipboard))); |
113 return; | 125 return; |
114 } | 126 } |
115 | 127 |
(...skipping 28 matching lines...) Expand all Loading... |
144 if (dom_code == ui::DomCode::DEL && | 156 if (dom_code == ui::DomCode::DEL && |
145 CheckCtrlAndAltArePressed(pressed_keys_)) { | 157 CheckCtrlAndAltArePressed(pressed_keys_)) { |
146 VLOG(3) << "Sending Secure Attention Sequence to the session"; | 158 VLOG(3) << "Sending Secure Attention Sequence to the session"; |
147 | 159 |
148 if (base::win::GetVersion() < base::win::VERSION_VISTA) { | 160 if (base::win::GetVersion() < base::win::VERSION_VISTA) { |
149 if (!sas_injector_) | 161 if (!sas_injector_) |
150 sas_injector_ = SasInjector::Create(); | 162 sas_injector_ = SasInjector::Create(); |
151 if (!sas_injector_->InjectSas()) | 163 if (!sas_injector_->InjectSas()) |
152 LOG(ERROR) << "Failed to inject Secure Attention Sequence."; | 164 LOG(ERROR) << "Failed to inject Secure Attention Sequence."; |
153 } else { | 165 } else { |
154 inject_sas_task_runner_->PostTask(FROM_HERE, inject_sas_); | 166 execute_action_task_runner_->PostTask(FROM_HERE, inject_sas_); |
155 } | 167 } |
| 168 } else if (dom_code == ui::DomCode::US_L && |
| 169 IsWinKeyPressed(pressed_keys_)) { |
| 170 execute_action_task_runner_->PostTask(FROM_HERE, lock_workstation_); |
156 } | 171 } |
157 | 172 |
158 pressed_keys_.insert(dom_code); | 173 pressed_keys_.insert(dom_code); |
159 } else { | 174 } else { |
160 pressed_keys_.erase(dom_code); | 175 pressed_keys_.erase(dom_code); |
161 } | 176 } |
162 } | 177 } |
163 | 178 |
164 SwitchToInputDesktop(); | 179 SwitchToInputDesktop(); |
165 nested_executor_->InjectKeyEvent(event); | 180 nested_executor_->InjectKeyEvent(event); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 // If SetThreadDesktop() fails, the thread is still assigned a desktop. | 225 // If SetThreadDesktop() fails, the thread is still assigned a desktop. |
211 // So we can continue capture screen bits, just from a diffected desktop. | 226 // So we can continue capture screen bits, just from a diffected desktop. |
212 desktop_.SetThreadDesktop(input_desktop.release()); | 227 desktop_.SetThreadDesktop(input_desktop.release()); |
213 } | 228 } |
214 } | 229 } |
215 | 230 |
216 SessionInputInjectorWin::SessionInputInjectorWin( | 231 SessionInputInjectorWin::SessionInputInjectorWin( |
217 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, | 232 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, |
218 std::unique_ptr<InputInjector> nested_executor, | 233 std::unique_ptr<InputInjector> nested_executor, |
219 scoped_refptr<base::SingleThreadTaskRunner> inject_sas_task_runner, | 234 scoped_refptr<base::SingleThreadTaskRunner> inject_sas_task_runner, |
220 const base::Closure& inject_sas) { | 235 const base::Closure& inject_sas, |
| 236 const base::Closure& lock_workstation) { |
221 core_ = new Core(input_task_runner, std::move(nested_executor), | 237 core_ = new Core(input_task_runner, std::move(nested_executor), |
222 inject_sas_task_runner, inject_sas); | 238 inject_sas_task_runner, inject_sas, lock_workstation); |
223 } | 239 } |
224 | 240 |
225 SessionInputInjectorWin::~SessionInputInjectorWin() { | 241 SessionInputInjectorWin::~SessionInputInjectorWin() { |
226 } | 242 } |
227 | 243 |
228 void SessionInputInjectorWin::Start( | 244 void SessionInputInjectorWin::Start( |
229 std::unique_ptr<protocol::ClipboardStub> client_clipboard) { | 245 std::unique_ptr<protocol::ClipboardStub> client_clipboard) { |
230 core_->Start(std::move(client_clipboard)); | 246 core_->Start(std::move(client_clipboard)); |
231 } | 247 } |
232 | 248 |
(...skipping 15 matching lines...) Expand all Loading... |
248 const protocol::MouseEvent& event) { | 264 const protocol::MouseEvent& event) { |
249 core_->InjectMouseEvent(event); | 265 core_->InjectMouseEvent(event); |
250 } | 266 } |
251 | 267 |
252 void SessionInputInjectorWin::InjectTouchEvent( | 268 void SessionInputInjectorWin::InjectTouchEvent( |
253 const protocol::TouchEvent& event) { | 269 const protocol::TouchEvent& event) { |
254 core_->InjectTouchEvent(event); | 270 core_->InjectTouchEvent(event); |
255 } | 271 } |
256 | 272 |
257 } // namespace remoting | 273 } // namespace remoting |
OLD | NEW |