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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 case media::MEDIA_VIDEO_FACING_USER: | 90 case media::MEDIA_VIDEO_FACING_USER: |
90 return ::mojom::FacingMode::USER; | 91 return ::mojom::FacingMode::USER; |
91 case media::MEDIA_VIDEO_FACING_ENVIRONMENT: | 92 case media::MEDIA_VIDEO_FACING_ENVIRONMENT: |
92 return ::mojom::FacingMode::ENVIRONMENT; | 93 return ::mojom::FacingMode::ENVIRONMENT; |
93 default: | 94 default: |
94 NOTREACHED(); | 95 NOTREACHED(); |
95 return ::mojom::FacingMode::NONE; | 96 return ::mojom::FacingMode::NONE; |
96 } | 97 } |
97 } | 98 } |
98 | 99 |
| 100 std::vector<::mojom::AudioInputDeviceCapabilitiesPtr> |
| 101 ToVectorAudioInputDeviceCapabilitiesPtr( |
| 102 const std::vector<::mojom::AudioInputDeviceCapabilities>& |
| 103 capabilities_vector, |
| 104 const url::Origin& security_origin, |
| 105 const std::string& salt) { |
| 106 std::vector<::mojom::AudioInputDeviceCapabilitiesPtr> result; |
| 107 result.reserve(capabilities_vector.size()); |
| 108 for (auto& capabilities : capabilities_vector) { |
| 109 ::mojom::AudioInputDeviceCapabilitiesPtr capabilities_ptr = |
| 110 ::mojom::AudioInputDeviceCapabilities::New(); |
| 111 capabilities_ptr->device_id = |
| 112 GetHMACForMediaDeviceID(salt, security_origin, capabilities.device_id); |
| 113 capabilities_ptr->parameters = capabilities.parameters; |
| 114 result.push_back(std::move(capabilities_ptr)); |
| 115 } |
| 116 return result; |
| 117 } |
| 118 |
99 } // namespace | 119 } // namespace |
100 | 120 |
101 // static | 121 // static |
102 void MediaDevicesDispatcherHost::Create( | 122 void MediaDevicesDispatcherHost::Create( |
103 int render_process_id, | 123 int render_process_id, |
104 int render_frame_id, | 124 int render_frame_id, |
105 const std::string& device_id_salt, | 125 const std::string& device_id_salt, |
106 MediaStreamManager* media_stream_manager, | 126 MediaStreamManager* media_stream_manager, |
107 const service_manager::BindSourceInfo& source_info, | 127 const service_manager::BindSourceInfo& source_info, |
108 ::mojom::MediaDevicesDispatcherHostRequest request) { | 128 ::mojom::MediaDevicesDispatcherHostRequest request) { |
109 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 129 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
110 mojo::MakeStrongBinding(base::MakeUnique<MediaDevicesDispatcherHost>( | 130 mojo::MakeStrongBinding(base::MakeUnique<MediaDevicesDispatcherHost>( |
111 render_process_id, render_frame_id, | 131 render_process_id, render_frame_id, |
112 device_id_salt, media_stream_manager), | 132 device_id_salt, media_stream_manager), |
113 std::move(request)); | 133 std::move(request)); |
114 } | 134 } |
115 | 135 |
116 MediaDevicesDispatcherHost::MediaDevicesDispatcherHost( | 136 MediaDevicesDispatcherHost::MediaDevicesDispatcherHost( |
117 int render_process_id, | 137 int render_process_id, |
118 int render_frame_id, | 138 int render_frame_id, |
119 const std::string& device_id_salt, | 139 const std::string& device_id_salt, |
120 MediaStreamManager* media_stream_manager) | 140 MediaStreamManager* media_stream_manager) |
121 : render_process_id_(render_process_id), | 141 : render_process_id_(render_process_id), |
122 render_frame_id_(render_frame_id), | 142 render_frame_id_(render_frame_id), |
123 device_id_salt_(device_id_salt), | 143 device_id_salt_(device_id_salt), |
124 group_id_salt_(BrowserContext::CreateRandomMediaDeviceIDSalt()), | 144 group_id_salt_(BrowserContext::CreateRandomMediaDeviceIDSalt()), |
125 media_stream_manager_(media_stream_manager), | 145 media_stream_manager_(media_stream_manager), |
126 permission_checker_(base::MakeUnique<MediaDevicesPermissionChecker>()), | 146 permission_checker_(base::MakeUnique<MediaDevicesPermissionChecker>()), |
| 147 num_pending_audio_input_parameters_(0), |
127 weak_factory_(this) { | 148 weak_factory_(this) { |
128 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 149 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
129 } | 150 } |
130 | 151 |
131 MediaDevicesDispatcherHost::~MediaDevicesDispatcherHost() { | 152 MediaDevicesDispatcherHost::~MediaDevicesDispatcherHost() { |
132 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 153 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
133 // It may happen that media_devices_manager() is destroyed before MDDH on some | 154 // It may happen that media_devices_manager() is destroyed before MDDH on some |
134 // shutdown scenarios. | 155 // shutdown scenarios. |
135 if (!media_stream_manager_->media_devices_manager()) | 156 if (!media_stream_manager_->media_devices_manager()) |
136 return; | 157 return; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 GetVideoInputCapabilitiesCallback client_callback) { | 197 GetVideoInputCapabilitiesCallback client_callback) { |
177 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 198 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
178 base::PostTaskAndReplyWithResult( | 199 base::PostTaskAndReplyWithResult( |
179 BrowserThread::GetTaskRunnerForThread(BrowserThread::UI).get(), FROM_HERE, | 200 BrowserThread::GetTaskRunnerForThread(BrowserThread::UI).get(), FROM_HERE, |
180 base::Bind(GetOrigin, render_process_id_, render_frame_id_, | 201 base::Bind(GetOrigin, render_process_id_, render_frame_id_, |
181 security_origin_for_testing_), | 202 security_origin_for_testing_), |
182 base::Bind(&MediaDevicesDispatcherHost::GetDefaultVideoInputDeviceID, | 203 base::Bind(&MediaDevicesDispatcherHost::GetDefaultVideoInputDeviceID, |
183 weak_factory_.GetWeakPtr(), base::Passed(&client_callback))); | 204 weak_factory_.GetWeakPtr(), base::Passed(&client_callback))); |
184 } | 205 } |
185 | 206 |
| 207 void MediaDevicesDispatcherHost::GetAudioInputCapabilities( |
| 208 GetAudioInputCapabilitiesCallback client_callback) { |
| 209 base::PostTaskAndReplyWithResult( |
| 210 BrowserThread::GetTaskRunnerForThread(BrowserThread::UI).get(), FROM_HERE, |
| 211 base::Bind(GetOrigin, render_process_id_, render_frame_id_, |
| 212 security_origin_for_testing_), |
| 213 base::Bind(&MediaDevicesDispatcherHost::GetDefaultAudioInputDeviceID, |
| 214 weak_factory_.GetWeakPtr(), base::Passed(&client_callback))); |
| 215 } |
| 216 |
186 void MediaDevicesDispatcherHost::SubscribeDeviceChangeNotifications( | 217 void MediaDevicesDispatcherHost::SubscribeDeviceChangeNotifications( |
187 MediaDeviceType type, | 218 MediaDeviceType type, |
188 uint32_t subscription_id) { | 219 uint32_t subscription_id) { |
189 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 220 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
190 DCHECK(IsValidMediaDeviceType(type)); | 221 DCHECK(IsValidMediaDeviceType(type)); |
191 auto it = | 222 auto it = |
192 std::find(device_change_subscriptions_[type].begin(), | 223 std::find(device_change_subscriptions_[type].begin(), |
193 device_change_subscriptions_[type].end(), subscription_id); | 224 device_change_subscriptions_[type].end(), subscription_id); |
194 if (it != device_change_subscriptions_[type].end()) { | 225 if (it != device_change_subscriptions_[type].end()) { |
195 bad_message::ReceivedBadMessage( | 226 bad_message::ReceivedBadMessage( |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
419 if (format.has_value()) { | 450 if (format.has_value()) { |
420 formats.push_back(format.value()); | 451 formats.push_back(format.value()); |
421 return formats; | 452 return formats; |
422 } | 453 } |
423 | 454 |
424 media_stream_manager_->video_capture_manager()->GetDeviceSupportedFormats( | 455 media_stream_manager_->video_capture_manager()->GetDeviceSupportedFormats( |
425 device_id, &formats); | 456 device_id, &formats); |
426 return formats; | 457 return formats; |
427 } | 458 } |
428 | 459 |
| 460 struct MediaDevicesDispatcherHost::AudioInputCapabilitiesRequest { |
| 461 url::Origin security_origin; |
| 462 GetAudioInputCapabilitiesCallback client_callback; |
| 463 }; |
| 464 |
| 465 void MediaDevicesDispatcherHost::GetDefaultAudioInputDeviceID( |
| 466 GetAudioInputCapabilitiesCallback client_callback, |
| 467 const url::Origin& security_origin) { |
| 468 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 469 pending_audio_input_capabilities_requests_.push_back( |
| 470 AudioInputCapabilitiesRequest{security_origin, |
| 471 std::move(client_callback)}); |
| 472 if (pending_audio_input_capabilities_requests_.size() > 1U) |
| 473 return; |
| 474 |
| 475 DCHECK(current_audio_input_capabilities_.empty()); |
| 476 GetDefaultMediaDeviceID( |
| 477 MEDIA_DEVICE_TYPE_AUDIO_INPUT, render_process_id_, render_frame_id_, |
| 478 base::Bind(&MediaDevicesDispatcherHost::GotDefaultAudioInputDeviceID, |
| 479 weak_factory_.GetWeakPtr())); |
| 480 } |
| 481 |
| 482 void MediaDevicesDispatcherHost::GotDefaultAudioInputDeviceID( |
| 483 const std::string& default_device_id) { |
| 484 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 485 DCHECK_GT(pending_audio_input_capabilities_requests_.size(), 0U); |
| 486 DCHECK(current_audio_input_capabilities_.empty()); |
| 487 MediaDevicesManager::BoolDeviceTypes devices_to_enumerate; |
| 488 devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_INPUT] = true; |
| 489 media_stream_manager_->media_devices_manager()->EnumerateDevices( |
| 490 devices_to_enumerate, |
| 491 base::Bind(&MediaDevicesDispatcherHost::GotAudioInputEnumeration, |
| 492 weak_factory_.GetWeakPtr(), default_device_id)); |
| 493 } |
| 494 |
| 495 void MediaDevicesDispatcherHost::GotAudioInputEnumeration( |
| 496 const std::string& default_device_id, |
| 497 const MediaDeviceEnumeration& enumeration) { |
| 498 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 499 DCHECK_GT(pending_audio_input_capabilities_requests_.size(), 0U); |
| 500 DCHECK(current_audio_input_capabilities_.empty()); |
| 501 for (const auto& device_info : enumeration[MEDIA_DEVICE_TYPE_AUDIO_INPUT]) { |
| 502 ::mojom::AudioInputDeviceCapabilities capabilities( |
| 503 device_info.device_id, media::AudioParameters()); |
| 504 if (device_info.device_id == default_device_id) |
| 505 current_audio_input_capabilities_.insert( |
| 506 current_audio_input_capabilities_.begin(), std::move(capabilities)); |
| 507 else |
| 508 current_audio_input_capabilities_.push_back(std::move(capabilities)); |
| 509 } |
| 510 // No devices, no need to read audio parameters. |
| 511 if (current_audio_input_capabilities_.empty()) { |
| 512 FinalizeGetAudioInputCapabilities(); |
| 513 return; |
| 514 } |
| 515 |
| 516 num_pending_audio_input_parameters_ = |
| 517 current_audio_input_capabilities_.size(); |
| 518 for (size_t i = 0; i < num_pending_audio_input_parameters_; ++i) { |
| 519 media_stream_manager_->audio_system()->GetInputStreamParameters( |
| 520 current_audio_input_capabilities_[i].device_id, |
| 521 base::Bind(&MediaDevicesDispatcherHost::GotAudioInputParameters, |
| 522 weak_factory_.GetWeakPtr(), i)); |
| 523 } |
| 524 } |
| 525 |
| 526 void MediaDevicesDispatcherHost::GotAudioInputParameters( |
| 527 size_t index, |
| 528 const media::AudioParameters& parameters) { |
| 529 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 530 DCHECK_GT(pending_audio_input_capabilities_requests_.size(), 0U); |
| 531 DCHECK_GT(current_audio_input_capabilities_.size(), index); |
| 532 DCHECK_GT(num_pending_audio_input_parameters_, 0U); |
| 533 |
| 534 current_audio_input_capabilities_[index].parameters = |
| 535 parameters.IsValid() ? parameters |
| 536 : media::AudioParameters::UnavailableDeviceParams(); |
| 537 if (--num_pending_audio_input_parameters_ == 0U) |
| 538 FinalizeGetAudioInputCapabilities(); |
| 539 } |
| 540 |
| 541 void MediaDevicesDispatcherHost::FinalizeGetAudioInputCapabilities() { |
| 542 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 543 DCHECK_GT(pending_audio_input_capabilities_requests_.size(), 0U); |
| 544 DCHECK_EQ(0U, num_pending_audio_input_parameters_); |
| 545 |
| 546 for (auto& request : pending_audio_input_capabilities_requests_) { |
| 547 std::move(request.client_callback) |
| 548 .Run(ToVectorAudioInputDeviceCapabilitiesPtr( |
| 549 current_audio_input_capabilities_, request.security_origin, |
| 550 device_id_salt_)); |
| 551 } |
| 552 |
| 553 current_audio_input_capabilities_.clear(); |
| 554 pending_audio_input_capabilities_requests_.clear(); |
| 555 } |
| 556 |
429 } // namespace content | 557 } // namespace content |
OLD | NEW |