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

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

Issue 13983010: Use webrtc::DesktopCapturer for screen capturer implementation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: q Created 7 years, 8 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/process_util.h"
11 #include "base/memory/shared_memory.h"
11 #include "base/single_thread_task_runner.h" 12 #include "base/single_thread_task_runner.h"
12 #include "ipc/ipc_channel_proxy.h" 13 #include "ipc/ipc_channel_proxy.h"
13 #include "ipc/ipc_message_macros.h" 14 #include "ipc/ipc_message_macros.h"
14 #include "media/video/capture/screen/screen_capture_data.h"
15 #include "remoting/base/capabilities.h" 15 #include "remoting/base/capabilities.h"
16 #include "remoting/host/chromoting_messages.h" 16 #include "remoting/host/chromoting_messages.h"
17 #include "remoting/host/client_session.h" 17 #include "remoting/host/client_session.h"
18 #include "remoting/host/client_session_control.h" 18 #include "remoting/host/client_session_control.h"
19 #include "remoting/host/desktop_session_connector.h" 19 #include "remoting/host/desktop_session_connector.h"
20 #include "remoting/host/ipc_audio_capturer.h" 20 #include "remoting/host/ipc_audio_capturer.h"
21 #include "remoting/host/ipc_input_injector.h" 21 #include "remoting/host/ipc_input_injector.h"
22 #include "remoting/host/ipc_screen_controls.h" 22 #include "remoting/host/ipc_screen_controls.h"
23 #include "remoting/host/ipc_video_frame_capturer.h" 23 #include "remoting/host/ipc_video_frame_capturer.h"
24 #include "remoting/proto/audio.pb.h" 24 #include "remoting/proto/audio.pb.h"
25 #include "remoting/proto/control.pb.h" 25 #include "remoting/proto/control.pb.h"
26 #include "remoting/proto/event.pb.h" 26 #include "remoting/proto/event.pb.h"
27 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
28 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
29 #include "third_party/webrtc/modules/desktop_capture/shared_memory.h"
27 30
28 #if defined(OS_WIN) 31 #if defined(OS_WIN)
29 #include "base/win/scoped_handle.h" 32 #include "base/win/scoped_handle.h"
30 #endif // defined(OS_WIN) 33 #endif // defined(OS_WIN)
31 34
35 const bool kReadOnly = true;
32 const char kSendInitialResolution[] = "sendInitialResolution"; 36 const char kSendInitialResolution[] = "sendInitialResolution";
33 37
34 namespace remoting { 38 namespace remoting {
35 39
40 class DesktopSessionProxy::IpcSharedBufferCore
41 : public base::RefCountedThreadSafe<IpcSharedBufferCore> {
42 public:
43 IpcSharedBufferCore(int id,
44 base::SharedMemoryHandle handle,
45 size_t size)
46 : id_(id),
47 shared_memory_(handle, kReadOnly),
48 size_(size) {
49 shared_memory_.Map(size);
50 }
51
52 IpcSharedBufferCore(int id,
53 base::SharedMemoryHandle handle,
54 base::ProcessHandle process,
55 size_t size)
56 : id_(id),
57 shared_memory_(handle, kReadOnly, process),
58 size_(size) {
59 shared_memory_.Map(size);
60 }
61
62 int id() { return id_; }
63 size_t size() { return size_; }
64 void* memory() { return shared_memory_.memory(); }
65 webrtc::SharedMemory::Handle handle() {
66 #if defined(OS_WIN)
67 return shared_memory_.handle();
68 #else
69 return shared_memory_.handle().fd;
70 #endif
71 }
72
73
74 private:
75 virtual ~IpcSharedBufferCore() {}
76 friend class base::RefCountedThreadSafe<IpcSharedBufferCore>;
77
78 int id_;
79 base::SharedMemory shared_memory_;
80 size_t size_;
81
82 DISALLOW_COPY_AND_ASSIGN(IpcSharedBufferCore);
83 };
84
85 class DesktopSessionProxy::IpcSharedBuffer : public webrtc::SharedMemory {
alexeypa (please no reviews) 2013/04/26 21:33:58 nit: I think it is OK to use the ref-counted class
Sergey Ulanov 2013/05/07 22:25:50 Not sure I understand what you are suggesting here
alexeypa (please no reviews) 2013/05/08 22:24:59 Nevermind. I did't understand how that code worked
86 public:
87 IpcSharedBuffer(scoped_refptr<IpcSharedBufferCore> core)
88 : SharedMemory(core->memory(), core->size(),
89 core->handle(), core->id()),
90 core_(core) {
91 }
92
93 private:
94 scoped_refptr<IpcSharedBufferCore> core_;
95
96 DISALLOW_COPY_AND_ASSIGN(IpcSharedBuffer);
97 };
98
36 DesktopSessionProxy::DesktopSessionProxy( 99 DesktopSessionProxy::DesktopSessionProxy(
37 scoped_refptr<base::SingleThreadTaskRunner> audio_capture_task_runner, 100 scoped_refptr<base::SingleThreadTaskRunner> audio_capture_task_runner,
38 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, 101 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
39 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, 102 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
40 scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, 103 scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner,
41 base::WeakPtr<ClientSessionControl> client_session_control, 104 base::WeakPtr<ClientSessionControl> client_session_control,
42 base::WeakPtr<DesktopSessionConnector> desktop_session_connector, 105 base::WeakPtr<DesktopSessionConnector> desktop_session_connector,
43 bool virtual_terminal) 106 bool virtual_terminal)
44 : audio_capture_task_runner_(audio_capture_task_runner), 107 : audio_capture_task_runner_(audio_capture_task_runner),
45 caller_task_runner_(caller_task_runner), 108 caller_task_runner_(caller_task_runner),
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 if (desktop_process_ != base::kNullProcessHandle) { 269 if (desktop_process_ != base::kNullProcessHandle) {
207 base::CloseProcessHandle(desktop_process_); 270 base::CloseProcessHandle(desktop_process_);
208 desktop_process_ = base::kNullProcessHandle; 271 desktop_process_ = base::kNullProcessHandle;
209 } 272 }
210 273
211 shared_buffers_.clear(); 274 shared_buffers_.clear();
212 275
213 // Generate fake responses to keep the video capturer in sync. 276 // Generate fake responses to keep the video capturer in sync.
214 while (pending_capture_frame_requests_) { 277 while (pending_capture_frame_requests_) {
215 --pending_capture_frame_requests_; 278 --pending_capture_frame_requests_;
216 PostCaptureCompleted(scoped_refptr<media::ScreenCaptureData>()); 279 PostCaptureCompleted(scoped_ptr<webrtc::DesktopFrame>());
217 } 280 }
218 } 281 }
219 282
220 void DesktopSessionProxy::SetAudioCapturer( 283 void DesktopSessionProxy::SetAudioCapturer(
221 const base::WeakPtr<IpcAudioCapturer>& audio_capturer) { 284 const base::WeakPtr<IpcAudioCapturer>& audio_capturer) {
222 DCHECK(audio_capture_task_runner_->BelongsToCurrentThread()); 285 DCHECK(audio_capture_task_runner_->BelongsToCurrentThread());
223 286
224 audio_capturer_ = audio_capturer; 287 audio_capturer_ = audio_capturer;
225 } 288 }
226 289
227 void DesktopSessionProxy::CaptureFrame() { 290 void DesktopSessionProxy::CaptureFrame() {
228 if (!caller_task_runner_->BelongsToCurrentThread()) { 291 if (!caller_task_runner_->BelongsToCurrentThread()) {
229 caller_task_runner_->PostTask( 292 caller_task_runner_->PostTask(
230 FROM_HERE, base::Bind(&DesktopSessionProxy::CaptureFrame, this)); 293 FROM_HERE, base::Bind(&DesktopSessionProxy::CaptureFrame, this));
231 return; 294 return;
232 } 295 }
233 296
234 if (desktop_channel_) { 297 if (desktop_channel_) {
235 ++pending_capture_frame_requests_; 298 ++pending_capture_frame_requests_;
236 SendToDesktop(new ChromotingNetworkDesktopMsg_CaptureFrame()); 299 SendToDesktop(new ChromotingNetworkDesktopMsg_CaptureFrame());
237 } else { 300 } else {
238 PostCaptureCompleted(scoped_refptr<media::ScreenCaptureData>()); 301 PostCaptureCompleted(scoped_ptr<webrtc::DesktopFrame>());
239 } 302 }
240 } 303 }
241 304
242 void DesktopSessionProxy::SetVideoCapturer( 305 void DesktopSessionProxy::SetVideoCapturer(
243 const base::WeakPtr<IpcVideoFrameCapturer> video_capturer) { 306 const base::WeakPtr<IpcVideoFrameCapturer> video_capturer) {
244 DCHECK(video_capture_task_runner_->BelongsToCurrentThread()); 307 DCHECK(video_capture_task_runner_->BelongsToCurrentThread());
245 308
246 video_capturer_ = video_capturer; 309 video_capturer_ = video_capturer;
247 } 310 }
248 311
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 scoped_ptr<protocol::ClipboardStub> client_clipboard) { 361 scoped_ptr<protocol::ClipboardStub> client_clipboard) {
299 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 362 DCHECK(caller_task_runner_->BelongsToCurrentThread());
300 363
301 client_clipboard_ = client_clipboard.Pass(); 364 client_clipboard_ = client_clipboard.Pass();
302 } 365 }
303 366
304 void DesktopSessionProxy::SetScreenResolution( 367 void DesktopSessionProxy::SetScreenResolution(
305 const ScreenResolution& resolution) { 368 const ScreenResolution& resolution) {
306 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 369 DCHECK(caller_task_runner_->BelongsToCurrentThread());
307 370
308 if (!resolution.IsValid()) 371 if (!resolution.IsEmpty())
309 return; 372 return;
310 373
311 screen_resolution_ = resolution; 374 screen_resolution_ = resolution;
312 375
313 // Connect to the desktop session if it is not done yet. 376 // Connect to the desktop session if it is not done yet.
314 if (!is_desktop_session_connected_) { 377 if (!is_desktop_session_connected_) {
315 is_desktop_session_connected_ = true; 378 is_desktop_session_connected_ = true;
316 if (desktop_session_connector_) { 379 if (desktop_session_connector_) {
317 desktop_session_connector_->ConnectTerminal(this, screen_resolution_, 380 desktop_session_connector_->ConnectTerminal(this, screen_resolution_,
318 virtual_terminal_); 381 virtual_terminal_);
(...skipping 16 matching lines...) Expand all
335 398
336 if (desktop_session_connector_ && is_desktop_session_connected_) 399 if (desktop_session_connector_ && is_desktop_session_connected_)
337 desktop_session_connector_->DisconnectTerminal(this); 400 desktop_session_connector_->DisconnectTerminal(this);
338 401
339 if (desktop_process_ != base::kNullProcessHandle) { 402 if (desktop_process_ != base::kNullProcessHandle) {
340 base::CloseProcessHandle(desktop_process_); 403 base::CloseProcessHandle(desktop_process_);
341 desktop_process_ = base::kNullProcessHandle; 404 desktop_process_ = base::kNullProcessHandle;
342 } 405 }
343 } 406 }
344 407
345 scoped_refptr<media::SharedBuffer> DesktopSessionProxy::GetSharedBuffer( 408 scoped_refptr<DesktopSessionProxy::IpcSharedBufferCore>
346 int id) { 409 DesktopSessionProxy::GetSharedBufferCore(int id) {
347 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 410 DCHECK(caller_task_runner_->BelongsToCurrentThread());
348 411
349 SharedBuffers::const_iterator i = shared_buffers_.find(id); 412 SharedBuffers::const_iterator i = shared_buffers_.find(id);
350 if (i != shared_buffers_.end()) { 413 if (i != shared_buffers_.end()) {
351 return i->second; 414 return i->second;
352 } else { 415 } else {
353 LOG(ERROR) << "Failed to find the shared buffer " << id; 416 LOG(ERROR) << "Failed to find the shared buffer " << id;
354 return scoped_refptr<media::SharedBuffer>(); 417 return NULL;
355 } 418 }
356 } 419 }
357 420
358 void DesktopSessionProxy::OnAudioPacket(const std::string& serialized_packet) { 421 void DesktopSessionProxy::OnAudioPacket(const std::string& serialized_packet) {
359 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 422 DCHECK(caller_task_runner_->BelongsToCurrentThread());
360 423
361 // Parse a serialized audio packet. No further validation is done since 424 // Parse a serialized audio packet. No further validation is done since
362 // the message was sent by more privileged process. 425 // the message was sent by more privileged process.
363 scoped_ptr<AudioPacket> packet(new AudioPacket()); 426 scoped_ptr<AudioPacket> packet(new AudioPacket());
364 if (!packet->ParseFromString(serialized_packet)) { 427 if (!packet->ParseFromString(serialized_packet)) {
365 LOG(ERROR) << "Failed to parse AudioPacket."; 428 LOG(ERROR) << "Failed to parse AudioPacket.";
366 return; 429 return;
367 } 430 }
368 431
369 // Pass a captured audio packet to |audio_capturer_|. 432 // Pass a captured audio packet to |audio_capturer_|.
370 audio_capture_task_runner_->PostTask( 433 audio_capture_task_runner_->PostTask(
371 FROM_HERE, base::Bind(&IpcAudioCapturer::OnAudioPacket, audio_capturer_, 434 FROM_HERE, base::Bind(&IpcAudioCapturer::OnAudioPacket, audio_capturer_,
372 base::Passed(&packet))); 435 base::Passed(&packet)));
373 } 436 }
374 437
375 void DesktopSessionProxy::OnCreateSharedBuffer( 438 void DesktopSessionProxy::OnCreateSharedBuffer(
376 int id, 439 int id,
377 IPC::PlatformFileForTransit handle, 440 IPC::PlatformFileForTransit handle,
378 uint32 size) { 441 uint32 size) {
379 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 442 DCHECK(caller_task_runner_->BelongsToCurrentThread());
380 443
381 scoped_refptr<media::SharedBuffer> shared_buffer; 444 scoped_refptr<IpcSharedBufferCore> shared_buffer;
382 445
383 #if defined(OS_WIN) 446 #if defined(OS_WIN)
384 shared_buffer = new media::SharedBuffer(id, handle, desktop_process_, size); 447 shared_buffer = new IpcSharedBufferCore(id, handle, desktop_process_, size);
385 #elif defined(OS_POSIX) 448 #elif defined(OS_POSIX)
386 shared_buffer = new media::SharedBuffer(id, handle, size); 449 shared_buffer = new IpcSharedBufferCore(id, handle, size);
387 #else 450 #else
388 #error Unsupported platform. 451 #error Unsupported platform.
389 #endif 452 #endif
390 453
391 // Check if the buffer has been successfully mapped. 454 // Check if the buffer has been successfully mapped.
392 bool mapped = shared_buffer->ptr() != NULL; 455 bool mapped = shared_buffer->memory() != NULL;
393 if (!mapped) { 456 if (!mapped) {
394 #if defined(OS_WIN) 457 #if defined(OS_WIN)
395 LOG(ERROR) << "Failed to map a shared buffer: id=" << id 458 LOG(ERROR) << "Failed to map a shared buffer: id=" << id
396 << ", handle=" << handle 459 << ", handle=" << handle
397 << ", size=" << size; 460 << ", size=" << size;
398 #elif defined(OS_POSIX) 461 #elif defined(OS_POSIX)
399 LOG(ERROR) << "Failed to map a shared buffer: id=" << id 462 LOG(ERROR) << "Failed to map a shared buffer: id=" << id
400 << ", handle.fd=" << handle.fd 463 << ", handle.fd=" << handle.fd
401 << ", size=" << size; 464 << ", size=" << size;
402 #endif 465 #endif
403 } 466 }
404 467
405 if (mapped && 468 if (mapped &&
406 !shared_buffers_.insert(std::make_pair(id, shared_buffer)).second) { 469 !shared_buffers_.insert(std::make_pair(id, shared_buffer)).second) {
407 LOG(ERROR) << "Duplicate shared buffer id " << id << " encountered"; 470 LOG(ERROR) << "Duplicate shared buffer id " << id << " encountered";
408 } 471 }
409
410 // Notify the desktop process that the buffer has been seen and can now be
411 // safely deleted if needed.
412 SendToDesktop(new ChromotingNetworkDesktopMsg_SharedBufferCreated(id));
413 } 472 }
414 473
415 void DesktopSessionProxy::OnReleaseSharedBuffer(int id) { 474 void DesktopSessionProxy::OnReleaseSharedBuffer(int id) {
416 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 475 DCHECK(caller_task_runner_->BelongsToCurrentThread());
417 476
418 // Drop the cached reference to the buffer. 477 // Drop the cached reference to the buffer.
419 shared_buffers_.erase(id); 478 shared_buffers_.erase(id);
420 } 479 }
421 480
422 void DesktopSessionProxy::OnCaptureCompleted( 481 void DesktopSessionProxy::OnCaptureCompleted(
423 const SerializedCapturedData& serialized_data) { 482 const SerializedDesktopFrame& serialized_frame) {
424 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 483 DCHECK(caller_task_runner_->BelongsToCurrentThread());
425 484
426 // Assume that |serialized_data| is well formed because it was received from 485 // Assume that |serialized_frame| is well formed because it was received from
alexeypa (please no reviews) 2013/04/26 21:33:58 nit: well-formed
Sergey Ulanov 2013/05/07 22:25:50 Done.
427 // a more privileged process. 486 // a more privileged process.
428 scoped_refptr<media::ScreenCaptureData> capture_data; 487 scoped_refptr<IpcSharedBufferCore> shared_buffer_core =
429 scoped_refptr<media::SharedBuffer> shared_buffer = 488 GetSharedBufferCore(serialized_frame.shared_buffer_id);
430 GetSharedBuffer(serialized_data.shared_buffer_id); 489 CHECK(shared_buffer_core);
431 CHECK(shared_buffer);
432 490
433 capture_data = new media::ScreenCaptureData( 491 scoped_ptr<webrtc::DesktopFrame> frame(
434 reinterpret_cast<uint8*>(shared_buffer->ptr()), 492 new webrtc::SharedMemoryDesktopFrame(
435 serialized_data.bytes_per_row, 493 serialized_frame.dimensions, serialized_frame.bytes_per_row,
436 serialized_data.dimensions); 494 new IpcSharedBuffer(shared_buffer_core)));
437 capture_data->set_capture_time_ms(serialized_data.capture_time_ms); 495 frame->set_capture_time_ms(serialized_frame.capture_time_ms);
438 capture_data->set_client_sequence_number( 496 frame->set_dpi(serialized_frame.dpi);
439 serialized_data.client_sequence_number);
440 capture_data->set_dpi(serialized_data.dpi);
441 capture_data->set_shared_buffer(shared_buffer);
442 497
443 if (!serialized_data.dirty_region.empty()) { 498 for (size_t i = 0; i < serialized_frame.dirty_region.size(); ++i) {
444 capture_data->mutable_dirty_region().setRects( 499 frame->mutable_updated_region()->AddRect(serialized_frame.dirty_region[i]);
445 &serialized_data.dirty_region[0],
446 serialized_data.dirty_region.size());
447 } 500 }
448 501
449 --pending_capture_frame_requests_; 502 --pending_capture_frame_requests_;
450 PostCaptureCompleted(capture_data); 503 PostCaptureCompleted(frame.Pass());
451 } 504 }
452 505
453 void DesktopSessionProxy::OnCursorShapeChanged( 506 void DesktopSessionProxy::OnCursorShapeChanged(
454 const media::MouseCursorShape& cursor_shape) { 507 const media::MouseCursorShape& cursor_shape) {
455 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 508 DCHECK(caller_task_runner_->BelongsToCurrentThread());
456 PostCursorShape(scoped_ptr<media::MouseCursorShape>( 509 PostCursorShape(scoped_ptr<media::MouseCursorShape>(
457 new media::MouseCursorShape(cursor_shape))); 510 new media::MouseCursorShape(cursor_shape)));
458 } 511 }
459 512
460 void DesktopSessionProxy::OnInjectClipboardEvent( 513 void DesktopSessionProxy::OnInjectClipboardEvent(
461 const std::string& serialized_event) { 514 const std::string& serialized_event) {
462 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 515 DCHECK(caller_task_runner_->BelongsToCurrentThread());
463 516
464 if (client_clipboard_) { 517 if (client_clipboard_) {
465 protocol::ClipboardEvent event; 518 protocol::ClipboardEvent event;
466 if (!event.ParseFromString(serialized_event)) { 519 if (!event.ParseFromString(serialized_event)) {
467 LOG(ERROR) << "Failed to parse protocol::ClipboardEvent."; 520 LOG(ERROR) << "Failed to parse protocol::ClipboardEvent.";
468 return; 521 return;
469 } 522 }
470 523
471 client_clipboard_->InjectClipboardEvent(event); 524 client_clipboard_->InjectClipboardEvent(event);
472 } 525 }
473 } 526 }
474 527
475 void DesktopSessionProxy::PostCaptureCompleted( 528 void DesktopSessionProxy::PostCaptureCompleted(
476 scoped_refptr<media::ScreenCaptureData> capture_data) { 529 scoped_ptr<webrtc::DesktopFrame> frame) {
477 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 530 DCHECK(caller_task_runner_->BelongsToCurrentThread());
478 531
479 video_capture_task_runner_->PostTask( 532 video_capture_task_runner_->PostTask(
480 FROM_HERE, 533 FROM_HERE,
481 base::Bind(&IpcVideoFrameCapturer::OnCaptureCompleted, video_capturer_, 534 base::Bind(&IpcVideoFrameCapturer::OnCaptureCompleted, video_capturer_,
482 capture_data)); 535 base::Passed(&frame)));
483 } 536 }
484 537
485 void DesktopSessionProxy::PostCursorShape( 538 void DesktopSessionProxy::PostCursorShape(
486 scoped_ptr<media::MouseCursorShape> cursor_shape) { 539 scoped_ptr<media::MouseCursorShape> cursor_shape) {
487 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 540 DCHECK(caller_task_runner_->BelongsToCurrentThread());
488 541
489 video_capture_task_runner_->PostTask( 542 video_capture_task_runner_->PostTask(
490 FROM_HERE, 543 FROM_HERE,
491 base::Bind(&IpcVideoFrameCapturer::OnCursorShapeChanged, video_capturer_, 544 base::Bind(&IpcVideoFrameCapturer::OnCursorShapeChanged, video_capturer_,
492 base::Passed(&cursor_shape))); 545 base::Passed(&cursor_shape)));
(...skipping 10 matching lines...) Expand all
503 } 556 }
504 557
505 // static 558 // static
506 void DesktopSessionProxyTraits::Destruct( 559 void DesktopSessionProxyTraits::Destruct(
507 const DesktopSessionProxy* desktop_session_proxy) { 560 const DesktopSessionProxy* desktop_session_proxy) {
508 desktop_session_proxy->caller_task_runner_->DeleteSoon(FROM_HERE, 561 desktop_session_proxy->caller_task_runner_->DeleteSoon(FROM_HERE,
509 desktop_session_proxy); 562 desktop_session_proxy);
510 } 563 }
511 564
512 } // namespace remoting 565 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698