Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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_devices_dispatcher_host.h" | 5 #include "content/browser/renderer_host/media/media_devices_dispatcher_host.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/bind_helpers.h" | 12 #include "base/bind_helpers.h" |
| 13 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" |
| 14 #include "content/browser/bad_message.h" | 14 #include "content/browser/bad_message.h" |
| 15 #include "content/browser/media/media_devices_util.h" | 15 #include "content/browser/media/media_devices_util.h" |
| 16 #include "content/browser/renderer_host/media/media_stream_manager.h" | 16 #include "content/browser/renderer_host/media/media_stream_manager.h" |
| 17 #include "content/browser/renderer_host/media/video_capture_manager.h" | 17 #include "content/browser/renderer_host/media/video_capture_manager.h" |
| 18 #include "content/common/media/media_devices.h" | 18 #include "content/common/media/media_devices.h" |
| 19 #include "content/public/browser/browser_context.h" | 19 #include "content/public/browser/browser_context.h" |
| 20 #include "content/public/browser/browser_thread.h" | 20 #include "content/public/browser/browser_thread.h" |
| 21 #include "content/public/browser/media_device_id.h" | 21 #include "content/public/browser/media_device_id.h" |
| 22 #include "content/public/browser/render_frame_host.h" | 22 #include "content/public/browser/render_frame_host.h" |
| 23 #include "content/public/common/media_stream_request.h" | 23 #include "content/public/common/media_stream_request.h" |
| 24 #include "media/audio/audio_system.h" | |
| 24 #include "media/base/video_facing.h" | 25 #include "media/base/video_facing.h" |
| 25 #include "mojo/public/cpp/bindings/strong_binding.h" | 26 #include "mojo/public/cpp/bindings/strong_binding.h" |
| 26 #include "services/service_manager/public/cpp/interface_provider.h" | 27 #include "services/service_manager/public/cpp/interface_provider.h" |
| 27 #include "url/origin.h" | 28 #include "url/origin.h" |
| 28 | 29 |
| 29 namespace content { | 30 namespace content { |
| 30 | 31 |
| 31 namespace { | 32 namespace { |
| 32 | 33 |
| 33 // Resolutions used if the source doesn't support capability enumeration. | 34 // Resolutions used if the source doesn't support capability enumeration. |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 78 case media::MEDIA_VIDEO_FACING_USER: | 79 case media::MEDIA_VIDEO_FACING_USER: |
| 79 return ::mojom::FacingMode::USER; | 80 return ::mojom::FacingMode::USER; |
| 80 case media::MEDIA_VIDEO_FACING_ENVIRONMENT: | 81 case media::MEDIA_VIDEO_FACING_ENVIRONMENT: |
| 81 return ::mojom::FacingMode::ENVIRONMENT; | 82 return ::mojom::FacingMode::ENVIRONMENT; |
| 82 default: | 83 default: |
| 83 NOTREACHED(); | 84 NOTREACHED(); |
| 84 return ::mojom::FacingMode::NONE; | 85 return ::mojom::FacingMode::NONE; |
| 85 } | 86 } |
| 86 } | 87 } |
| 87 | 88 |
| 89 std::vector<::mojom::AudioInputDeviceCapabilitiesPtr> | |
| 90 ToVectorAudioInputDeviceCapabilitiesPtr( | |
| 91 const std::vector<::mojom::AudioInputDeviceCapabilities>& | |
| 92 capabilities_vector) { | |
| 93 std::vector<::mojom::AudioInputDeviceCapabilitiesPtr> result; | |
| 94 result.reserve(capabilities_vector.size()); | |
| 95 for (auto& capabilities : capabilities_vector) { | |
| 96 ::mojom::AudioInputDeviceCapabilitiesPtr capabilities_ptr = | |
| 97 ::mojom::AudioInputDeviceCapabilities::New(); | |
| 98 *capabilities_ptr = capabilities; | |
| 99 result.push_back(std::move(capabilities_ptr)); | |
| 100 } | |
| 101 return result; | |
| 102 } | |
| 103 | |
| 88 } // namespace | 104 } // namespace |
| 89 | 105 |
| 90 struct MediaDevicesDispatcherHost::SubscriptionInfo { | 106 struct MediaDevicesDispatcherHost::SubscriptionInfo { |
| 91 uint32_t subscription_id; | 107 uint32_t subscription_id; |
| 92 url::Origin security_origin; | 108 url::Origin security_origin; |
| 93 }; | 109 }; |
| 94 | 110 |
| 95 // static | 111 // static |
| 96 void MediaDevicesDispatcherHost::Create( | 112 void MediaDevicesDispatcherHost::Create( |
| 97 int render_process_id, | 113 int render_process_id, |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 111 int render_process_id, | 127 int render_process_id, |
| 112 int render_frame_id, | 128 int render_frame_id, |
| 113 const std::string& device_id_salt, | 129 const std::string& device_id_salt, |
| 114 MediaStreamManager* media_stream_manager) | 130 MediaStreamManager* media_stream_manager) |
| 115 : render_process_id_(render_process_id), | 131 : render_process_id_(render_process_id), |
| 116 render_frame_id_(render_frame_id), | 132 render_frame_id_(render_frame_id), |
| 117 device_id_salt_(device_id_salt), | 133 device_id_salt_(device_id_salt), |
| 118 group_id_salt_(BrowserContext::CreateRandomMediaDeviceIDSalt()), | 134 group_id_salt_(BrowserContext::CreateRandomMediaDeviceIDSalt()), |
| 119 media_stream_manager_(media_stream_manager), | 135 media_stream_manager_(media_stream_manager), |
| 120 permission_checker_(base::MakeUnique<MediaDevicesPermissionChecker>()), | 136 permission_checker_(base::MakeUnique<MediaDevicesPermissionChecker>()), |
| 137 num_pending_audio_input_parameters_(0), | |
| 121 weak_factory_(this) { | 138 weak_factory_(this) { |
| 122 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 139 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 123 } | 140 } |
| 124 | 141 |
| 125 MediaDevicesDispatcherHost::~MediaDevicesDispatcherHost() { | 142 MediaDevicesDispatcherHost::~MediaDevicesDispatcherHost() { |
| 126 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 143 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 127 // It may happen that media_devices_manager() is destroyed before MDDH on some | 144 // It may happen that media_devices_manager() is destroyed before MDDH on some |
| 128 // shutdown scenarios. | 145 // shutdown scenarios. |
| 129 if (!media_stream_manager_->media_devices_manager()) | 146 if (!media_stream_manager_->media_devices_manager()) |
| 130 return; | 147 return; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 194 return; | 211 return; |
| 195 } | 212 } |
| 196 | 213 |
| 197 GetDefaultMediaDeviceID( | 214 GetDefaultMediaDeviceID( |
| 198 MEDIA_DEVICE_TYPE_VIDEO_INPUT, render_process_id_, render_frame_id_, | 215 MEDIA_DEVICE_TYPE_VIDEO_INPUT, render_process_id_, render_frame_id_, |
| 199 base::Bind(&MediaDevicesDispatcherHost::GotDefaultVideoInputDeviceID, | 216 base::Bind(&MediaDevicesDispatcherHost::GotDefaultVideoInputDeviceID, |
| 200 weak_factory_.GetWeakPtr(), security_origin, | 217 weak_factory_.GetWeakPtr(), security_origin, |
| 201 base::Passed(&client_callback))); | 218 base::Passed(&client_callback))); |
| 202 } | 219 } |
| 203 | 220 |
| 221 void MediaDevicesDispatcherHost::GetAudioInputCapabilities( | |
| 222 const url::Origin& security_origin, | |
| 223 GetAudioInputCapabilitiesCallback client_callback) { | |
| 224 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 225 if (!MediaStreamManager::IsOriginAllowed(render_process_id_, | |
| 226 security_origin)) { | |
| 227 bad_message::ReceivedBadMessage(render_process_id_, | |
| 228 bad_message::MDDH_UNAUTHORIZED_ORIGIN); | |
| 229 return; | |
| 230 } | |
| 231 | |
| 232 pending_audio_input_capabilities_callbacks_.push_back( | |
| 233 std::move(client_callback)); | |
| 234 if (pending_audio_input_capabilities_callbacks_.size() > 1U) | |
| 235 return; | |
| 236 | |
| 237 DCHECK(current_audio_input_capabilities_.empty()); | |
| 238 GetDefaultMediaDeviceID( | |
| 239 MEDIA_DEVICE_TYPE_AUDIO_INPUT, render_process_id_, render_frame_id_, | |
| 240 base::Bind(&MediaDevicesDispatcherHost::GotDefaultAudioInputDeviceID, | |
| 241 weak_factory_.GetWeakPtr(), security_origin)); | |
| 242 } | |
| 243 | |
| 204 void MediaDevicesDispatcherHost::SubscribeDeviceChangeNotifications( | 244 void MediaDevicesDispatcherHost::SubscribeDeviceChangeNotifications( |
| 205 MediaDeviceType type, | 245 MediaDeviceType type, |
| 206 uint32_t subscription_id, | 246 uint32_t subscription_id, |
| 207 const url::Origin& security_origin) { | 247 const url::Origin& security_origin) { |
| 208 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 248 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 209 DCHECK(IsValidMediaDeviceType(type)); | 249 DCHECK(IsValidMediaDeviceType(type)); |
| 210 // Ignore requests from unique origins, but do not crash the renderer. | 250 // Ignore requests from unique origins, but do not crash the renderer. |
| 211 if (security_origin.unique()) | 251 if (security_origin.unique()) |
| 212 return; | 252 return; |
| 213 | 253 |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 351 security_origin, device_info)); | 391 security_origin, device_info)); |
| 352 } | 392 } |
| 353 } | 393 } |
| 354 std::move(client_callback).Run(result); | 394 std::move(client_callback).Run(result); |
| 355 } | 395 } |
| 356 | 396 |
| 357 void MediaDevicesDispatcherHost::GotDefaultVideoInputDeviceID( | 397 void MediaDevicesDispatcherHost::GotDefaultVideoInputDeviceID( |
| 358 const url::Origin& security_origin, | 398 const url::Origin& security_origin, |
| 359 GetVideoInputCapabilitiesCallback client_callback, | 399 GetVideoInputCapabilitiesCallback client_callback, |
| 360 const std::string& default_device_id) { | 400 const std::string& default_device_id) { |
| 361 MediaDevicesManager::BoolDeviceTypes devices_to_enumerate; | |
| 362 devices_to_enumerate[MEDIA_DEVICE_TYPE_VIDEO_INPUT] = true; | |
| 363 media_stream_manager_->video_capture_manager()->EnumerateDevices( | 401 media_stream_manager_->video_capture_manager()->EnumerateDevices( |
| 364 base::Bind(&MediaDevicesDispatcherHost::FinalizeGetVideoInputCapabilities, | 402 base::Bind(&MediaDevicesDispatcherHost::FinalizeGetVideoInputCapabilities, |
| 365 weak_factory_.GetWeakPtr(), security_origin, | 403 weak_factory_.GetWeakPtr(), security_origin, |
| 366 base::Passed(&client_callback), default_device_id)); | 404 base::Passed(&client_callback), default_device_id)); |
| 367 } | 405 } |
| 368 | 406 |
| 369 void MediaDevicesDispatcherHost::FinalizeGetVideoInputCapabilities( | 407 void MediaDevicesDispatcherHost::FinalizeGetVideoInputCapabilities( |
| 370 const url::Origin& security_origin, | 408 const url::Origin& security_origin, |
| 371 GetVideoInputCapabilitiesCallback client_callback, | 409 GetVideoInputCapabilitiesCallback client_callback, |
| 372 const std::string& default_device_id, | 410 const std::string& default_device_id, |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 424 if (format.has_value()) { | 462 if (format.has_value()) { |
| 425 formats.push_back(format.value()); | 463 formats.push_back(format.value()); |
| 426 return formats; | 464 return formats; |
| 427 } | 465 } |
| 428 | 466 |
| 429 media_stream_manager_->video_capture_manager()->GetDeviceSupportedFormats( | 467 media_stream_manager_->video_capture_manager()->GetDeviceSupportedFormats( |
| 430 device_id, &formats); | 468 device_id, &formats); |
| 431 return formats; | 469 return formats; |
| 432 } | 470 } |
| 433 | 471 |
| 472 void MediaDevicesDispatcherHost::GotDefaultAudioInputDeviceID( | |
| 473 const url::Origin& security_origin, | |
| 474 const std::string& default_device_id) { | |
| 475 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 476 DCHECK_GT(pending_audio_input_capabilities_callbacks_.size(), 0U); | |
| 477 DCHECK(current_audio_input_capabilities_.empty()); | |
| 478 MediaDevicesManager::BoolDeviceTypes devices_to_enumerate; | |
| 479 devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_INPUT] = true; | |
| 480 media_stream_manager_->media_devices_manager()->EnumerateDevices( | |
| 481 devices_to_enumerate, | |
| 482 base::Bind(&MediaDevicesDispatcherHost::GotAudioInputEnumeration, | |
| 483 weak_factory_.GetWeakPtr(), security_origin, | |
| 484 default_device_id)); | |
| 485 } | |
| 486 | |
| 487 void MediaDevicesDispatcherHost::GotAudioInputEnumeration( | |
| 488 const url::Origin& security_origin, | |
| 489 const std::string& default_device_id, | |
| 490 const MediaDeviceEnumeration& enumeration) { | |
| 491 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 492 DCHECK_GT(pending_audio_input_capabilities_callbacks_.size(), 0U); | |
| 493 DCHECK(current_audio_input_capabilities_.empty()); | |
| 494 for (const auto& device_info : enumeration[MEDIA_DEVICE_TYPE_AUDIO_INPUT]) { | |
| 495 ::mojom::AudioInputDeviceCapabilities capabilities( | |
| 496 device_info.device_id, media::AudioParameters()); | |
| 497 if (device_info.device_id == default_device_id) | |
|
tommi (sloooow) - chröme
2017/05/08 17:52:54
nit: {}
| |
| 498 current_audio_input_capabilities_.insert( | |
| 499 current_audio_input_capabilities_.begin(), std::move(capabilities)); | |
| 500 else | |
| 501 current_audio_input_capabilities_.push_back(std::move(capabilities)); | |
| 502 } | |
| 503 if (current_audio_input_capabilities_.empty()) { | |
| 504 FinalizeGetAudioInputCapabilities(); | |
| 505 return; | |
| 506 } | |
| 507 | |
| 508 num_pending_audio_input_parameters_ = | |
| 509 current_audio_input_capabilities_.size(); | |
| 510 for (size_t i = 0; i < num_pending_audio_input_parameters_; ++i) { | |
| 511 std::string raw_device_id = | |
| 512 std::move(current_audio_input_capabilities_[i].device_id); | |
| 513 current_audio_input_capabilities_[i].device_id = GetHMACForMediaDeviceID( | |
| 514 device_id_salt_, security_origin, raw_device_id); | |
| 515 media_stream_manager_->audio_system()->GetInputStreamParameters( | |
| 516 raw_device_id, | |
| 517 base::Bind(&MediaDevicesDispatcherHost::GotAudioInputParameters, | |
| 518 weak_factory_.GetWeakPtr(), i)); | |
| 519 } | |
| 520 } | |
| 521 | |
| 522 void MediaDevicesDispatcherHost::GotAudioInputParameters( | |
| 523 size_t index, | |
| 524 const media::AudioParameters& parameters) { | |
| 525 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 526 DCHECK_GT(pending_audio_input_capabilities_callbacks_.size(), 0U); | |
| 527 DCHECK_GT(current_audio_input_capabilities_.size(), index); | |
| 528 DCHECK_GT(num_pending_audio_input_parameters_, 0U); | |
| 529 | |
| 530 current_audio_input_capabilities_[index].parameters = | |
| 531 parameters.IsValid() ? parameters | |
| 532 : media::AudioParameters::UnavailableDeviceParams(); | |
| 533 if (--num_pending_audio_input_parameters_ == 0U) | |
| 534 FinalizeGetAudioInputCapabilities(); | |
| 535 } | |
| 536 | |
| 537 void MediaDevicesDispatcherHost::FinalizeGetAudioInputCapabilities() { | |
| 538 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 539 DCHECK_GT(pending_audio_input_capabilities_callbacks_.size(), 0U); | |
| 540 DCHECK_EQ(0U, num_pending_audio_input_parameters_); | |
| 541 | |
| 542 for (auto& callback : pending_audio_input_capabilities_callbacks_) { | |
| 543 std::move(callback).Run(ToVectorAudioInputDeviceCapabilitiesPtr( | |
| 544 current_audio_input_capabilities_)); | |
| 545 } | |
| 546 | |
| 547 current_audio_input_capabilities_.clear(); | |
| 548 pending_audio_input_capabilities_callbacks_.clear(); | |
| 549 } | |
| 550 | |
| 434 } // namespace content | 551 } // namespace content |
| OLD | NEW |