| 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/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/process/process_handle.h" | 9 #include "base/process/process_handle.h" |
| 10 #include "base/memory/shared_memory.h" | 10 #include "base/memory/shared_memory.h" |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, | 107 scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, |
| 108 base::WeakPtr<ClientSessionControl> client_session_control, | 108 base::WeakPtr<ClientSessionControl> client_session_control, |
| 109 base::WeakPtr<DesktopSessionConnector> desktop_session_connector, | 109 base::WeakPtr<DesktopSessionConnector> desktop_session_connector, |
| 110 bool virtual_terminal) | 110 bool virtual_terminal) |
| 111 : audio_capture_task_runner_(audio_capture_task_runner), | 111 : audio_capture_task_runner_(audio_capture_task_runner), |
| 112 caller_task_runner_(caller_task_runner), | 112 caller_task_runner_(caller_task_runner), |
| 113 io_task_runner_(io_task_runner), | 113 io_task_runner_(io_task_runner), |
| 114 video_capture_task_runner_(video_capture_task_runner), | 114 video_capture_task_runner_(video_capture_task_runner), |
| 115 client_session_control_(client_session_control), | 115 client_session_control_(client_session_control), |
| 116 desktop_session_connector_(desktop_session_connector), | 116 desktop_session_connector_(desktop_session_connector), |
| 117 desktop_process_(base::kNullProcessHandle), | |
| 118 pending_capture_frame_requests_(0), | 117 pending_capture_frame_requests_(0), |
| 119 is_desktop_session_connected_(false), | 118 is_desktop_session_connected_(false), |
| 120 virtual_terminal_(virtual_terminal) { | 119 virtual_terminal_(virtual_terminal) { |
| 121 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 120 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| 122 } | 121 } |
| 123 | 122 |
| 124 scoped_ptr<AudioCapturer> DesktopSessionProxy::CreateAudioCapturer() { | 123 scoped_ptr<AudioCapturer> DesktopSessionProxy::CreateAudioCapturer() { |
| 125 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 124 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| 126 | 125 |
| 127 return make_scoped_ptr(new IpcAudioCapturer(this)); | 126 return make_scoped_ptr(new IpcAudioCapturer(this)); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 VLOG(1) << "IPC: network <- desktop (" << peer_pid << ")"; | 210 VLOG(1) << "IPC: network <- desktop (" << peer_pid << ")"; |
| 212 } | 211 } |
| 213 | 212 |
| 214 void DesktopSessionProxy::OnChannelError() { | 213 void DesktopSessionProxy::OnChannelError() { |
| 215 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 214 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| 216 | 215 |
| 217 DetachFromDesktop(); | 216 DetachFromDesktop(); |
| 218 } | 217 } |
| 219 | 218 |
| 220 bool DesktopSessionProxy::AttachToDesktop( | 219 bool DesktopSessionProxy::AttachToDesktop( |
| 221 base::ProcessHandle desktop_process, | 220 base::Process desktop_process, |
| 222 IPC::PlatformFileForTransit desktop_pipe) { | 221 IPC::PlatformFileForTransit desktop_pipe) { |
| 223 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 222 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| 224 DCHECK(!desktop_channel_); | 223 DCHECK(!desktop_channel_); |
| 225 DCHECK_EQ(desktop_process_, base::kNullProcessHandle); | 224 DCHECK(!desktop_process_.IsValid()); |
| 226 | 225 |
| 227 // Ignore the attach notification if the client session has been disconnected | 226 // Ignore the attach notification if the client session has been disconnected |
| 228 // already. | 227 // already. |
| 229 if (!client_session_control_.get()) { | 228 if (!client_session_control_.get()) |
| 230 base::CloseProcessHandle(desktop_process); | |
| 231 return false; | 229 return false; |
| 232 } | |
| 233 | 230 |
| 234 desktop_process_ = desktop_process; | 231 desktop_process_ = desktop_process.Pass(); |
| 235 | 232 |
| 236 #if defined(OS_WIN) | 233 #if defined(OS_WIN) |
| 237 // On Windows: |desktop_process| is a valid handle, but |desktop_pipe| needs | 234 // On Windows: |desktop_process| is a valid handle, but |desktop_pipe| needs |
| 238 // to be duplicated from the desktop process. | 235 // to be duplicated from the desktop process. |
| 239 HANDLE temp_handle; | 236 HANDLE temp_handle; |
| 240 if (!DuplicateHandle(desktop_process_, desktop_pipe, GetCurrentProcess(), | 237 if (!DuplicateHandle(desktop_process_.Handle(), desktop_pipe, |
| 241 &temp_handle, 0, FALSE, DUPLICATE_SAME_ACCESS)) { | 238 GetCurrentProcess(), &temp_handle, 0, |
| 239 FALSE, DUPLICATE_SAME_ACCESS)) { |
| 242 PLOG(ERROR) << "Failed to duplicate the desktop-to-network pipe handle"; | 240 PLOG(ERROR) << "Failed to duplicate the desktop-to-network pipe handle"; |
| 243 | 241 |
| 244 desktop_process_ = base::kNullProcessHandle; | 242 desktop_process_.Close(); |
| 245 base::CloseProcessHandle(desktop_process); | |
| 246 return false; | 243 return false; |
| 247 } | 244 } |
| 248 base::win::ScopedHandle pipe(temp_handle); | 245 base::win::ScopedHandle pipe(temp_handle); |
| 249 | 246 |
| 250 IPC::ChannelHandle desktop_channel_handle(pipe.Get()); | 247 IPC::ChannelHandle desktop_channel_handle(pipe.Get()); |
| 251 | 248 |
| 252 #elif defined(OS_POSIX) | 249 #elif defined(OS_POSIX) |
| 253 // On posix: |desktop_pipe| is a valid file descriptor. | 250 // On posix: |desktop_pipe| is a valid file descriptor. |
| 254 DCHECK(desktop_pipe.auto_close); | 251 DCHECK(desktop_pipe.auto_close); |
| 255 | 252 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 273 virtual_terminal_)); | 270 virtual_terminal_)); |
| 274 | 271 |
| 275 return true; | 272 return true; |
| 276 } | 273 } |
| 277 | 274 |
| 278 void DesktopSessionProxy::DetachFromDesktop() { | 275 void DesktopSessionProxy::DetachFromDesktop() { |
| 279 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 276 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| 280 | 277 |
| 281 desktop_channel_.reset(); | 278 desktop_channel_.reset(); |
| 282 | 279 |
| 283 if (desktop_process_ != base::kNullProcessHandle) { | 280 if (desktop_process_.IsValid()) |
| 284 base::CloseProcessHandle(desktop_process_); | 281 desktop_process_.Close(); |
| 285 desktop_process_ = base::kNullProcessHandle; | |
| 286 } | |
| 287 | 282 |
| 288 shared_buffers_.clear(); | 283 shared_buffers_.clear(); |
| 289 | 284 |
| 290 // Generate fake responses to keep the video capturer in sync. | 285 // Generate fake responses to keep the video capturer in sync. |
| 291 while (pending_capture_frame_requests_) { | 286 while (pending_capture_frame_requests_) { |
| 292 --pending_capture_frame_requests_; | 287 --pending_capture_frame_requests_; |
| 293 PostCaptureCompleted(nullptr); | 288 PostCaptureCompleted(nullptr); |
| 294 } | 289 } |
| 295 } | 290 } |
| 296 | 291 |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 425 desktop_session_connector_->SetScreenResolution(this, screen_resolution_); | 420 desktop_session_connector_->SetScreenResolution(this, screen_resolution_); |
| 426 SendToDesktop( | 421 SendToDesktop( |
| 427 new ChromotingNetworkDesktopMsg_SetScreenResolution(screen_resolution_)); | 422 new ChromotingNetworkDesktopMsg_SetScreenResolution(screen_resolution_)); |
| 428 } | 423 } |
| 429 | 424 |
| 430 DesktopSessionProxy::~DesktopSessionProxy() { | 425 DesktopSessionProxy::~DesktopSessionProxy() { |
| 431 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 426 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| 432 | 427 |
| 433 if (desktop_session_connector_.get() && is_desktop_session_connected_) | 428 if (desktop_session_connector_.get() && is_desktop_session_connected_) |
| 434 desktop_session_connector_->DisconnectTerminal(this); | 429 desktop_session_connector_->DisconnectTerminal(this); |
| 435 | |
| 436 if (desktop_process_ != base::kNullProcessHandle) { | |
| 437 base::CloseProcessHandle(desktop_process_); | |
| 438 desktop_process_ = base::kNullProcessHandle; | |
| 439 } | |
| 440 } | 430 } |
| 441 | 431 |
| 442 scoped_refptr<DesktopSessionProxy::IpcSharedBufferCore> | 432 scoped_refptr<DesktopSessionProxy::IpcSharedBufferCore> |
| 443 DesktopSessionProxy::GetSharedBufferCore(int id) { | 433 DesktopSessionProxy::GetSharedBufferCore(int id) { |
| 444 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 434 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| 445 | 435 |
| 446 SharedBuffers::const_iterator i = shared_buffers_.find(id); | 436 SharedBuffers::const_iterator i = shared_buffers_.find(id); |
| 447 if (i != shared_buffers_.end()) { | 437 if (i != shared_buffers_.end()) { |
| 448 return i->second; | 438 return i->second; |
| 449 } else { | 439 } else { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 469 base::Passed(&packet))); | 459 base::Passed(&packet))); |
| 470 } | 460 } |
| 471 | 461 |
| 472 void DesktopSessionProxy::OnCreateSharedBuffer( | 462 void DesktopSessionProxy::OnCreateSharedBuffer( |
| 473 int id, | 463 int id, |
| 474 IPC::PlatformFileForTransit handle, | 464 IPC::PlatformFileForTransit handle, |
| 475 uint32 size) { | 465 uint32 size) { |
| 476 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 466 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| 477 | 467 |
| 478 scoped_refptr<IpcSharedBufferCore> shared_buffer = | 468 scoped_refptr<IpcSharedBufferCore> shared_buffer = |
| 479 new IpcSharedBufferCore(id, handle, desktop_process_, size); | 469 new IpcSharedBufferCore(id, handle, desktop_process_.Handle(), size); |
| 480 | 470 |
| 481 if (shared_buffer->memory() != nullptr && | 471 if (shared_buffer->memory() != nullptr && |
| 482 !shared_buffers_.insert(std::make_pair(id, shared_buffer)).second) { | 472 !shared_buffers_.insert(std::make_pair(id, shared_buffer)).second) { |
| 483 LOG(ERROR) << "Duplicate shared buffer id " << id << " encountered"; | 473 LOG(ERROR) << "Duplicate shared buffer id " << id << " encountered"; |
| 484 } | 474 } |
| 485 } | 475 } |
| 486 | 476 |
| 487 void DesktopSessionProxy::OnReleaseSharedBuffer(int id) { | 477 void DesktopSessionProxy::OnReleaseSharedBuffer(int id) { |
| 488 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 478 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| 489 | 479 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 568 } | 558 } |
| 569 | 559 |
| 570 // static | 560 // static |
| 571 void DesktopSessionProxyTraits::Destruct( | 561 void DesktopSessionProxyTraits::Destruct( |
| 572 const DesktopSessionProxy* desktop_session_proxy) { | 562 const DesktopSessionProxy* desktop_session_proxy) { |
| 573 desktop_session_proxy->caller_task_runner_->DeleteSoon(FROM_HERE, | 563 desktop_session_proxy->caller_task_runner_->DeleteSoon(FROM_HERE, |
| 574 desktop_session_proxy); | 564 desktop_session_proxy); |
| 575 } | 565 } |
| 576 | 566 |
| 577 } // namespace remoting | 567 } // namespace remoting |
| OLD | NEW |