| 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 |