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_agent.h" | 5 #include "remoting/host/desktop_session_agent.h" |
6 | 6 |
7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/memory/shared_memory.h" |
9 #include "ipc/ipc_channel_proxy.h" | 10 #include "ipc/ipc_channel_proxy.h" |
10 #include "ipc/ipc_message.h" | 11 #include "ipc/ipc_message.h" |
11 #include "ipc/ipc_message_macros.h" | 12 #include "ipc/ipc_message_macros.h" |
12 #include "media/video/capture/screen/screen_capture_data.h" | |
13 #include "remoting/base/auto_thread_task_runner.h" | 13 #include "remoting/base/auto_thread_task_runner.h" |
14 #include "remoting/base/constants.h" | 14 #include "remoting/base/constants.h" |
15 #include "remoting/host/audio_capturer.h" | 15 #include "remoting/host/audio_capturer.h" |
16 #include "remoting/host/chromoting_messages.h" | 16 #include "remoting/host/chromoting_messages.h" |
17 #include "remoting/host/desktop_environment.h" | 17 #include "remoting/host/desktop_environment.h" |
18 #include "remoting/host/input_injector.h" | 18 #include "remoting/host/input_injector.h" |
19 #include "remoting/host/remote_input_filter.h" | 19 #include "remoting/host/remote_input_filter.h" |
20 #include "remoting/host/screen_controls.h" | 20 #include "remoting/host/screen_controls.h" |
21 #include "remoting/host/screen_resolution.h" | 21 #include "remoting/host/screen_resolution.h" |
22 #include "remoting/proto/audio.pb.h" | 22 #include "remoting/proto/audio.pb.h" |
23 #include "remoting/proto/control.pb.h" | 23 #include "remoting/proto/control.pb.h" |
24 #include "remoting/proto/event.pb.h" | 24 #include "remoting/proto/event.pb.h" |
25 #include "remoting/protocol/clipboard_stub.h" | 25 #include "remoting/protocol/clipboard_stub.h" |
26 #include "remoting/protocol/input_event_tracker.h" | 26 #include "remoting/protocol/input_event_tracker.h" |
27 #include "third_party/skia/include/core/SkRegion.h" | 27 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" |
| 28 #include "third_party/webrtc/modules/desktop_capture/shared_memory.h" |
28 | 29 |
29 namespace remoting { | 30 namespace remoting { |
30 | 31 |
31 namespace { | 32 namespace { |
32 | 33 |
33 // Routes local clipboard events though the IPC channel to the network process. | 34 // Routes local clipboard events though the IPC channel to the network process. |
34 class DesktopSesssionClipboardStub : public protocol::ClipboardStub { | 35 class DesktopSesssionClipboardStub : public protocol::ClipboardStub { |
35 public: | 36 public: |
36 explicit DesktopSesssionClipboardStub( | 37 explicit DesktopSesssionClipboardStub( |
37 scoped_refptr<DesktopSessionAgent> desktop_session_agent); | 38 scoped_refptr<DesktopSessionAgent> desktop_session_agent); |
(...skipping 17 matching lines...) Expand all Loading... |
55 DesktopSesssionClipboardStub::~DesktopSesssionClipboardStub() { | 56 DesktopSesssionClipboardStub::~DesktopSesssionClipboardStub() { |
56 } | 57 } |
57 | 58 |
58 void DesktopSesssionClipboardStub::InjectClipboardEvent( | 59 void DesktopSesssionClipboardStub::InjectClipboardEvent( |
59 const protocol::ClipboardEvent& event) { | 60 const protocol::ClipboardEvent& event) { |
60 desktop_session_agent_->InjectClipboardEvent(event); | 61 desktop_session_agent_->InjectClipboardEvent(event); |
61 } | 62 } |
62 | 63 |
63 } // namespace | 64 } // namespace |
64 | 65 |
| 66 // webrtc::SharedMemory implementation that notifies creating |
| 67 // DesktopSessionAgent when it's deleted. |
| 68 class DesktopSessionAgent::SharedBuffer : public webrtc::SharedMemory { |
| 69 public: |
| 70 static scoped_ptr<SharedBuffer> Create(DesktopSessionAgent* agent, |
| 71 size_t size, |
| 72 int id) { |
| 73 scoped_ptr<base::SharedMemory> memory(new base::SharedMemory()); |
| 74 if (!memory->CreateAndMapAnonymous(size)) |
| 75 return scoped_ptr<SharedBuffer>(); |
| 76 return scoped_ptr<SharedBuffer>( |
| 77 new SharedBuffer(agent, memory.Pass(), size, id)); |
| 78 } |
| 79 |
| 80 virtual ~SharedBuffer() { |
| 81 agent_->OnSharedBufferDeleted(id()); |
| 82 } |
| 83 |
| 84 private: |
| 85 SharedBuffer(DesktopSessionAgent* agent, |
| 86 scoped_ptr<base::SharedMemory> memory, |
| 87 size_t size, |
| 88 int id) |
| 89 : SharedMemory(memory->memory(), size, |
| 90 #if defined(OS_WIN) |
| 91 memory->handle(), |
| 92 #else |
| 93 memory->handle().fd, |
| 94 #endif |
| 95 id), |
| 96 agent_(agent), |
| 97 shared_memory_(memory.Pass()) { |
| 98 } |
| 99 |
| 100 DesktopSessionAgent* agent_; |
| 101 scoped_ptr<base::SharedMemory> shared_memory_; |
| 102 |
| 103 DISALLOW_COPY_AND_ASSIGN(SharedBuffer); |
| 104 }; |
| 105 |
65 DesktopSessionAgent::Delegate::~Delegate() { | 106 DesktopSessionAgent::Delegate::~Delegate() { |
66 } | 107 } |
67 | 108 |
68 DesktopSessionAgent::~DesktopSessionAgent() { | 109 DesktopSessionAgent::~DesktopSessionAgent() { |
69 DCHECK(!audio_capturer_); | 110 DCHECK(!audio_capturer_); |
70 DCHECK(!desktop_environment_); | 111 DCHECK(!desktop_environment_); |
71 DCHECK(!network_channel_); | 112 DCHECK(!network_channel_); |
72 DCHECK(!screen_controls_); | 113 DCHECK(!screen_controls_); |
73 DCHECK(!video_capturer_); | 114 DCHECK(!video_capturer_); |
74 | 115 |
75 CloseDesktopPipeHandle(); | 116 CloseDesktopPipeHandle(); |
76 } | 117 } |
77 | 118 |
78 bool DesktopSessionAgent::OnMessageReceived(const IPC::Message& message) { | 119 bool DesktopSessionAgent::OnMessageReceived(const IPC::Message& message) { |
79 DCHECK(caller_task_runner()->BelongsToCurrentThread()); | 120 DCHECK(caller_task_runner()->BelongsToCurrentThread()); |
80 | 121 |
81 bool handled = true; | 122 bool handled = true; |
82 if (started_) { | 123 if (started_) { |
83 IPC_BEGIN_MESSAGE_MAP(DesktopSessionAgent, message) | 124 IPC_BEGIN_MESSAGE_MAP(DesktopSessionAgent, message) |
84 IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_CaptureFrame, | 125 IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_CaptureFrame, |
85 OnCaptureFrame) | 126 OnCaptureFrame) |
86 IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_SharedBufferCreated, | |
87 OnSharedBufferCreated) | |
88 IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_InjectClipboardEvent, | 127 IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_InjectClipboardEvent, |
89 OnInjectClipboardEvent) | 128 OnInjectClipboardEvent) |
90 IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_InjectKeyEvent, | 129 IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_InjectKeyEvent, |
91 OnInjectKeyEvent) | 130 OnInjectKeyEvent) |
92 IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_InjectMouseEvent, | 131 IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_InjectMouseEvent, |
93 OnInjectMouseEvent) | 132 OnInjectMouseEvent) |
94 IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_SetScreenResolution, | 133 IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_SetScreenResolution, |
95 SetScreenResolution) | 134 SetScreenResolution) |
96 IPC_MESSAGE_UNHANDLED(handled = false) | 135 IPC_MESSAGE_UNHANDLED(handled = false) |
97 IPC_END_MESSAGE_MAP() | 136 IPC_END_MESSAGE_MAP() |
(...skipping 22 matching lines...) Expand all Loading... |
120 | 159 |
121 // Make sure the channel is closed. | 160 // Make sure the channel is closed. |
122 network_channel_.reset(); | 161 network_channel_.reset(); |
123 CloseDesktopPipeHandle(); | 162 CloseDesktopPipeHandle(); |
124 | 163 |
125 // Notify the caller that the channel has been disconnected. | 164 // Notify the caller that the channel has been disconnected. |
126 if (delegate_.get()) | 165 if (delegate_.get()) |
127 delegate_->OnNetworkProcessDisconnected(); | 166 delegate_->OnNetworkProcessDisconnected(); |
128 } | 167 } |
129 | 168 |
130 scoped_refptr<media::SharedBuffer> DesktopSessionAgent::CreateSharedBuffer( | 169 webrtc::SharedMemory* DesktopSessionAgent::CreateSharedMemory(size_t size) { |
131 uint32 size) { | |
132 DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); | 170 DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); |
133 | 171 |
134 scoped_refptr<media::SharedBuffer> buffer = new media::SharedBuffer(size); | 172 scoped_ptr<SharedBuffer> buffer = |
135 if (buffer->ptr() != NULL) { | 173 SharedBuffer::Create(this, size, next_shared_buffer_id_); |
136 buffer->set_id(next_shared_buffer_id_); | 174 if (buffer) { |
137 shared_buffers_.push_back(buffer); | 175 shared_buffers_++; |
138 | 176 |
139 // |next_shared_buffer_id_| starts from 1 and incrementing it by 2 makes | 177 // |next_shared_buffer_id_| starts from 1 and incrementing it by 2 makes |
140 // sure it is always odd and therefore zero is never used as a valid buffer | 178 // sure it is always odd and therefore zero is never used as a valid buffer |
141 // ID. | 179 // ID. |
142 // | 180 // |
143 // It is very unlikely (though theoretically possible) to allocate the same | 181 // It is very unlikely (though theoretically possible) to allocate the same |
144 // ID for two different buffers due to integer overflow. It should take | 182 // ID for two different buffers due to integer overflow. It should take |
145 // about a year of allocating 100 new buffers every second. Practically | 183 // about a year of allocating 100 new buffers every second. Practically |
146 // speaking it never happens. | 184 // speaking it never happens. |
147 next_shared_buffer_id_ += 2; | 185 next_shared_buffer_id_ += 2; |
148 | 186 |
| 187 IPC::PlatformFileForTransit handle; |
| 188 #if defined(OS_WIN) |
| 189 handle = buffer->handle(); |
| 190 #else |
| 191 handle = base::FileDescriptor(buffer->handle(), false); |
| 192 #endif |
149 SendToNetwork(new ChromotingDesktopNetworkMsg_CreateSharedBuffer( | 193 SendToNetwork(new ChromotingDesktopNetworkMsg_CreateSharedBuffer( |
150 buffer->id(), buffer->handle(), buffer->size())); | 194 buffer->id(), handle, buffer->size())); |
151 } | 195 } |
152 | 196 |
153 return buffer; | 197 return buffer.release(); |
154 } | |
155 | |
156 void DesktopSessionAgent::ReleaseSharedBuffer( | |
157 scoped_refptr<media::SharedBuffer> buffer) { | |
158 DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); | |
159 DCHECK(buffer->id() != 0); | |
160 | |
161 SendToNetwork( | |
162 new ChromotingDesktopNetworkMsg_ReleaseSharedBuffer(buffer->id())); | |
163 } | 198 } |
164 | 199 |
165 const std::string& DesktopSessionAgent::client_jid() const { | 200 const std::string& DesktopSessionAgent::client_jid() const { |
166 return client_jid_; | 201 return client_jid_; |
167 } | 202 } |
168 | 203 |
169 void DesktopSessionAgent::DisconnectSession() { | 204 void DesktopSessionAgent::DisconnectSession() { |
170 SendToNetwork(new ChromotingDesktopNetworkMsg_DisconnectSession()); | 205 SendToNetwork(new ChromotingDesktopNetworkMsg_DisconnectSession()); |
171 } | 206 } |
172 | 207 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 audio_capture_task_runner()->PostTask( | 264 audio_capture_task_runner()->PostTask( |
230 FROM_HERE, base::Bind(&DesktopSessionAgent::StartAudioCapturer, this)); | 265 FROM_HERE, base::Bind(&DesktopSessionAgent::StartAudioCapturer, this)); |
231 } | 266 } |
232 | 267 |
233 // Start the video capturer. | 268 // Start the video capturer. |
234 video_capturer_ = desktop_environment_->CreateVideoCapturer(); | 269 video_capturer_ = desktop_environment_->CreateVideoCapturer(); |
235 video_capture_task_runner()->PostTask( | 270 video_capture_task_runner()->PostTask( |
236 FROM_HERE, base::Bind(&DesktopSessionAgent::StartVideoCapturer, this)); | 271 FROM_HERE, base::Bind(&DesktopSessionAgent::StartVideoCapturer, this)); |
237 } | 272 } |
238 | 273 |
239 void DesktopSessionAgent::OnCaptureCompleted( | 274 void DesktopSessionAgent::OnCaptureCompleted(webrtc::DesktopFrame* frame) { |
240 scoped_refptr<media::ScreenCaptureData> capture_data) { | |
241 DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); | 275 DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); |
242 | 276 |
243 current_size_ = capture_data->size(); | 277 last_frame_.reset(frame); |
244 | 278 |
245 // Serialize media::ScreenCaptureData | 279 current_size_ = frame->size(); |
246 SerializedCapturedData serialized_data; | 280 |
247 serialized_data.shared_buffer_id = capture_data->shared_buffer()->id(); | 281 // Serialize webrtc::DesktopFrame. |
248 serialized_data.bytes_per_row = capture_data->stride(); | 282 SerializedDesktopFrame serialized_frame; |
249 serialized_data.dimensions = capture_data->size(); | 283 serialized_frame.shared_buffer_id = frame->shared_memory()->id(); |
250 serialized_data.capture_time_ms = capture_data->capture_time_ms(); | 284 serialized_frame.bytes_per_row = frame->stride(); |
251 serialized_data.client_sequence_number = | 285 serialized_frame.dimensions = frame->size(); |
252 capture_data->client_sequence_number(); | 286 serialized_frame.capture_time_ms = frame->capture_time_ms(); |
253 serialized_data.dpi = capture_data->dpi(); | 287 serialized_frame.dpi = frame->dpi(); |
254 for (SkRegion::Iterator i(capture_data->dirty_region()); !i.done(); i.next()) | 288 for (webrtc::DesktopRegion::Iterator i(frame->updated_region()); |
255 serialized_data.dirty_region.push_back(i.rect()); | 289 !i.IsAtEnd(); i.Advance()) { |
| 290 serialized_frame.dirty_region.push_back(i.rect()); |
| 291 } |
256 | 292 |
257 SendToNetwork( | 293 SendToNetwork( |
258 new ChromotingDesktopNetworkMsg_CaptureCompleted(serialized_data)); | 294 new ChromotingDesktopNetworkMsg_CaptureCompleted(serialized_frame)); |
259 } | 295 } |
260 | 296 |
261 void DesktopSessionAgent::OnCursorShapeChanged( | 297 void DesktopSessionAgent::OnCursorShapeChanged( |
262 scoped_ptr<media::MouseCursorShape> cursor_shape) { | 298 scoped_ptr<media::MouseCursorShape> cursor_shape) { |
263 DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); | 299 DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); |
264 | 300 |
265 SendToNetwork(new ChromotingDesktopNetworkMsg_CursorShapeChanged( | 301 SendToNetwork(new ChromotingDesktopNetworkMsg_CursorShapeChanged( |
266 *cursor_shape)); | 302 *cursor_shape)); |
267 } | 303 } |
268 | 304 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 FROM_HERE, | 383 FROM_HERE, |
348 base::Bind(&DesktopSessionAgent::OnCaptureFrame, this)); | 384 base::Bind(&DesktopSessionAgent::OnCaptureFrame, this)); |
349 return; | 385 return; |
350 } | 386 } |
351 | 387 |
352 // media::ScreenCapturer supports a very few (currently 2) outstanding capture | 388 // media::ScreenCapturer supports a very few (currently 2) outstanding capture |
353 // requests. The requests are serialized on |video_capture_task_runner()| task | 389 // requests. The requests are serialized on |video_capture_task_runner()| task |
354 // runner. If the client issues more requests, pixel data in captured frames | 390 // runner. If the client issues more requests, pixel data in captured frames |
355 // will likely be corrupted but stability of media::ScreenCapturer will not be | 391 // will likely be corrupted but stability of media::ScreenCapturer will not be |
356 // affected. | 392 // affected. |
357 video_capturer_->CaptureFrame(); | 393 video_capturer_->Capture(webrtc::DesktopRegion()); |
358 } | |
359 | |
360 void DesktopSessionAgent::OnSharedBufferCreated(int id) { | |
361 if (!video_capture_task_runner()->BelongsToCurrentThread()) { | |
362 video_capture_task_runner()->PostTask( | |
363 FROM_HERE, | |
364 base::Bind(&DesktopSessionAgent::OnSharedBufferCreated, this, id)); | |
365 return; | |
366 } | |
367 | |
368 // Drop the cached reference to the buffer. | |
369 SharedBuffers::iterator i = shared_buffers_.begin(); | |
370 for (; i != shared_buffers_.end(); ++i) { | |
371 if ((*i)->id() == id) { | |
372 shared_buffers_.erase(i); | |
373 break; | |
374 } | |
375 } | |
376 } | 394 } |
377 | 395 |
378 void DesktopSessionAgent::OnInjectClipboardEvent( | 396 void DesktopSessionAgent::OnInjectClipboardEvent( |
379 const std::string& serialized_event) { | 397 const std::string& serialized_event) { |
380 DCHECK(caller_task_runner()->BelongsToCurrentThread()); | 398 DCHECK(caller_task_runner()->BelongsToCurrentThread()); |
381 | 399 |
382 protocol::ClipboardEvent event; | 400 protocol::ClipboardEvent event; |
383 if (!event.ParseFromString(serialized_event)) { | 401 if (!event.ParseFromString(serialized_event)) { |
384 LOG(ERROR) << "Failed to parse protocol::ClipboardEvent."; | 402 LOG(ERROR) << "Failed to parse protocol::ClipboardEvent."; |
385 return; | 403 return; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 | 440 |
423 // InputStub implementations must verify events themselves, so we don't need | 441 // InputStub implementations must verify events themselves, so we don't need |
424 // verification here. This matches HostEventDispatcher. | 442 // verification here. This matches HostEventDispatcher. |
425 remote_input_filter_->InjectMouseEvent(event); | 443 remote_input_filter_->InjectMouseEvent(event); |
426 } | 444 } |
427 | 445 |
428 void DesktopSessionAgent::SetScreenResolution( | 446 void DesktopSessionAgent::SetScreenResolution( |
429 const ScreenResolution& resolution) { | 447 const ScreenResolution& resolution) { |
430 DCHECK(caller_task_runner()->BelongsToCurrentThread()); | 448 DCHECK(caller_task_runner()->BelongsToCurrentThread()); |
431 | 449 |
432 if (screen_controls_ && resolution.IsValid()) | 450 if (screen_controls_ && resolution.IsEmpty()) |
433 screen_controls_->SetScreenResolution(resolution); | 451 screen_controls_->SetScreenResolution(resolution); |
434 } | 452 } |
435 | 453 |
436 void DesktopSessionAgent::SendToNetwork(IPC::Message* message) { | 454 void DesktopSessionAgent::SendToNetwork(IPC::Message* message) { |
437 if (!caller_task_runner()->BelongsToCurrentThread()) { | 455 if (!caller_task_runner()->BelongsToCurrentThread()) { |
438 caller_task_runner()->PostTask( | 456 caller_task_runner()->PostTask( |
439 FROM_HERE, | 457 FROM_HERE, |
440 base::Bind(&DesktopSessionAgent::SendToNetwork, this, message)); | 458 base::Bind(&DesktopSessionAgent::SendToNetwork, this, message)); |
441 return; | 459 return; |
442 } | 460 } |
(...skipping 16 matching lines...) Expand all Loading... |
459 | 477 |
460 void DesktopSessionAgent::StopAudioCapturer() { | 478 void DesktopSessionAgent::StopAudioCapturer() { |
461 DCHECK(audio_capture_task_runner()->BelongsToCurrentThread()); | 479 DCHECK(audio_capture_task_runner()->BelongsToCurrentThread()); |
462 | 480 |
463 audio_capturer_.reset(); | 481 audio_capturer_.reset(); |
464 } | 482 } |
465 | 483 |
466 void DesktopSessionAgent::StartVideoCapturer() { | 484 void DesktopSessionAgent::StartVideoCapturer() { |
467 DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); | 485 DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); |
468 | 486 |
469 if (video_capturer_) | 487 if (video_capturer_) { |
| 488 video_capturer_->SetMouseShapeObserver(this); |
470 video_capturer_->Start(this); | 489 video_capturer_->Start(this); |
| 490 } |
471 } | 491 } |
472 | 492 |
473 void DesktopSessionAgent::StopVideoCapturer() { | 493 void DesktopSessionAgent::StopVideoCapturer() { |
474 DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); | 494 DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); |
475 | 495 |
476 video_capturer_.reset(); | 496 video_capturer_.reset(); |
| 497 last_frame_.reset(); |
477 | 498 |
478 // Free any shared buffers left. | 499 // Video capturer must delete all buffers. |
479 shared_buffers_.clear(); | 500 DCHECK_EQ(shared_buffers_, 0); |
480 } | 501 } |
481 | 502 |
482 DesktopSessionAgent::DesktopSessionAgent( | 503 DesktopSessionAgent::DesktopSessionAgent( |
483 scoped_refptr<AutoThreadTaskRunner> audio_capture_task_runner, | 504 scoped_refptr<AutoThreadTaskRunner> audio_capture_task_runner, |
484 scoped_refptr<AutoThreadTaskRunner> caller_task_runner, | 505 scoped_refptr<AutoThreadTaskRunner> caller_task_runner, |
485 scoped_refptr<AutoThreadTaskRunner> input_task_runner, | 506 scoped_refptr<AutoThreadTaskRunner> input_task_runner, |
486 scoped_refptr<AutoThreadTaskRunner> io_task_runner, | 507 scoped_refptr<AutoThreadTaskRunner> io_task_runner, |
487 scoped_refptr<AutoThreadTaskRunner> video_capture_task_runner) | 508 scoped_refptr<AutoThreadTaskRunner> video_capture_task_runner) |
488 : audio_capture_task_runner_(audio_capture_task_runner), | 509 : audio_capture_task_runner_(audio_capture_task_runner), |
489 caller_task_runner_(caller_task_runner), | 510 caller_task_runner_(caller_task_runner), |
490 input_task_runner_(input_task_runner), | 511 input_task_runner_(input_task_runner), |
491 io_task_runner_(io_task_runner), | 512 io_task_runner_(io_task_runner), |
492 video_capture_task_runner_(video_capture_task_runner), | 513 video_capture_task_runner_(video_capture_task_runner), |
493 control_factory_(this), | 514 control_factory_(this), |
494 desktop_pipe_(IPC::InvalidPlatformFileForTransit()), | 515 desktop_pipe_(IPC::InvalidPlatformFileForTransit()), |
495 current_size_(SkISize::Make(0, 0)), | |
496 next_shared_buffer_id_(1), | 516 next_shared_buffer_id_(1), |
| 517 shared_buffers_(0), |
497 started_(false) { | 518 started_(false) { |
498 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 519 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
499 } | 520 } |
500 | 521 |
| 522 void DesktopSessionAgent::OnSharedBufferDeleted(int id) { |
| 523 DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); |
| 524 DCHECK(id != 0); |
| 525 |
| 526 shared_buffers_--; |
| 527 DCHECK_GE(shared_buffers_, 0); |
| 528 SendToNetwork(new ChromotingDesktopNetworkMsg_ReleaseSharedBuffer(id)); |
| 529 } |
| 530 |
501 void DesktopSessionAgent::CloseDesktopPipeHandle() { | 531 void DesktopSessionAgent::CloseDesktopPipeHandle() { |
502 if (!(desktop_pipe_ == IPC::InvalidPlatformFileForTransit())) { | 532 if (!(desktop_pipe_ == IPC::InvalidPlatformFileForTransit())) { |
503 #if defined(OS_WIN) | 533 #if defined(OS_WIN) |
504 base::ClosePlatformFile(desktop_pipe_); | 534 base::ClosePlatformFile(desktop_pipe_); |
505 #elif defined(OS_POSIX) | 535 #elif defined(OS_POSIX) |
506 base::ClosePlatformFile(desktop_pipe_.fd); | 536 base::ClosePlatformFile(desktop_pipe_.fd); |
507 #else // !defined(OS_POSIX) | 537 #else // !defined(OS_POSIX) |
508 #error Unsupported platform. | 538 #error Unsupported platform. |
509 #endif // !defined(OS_POSIX) | 539 #endif // !defined(OS_POSIX) |
510 | 540 |
511 desktop_pipe_ = IPC::InvalidPlatformFileForTransit(); | 541 desktop_pipe_ = IPC::InvalidPlatformFileForTransit(); |
512 } | 542 } |
513 } | 543 } |
514 | 544 |
515 } // namespace remoting | 545 } // namespace remoting |
OLD | NEW |