| 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/renderer/media/user_media_client_impl.h" | 5 #include "content/renderer/media/user_media_client_impl.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <utility> | 10 #include <utility> |
| 11 | 11 |
| 12 #include "base/hash.h" | 12 #include "base/hash.h" |
| 13 #include "base/location.h" | 13 #include "base/location.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
| 16 #include "base/single_thread_task_runner.h" | 16 #include "base/single_thread_task_runner.h" |
| 17 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
| 18 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
| 19 #include "base/strings/stringprintf.h" | 19 #include "base/strings/stringprintf.h" |
| 20 #include "base/strings/utf_string_conversions.h" | 20 #include "base/strings/utf_string_conversions.h" |
| 21 #include "base/task_runner.h" | 21 #include "base/task_runner.h" |
| 22 #include "base/task_runner_util.h" | 22 #include "base/task_runner_util.h" |
| 23 #include "base/threading/thread_task_runner_handle.h" | 23 #include "base/threading/thread_task_runner_handle.h" |
| 24 #include "build/build_config.h" | 24 #include "build/build_config.h" |
| 25 #include "content/public/renderer/render_frame.h" | 25 #include "content/public/renderer/render_frame.h" |
| 26 #include "content/renderer/media/local_media_stream_audio_source.h" | 26 #include "content/renderer/media/local_media_stream_audio_source.h" |
| 27 #include "content/renderer/media/media_stream.h" | 27 #include "content/renderer/media/media_stream.h" |
| 28 #include "content/renderer/media/media_stream_constraints_util.h" | 28 #include "content/renderer/media/media_stream_constraints_util.h" |
| 29 #include "content/renderer/media/media_stream_constraints_util_video_content.h" |
| 29 #include "content/renderer/media/media_stream_constraints_util_video_device.h" | 30 #include "content/renderer/media/media_stream_constraints_util_video_device.h" |
| 30 #include "content/renderer/media/media_stream_dispatcher.h" | 31 #include "content/renderer/media/media_stream_dispatcher.h" |
| 31 #include "content/renderer/media/media_stream_video_capturer_source.h" | 32 #include "content/renderer/media/media_stream_video_capturer_source.h" |
| 32 #include "content/renderer/media/media_stream_video_track.h" | 33 #include "content/renderer/media/media_stream_video_track.h" |
| 33 #include "content/renderer/media/peer_connection_tracker.h" | 34 #include "content/renderer/media/peer_connection_tracker.h" |
| 34 #include "content/renderer/media/webrtc/processed_local_audio_source.h" | 35 #include "content/renderer/media/webrtc/processed_local_audio_source.h" |
| 35 #include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h" | 36 #include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h" |
| 36 #include "content/renderer/media/webrtc_logging.h" | 37 #include "content/renderer/media/webrtc_logging.h" |
| 37 #include "content/renderer/media/webrtc_uma_histograms.h" | 38 #include "content/renderer/media/webrtc_uma_histograms.h" |
| 38 #include "content/renderer/render_thread_impl.h" | 39 #include "content/renderer/render_thread_impl.h" |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 } | 123 } |
| 123 | 124 |
| 124 // No valid alternate device ID found. Select default device. | 125 // No valid alternate device ID found. Select default device. |
| 125 return true; | 126 return true; |
| 126 } | 127 } |
| 127 | 128 |
| 128 bool IsDeviceSource(const std::string& source) { | 129 bool IsDeviceSource(const std::string& source) { |
| 129 return source.empty(); | 130 return source.empty(); |
| 130 } | 131 } |
| 131 | 132 |
| 133 // TODO(guidou): Remove once audio constraints are processed with spec-compliant |
| 134 // algorithm. See http://crbug.com/657733. |
| 132 void CopyConstraintsToTrackControls( | 135 void CopyConstraintsToTrackControls( |
| 133 const blink::WebMediaConstraints& constraints, | 136 const blink::WebMediaConstraints& constraints, |
| 134 TrackControls* track_controls, | 137 TrackControls* track_controls, |
| 135 bool* request_devices) { | 138 bool* request_devices) { |
| 136 DCHECK(!constraints.isNull()); | 139 DCHECK(!constraints.isNull()); |
| 137 track_controls->requested = true; | 140 track_controls->requested = true; |
| 138 CopyFirstString(constraints.basic().mediaStreamSource, | 141 CopyFirstString(constraints.basic().mediaStreamSource, |
| 139 &track_controls->stream_source); | 142 &track_controls->stream_source); |
| 140 if (IsDeviceSource(track_controls->stream_source)) { | 143 if (IsDeviceSource(track_controls->stream_source)) { |
| 141 bool request_devices_advanced = false; | 144 bool request_devices_advanced = false; |
| 142 for (const auto& advanced : constraints.advanced()) { | 145 for (const auto& advanced : constraints.advanced()) { |
| 143 if (!advanced.deviceId.isEmpty()) { | 146 if (!advanced.deviceId.isEmpty()) { |
| 144 request_devices_advanced = true; | 147 request_devices_advanced = true; |
| 145 break; | 148 break; |
| 146 } | 149 } |
| 147 } | 150 } |
| 148 *request_devices = | 151 *request_devices = |
| 149 request_devices_advanced || !constraints.basic().deviceId.isEmpty(); | 152 request_devices_advanced || !constraints.basic().deviceId.isEmpty(); |
| 150 } else { | 153 } else { |
| 151 CopyFirstString(constraints.basic().deviceId, &track_controls->device_id); | 154 CopyFirstString(constraints.basic().deviceId, &track_controls->device_id); |
| 152 *request_devices = false; | 155 *request_devices = false; |
| 153 } | 156 } |
| 154 } | 157 } |
| 155 | 158 |
| 159 void InitializeTrackControls(const blink::WebMediaConstraints& constraints, |
| 160 TrackControls* track_controls) { |
| 161 DCHECK(!constraints.isNull()); |
| 162 track_controls->requested = true; |
| 163 CopyFirstString(constraints.basic().mediaStreamSource, |
| 164 &track_controls->stream_source); |
| 165 } |
| 166 |
| 156 void CopyHotwordAndLocalEchoToStreamControls( | 167 void CopyHotwordAndLocalEchoToStreamControls( |
| 157 const blink::WebMediaConstraints& audio_constraints, | 168 const blink::WebMediaConstraints& audio_constraints, |
| 158 StreamControls* controls) { | 169 StreamControls* controls) { |
| 159 if (audio_constraints.isNull()) | 170 if (audio_constraints.isNull()) |
| 160 return; | 171 return; |
| 161 | 172 |
| 162 if (audio_constraints.basic().hotwordEnabled.hasExact()) { | 173 if (audio_constraints.basic().hotwordEnabled.hasExact()) { |
| 163 controls->hotword_enabled = | 174 controls->hotword_enabled = |
| 164 audio_constraints.basic().hotwordEnabled.exact(); | 175 audio_constraints.basic().hotwordEnabled.exact(); |
| 165 } else { | 176 } else { |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 } | 264 } |
| 254 | 265 |
| 255 void UserMediaClientImpl::requestUserMedia( | 266 void UserMediaClientImpl::requestUserMedia( |
| 256 const blink::WebUserMediaRequest& user_media_request) { | 267 const blink::WebUserMediaRequest& user_media_request) { |
| 257 // Save histogram data so we can see how much GetUserMedia is used. | 268 // Save histogram data so we can see how much GetUserMedia is used. |
| 258 // The histogram counts the number of calls to the JS API | 269 // The histogram counts the number of calls to the JS API |
| 259 // webGetUserMedia. | 270 // webGetUserMedia. |
| 260 UpdateWebRTCMethodCount(WEBKIT_GET_USER_MEDIA); | 271 UpdateWebRTCMethodCount(WEBKIT_GET_USER_MEDIA); |
| 261 DCHECK(CalledOnValidThread()); | 272 DCHECK(CalledOnValidThread()); |
| 262 DCHECK(!user_media_request.isNull()); | 273 DCHECK(!user_media_request.isNull()); |
| 274 DCHECK(user_media_request.audio() || user_media_request.video()); |
| 263 // ownerDocument may be null if we are in a test. | 275 // ownerDocument may be null if we are in a test. |
| 264 // In that case, it's OK to not check frame(). | 276 // In that case, it's OK to not check frame(). |
| 265 DCHECK(user_media_request.ownerDocument().isNull() || | 277 DCHECK(user_media_request.ownerDocument().isNull() || |
| 266 render_frame()->GetWebFrame() == | 278 render_frame()->GetWebFrame() == |
| 267 static_cast<blink::WebFrame*>( | 279 static_cast<blink::WebFrame*>( |
| 268 user_media_request.ownerDocument().frame())); | 280 user_media_request.ownerDocument().frame())); |
| 269 | 281 |
| 270 if (RenderThreadImpl::current()) { | 282 if (RenderThreadImpl::current()) { |
| 271 RenderThreadImpl::current()->peer_connection_tracker()->TrackGetUserMedia( | 283 RenderThreadImpl::current()->peer_connection_tracker()->TrackGetUserMedia( |
| 272 user_media_request); | 284 user_media_request); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 | 343 |
| 332 SetupVideoInput(request_id, user_media_request, std::move(controls), | 344 SetupVideoInput(request_id, user_media_request, std::move(controls), |
| 333 request_settings); | 345 request_settings); |
| 334 } | 346 } |
| 335 | 347 |
| 336 void UserMediaClientImpl::SetupVideoInput( | 348 void UserMediaClientImpl::SetupVideoInput( |
| 337 int request_id, | 349 int request_id, |
| 338 const blink::WebUserMediaRequest& user_media_request, | 350 const blink::WebUserMediaRequest& user_media_request, |
| 339 std::unique_ptr<StreamControls> controls, | 351 std::unique_ptr<StreamControls> controls, |
| 340 const RequestSettings& request_settings) { | 352 const RequestSettings& request_settings) { |
| 341 if (user_media_request.video()) { | 353 if (!user_media_request.video()) { |
| 342 bool ignore; | 354 FinalizeRequestUserMedia(request_id, user_media_request, |
| 343 CopyConstraintsToTrackControls(user_media_request.videoConstraints(), | 355 std::move(controls), request_settings); |
| 344 &controls->video, &ignore); | 356 return; |
| 345 if (IsDeviceSource(controls->video.stream_source)) { | |
| 346 GetMediaDevicesDispatcher()->GetVideoInputCapabilities( | |
| 347 request_settings.security_origin, | |
| 348 base::Bind(&UserMediaClientImpl::SelectVideoDeviceSourceSettings, | |
| 349 weak_factory_.GetWeakPtr(), request_id, user_media_request, | |
| 350 base::Passed(&controls), request_settings)); | |
| 351 return; | |
| 352 } | |
| 353 } | 357 } |
| 354 FinalizeRequestUserMedia(request_id, user_media_request, std::move(controls), | 358 InitializeTrackControls(user_media_request.videoConstraints(), |
| 355 request_settings); | 359 &controls->video); |
| 360 if (IsDeviceSource(controls->video.stream_source)) { |
| 361 GetMediaDevicesDispatcher()->GetVideoInputCapabilities( |
| 362 request_settings.security_origin, |
| 363 base::Bind(&UserMediaClientImpl::SelectVideoDeviceSourceSettings, |
| 364 weak_factory_.GetWeakPtr(), request_id, user_media_request, |
| 365 base::Passed(&controls), request_settings)); |
| 366 } else { |
| 367 base::PostTaskAndReplyWithResult( |
| 368 worker_task_runner_.get(), FROM_HERE, |
| 369 base::Bind(&SelectVideoContentCaptureSourceSettings, |
| 370 user_media_request.videoConstraints()), |
| 371 base::Bind( |
| 372 &UserMediaClientImpl::FinalizeSelectVideoContentSourceSettings, |
| 373 weak_factory_.GetWeakPtr(), request_id, user_media_request, |
| 374 base::Passed(&controls), request_settings)); |
| 375 } |
| 356 } | 376 } |
| 357 | 377 |
| 358 void UserMediaClientImpl::SelectVideoDeviceSourceSettings( | 378 void UserMediaClientImpl::SelectVideoDeviceSourceSettings( |
| 359 int request_id, | 379 int request_id, |
| 360 const blink::WebUserMediaRequest& user_media_request, | 380 const blink::WebUserMediaRequest& user_media_request, |
| 361 std::unique_ptr<StreamControls> controls, | 381 std::unique_ptr<StreamControls> controls, |
| 362 const RequestSettings& request_settings, | 382 const RequestSettings& request_settings, |
| 363 std::vector<::mojom::VideoInputDeviceCapabilitiesPtr> | 383 std::vector<::mojom::VideoInputDeviceCapabilitiesPtr> |
| 364 video_input_capabilities) { | 384 video_input_capabilities) { |
| 365 DCHECK(CalledOnValidThread()); | 385 DCHECK(CalledOnValidThread()); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 GetUserMediaRequestFailed(user_media_request, | 430 GetUserMediaRequestFailed(user_media_request, |
| 411 MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED, | 431 MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED, |
| 412 failed_constraint_name); | 432 failed_constraint_name); |
| 413 return; | 433 return; |
| 414 } | 434 } |
| 415 } | 435 } |
| 416 FinalizeRequestUserMedia(request_id, user_media_request, std::move(controls), | 436 FinalizeRequestUserMedia(request_id, user_media_request, std::move(controls), |
| 417 request_settings); | 437 request_settings); |
| 418 } | 438 } |
| 419 | 439 |
| 440 void UserMediaClientImpl::FinalizeSelectVideoContentSourceSettings( |
| 441 int request_id, |
| 442 const blink::WebUserMediaRequest& user_media_request, |
| 443 std::unique_ptr<StreamControls> controls, |
| 444 const RequestSettings& request_settings, |
| 445 const VideoContentCaptureSourceSelectionResult& selection_result) { |
| 446 DCHECK(CalledOnValidThread()); |
| 447 if (!selection_result.HasValue()) { |
| 448 blink::WebString failed_constraint_name = |
| 449 blink::WebString::fromASCII(selection_result.failed_constraint_name()); |
| 450 DCHECK(!failed_constraint_name.isEmpty()); |
| 451 blink::WebString device_id_constraint_name = blink::WebString::fromASCII( |
| 452 user_media_request.videoConstraints().basic().deviceId.name()); |
| 453 GetUserMediaRequestFailed(user_media_request, |
| 454 MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED, |
| 455 failed_constraint_name); |
| 456 return; |
| 457 } |
| 458 controls->video.device_id = selection_result.device_id(); |
| 459 FinalizeRequestUserMedia(request_id, user_media_request, std::move(controls), |
| 460 request_settings); |
| 461 } |
| 462 |
| 420 void UserMediaClientImpl::FinalizeRequestUserMedia( | 463 void UserMediaClientImpl::FinalizeRequestUserMedia( |
| 421 int request_id, | 464 int request_id, |
| 422 const blink::WebUserMediaRequest& user_media_request, | 465 const blink::WebUserMediaRequest& user_media_request, |
| 423 std::unique_ptr<StreamControls> controls, | 466 std::unique_ptr<StreamControls> controls, |
| 424 const RequestSettings& request_settings) { | 467 const RequestSettings& request_settings) { |
| 425 DCHECK(CalledOnValidThread()); | 468 DCHECK(CalledOnValidThread()); |
| 426 | 469 |
| 427 WebRtcLogMessage( | 470 WebRtcLogMessage( |
| 428 base::StringPrintf("MSI::requestUserMedia. request_id=%d" | 471 base::StringPrintf("MSI::requestUserMedia. request_id=%d" |
| 429 ", audio source id=%s" | 472 ", audio source id=%s" |
| (...skipping 817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1247 sources_waiting_for_callback_.end(), source); | 1290 sources_waiting_for_callback_.end(), source); |
| 1248 if (found != sources_waiting_for_callback_.end()) | 1291 if (found != sources_waiting_for_callback_.end()) |
| 1249 OnTrackStarted(source, result, result_name); | 1292 OnTrackStarted(source, result, result_name); |
| 1250 } | 1293 } |
| 1251 | 1294 |
| 1252 void UserMediaClientImpl::OnDestruct() { | 1295 void UserMediaClientImpl::OnDestruct() { |
| 1253 delete this; | 1296 delete this; |
| 1254 } | 1297 } |
| 1255 | 1298 |
| 1256 } // namespace content | 1299 } // namespace content |
| OLD | NEW |