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

Side by Side Diff: content/browser/renderer_host/media/video_capture_manager.cc

Issue 899943004: Fix race when setting Desktop window id. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed comments. Created 5 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
« no previous file with comments | « content/browser/renderer_host/media/video_capture_manager.h ('k') | no next file » | 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 "content/browser/renderer_host/media/video_capture_manager.h" 5 #include "content/browser/renderer_host/media/video_capture_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 MediaStreamType stream_type, 106 MediaStreamType stream_type,
107 const std::string& id, 107 const std::string& id,
108 scoped_ptr<VideoCaptureController> controller) 108 scoped_ptr<VideoCaptureController> controller)
109 : serial_id(g_device_start_id++), 109 : serial_id(g_device_start_id++),
110 stream_type(stream_type), 110 stream_type(stream_type),
111 id(id), 111 id(id),
112 video_capture_controller_(controller.Pass()) {} 112 video_capture_controller_(controller.Pass()) {}
113 113
114 VideoCaptureManager::DeviceEntry::~DeviceEntry() { 114 VideoCaptureManager::DeviceEntry::~DeviceEntry() {
115 DCHECK(thread_checker_.CalledOnValidThread()); 115 DCHECK(thread_checker_.CalledOnValidThread());
116 // DCHECK that this DeviceEntry does not still own a
117 // media::VideoCaptureDevice. media::VideoCaptureDevice must be deleted on
118 // the device thread.
119 DCHECK(video_capture_device_ == nullptr);
116 } 120 }
117 121
118 void VideoCaptureManager::DeviceEntry::SetVideoCaptureDevice( 122 void VideoCaptureManager::DeviceEntry::SetVideoCaptureDevice(
119 scoped_ptr<media::VideoCaptureDevice> device) { 123 scoped_ptr<media::VideoCaptureDevice> device) {
120 DCHECK(thread_checker_.CalledOnValidThread()); 124 DCHECK(thread_checker_.CalledOnValidThread());
121 video_capture_device_.swap(device); 125 video_capture_device_.swap(device);
122 } 126 }
123 127
124 scoped_ptr<media::VideoCaptureDevice> 128 scoped_ptr<media::VideoCaptureDevice>
125 VideoCaptureManager::DeviceEntry::ReleaseVideoCaptureDevice() { 129 VideoCaptureManager::DeviceEntry::ReleaseVideoCaptureDevice() {
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 // PostTask failed. The device must be stopped anyway. 356 // PostTask failed. The device must be stopped anyway.
353 device_ptr->StopAndDeAllocate(); 357 device_ptr->StopAndDeAllocate();
354 } 358 }
355 } else { 359 } else {
356 DeviceEntries::iterator entry_it = std::find_if( 360 DeviceEntries::iterator entry_it = std::find_if(
357 devices_.begin(), devices_.end(), 361 devices_.begin(), devices_.end(),
358 [serial_id] (const DeviceEntry* e) { 362 [serial_id] (const DeviceEntry* e) {
359 return e->serial_id == serial_id; 363 return e->serial_id == serial_id;
360 }); 364 });
361 DCHECK(entry_it != devices_.end()); 365 DCHECK(entry_it != devices_.end());
362 DCHECK(!(*entry_it)->video_capture_device()); 366 DeviceEntry* entry = *entry_it;
363 (*entry_it)->SetVideoCaptureDevice(device.Pass()); 367 DCHECK(!entry->video_capture_device());
368 entry->SetVideoCaptureDevice(device.Pass());
369
370 if (entry->stream_type == MEDIA_DESKTOP_VIDEO_CAPTURE) {
371 const media::VideoCaptureSessionId session_id =
372 device_start_queue_.front().session_id();
373 MaybePostDesktopCaptureWindowId(session_id);
374 }
364 } 375 }
365 376
366 device_start_queue_.pop_front(); 377 device_start_queue_.pop_front();
367 HandleQueuedStartRequest(); 378 HandleQueuedStartRequest();
368 } 379 }
369 380
370 scoped_ptr<media::VideoCaptureDevice> 381 scoped_ptr<media::VideoCaptureDevice>
371 VideoCaptureManager::DoStartDeviceOnDeviceThread( 382 VideoCaptureManager::DoStartDeviceOnDeviceThread(
372 media::VideoCaptureSessionId session_id, 383 media::VideoCaptureSessionId session_id,
373 const std::string& id, 384 const std::string& id,
(...skipping 27 matching lines...) Expand all
401 DesktopMediaID desktop_id = DesktopMediaID::Parse(id); 412 DesktopMediaID desktop_id = DesktopMediaID::Parse(id);
402 #if defined(USE_AURA) 413 #if defined(USE_AURA)
403 if (desktop_id.type == DesktopMediaID::TYPE_AURA_WINDOW) { 414 if (desktop_id.type == DesktopMediaID::TYPE_AURA_WINDOW) {
404 video_capture_device.reset( 415 video_capture_device.reset(
405 DesktopCaptureDeviceAura::Create(desktop_id)); 416 DesktopCaptureDeviceAura::Create(desktop_id));
406 } else 417 } else
407 #endif 418 #endif
408 if (desktop_id.type != DesktopMediaID::TYPE_NONE && 419 if (desktop_id.type != DesktopMediaID::TYPE_NONE &&
409 desktop_id.type != DesktopMediaID::TYPE_AURA_WINDOW) { 420 desktop_id.type != DesktopMediaID::TYPE_AURA_WINDOW) {
410 video_capture_device = DesktopCaptureDevice::Create(desktop_id); 421 video_capture_device = DesktopCaptureDevice::Create(desktop_id);
411 if (notification_window_ids_.find(session_id) !=
412 notification_window_ids_.end()) {
413 static_cast<DesktopCaptureDevice*>(video_capture_device.get())
414 ->SetNotificationWindowId(notification_window_ids_[session_id]);
415 VLOG(2) << "Screen capture notification window passed for session "
416 << session_id;
417 }
418 } 422 }
419 #endif // defined(ENABLE_SCREEN_CAPTURE) 423 #endif // defined(ENABLE_SCREEN_CAPTURE)
420 break; 424 break;
421 } 425 }
422 default: { 426 default: {
423 NOTIMPLEMENTED(); 427 NOTIMPLEMENTED();
424 break; 428 break;
425 } 429 }
426 } 430 }
427 431
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 } 612 }
609 return true; 613 return true;
610 } 614 }
611 615
612 void VideoCaptureManager::SetDesktopCaptureWindowId( 616 void VideoCaptureManager::SetDesktopCaptureWindowId(
613 media::VideoCaptureSessionId session_id, 617 media::VideoCaptureSessionId session_id,
614 gfx::NativeViewId window_id) { 618 gfx::NativeViewId window_id) {
615 DCHECK_CURRENTLY_ON(BrowserThread::IO); 619 DCHECK_CURRENTLY_ON(BrowserThread::IO);
616 VLOG(2) << "SetDesktopCaptureWindowId called for session " << session_id; 620 VLOG(2) << "SetDesktopCaptureWindowId called for session " << session_id;
617 621
622 notification_window_ids_[session_id] = window_id;
623 MaybePostDesktopCaptureWindowId(session_id);
624 }
625
626 void VideoCaptureManager::MaybePostDesktopCaptureWindowId(
627 media::VideoCaptureSessionId session_id) {
618 SessionMap::iterator session_it = sessions_.find(session_id); 628 SessionMap::iterator session_it = sessions_.find(session_id);
619 if (session_it == sessions_.end()) { 629 if (session_it == sessions_.end()) {
620 VLOG(2) << "Session not found, will save the notification window.";
621 device_task_runner_->PostTask(
622 FROM_HERE,
623 base::Bind(
624 &VideoCaptureManager::SaveDesktopCaptureWindowIdOnDeviceThread,
625 this,
626 session_id,
627 window_id));
628 return; 630 return;
629 } 631 }
630 632
631 DeviceEntry* const existing_device = 633 DeviceEntry* const existing_device =
632 GetDeviceEntryForMediaStreamDevice(session_it->second); 634 GetDeviceEntryForMediaStreamDevice(session_it->second);
633 if (!existing_device) { 635 if (!existing_device) {
634 VLOG(2) << "Failed to find an existing device."; 636 DVLOG(2) << "Failed to find an existing screen capture device.";
635 return; 637 return;
636 } 638 }
637 639
640 if (!existing_device->video_capture_device()) {
641 DVLOG(2) << "Screen capture device not yet started.";
642 return;
643 }
644
638 DCHECK_EQ(MEDIA_DESKTOP_VIDEO_CAPTURE, existing_device->stream_type); 645 DCHECK_EQ(MEDIA_DESKTOP_VIDEO_CAPTURE, existing_device->stream_type);
639 DesktopMediaID id = DesktopMediaID::Parse(existing_device->id); 646 DesktopMediaID id = DesktopMediaID::Parse(existing_device->id);
640 if (id.type == DesktopMediaID::TYPE_NONE || 647 if (id.type == DesktopMediaID::TYPE_NONE ||
641 id.type == DesktopMediaID::TYPE_AURA_WINDOW) { 648 id.type == DesktopMediaID::TYPE_AURA_WINDOW) {
642 VLOG(2) << "Video capture device type mismatch."; 649 VLOG(2) << "Video capture device type mismatch.";
643 return; 650 return;
644 } 651 }
645 652
653 auto window_id_it = notification_window_ids_.find(session_id);
654 if (window_id_it == notification_window_ids_.end()) {
655 DVLOG(2) << "Notification window id not set for screen capture.";
656 return;
657 }
658
646 // Post |existing_device->video_capture_device| to the VideoCaptureDevice to 659 // Post |existing_device->video_capture_device| to the VideoCaptureDevice to
647 // the device_task_runner_. This is safe since the device is destroyed on the 660 // the device_task_runner_. This is safe since the device is destroyed on the
648 // device_task_runner_. 661 // device_task_runner_.
649 device_task_runner_->PostTask( 662 device_task_runner_->PostTask(
650 FROM_HERE, 663 FROM_HERE,
651 base::Bind(&VideoCaptureManager::SetDesktopCaptureWindowIdOnDeviceThread, 664 base::Bind(&VideoCaptureManager::SetDesktopCaptureWindowIdOnDeviceThread,
652 this, 665 this,
653 existing_device->video_capture_device(), 666 existing_device->video_capture_device(),
654 window_id)); 667 window_id_it->second));
668
669 notification_window_ids_.erase(window_id_it);
655 } 670 }
656 671
657 void VideoCaptureManager::DoStopDeviceOnDeviceThread( 672 void VideoCaptureManager::DoStopDeviceOnDeviceThread(
658 scoped_ptr<media::VideoCaptureDevice> device) { 673 scoped_ptr<media::VideoCaptureDevice> device) {
659 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime"); 674 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime");
660 DCHECK(IsOnDeviceThread()); 675 DCHECK(IsOnDeviceThread());
661 device->StopAndDeAllocate(); 676 device->StopAndDeAllocate();
662 DVLOG(3) << "DoStopDeviceOnDeviceThread"; 677 DVLOG(3) << "DoStopDeviceOnDeviceThread";
663 } 678 }
664 679
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
842 gfx::NativeViewId window_id) { 857 gfx::NativeViewId window_id) {
843 DCHECK(IsOnDeviceThread()); 858 DCHECK(IsOnDeviceThread());
844 #if defined(ENABLE_SCREEN_CAPTURE) 859 #if defined(ENABLE_SCREEN_CAPTURE)
845 DesktopCaptureDevice* desktop_device = 860 DesktopCaptureDevice* desktop_device =
846 static_cast<DesktopCaptureDevice*>(device); 861 static_cast<DesktopCaptureDevice*>(device);
847 desktop_device->SetNotificationWindowId(window_id); 862 desktop_device->SetNotificationWindowId(window_id);
848 VLOG(2) << "Screen capture notification window passed on device thread."; 863 VLOG(2) << "Screen capture notification window passed on device thread.";
849 #endif 864 #endif
850 } 865 }
851 866
852 void VideoCaptureManager::SaveDesktopCaptureWindowIdOnDeviceThread(
853 media::VideoCaptureSessionId session_id,
854 gfx::NativeViewId window_id) {
855 DCHECK(IsOnDeviceThread());
856 DCHECK(notification_window_ids_.find(session_id) ==
857 notification_window_ids_.end());
858 notification_window_ids_[session_id] = window_id;
859 VLOG(2) << "Screen capture notification window saved for session "
860 << session_id << " on device thread.";
861 }
862
863 } // namespace content 867 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/media/video_capture_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698