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

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

Issue 10829190: Resolve the problems where we can leak the system tray UI (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: addressed the comments and added unit tests to media_stream_device_settings_unittest Created 8 years, 4 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 "content/browser/renderer_host/media/media_stream_manager.h" 5 #include "content/browser/renderer_host/media/media_stream_manager.h"
6 6
7 #include <list> 7 #include <list>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
172 172
173 // Create a new request based on options. 173 // Create a new request based on options.
174 DeviceRequest new_request(requester, options, 174 DeviceRequest new_request(requester, options,
175 render_process_id, 175 render_process_id,
176 render_view_id, 176 render_view_id,
177 security_origin); 177 security_origin);
178 StartEnumeration(&new_request, label); 178 StartEnumeration(&new_request, label);
179 } 179 }
180 180
181 void MediaStreamManager::CancelRequests(MediaStreamRequester* requester) {
182 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
183 DeviceRequests::iterator it = requests_.begin();
184 while (it != requests_.end()) {
185 if (it->second.requester == requester && !RequestDone(it->second)) {
186 // The request isn't complete, but there might be some devices already
187 // opened -> close them.
188 DeviceRequest* request = &(it->second);
189 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE] ==
190 DeviceRequest::kOpening) {
191 for (StreamDeviceInfoArray::iterator it =
192 request->audio_devices.begin(); it != request->audio_devices.end();
193 ++it) {
194 audio_input_device_manager()->Close(it->session_id);
195 }
196 }
197 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE] ==
198 DeviceRequest::kOpening) {
199 for (StreamDeviceInfoArray::iterator it =
200 request->video_devices.begin(); it != request->video_devices.end();
201 ++it) {
202 video_capture_manager()->Close(it->session_id);
203 }
204 }
205 requests_.erase(it++);
206 } else {
207 ++it;
208 }
209 }
210 }
211
212 void MediaStreamManager::CancelGenerateStream(const std::string& label) { 181 void MediaStreamManager::CancelGenerateStream(const std::string& label) {
213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 182 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
214 183
215 DeviceRequests::iterator it = requests_.find(label); 184 DeviceRequests::iterator it = requests_.find(label);
216 if (it != requests_.end()) { 185 if (it != requests_.end()) {
217 // The request isn't complete. 186 // The request isn't complete.
218 if (!RequestDone(it->second)) { 187 if (!RequestDone(it->second)) {
219 DeviceRequest* request = &(it->second); 188 DeviceRequest* request = &(it->second);
220 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE] == 189 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE] ==
221 DeviceRequest::kOpening) { 190 DeviceRequest::kOpening) {
(...skipping 27 matching lines...) Expand all
249 for (StreamDeviceInfoArray::iterator audio_it = 218 for (StreamDeviceInfoArray::iterator audio_it =
250 it->second.audio_devices.begin(); 219 it->second.audio_devices.begin();
251 audio_it != it->second.audio_devices.end(); ++audio_it) { 220 audio_it != it->second.audio_devices.end(); ++audio_it) {
252 audio_input_device_manager()->Close(audio_it->session_id); 221 audio_input_device_manager()->Close(audio_it->session_id);
253 } 222 }
254 for (StreamDeviceInfoArray::iterator video_it = 223 for (StreamDeviceInfoArray::iterator video_it =
255 it->second.video_devices.begin(); 224 it->second.video_devices.begin();
256 video_it != it->second.video_devices.end(); ++video_it) { 225 video_it != it->second.video_devices.end(); ++video_it) {
257 video_capture_manager()->Close(video_it->session_id); 226 video_capture_manager()->Close(video_it->session_id);
258 } 227 }
259 if (it->second.type == DeviceRequest::kGenerateStream) { 228
229 if (it->second.type == DeviceRequest::kGenerateStream &&
230 RequestDone(it->second)) {
260 NotifyObserverDevicesClosed(&(it->second)); 231 NotifyObserverDevicesClosed(&(it->second));
261 } 232 }
262 requests_.erase(it); 233 requests_.erase(it);
263 return; 234 return;
264 } 235 }
265 } 236 }
266 237
267 void MediaStreamManager::EnumerateDevices( 238 void MediaStreamManager::EnumerateDevices(
268 MediaStreamRequester* requester, 239 MediaStreamRequester* requester,
269 int render_process_id, 240 int render_process_id,
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 311
341 // Create a label for this request and verify it is unique. 312 // Create a label for this request and verify it is unique.
342 std::string request_label; 313 std::string request_label;
343 do { 314 do {
344 request_label = RandomLabel(); 315 request_label = RandomLabel();
345 } while (requests_.find(request_label) != requests_.end()); 316 } while (requests_.find(request_label) != requests_.end());
346 317
347 requests_.insert(std::make_pair(request_label, *new_request)); 318 requests_.insert(std::make_pair(request_label, *new_request));
348 319
349 // Get user confirmation to use capture devices. 320 // Get user confirmation to use capture devices.
350 // Need to make an asynchronous call to make sure the |requester| gets the
351 // |label| before it would receive any event.
352 if (new_request->type == DeviceRequest::kGenerateStream) { 321 if (new_request->type == DeviceRequest::kGenerateStream) {
353 BrowserThread::PostTask(BrowserThread::IO, 322 device_settings_->RequestCaptureDeviceUsage(request_label,
354 FROM_HERE, 323 new_request->render_process_id,
355 base::Bind(&MediaStreamDeviceSettings::RequestCaptureDeviceUsage, 324 new_request->render_view_id,
356 base::Unretained(device_settings_.get()), 325 new_request->options,
357 request_label, new_request->render_process_id, 326 new_request->security_origin);
358 new_request->render_view_id, new_request->options,
359 new_request->security_origin));
360 } 327 }
361 328
362 (*label) = request_label; 329 (*label) = request_label;
363 } 330 }
364 331
365 void MediaStreamManager::EnsureDeviceThreadAndListener() { 332 void MediaStreamManager::EnsureDeviceThreadAndListener() {
366 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 333 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
367 if (device_thread_.get()) 334 if (device_thread_.get())
368 return; 335 return;
369 336
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 request.state[device_it->stream_type] = DeviceRequest::kOpening; 454 request.state[device_it->stream_type] = DeviceRequest::kOpening;
488 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) 455 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE)
489 request.audio_devices.push_back(device); 456 request.audio_devices.push_back(device);
490 else 457 else
491 request.video_devices.push_back(device); 458 request.video_devices.push_back(device);
492 break; 459 break;
493 } 460 }
494 } 461 }
495 break; 462 break;
496 default: 463 default:
497 BrowserThread::PostTask(BrowserThread::IO, 464 device_settings_->AvailableDevices(*it, stream_type, devices);
498 FROM_HERE,
499 base::Bind(&MediaStreamDeviceSettings::AvailableDevices,
500 base::Unretained(device_settings_.get()),
501 *it, stream_type, devices));
502 } 465 }
503 } 466 }
504 label_list.clear(); 467 label_list.clear();
505 enumeration_in_progress_[stream_type] = false; 468 enumeration_in_progress_[stream_type] = false;
506 } 469 }
507 470
508 void MediaStreamManager::Error(MediaStreamType stream_type, 471 void MediaStreamManager::Error(MediaStreamType stream_type,
509 int capture_session_id, 472 int capture_session_id,
510 MediaStreamProviderError error) { 473 MediaStreamProviderError error) {
511 // Find the device for the error call. 474 // Find the device for the error call.
(...skipping 18 matching lines...) Expand all
530 // 1. Already opened -> signal device failure and close device. 493 // 1. Already opened -> signal device failure and close device.
531 // Use device_idx to signal which of the devices encountered an 494 // Use device_idx to signal which of the devices encountered an
532 // error. 495 // error.
533 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { 496 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) {
534 it->second.requester->AudioDeviceFailed(it->first, device_idx); 497 it->second.requester->AudioDeviceFailed(it->first, device_idx);
535 } else if (stream_type == 498 } else if (stream_type ==
536 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { 499 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) {
537 it->second.requester->VideoDeviceFailed(it->first, device_idx); 500 it->second.requester->VideoDeviceFailed(it->first, device_idx);
538 } 501 }
539 GetDeviceManager(stream_type)->Close(capture_session_id); 502 GetDeviceManager(stream_type)->Close(capture_session_id);
540 devices->erase(device_it); 503 // We don't erase the devices here so that we can update the UI
541 } else if (it->second.audio_devices.size() 504 // properly in StopGeneratedStream().
542 + it->second.video_devices.size() <= 1) { 505 it->second.state[stream_type] = DeviceRequest::kError;
543 // 2. Device not opened and no other devices for this request ->
544 // signal stream error and remove the request.
545 it->second.requester->StreamGenerationFailed(it->first);
546 requests_.erase(it);
547 } else { 506 } else {
548 // 3. Not opened but other devices exists for this request -> remove 507 // Request is not done, devices are not opened in this case.
549 // device from list, but don't signal an error. 508 if (it->second.audio_devices.size()
550 devices->erase(device_it); 509 + it->second.video_devices.size() <= 1) {
510 // 2. Device not opened and no other devices for this request ->
511 // signal stream error and remove the request.
512 it->second.requester->StreamGenerationFailed(it->first);
513 requests_.erase(it);
514 } else {
515 // 3. Not opened but other devices exists for this request -> remove
516 // device from list, but don't signal an error.
517 devices->erase(device_it);
518 }
551 } 519 }
552 return; 520 return;
553 } 521 }
554 } 522 }
555 } 523 }
556 } 524 }
557 525
558 void MediaStreamManager::DevicesAccepted(const std::string& label, 526 void MediaStreamManager::DevicesAccepted(const std::string& label,
559 const StreamDeviceInfoArray& devices) { 527 const StreamDeviceInfoArray& devices) {
560 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 528 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 content::MediaStreamDevice( 647 content::MediaStreamDevice(
680 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE, 648 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE,
681 it->device_id, 649 it->device_id,
682 it->name)); 650 it->name));
683 } 651 }
684 } 652 }
685 653
686 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { 654 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const {
687 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 655 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
688 // Check if all devices are opened. 656 // Check if all devices are opened.
689 if (Requested(request.options, 657 MediaStreamType stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE;
690 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE)) { 658 if (Requested(request.options, stream_type)) {
659 if (request.state[stream_type] != DeviceRequest::kDone &&
660 request.state[stream_type] != DeviceRequest::kError)
661 return false;
662
691 for (StreamDeviceInfoArray::const_iterator it = 663 for (StreamDeviceInfoArray::const_iterator it =
692 request.audio_devices.begin(); it != request.audio_devices.end(); 664 request.audio_devices.begin(); it != request.audio_devices.end();
693 ++it) { 665 ++it) {
694 if (it->in_use == false) { 666 if (it->in_use == false) {
695 return false; 667 return false;
696 } 668 }
697 } 669 }
698 } 670 }
699 if (Requested(request.options, 671
700 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE)) { 672 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE;
673 if (Requested(request.options, stream_type)) {
674 if (request.state[stream_type] != DeviceRequest::kDone &&
675 request.state[stream_type] != DeviceRequest::kError)
676 return false;
677
701 for (StreamDeviceInfoArray::const_iterator it = 678 for (StreamDeviceInfoArray::const_iterator it =
702 request.video_devices.begin(); it != request.video_devices.end(); 679 request.video_devices.begin(); it != request.video_devices.end();
703 ++it) { 680 ++it) {
704 if (it->in_use == false) { 681 if (it->in_use == false) {
705 return false; 682 return false;
706 } 683 }
707 } 684 }
708 } 685 }
686
709 return true; 687 return true;
710 } 688 }
711 689
712 // Called to get media capture device manager of specified type. 690 // Called to get media capture device manager of specified type.
713 MediaStreamProvider* MediaStreamManager::GetDeviceManager( 691 MediaStreamProvider* MediaStreamManager::GetDeviceManager(
714 MediaStreamType stream_type) { 692 MediaStreamType stream_type) {
715 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { 693 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) {
716 return video_capture_manager(); 694 return video_capture_manager();
717 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { 695 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) {
718 return audio_input_device_manager(); 696 return audio_input_device_manager();
719 } 697 }
720 NOTREACHED(); 698 NOTREACHED();
721 return NULL; 699 return NULL;
722 } 700 }
723 701
724 } // namespace media_stream 702 } // namespace media_stream
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698