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

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

Issue 12096071: Adding a unit test to verify the IPC channel between the network and desktop processes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 10 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
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/desktop_session_proxy.h" 5 #include "remoting/host/desktop_session_proxy.h"
6 6
7 #include "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/platform_file.h" 9 #include "base/platform_file.h"
10 #include "base/process_util.h"
10 #include "base/single_thread_task_runner.h" 11 #include "base/single_thread_task_runner.h"
11 #include "ipc/ipc_channel_proxy.h" 12 #include "ipc/ipc_channel_proxy.h"
12 #include "ipc/ipc_message_macros.h" 13 #include "ipc/ipc_message_macros.h"
13 #include "media/video/capture/screen/screen_capture_data.h" 14 #include "media/video/capture/screen/screen_capture_data.h"
14 #include "remoting/host/audio_capturer.h" 15 #include "remoting/host/audio_capturer.h"
15 #include "remoting/host/chromoting_messages.h" 16 #include "remoting/host/chromoting_messages.h"
16 #include "remoting/host/client_session.h" 17 #include "remoting/host/client_session.h"
17 #include "remoting/host/ipc_audio_capturer.h" 18 #include "remoting/host/ipc_audio_capturer.h"
18 #include "remoting/host/ipc_event_executor.h" 19 #include "remoting/host/ipc_event_executor.h"
19 #include "remoting/host/ipc_video_frame_capturer.h" 20 #include "remoting/host/ipc_video_frame_capturer.h"
20 #include "remoting/proto/audio.pb.h" 21 #include "remoting/proto/audio.pb.h"
21 #include "remoting/proto/control.pb.h" 22 #include "remoting/proto/control.pb.h"
22 #include "remoting/proto/event.pb.h" 23 #include "remoting/proto/event.pb.h"
23 24
24 #if defined(OS_WIN) 25 #if defined(OS_WIN)
25 #include "base/win/scoped_handle.h" 26 #include "base/win/scoped_handle.h"
26 #endif // defined(OS_WIN) 27 #endif // defined(OS_WIN)
27 28
28 namespace remoting { 29 namespace remoting {
29 30
30 DesktopSessionProxy::DesktopSessionProxy( 31 DesktopSessionProxy::DesktopSessionProxy(
31 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, 32 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
33 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
32 const std::string& client_jid, 34 const std::string& client_jid,
33 const base::Closure& disconnect_callback) 35 const base::Closure& disconnect_callback)
34 : caller_task_runner_(caller_task_runner), 36 : caller_task_runner_(caller_task_runner),
37 io_task_runner_(io_task_runner),
35 audio_capturer_(NULL), 38 audio_capturer_(NULL),
36 client_jid_(client_jid), 39 client_jid_(client_jid),
37 disconnect_callback_(disconnect_callback), 40 disconnect_callback_(disconnect_callback),
41 desktop_process_(base::kNullProcessHandle),
38 pending_capture_frame_requests_(0), 42 pending_capture_frame_requests_(0),
39 video_capturer_(NULL) { 43 video_capturer_(NULL) {
40 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 44 DCHECK(caller_task_runner_->BelongsToCurrentThread());
41 DCHECK(!client_jid_.empty()); 45 DCHECK(!client_jid_.empty());
42 DCHECK(!disconnect_callback_.is_null()); 46 DCHECK(!disconnect_callback_.is_null());
43 } 47 }
44 48
45 scoped_ptr<AudioCapturer> DesktopSessionProxy::CreateAudioCapturer( 49 scoped_ptr<AudioCapturer> DesktopSessionProxy::CreateAudioCapturer(
46 scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner) { 50 scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner) {
47 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 51 DCHECK(caller_task_runner_->BelongsToCurrentThread());
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 VLOG(1) << "IPC: network <- desktop (" << peer_pid << ")"; 103 VLOG(1) << "IPC: network <- desktop (" << peer_pid << ")";
100 } 104 }
101 105
102 void DesktopSessionProxy::OnChannelError() { 106 void DesktopSessionProxy::OnChannelError() {
103 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 107 DCHECK(caller_task_runner_->BelongsToCurrentThread());
104 108
105 DetachFromDesktop(); 109 DetachFromDesktop();
106 } 110 }
107 111
108 bool DesktopSessionProxy::AttachToDesktop( 112 bool DesktopSessionProxy::AttachToDesktop(
109 IPC::PlatformFileForTransit desktop_process, 113 base::ProcessHandle desktop_process,
110 IPC::PlatformFileForTransit desktop_pipe) { 114 IPC::PlatformFileForTransit desktop_pipe) {
111 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 115 DCHECK(caller_task_runner_->BelongsToCurrentThread());
112 DCHECK(!client_jid_.empty()); 116 DCHECK(!client_jid_.empty());
113 DCHECK(!desktop_channel_); 117 DCHECK(!desktop_channel_);
118 DCHECK(desktop_process_ == base::kNullProcessHandle);
Sergey Ulanov 2013/02/04 21:04:41 nit: DCHECK_EQ
alexeypa (please no reviews) 2013/02/04 23:45:58 Done.
114 DCHECK(!disconnect_callback_.is_null()); 119 DCHECK(!disconnect_callback_.is_null());
115 120
121 desktop_process_ = desktop_process;
122
116 #if defined(OS_WIN) 123 #if defined(OS_WIN)
117 // On Windows: |desktop_process| is a valid handle, but |desktop_pipe| needs 124 // On Windows: |desktop_process| is a valid handle, but |desktop_pipe| needs
118 // to be duplicated from the desktop process. 125 // to be duplicated from the desktop process.
119 desktop_process_.Set(desktop_process);
120
121 base::win::ScopedHandle pipe; 126 base::win::ScopedHandle pipe;
122 if (!DuplicateHandle(desktop_process_, desktop_pipe, GetCurrentProcess(), 127 if (!DuplicateHandle(desktop_process_, desktop_pipe, GetCurrentProcess(),
123 pipe.Receive(), 0, FALSE, DUPLICATE_SAME_ACCESS)) { 128 pipe.Receive(), 0, FALSE, DUPLICATE_SAME_ACCESS)) {
124 LOG_GETLASTERROR(ERROR) << "Failed to duplicate the desktop-to-network" 129 LOG_GETLASTERROR(ERROR) << "Failed to duplicate the desktop-to-network"
125 " pipe handle"; 130 " pipe handle";
126 return false; 131 return false;
127 } 132 }
128 133
129 // Connect to the desktop process. 134 // Connect to the desktop process.
130 desktop_channel_.reset(new IPC::ChannelProxy(IPC::ChannelHandle(pipe), 135 desktop_channel_.reset(new IPC::ChannelProxy(IPC::ChannelHandle(pipe),
131 IPC::Channel::MODE_CLIENT, 136 IPC::Channel::MODE_CLIENT,
132 this, 137 this,
133 caller_task_runner_)); 138 io_task_runner_));
134 #elif defined(OS_POSIX) 139 #elif defined(OS_POSIX)
135 // On posix: both |desktop_process| and |desktop_pipe| are valid file 140 // On posix: |desktop_pipe| is a valid file descriptor.
136 // descriptors.
137 DCHECK(desktop_process.auto_close);
138 DCHECK(desktop_pipe.auto_close); 141 DCHECK(desktop_pipe.auto_close);
139 142
140 base::ClosePlatformFile(desktop_process.fd);
141
142 // Connect to the desktop process. 143 // Connect to the desktop process.
143 desktop_channel_.reset(new IPC::ChannelProxy( 144 desktop_channel_.reset(new IPC::ChannelProxy(
Sergey Ulanov 2013/02/04 21:04:41 I think you can move this out of the ifdef. It's o
alexeypa (please no reviews) 2013/02/04 23:45:58 Done.
144 IPC::ChannelHandle("", desktop_pipe), 145 IPC::ChannelHandle("", desktop_pipe),
145 IPC::Channel::MODE_CLIENT, 146 IPC::Channel::MODE_CLIENT,
146 this, 147 this,
147 caller_task_runner_)); 148 caller_task_runner_));
Sergey Ulanov 2013/02/04 21:04:41 Should this be changed to io_task_runner_ too?
alexeypa (please no reviews) 2013/02/04 23:45:58 Done.
148 #else 149 #else
149 #error Unsupported platform. 150 #error Unsupported platform.
150 #endif 151 #endif
151 152
152 // Pass ID of the client (which is authenticated at this point) to the desktop 153 // Pass ID of the client (which is authenticated at this point) to the desktop
153 // session agent and start the agent. 154 // session agent and start the agent.
154 SendToDesktop(new ChromotingNetworkDesktopMsg_StartSessionAgent(client_jid_)); 155 SendToDesktop(new ChromotingNetworkDesktopMsg_StartSessionAgent(client_jid_));
155 return true; 156 return true;
156 } 157 }
157 158
158 void DesktopSessionProxy::DetachFromDesktop() { 159 void DesktopSessionProxy::DetachFromDesktop() {
159 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 160 DCHECK(caller_task_runner_->BelongsToCurrentThread());
160 161
161 desktop_channel_.reset(); 162 desktop_channel_.reset();
162 163
163 #if defined(OS_WIN) 164 if (desktop_process_ != base::kNullProcessHandle) {
164 desktop_process_.Close(); 165 base::CloseProcessHandle(desktop_process_);
165 #endif // defined(OS_WIN) 166 desktop_process_ = base::kNullProcessHandle;
167 }
166 168
167 shared_buffers_.clear(); 169 shared_buffers_.clear();
168 170
169 // Generate fake responses to keep the video capturer in sync. 171 // Generate fake responses to keep the video capturer in sync.
170 while (pending_capture_frame_requests_) { 172 while (pending_capture_frame_requests_) {
171 --pending_capture_frame_requests_; 173 --pending_capture_frame_requests_;
172 PostCaptureCompleted(scoped_refptr<media::ScreenCaptureData>()); 174 PostCaptureCompleted(scoped_refptr<media::ScreenCaptureData>());
173 } 175 }
174 } 176 }
175 177
(...skipping 11 matching lines...) Expand all
187 } 189 }
188 190
189 void DesktopSessionProxy::InvalidateRegion(const SkRegion& invalid_region) { 191 void DesktopSessionProxy::InvalidateRegion(const SkRegion& invalid_region) {
190 if (!caller_task_runner_->BelongsToCurrentThread()) { 192 if (!caller_task_runner_->BelongsToCurrentThread()) {
191 caller_task_runner_->PostTask( 193 caller_task_runner_->PostTask(
192 FROM_HERE, base::Bind(&DesktopSessionProxy::InvalidateRegion, this, 194 FROM_HERE, base::Bind(&DesktopSessionProxy::InvalidateRegion, this,
193 invalid_region)); 195 invalid_region));
194 return; 196 return;
195 } 197 }
196 198
197 std::vector<SkIRect> invalid_rects; 199 if (desktop_channel_) {
198 for (SkRegion::Iterator i(invalid_region); !i.done(); i.next()) 200 std::vector<SkIRect> invalid_rects;
199 invalid_rects.push_back(i.rect()); 201 for (SkRegion::Iterator i(invalid_region); !i.done(); i.next())
202 invalid_rects.push_back(i.rect());
200 203
201 SendToDesktop( 204 SendToDesktop(
202 new ChromotingNetworkDesktopMsg_InvalidateRegion(invalid_rects)); 205 new ChromotingNetworkDesktopMsg_InvalidateRegion(invalid_rects));
206 }
203 } 207 }
204 208
205 void DesktopSessionProxy::CaptureFrame() { 209 void DesktopSessionProxy::CaptureFrame() {
206 if (!caller_task_runner_->BelongsToCurrentThread()) { 210 if (!caller_task_runner_->BelongsToCurrentThread()) {
207 caller_task_runner_->PostTask( 211 caller_task_runner_->PostTask(
208 FROM_HERE, base::Bind(&DesktopSessionProxy::CaptureFrame, this)); 212 FROM_HERE, base::Bind(&DesktopSessionProxy::CaptureFrame, this));
209 return; 213 return;
210 } 214 }
211 215
212 ++pending_capture_frame_requests_; 216 if (desktop_channel_) {
213 SendToDesktop(new ChromotingNetworkDesktopMsg_CaptureFrame()); 217 ++pending_capture_frame_requests_;
218 SendToDesktop(new ChromotingNetworkDesktopMsg_CaptureFrame());
219 } else {
220 PostCaptureCompleted(scoped_refptr<media::ScreenCaptureData>());
Sergey Ulanov 2013/02/04 21:04:41 Why do we need to do this? I don't see anything in
alexeypa (please no reviews) 2013/02/04 23:45:58 VideoFrameCapturer::Delegate requires OnCaptureCom
221 }
214 } 222 }
215 223
216 void DesktopSessionProxy::StartVideoCapturer( 224 void DesktopSessionProxy::StartVideoCapturer(
217 IpcVideoFrameCapturer* video_capturer) { 225 IpcVideoFrameCapturer* video_capturer) {
218 DCHECK(video_capture_task_runner_->BelongsToCurrentThread()); 226 DCHECK(video_capture_task_runner_->BelongsToCurrentThread());
219 DCHECK(video_capturer_ == NULL); 227 DCHECK(video_capturer_ == NULL);
220 228
221 video_capturer_ = video_capturer; 229 video_capturer_ = video_capturer;
222 } 230 }
223 231
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 } 283 }
276 284
277 void DesktopSessionProxy::StartEventExecutor( 285 void DesktopSessionProxy::StartEventExecutor(
278 scoped_ptr<protocol::ClipboardStub> client_clipboard) { 286 scoped_ptr<protocol::ClipboardStub> client_clipboard) {
279 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 287 DCHECK(caller_task_runner_->BelongsToCurrentThread());
280 288
281 client_clipboard_ = client_clipboard.Pass(); 289 client_clipboard_ = client_clipboard.Pass();
282 } 290 }
283 291
284 DesktopSessionProxy::~DesktopSessionProxy() { 292 DesktopSessionProxy::~DesktopSessionProxy() {
293 if (desktop_process_ != base::kNullProcessHandle) {
294 base::CloseProcessHandle(desktop_process_);
295 desktop_process_ = base::kNullProcessHandle;
296 }
285 } 297 }
286 298
287 scoped_refptr<media::SharedBuffer> DesktopSessionProxy::GetSharedBuffer( 299 scoped_refptr<media::SharedBuffer> DesktopSessionProxy::GetSharedBuffer(
288 int id) { 300 int id) {
289 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 301 DCHECK(caller_task_runner_->BelongsToCurrentThread());
290 302
291 SharedBuffers::const_iterator i = shared_buffers_.find(id); 303 SharedBuffers::const_iterator i = shared_buffers_.find(id);
292 if (i != shared_buffers_.end()) { 304 if (i != shared_buffers_.end()) {
293 return i->second; 305 return i->second;
294 } else { 306 } else {
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 465 DCHECK(caller_task_runner_->BelongsToCurrentThread());
454 466
455 if (desktop_channel_) { 467 if (desktop_channel_) {
456 desktop_channel_->Send(message); 468 desktop_channel_->Send(message);
457 } else { 469 } else {
458 delete message; 470 delete message;
459 } 471 }
460 } 472 }
461 473
462 } // namespace remoting 474 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698