Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(198)

Side by Side Diff: remoting/host/session_event_executor_win.cc

Issue 10572005: Use SingleThreadTaskRunner instead of MessageLoopProxy in remoting/host. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « remoting/host/session_event_executor_win.h ('k') | remoting/host/simple_host_process.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/session_event_executor_win.h" 5 #include "remoting/host/session_event_executor_win.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/compiler_specific.h" 11 #include "base/compiler_specific.h"
12 #include "base/message_loop.h" 12 #include "base/single_thread_task_runner.h"
13 #include "base/win/windows_version.h" 13 #include "base/win/windows_version.h"
14 #include "ipc/ipc_channel.h" 14 #include "ipc/ipc_channel.h"
15 #include "ipc/ipc_channel_proxy.h" 15 #include "ipc/ipc_channel_proxy.h"
16 #include "remoting/proto/event.pb.h" 16 #include "remoting/proto/event.pb.h"
17 #include "remoting/host/chromoting_messages.h" 17 #include "remoting/host/chromoting_messages.h"
18 #include "remoting/host/desktop_win.h" 18 #include "remoting/host/desktop_win.h"
19 #include "remoting/host/scoped_thread_desktop_win.h" 19 #include "remoting/host/scoped_thread_desktop_win.h"
20 20
21 namespace { 21 namespace {
22 22
23 // The command line switch specifying the name of the Chromoting IPC channel. 23 // The command line switch specifying the name of the Chromoting IPC channel.
24 const char kProcessChannelId[] = "chromoting-ipc"; 24 const char kProcessChannelId[] = "chromoting-ipc";
25 25
26 const uint32 kUsbLeftControl = 0x0700e0; 26 const uint32 kUsbLeftControl = 0x0700e0;
27 const uint32 kUsbRightControl = 0x0700e4; 27 const uint32 kUsbRightControl = 0x0700e4;
28 const uint32 kUsbLeftAlt = 0x0700e2; 28 const uint32 kUsbLeftAlt = 0x0700e2;
29 const uint32 kUsbRightAlt = 0x0700e6; 29 const uint32 kUsbRightAlt = 0x0700e6;
30 const uint32 kUsbDelete = 0x07004c; 30 const uint32 kUsbDelete = 0x07004c;
31 31
32 bool areCtrlAndAltPressed(const std::set<uint32>& pressed_keys) { 32 bool CheckCtrlAndAltArePressed(const std::set<uint32>& pressed_keys) {
33 size_t ctrl_keys = pressed_keys.count(kUsbLeftControl) + 33 size_t ctrl_keys = pressed_keys.count(kUsbLeftControl) +
34 pressed_keys.count(kUsbRightControl); 34 pressed_keys.count(kUsbRightControl);
35 size_t alt_keys = pressed_keys.count(kUsbLeftAlt) + 35 size_t alt_keys = pressed_keys.count(kUsbLeftAlt) +
36 pressed_keys.count(kUsbRightAlt); 36 pressed_keys.count(kUsbRightAlt);
37 return ctrl_keys != 0 && alt_keys != 0 && 37 return ctrl_keys != 0 && alt_keys != 0 &&
38 (ctrl_keys + alt_keys == pressed_keys.size()); 38 (ctrl_keys + alt_keys == pressed_keys.size());
39 } 39 }
40 40
41 // Emulates Secure Attention Sequence (Ctrl+Alt+Del) by switching to 41 // Emulates Secure Attention Sequence (Ctrl+Alt+Del) by switching to
42 // the Winlogon desktop and injecting Ctrl+Alt+Del as a hot key. 42 // the Winlogon desktop and injecting Ctrl+Alt+Del as a hot key.
43 // N.B. Windows XP/W2K3 only. 43 // N.B. Windows XP/W2K3 only.
44 void emulateSecureAttentionSequence() { 44 void EmulateSecureAttentionSequence() {
45 const wchar_t kWinlogonDesktopName[] = L"Winlogon"; 45 const wchar_t kWinlogonDesktopName[] = L"Winlogon";
46 const wchar_t kSasWindowClassName[] = L"SAS window class"; 46 const wchar_t kSasWindowClassName[] = L"SAS window class";
47 const wchar_t kSasWindowTitle[] = L"SAS window"; 47 const wchar_t kSasWindowTitle[] = L"SAS window";
48 48
49 scoped_ptr<remoting::DesktopWin> winlogon_desktop( 49 scoped_ptr<remoting::DesktopWin> winlogon_desktop(
50 remoting::DesktopWin::GetDesktop(kWinlogonDesktopName)); 50 remoting::DesktopWin::GetDesktop(kWinlogonDesktopName));
51 if (!winlogon_desktop.get()) 51 if (!winlogon_desktop.get())
52 return; 52 return;
53 53
54 remoting::ScopedThreadDesktopWin desktop; 54 remoting::ScopedThreadDesktopWin desktop;
(...skipping 12 matching lines...) Expand all
67 67
68 } // namespace 68 } // namespace
69 69
70 namespace remoting { 70 namespace remoting {
71 71
72 using protocol::ClipboardEvent; 72 using protocol::ClipboardEvent;
73 using protocol::MouseEvent; 73 using protocol::MouseEvent;
74 using protocol::KeyEvent; 74 using protocol::KeyEvent;
75 75
76 SessionEventExecutorWin::SessionEventExecutorWin( 76 SessionEventExecutorWin::SessionEventExecutorWin(
77 MessageLoop* message_loop, 77 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
78 base::MessageLoopProxy* io_message_loop, 78 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
79 scoped_ptr<EventExecutor> nested_executor) 79 scoped_ptr<EventExecutor> nested_executor)
80 : nested_executor_(nested_executor.Pass()), 80 : nested_executor_(nested_executor.Pass()),
81 message_loop_(message_loop), 81 task_runner_(main_task_runner),
82 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), 82 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)),
83 weak_ptr_(weak_ptr_factory_.GetWeakPtr()) { 83 weak_ptr_(weak_ptr_factory_.GetWeakPtr()) {
84 // Let weak_ptr_ be used on the message_loop_ thread. 84 // Let |weak_ptr_| be used on the |task_runner_| thread.
85 // weak_ptr_ and weak_ptr_factory_ share a ThreadChecker, so the following 85 // |weak_ptr_| and |weak_ptr_factory_| share a ThreadChecker, so the
86 // line affects both of them. 86 // following line affects both of them.
87 weak_ptr_factory_.DetachFromThread(); 87 weak_ptr_factory_.DetachFromThread();
88 88
89 std::string channel_name = 89 std::string channel_name =
90 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(kProcessChannelId); 90 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(kProcessChannelId);
91 91
92 // Connect to the Chromoting IPC channel if the name was passed in the command 92 // Connect to the Chromoting IPC channel if the name was passed in the command
93 // line. 93 // line.
94 if (!channel_name.empty()) { 94 if (!channel_name.empty()) {
95 chromoting_channel_.reset(new IPC::ChannelProxy( 95 chromoting_channel_.reset(new IPC::ChannelProxy(
96 channel_name, 96 channel_name, IPC::Channel::MODE_CLIENT, this, io_task_runner));
97 IPC::Channel::MODE_CLIENT,
98 this,
99 io_message_loop));
100 } 97 }
101 } 98 }
102 99
103 SessionEventExecutorWin::~SessionEventExecutorWin() { 100 SessionEventExecutorWin::~SessionEventExecutorWin() {
104 DCHECK(MessageLoop::current() == message_loop_); 101 DCHECK(task_runner_->BelongsToCurrentThread());
105 } 102 }
106 103
107 void SessionEventExecutorWin::OnSessionStarted( 104 void SessionEventExecutorWin::OnSessionStarted(
108 scoped_ptr<protocol::ClipboardStub> client_clipboard) { 105 scoped_ptr<protocol::ClipboardStub> client_clipboard) {
109 if (MessageLoop::current() != message_loop_) { 106 if (!task_runner_->BelongsToCurrentThread()) {
110 message_loop_->PostTask( 107 task_runner_->PostTask(
111 FROM_HERE, 108 FROM_HERE,
112 base::Bind(&SessionEventExecutorWin::OnSessionStarted, 109 base::Bind(&SessionEventExecutorWin::OnSessionStarted,
113 weak_ptr_, base::Passed(&client_clipboard))); 110 weak_ptr_, base::Passed(&client_clipboard)));
114 return; 111 return;
115 } 112 }
116 113
117 nested_executor_->OnSessionStarted(client_clipboard.Pass()); 114 nested_executor_->OnSessionStarted(client_clipboard.Pass());
118 } 115 }
119 116
120 void SessionEventExecutorWin::OnSessionFinished() { 117 void SessionEventExecutorWin::OnSessionFinished() {
121 if (MessageLoop::current() != message_loop_) { 118 if (!task_runner_->BelongsToCurrentThread()) {
122 message_loop_->PostTask( 119 task_runner_->PostTask(
123 FROM_HERE, 120 FROM_HERE,
124 base::Bind(&SessionEventExecutorWin::OnSessionFinished, 121 base::Bind(&SessionEventExecutorWin::OnSessionFinished,
125 weak_ptr_)); 122 weak_ptr_));
126 return; 123 return;
127 } 124 }
128 125
129 nested_executor_->OnSessionFinished(); 126 nested_executor_->OnSessionFinished();
130 } 127 }
131 128
132 void SessionEventExecutorWin::InjectClipboardEvent( 129 void SessionEventExecutorWin::InjectClipboardEvent(
133 const ClipboardEvent& event) { 130 const ClipboardEvent& event) {
134 if (MessageLoop::current() != message_loop_) { 131 if (!task_runner_->BelongsToCurrentThread()) {
135 message_loop_->PostTask( 132 task_runner_->PostTask(
136 FROM_HERE, 133 FROM_HERE,
137 base::Bind(&SessionEventExecutorWin::InjectClipboardEvent, 134 base::Bind(&SessionEventExecutorWin::InjectClipboardEvent,
138 weak_ptr_, event)); 135 weak_ptr_, event));
139 return; 136 return;
140 } 137 }
141 138
142 nested_executor_->InjectClipboardEvent(event); 139 nested_executor_->InjectClipboardEvent(event);
143 } 140 }
144 141
145 void SessionEventExecutorWin::InjectKeyEvent(const KeyEvent& event) { 142 void SessionEventExecutorWin::InjectKeyEvent(const KeyEvent& event) {
146 if (MessageLoop::current() != message_loop_) { 143 if (!task_runner_->BelongsToCurrentThread()) {
147 message_loop_->PostTask( 144 task_runner_->PostTask(
148 FROM_HERE, 145 FROM_HERE,
149 base::Bind(&SessionEventExecutorWin::InjectKeyEvent, 146 base::Bind(&SessionEventExecutorWin::InjectKeyEvent,
150 weak_ptr_, event)); 147 weak_ptr_, event));
151 return; 148 return;
152 } 149 }
153 150
154 // HostEventDispatcher should drop events lacking the pressed field. 151 // HostEventDispatcher should drop events lacking the pressed field.
155 DCHECK(event.has_pressed()); 152 DCHECK(event.has_pressed());
156 153
157 if (event.has_usb_keycode()) { 154 if (event.has_usb_keycode()) {
158 if (event.pressed()) { 155 if (event.pressed()) {
159 // Simulate secure attention sequence if Ctrl-Alt-Del was just pressed. 156 // Simulate secure attention sequence if Ctrl-Alt-Del was just pressed.
160 if (event.usb_keycode() == kUsbDelete && 157 if (event.usb_keycode() == kUsbDelete &&
161 areCtrlAndAltPressed(pressed_keys_)) { 158 CheckCtrlAndAltArePressed(pressed_keys_)) {
162 VLOG(3) << "Sending Secure Attention Sequence to console"; 159 VLOG(3) << "Sending Secure Attention Sequence to console";
163 160
164 if (base::win::GetVersion() == base::win::VERSION_XP) { 161 if (base::win::GetVersion() == base::win::VERSION_XP) {
165 emulateSecureAttentionSequence(); 162 EmulateSecureAttentionSequence();
166 } else if (chromoting_channel_.get()) { 163 } else if (chromoting_channel_.get()) {
167 chromoting_channel_->Send(new ChromotingHostMsg_SendSasToConsole()); 164 chromoting_channel_->Send(new ChromotingHostMsg_SendSasToConsole());
168 } 165 }
169 } 166 }
170 167
171 pressed_keys_.insert(event.usb_keycode()); 168 pressed_keys_.insert(event.usb_keycode());
172 } else { 169 } else {
173 pressed_keys_.erase(event.usb_keycode()); 170 pressed_keys_.erase(event.usb_keycode());
174 } 171 }
175 } 172 }
176 173
177 SwitchToInputDesktop(); 174 SwitchToInputDesktop();
178 nested_executor_->InjectKeyEvent(event); 175 nested_executor_->InjectKeyEvent(event);
179 } 176 }
180 177
181 void SessionEventExecutorWin::InjectMouseEvent(const MouseEvent& event) { 178 void SessionEventExecutorWin::InjectMouseEvent(const MouseEvent& event) {
182 if (MessageLoop::current() != message_loop_) { 179 if (!task_runner_->BelongsToCurrentThread()) {
183 message_loop_->PostTask( 180 task_runner_->PostTask(
184 FROM_HERE, 181 FROM_HERE,
185 base::Bind(&SessionEventExecutorWin::InjectMouseEvent, 182 base::Bind(&SessionEventExecutorWin::InjectMouseEvent,
186 weak_ptr_, event)); 183 weak_ptr_, event));
187 return; 184 return;
188 } 185 }
189 186
190 SwitchToInputDesktop(); 187 SwitchToInputDesktop();
191 nested_executor_->InjectMouseEvent(event); 188 nested_executor_->InjectMouseEvent(event);
192 } 189 }
193 190
194 bool SessionEventExecutorWin::OnMessageReceived(const IPC::Message& message) { 191 bool SessionEventExecutorWin::OnMessageReceived(const IPC::Message& message) {
195 return false; 192 return false;
196 } 193 }
197 194
198 void SessionEventExecutorWin::SwitchToInputDesktop() { 195 void SessionEventExecutorWin::SwitchToInputDesktop() {
199 // Switch to the desktop receiving user input if different from the current 196 // Switch to the desktop receiving user input if different from the current
200 // one. 197 // one.
201 scoped_ptr<DesktopWin> input_desktop = DesktopWin::GetInputDesktop(); 198 scoped_ptr<DesktopWin> input_desktop = DesktopWin::GetInputDesktop();
202 if (input_desktop.get() != NULL && !desktop_.IsSame(*input_desktop)) { 199 if (input_desktop.get() != NULL && !desktop_.IsSame(*input_desktop)) {
203 // If SetThreadDesktop() fails, the thread is still assigned a desktop. 200 // If SetThreadDesktop() fails, the thread is still assigned a desktop.
204 // So we can continue capture screen bits, just from a diffected desktop. 201 // So we can continue capture screen bits, just from a diffected desktop.
205 desktop_.SetThreadDesktop(input_desktop.Pass()); 202 desktop_.SetThreadDesktop(input_desktop.Pass());
206 } 203 }
207 } 204 }
208 205
209 } // namespace remoting 206 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/session_event_executor_win.h ('k') | remoting/host/simple_host_process.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698