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

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: Fix posix #2 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
« no previous file with comments | « remoting/host/desktop_session_proxy.h ('k') | remoting/host/ipc_desktop_environment.h » ('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/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_EQ(desktop_process_, base::kNullProcessHandle);
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 IPC::ChannelHandle desktop_channel_handle(pipe);
130 desktop_channel_.reset(new IPC::ChannelProxy(IPC::ChannelHandle(pipe), 135
131 IPC::Channel::MODE_CLIENT,
132 this,
133 caller_task_runner_));
134 #elif defined(OS_POSIX) 136 #elif defined(OS_POSIX)
135 // On posix: both |desktop_process| and |desktop_pipe| are valid file 137 // On posix: |desktop_pipe| is a valid file descriptor.
136 // descriptors.
137 DCHECK(desktop_process.auto_close);
138 DCHECK(desktop_pipe.auto_close); 138 DCHECK(desktop_pipe.auto_close);
139 139
140 base::ClosePlatformFile(desktop_process.fd); 140 IPC::ChannelHandle desktop_channel_handle("", desktop_pipe);
141 141
142 // Connect to the desktop process.
143 desktop_channel_.reset(new IPC::ChannelProxy(
144 IPC::ChannelHandle("", desktop_pipe),
145 IPC::Channel::MODE_CLIENT,
146 this,
147 caller_task_runner_));
148 #else 142 #else
149 #error Unsupported platform. 143 #error Unsupported platform.
150 #endif 144 #endif
151 145
146 // Connect to the desktop process.
147 desktop_channel_.reset(new IPC::ChannelProxy(desktop_channel_handle,
148 IPC::Channel::MODE_CLIENT,
149 this,
150 io_task_runner_));
151
152 // Pass ID of the client (which is authenticated at this point) to the desktop 152 // Pass ID of the client (which is authenticated at this point) to the desktop
153 // session agent and start the agent. 153 // session agent and start the agent.
154 SendToDesktop(new ChromotingNetworkDesktopMsg_StartSessionAgent(client_jid_)); 154 SendToDesktop(new ChromotingNetworkDesktopMsg_StartSessionAgent(client_jid_));
155 return true; 155 return true;
156 } 156 }
157 157
158 void DesktopSessionProxy::DetachFromDesktop() { 158 void DesktopSessionProxy::DetachFromDesktop() {
159 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 159 DCHECK(caller_task_runner_->BelongsToCurrentThread());
160 160
161 desktop_channel_.reset(); 161 desktop_channel_.reset();
162 162
163 #if defined(OS_WIN) 163 if (desktop_process_ != base::kNullProcessHandle) {
164 desktop_process_.Close(); 164 base::CloseProcessHandle(desktop_process_);
165 #endif // defined(OS_WIN) 165 desktop_process_ = base::kNullProcessHandle;
166 }
166 167
167 shared_buffers_.clear(); 168 shared_buffers_.clear();
168 169
169 // Generate fake responses to keep the video capturer in sync. 170 // Generate fake responses to keep the video capturer in sync.
170 while (pending_capture_frame_requests_) { 171 while (pending_capture_frame_requests_) {
171 --pending_capture_frame_requests_; 172 --pending_capture_frame_requests_;
172 PostCaptureCompleted(scoped_refptr<media::ScreenCaptureData>()); 173 PostCaptureCompleted(scoped_refptr<media::ScreenCaptureData>());
173 } 174 }
174 } 175 }
175 176
(...skipping 11 matching lines...) Expand all
187 } 188 }
188 189
189 void DesktopSessionProxy::InvalidateRegion(const SkRegion& invalid_region) { 190 void DesktopSessionProxy::InvalidateRegion(const SkRegion& invalid_region) {
190 if (!caller_task_runner_->BelongsToCurrentThread()) { 191 if (!caller_task_runner_->BelongsToCurrentThread()) {
191 caller_task_runner_->PostTask( 192 caller_task_runner_->PostTask(
192 FROM_HERE, base::Bind(&DesktopSessionProxy::InvalidateRegion, this, 193 FROM_HERE, base::Bind(&DesktopSessionProxy::InvalidateRegion, this,
193 invalid_region)); 194 invalid_region));
194 return; 195 return;
195 } 196 }
196 197
197 std::vector<SkIRect> invalid_rects; 198 if (desktop_channel_) {
198 for (SkRegion::Iterator i(invalid_region); !i.done(); i.next()) 199 std::vector<SkIRect> invalid_rects;
199 invalid_rects.push_back(i.rect()); 200 for (SkRegion::Iterator i(invalid_region); !i.done(); i.next())
201 invalid_rects.push_back(i.rect());
200 202
201 SendToDesktop( 203 SendToDesktop(
202 new ChromotingNetworkDesktopMsg_InvalidateRegion(invalid_rects)); 204 new ChromotingNetworkDesktopMsg_InvalidateRegion(invalid_rects));
205 }
203 } 206 }
204 207
205 void DesktopSessionProxy::CaptureFrame() { 208 void DesktopSessionProxy::CaptureFrame() {
206 if (!caller_task_runner_->BelongsToCurrentThread()) { 209 if (!caller_task_runner_->BelongsToCurrentThread()) {
207 caller_task_runner_->PostTask( 210 caller_task_runner_->PostTask(
208 FROM_HERE, base::Bind(&DesktopSessionProxy::CaptureFrame, this)); 211 FROM_HERE, base::Bind(&DesktopSessionProxy::CaptureFrame, this));
209 return; 212 return;
210 } 213 }
211 214
212 ++pending_capture_frame_requests_; 215 if (desktop_channel_) {
213 SendToDesktop(new ChromotingNetworkDesktopMsg_CaptureFrame()); 216 ++pending_capture_frame_requests_;
217 SendToDesktop(new ChromotingNetworkDesktopMsg_CaptureFrame());
218 } else {
219 PostCaptureCompleted(scoped_refptr<media::ScreenCaptureData>());
220 }
214 } 221 }
215 222
216 void DesktopSessionProxy::StartVideoCapturer( 223 void DesktopSessionProxy::StartVideoCapturer(
217 IpcVideoFrameCapturer* video_capturer) { 224 IpcVideoFrameCapturer* video_capturer) {
218 DCHECK(video_capture_task_runner_->BelongsToCurrentThread()); 225 DCHECK(video_capture_task_runner_->BelongsToCurrentThread());
219 DCHECK(video_capturer_ == NULL); 226 DCHECK(video_capturer_ == NULL);
220 227
221 video_capturer_ = video_capturer; 228 video_capturer_ = video_capturer;
222 } 229 }
223 230
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 } 282 }
276 283
277 void DesktopSessionProxy::StartEventExecutor( 284 void DesktopSessionProxy::StartEventExecutor(
278 scoped_ptr<protocol::ClipboardStub> client_clipboard) { 285 scoped_ptr<protocol::ClipboardStub> client_clipboard) {
279 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 286 DCHECK(caller_task_runner_->BelongsToCurrentThread());
280 287
281 client_clipboard_ = client_clipboard.Pass(); 288 client_clipboard_ = client_clipboard.Pass();
282 } 289 }
283 290
284 DesktopSessionProxy::~DesktopSessionProxy() { 291 DesktopSessionProxy::~DesktopSessionProxy() {
292 if (desktop_process_ != base::kNullProcessHandle) {
293 base::CloseProcessHandle(desktop_process_);
294 desktop_process_ = base::kNullProcessHandle;
295 }
285 } 296 }
286 297
287 scoped_refptr<media::SharedBuffer> DesktopSessionProxy::GetSharedBuffer( 298 scoped_refptr<media::SharedBuffer> DesktopSessionProxy::GetSharedBuffer(
288 int id) { 299 int id) {
289 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 300 DCHECK(caller_task_runner_->BelongsToCurrentThread());
290 301
291 SharedBuffers::const_iterator i = shared_buffers_.find(id); 302 SharedBuffers::const_iterator i = shared_buffers_.find(id);
292 if (i != shared_buffers_.end()) { 303 if (i != shared_buffers_.end()) {
293 return i->second; 304 return i->second;
294 } else { 305 } else {
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 464 DCHECK(caller_task_runner_->BelongsToCurrentThread());
454 465
455 if (desktop_channel_) { 466 if (desktop_channel_) {
456 desktop_channel_->Send(message); 467 desktop_channel_->Send(message);
457 } else { 468 } else {
458 delete message; 469 delete message;
459 } 470 }
460 } 471 }
461 472
462 } // namespace remoting 473 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/desktop_session_proxy.h ('k') | remoting/host/ipc_desktop_environment.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698