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

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: added dispatcher_host_unittests and addressed Perk's and Magnus' comments. 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 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 321 // Need to make an asynchronous call to make sure the |requester| gets the
351 // |label| before it would receive any event. 322 // |label| before it would receive any event.
wjia(left Chromium) 2012/08/10 01:23:13 remove the comments about posting task.
no longer working on chromium 2012/08/10 11:50:56 Done.
352 if (new_request->type == DeviceRequest::kGenerateStream) { 323 if (new_request->type == DeviceRequest::kGenerateStream) {
353 BrowserThread::PostTask(BrowserThread::IO, 324 device_settings_->RequestCaptureDeviceUsage(request_label,
354 FROM_HERE, 325 new_request->render_process_id,
355 base::Bind(&MediaStreamDeviceSettings::RequestCaptureDeviceUsage, 326 new_request->render_view_id,
356 base::Unretained(device_settings_.get()), 327 new_request->options,
357 request_label, new_request->render_process_id, 328 new_request->security_origin);
358 new_request->render_view_id, new_request->options,
359 new_request->security_origin));
360 } 329 }
361 330
362 (*label) = request_label; 331 (*label) = request_label;
363 } 332 }
364 333
365 void MediaStreamManager::EnsureDeviceThreadAndListener() { 334 void MediaStreamManager::EnsureDeviceThreadAndListener() {
366 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 335 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
367 if (device_thread_.get()) 336 if (device_thread_.get())
368 return; 337 return;
369 338
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 request.state[device_it->stream_type] = DeviceRequest::kOpening; 456 request.state[device_it->stream_type] = DeviceRequest::kOpening;
488 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) 457 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE)
489 request.audio_devices.push_back(device); 458 request.audio_devices.push_back(device);
490 else 459 else
491 request.video_devices.push_back(device); 460 request.video_devices.push_back(device);
492 break; 461 break;
493 } 462 }
494 } 463 }
495 break; 464 break;
496 default: 465 default:
497 BrowserThread::PostTask(BrowserThread::IO, 466 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 } 467 }
503 } 468 }
504 label_list.clear(); 469 label_list.clear();
505 enumeration_in_progress_[stream_type] = false; 470 enumeration_in_progress_[stream_type] = false;
506 } 471 }
507 472
508 void MediaStreamManager::Error(MediaStreamType stream_type, 473 void MediaStreamManager::Error(MediaStreamType stream_type,
509 int capture_session_id, 474 int capture_session_id,
510 MediaStreamProviderError error) { 475 MediaStreamProviderError error) {
511 // Find the device for the error call. 476 // Find the device for the error call.
(...skipping 18 matching lines...) Expand all
530 // 1. Already opened -> signal device failure and close device. 495 // 1. Already opened -> signal device failure and close device.
531 // Use device_idx to signal which of the devices encountered an 496 // Use device_idx to signal which of the devices encountered an
532 // error. 497 // error.
533 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { 498 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) {
534 it->second.requester->AudioDeviceFailed(it->first, device_idx); 499 it->second.requester->AudioDeviceFailed(it->first, device_idx);
535 } else if (stream_type == 500 } else if (stream_type ==
536 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { 501 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) {
537 it->second.requester->VideoDeviceFailed(it->first, device_idx); 502 it->second.requester->VideoDeviceFailed(it->first, device_idx);
538 } 503 }
539 GetDeviceManager(stream_type)->Close(capture_session_id); 504 GetDeviceManager(stream_type)->Close(capture_session_id);
540 devices->erase(device_it); 505 // We don't erase the devices here so that we can update the UI
541 } else if (it->second.audio_devices.size() 506 // properly in StopGeneratedStream().
542 + it->second.video_devices.size() <= 1) { 507 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 { 508 } else {
548 // 3. Not opened but other devices exists for this request -> remove 509 // Request is not done, devices are not opened in this case.
549 // device from list, but don't signal an error. 510 if (it->second.audio_devices.size()
550 devices->erase(device_it); 511 + it->second.video_devices.size() <= 1) {
512 // 2. Device not opened and no other devices for this request ->
513 // signal stream error and remove the request.
514 it->second.requester->StreamGenerationFailed(it->first);
515 requests_.erase(it);
516 } else {
517 // 3. Not opened but other devices exists for this request -> remove
518 // device from list, but don't signal an error.
519 devices->erase(device_it);
520 }
wjia(left Chromium) 2012/08/10 01:23:13 why this "else if" format change?
no longer working on chromium 2012/08/10 11:50:56 It is more readable in this way, because: The firs
551 } 521 }
552 return; 522 return;
553 } 523 }
554 } 524 }
555 } 525 }
556 } 526 }
557 527
558 void MediaStreamManager::DevicesAccepted(const std::string& label, 528 void MediaStreamManager::DevicesAccepted(const std::string& label,
559 const StreamDeviceInfoArray& devices) { 529 const StreamDeviceInfoArray& devices) {
560 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 530 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 content::MediaStreamDevice( 649 content::MediaStreamDevice(
680 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE, 650 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE,
681 it->device_id, 651 it->device_id,
682 it->name)); 652 it->name));
683 } 653 }
684 } 654 }
685 655
686 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { 656 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const {
687 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 657 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
688 // Check if all devices are opened. 658 // Check if all devices are opened.
689 if (Requested(request.options, 659 MediaStreamType stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE;
690 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE)) { 660 if (Requested(request.options, stream_type)) {
661 if (request.state[stream_type] != DeviceRequest::kDone &&
662 request.state[stream_type] != DeviceRequest::kError)
663 return false;
664
691 for (StreamDeviceInfoArray::const_iterator it = 665 for (StreamDeviceInfoArray::const_iterator it =
mflodman_chromium_OOO 2012/08/10 07:15:44 See comment in patch set #2.
no longer working on chromium 2012/08/10 11:50:56 After discussing offline, we decided to leave it a
692 request.audio_devices.begin(); it != request.audio_devices.end(); 666 request.audio_devices.begin(); it != request.audio_devices.end();
693 ++it) { 667 ++it) {
694 if (it->in_use == false) { 668 if (it->in_use == false) {
695 return false; 669 return false;
696 } 670 }
697 } 671 }
698 } 672 }
699 if (Requested(request.options, 673
700 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE)) { 674 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE;
675 if (Requested(request.options, stream_type)) {
676 if (request.state[stream_type] != DeviceRequest::kDone &&
677 request.state[stream_type] != DeviceRequest::kError)
678 return false;
679
701 for (StreamDeviceInfoArray::const_iterator it = 680 for (StreamDeviceInfoArray::const_iterator it =
702 request.video_devices.begin(); it != request.video_devices.end(); 681 request.video_devices.begin(); it != request.video_devices.end();
703 ++it) { 682 ++it) {
704 if (it->in_use == false) { 683 if (it->in_use == false) {
705 return false; 684 return false;
706 } 685 }
707 } 686 }
708 } 687 }
688
709 return true; 689 return true;
710 } 690 }
711 691
712 // Called to get media capture device manager of specified type. 692 // Called to get media capture device manager of specified type.
713 MediaStreamProvider* MediaStreamManager::GetDeviceManager( 693 MediaStreamProvider* MediaStreamManager::GetDeviceManager(
714 MediaStreamType stream_type) { 694 MediaStreamType stream_type) {
715 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { 695 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) {
716 return video_capture_manager(); 696 return video_capture_manager();
717 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { 697 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) {
718 return audio_input_device_manager(); 698 return audio_input_device_manager();
719 } 699 }
720 NOTREACHED(); 700 NOTREACHED();
721 return NULL; 701 return NULL;
722 } 702 }
723 703
724 } // namespace media_stream 704 } // namespace media_stream
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698