Chromium Code Reviews| 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 "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 Loading... | |
| 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 Loading... | |
| 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 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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. |
| 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 Loading... | |
| 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 Loading... | |
| 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 |requests_| here so that we can update the UI |
|
perkj_chrome
2012/08/09 07:31:14
? devices or requests? This previousely did device
no longer working on chromium
2012/08/09 15:54:54
Done.
| |
| 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 { |
|
mflodman_chromium_OOO
2012/08/09 09:57:05
A comment regarding the request is not done?
no longer working on chromium
2012/08/09 15:54:54
Done.
| |
| 548 // 3. Not opened but other devices exists for this request -> remove | 509 if (it->second.audio_devices.size() |
| 549 // device from list, but don't signal an error. | 510 + it->second.video_devices.size() <= 1) { |
| 550 devices->erase(device_it); | 511 // 2. Device not opened and no other devices for this request -> |
| 512 // signal stream error and remove the request. | |
| 513 it->second.requester->StreamGenerationFailed(it->first); | |
| 514 requests_.erase(it); | |
| 515 } else { | |
| 516 // 3. Not opened but other devices exists for this request -> remove | |
| 517 // device from list, but don't signal an error. | |
| 518 devices->erase(device_it); | |
| 519 } | |
| 551 } | 520 } |
| 552 return; | 521 return; |
| 553 } | 522 } |
| 554 } | 523 } |
| 555 } | 524 } |
| 556 } | 525 } |
| 557 | 526 |
| 558 void MediaStreamManager::DevicesAccepted(const std::string& label, | 527 void MediaStreamManager::DevicesAccepted(const std::string& label, |
| 559 const StreamDeviceInfoArray& devices) { | 528 const StreamDeviceInfoArray& devices) { |
| 560 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 529 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 679 content::MediaStreamDevice( | 648 content::MediaStreamDevice( |
| 680 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE, | 649 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE, |
| 681 it->device_id, | 650 it->device_id, |
| 682 it->name)); | 651 it->name)); |
| 683 } | 652 } |
| 684 } | 653 } |
| 685 | 654 |
| 686 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { | 655 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { |
| 687 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 656 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 688 // Check if all devices are opened. | 657 // Check if all devices are opened. |
| 689 if (Requested(request.options, | 658 MediaStreamType stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; |
| 690 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE)) { | 659 if (Requested(request.options, stream_type)) { |
| 660 if (request.state[stream_type] != DeviceRequest::kDone || | |
| 661 request.state[stream_type] != DeviceRequest::kError) | |
| 662 return false; | |
| 663 | |
| 691 for (StreamDeviceInfoArray::const_iterator it = | 664 for (StreamDeviceInfoArray::const_iterator it = |
|
perkj_chrome
2012/08/09 07:31:14
Why do you need to check both the state and each d
no longer working on chromium
2012/08/09 15:54:54
I honestly never understand why we have the state
mflodman_chromium_OOO
2012/08/10 07:15:44
Agree with Per. It should be enough to check the s
| |
| 692 request.audio_devices.begin(); it != request.audio_devices.end(); | 665 request.audio_devices.begin(); it != request.audio_devices.end(); |
| 693 ++it) { | 666 ++it) { |
| 694 if (it->in_use == false) { | 667 if (it->in_use == false) { |
| 695 return false; | 668 return false; |
| 696 } | 669 } |
| 697 } | 670 } |
| 698 } | 671 } |
| 699 if (Requested(request.options, | 672 |
| 700 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE)) { | 673 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; |
| 674 if (Requested(request.options, stream_type)) { | |
| 675 if (request.state[stream_type] == DeviceRequest::kDone || | |
| 676 request.state[stream_type] == DeviceRequest::kError) | |
| 677 return false; | |
| 678 | |
| 701 for (StreamDeviceInfoArray::const_iterator it = | 679 for (StreamDeviceInfoArray::const_iterator it = |
| 702 request.video_devices.begin(); it != request.video_devices.end(); | 680 request.video_devices.begin(); it != request.video_devices.end(); |
|
perkj_chrome
2012/08/09 07:31:14
dito?
no longer working on chromium
2012/08/09 15:54:54
Please see reply above.
| |
| 703 ++it) { | 681 ++it) { |
| 704 if (it->in_use == false) { | 682 if (it->in_use == false) { |
| 705 return false; | 683 return false; |
| 706 } | 684 } |
| 707 } | 685 } |
| 708 } | 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 |
| OLD | NEW |