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

Side by Side Diff: content/renderer/media/user_media_client_impl.cc

Issue 2764043002: Serialize processing of getUserMedia() requests. (Closed)
Patch Set: Address tommi's comments Created 3 years, 9 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
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/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"
13 #include "base/location.h" 12 #include "base/location.h"
14 #include "base/logging.h" 13 #include "base/logging.h"
15 #include "base/memory/ptr_util.h" 14 #include "base/memory/ptr_util.h"
16 #include "base/single_thread_task_runner.h" 15 #include "base/single_thread_task_runner.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/string_util.h"
19 #include "base/strings/stringprintf.h" 16 #include "base/strings/stringprintf.h"
20 #include "base/strings/utf_string_conversions.h"
21 #include "base/task_runner.h" 17 #include "base/task_runner.h"
22 #include "base/task_runner_util.h" 18 #include "base/task_runner_util.h"
23 #include "base/threading/thread_task_runner_handle.h" 19 #include "base/threading/thread_task_runner_handle.h"
24 #include "build/build_config.h"
25 #include "content/public/renderer/render_frame.h" 20 #include "content/public/renderer/render_frame.h"
26 #include "content/renderer/media/local_media_stream_audio_source.h" 21 #include "content/renderer/media/local_media_stream_audio_source.h"
27 #include "content/renderer/media/media_stream.h" 22 #include "content/renderer/media/media_stream.h"
28 #include "content/renderer/media/media_stream_constraints_util.h" 23 #include "content/renderer/media/media_stream_constraints_util.h"
29 #include "content/renderer/media/media_stream_constraints_util_video_content.h" 24 #include "content/renderer/media/media_stream_constraints_util_video_content.h"
30 #include "content/renderer/media/media_stream_constraints_util_video_device.h" 25 #include "content/renderer/media/media_stream_constraints_util_video_device.h"
31 #include "content/renderer/media/media_stream_dispatcher.h" 26 #include "content/renderer/media/media_stream_dispatcher.h"
32 #include "content/renderer/media/media_stream_video_capturer_source.h" 27 #include "content/renderer/media/media_stream_video_capturer_source.h"
33 #include "content/renderer/media/media_stream_video_track.h" 28 #include "content/renderer/media/media_stream_video_track.h"
34 #include "content/renderer/media/peer_connection_tracker.h" 29 #include "content/renderer/media/peer_connection_tracker.h"
35 #include "content/renderer/media/webrtc/processed_local_audio_source.h" 30 #include "content/renderer/media/webrtc/processed_local_audio_source.h"
36 #include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h"
37 #include "content/renderer/media/webrtc_logging.h" 31 #include "content/renderer/media/webrtc_logging.h"
38 #include "content/renderer/media/webrtc_uma_histograms.h" 32 #include "content/renderer/media/webrtc_uma_histograms.h"
39 #include "content/renderer/render_thread_impl.h" 33 #include "content/renderer/render_thread_impl.h"
40 #include "media/capture/video_capture_types.h" 34 #include "media/capture/video_capture_types.h"
41 #include "third_party/WebKit/public/platform/URLConversion.h"
42 #include "third_party/WebKit/public/platform/WebMediaConstraints.h" 35 #include "third_party/WebKit/public/platform/WebMediaConstraints.h"
43 #include "third_party/WebKit/public/platform/WebMediaDeviceInfo.h" 36 #include "third_party/WebKit/public/platform/WebMediaDeviceInfo.h"
44 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" 37 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
45 #include "third_party/WebKit/public/platform/WebString.h" 38 #include "third_party/WebKit/public/platform/WebString.h"
46 #include "third_party/WebKit/public/web/WebDocument.h" 39 #include "third_party/WebKit/public/web/WebDocument.h"
47 #include "third_party/WebKit/public/web/WebLocalFrame.h" 40 #include "third_party/WebKit/public/web/WebLocalFrame.h"
48 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h" 41 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
49 42
50 namespace content { 43 namespace content {
51 namespace { 44 namespace {
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 default: 216 default:
224 NOTREACHED(); 217 NOTREACHED();
225 return blink::WebMediaDeviceInfo::MediaDeviceKindAudioInput; 218 return blink::WebMediaDeviceInfo::MediaDeviceKindAudioInput;
226 } 219 }
227 } 220 }
228 221
229 static int g_next_request_id = 0; 222 static int g_next_request_id = 0;
230 223
231 } // namespace 224 } // namespace
232 225
233 struct UserMediaClientImpl::RequestSettings { 226 // Class for storing information about a Blink request to create a
234 RequestSettings(bool is_processing_user_gesture, url::Origin security_origin) 227 // MediaStream.
235 : enable_automatic_audio_output_device_selection(false), 228 class UserMediaClientImpl::UserMediaRequestInfo
236 is_processing_user_gesture(is_processing_user_gesture), 229 : public base::SupportsWeakPtr<UserMediaRequestInfo> {
237 security_origin(security_origin) {} 230 public:
238 ~RequestSettings() = default; 231 using ResourcesReady =
232 base::Callback<void(UserMediaRequestInfo* request_info,
233 MediaStreamRequestResult result,
234 const blink::WebString& result_name)>;
235 enum class State {
236 NOT_SENT_FOR_GENERATION,
237 SENT_FOR_GENERATION,
238 GENERATED,
239 };
239 240
240 bool enable_automatic_audio_output_device_selection; 241 UserMediaRequestInfo(int request_id,
241 bool is_processing_user_gesture; 242 const blink::WebUserMediaRequest& request,
242 url::Origin security_origin; 243 bool is_processing_user_gesture,
244 const url::Origin& security_origin);
245
246 void StartAudioTrack(const blink::WebMediaStreamTrack& track,
247 bool is_pending);
248
249 blink::WebMediaStreamTrack CreateAndStartVideoTrack(
250 const blink::WebMediaStreamSource& source,
251 const blink::WebMediaConstraints& constraints);
252
253 // Triggers |callback| when all sources used in this request have either
254 // successfully started, or a source has failed to start.
255 void CallbackOnTracksStarted(const ResourcesReady& callback);
256
257 bool HasPendingSources() const;
258
259 // Called when a local audio source has finished (or failed) initializing.
260 void OnAudioSourceStarted(MediaStreamSource* source,
261 MediaStreamRequestResult result,
262 const blink::WebString& result_name);
263
264 int request_id() const { return request_id_; }
265
266 State state() const { return state_; }
267 void set_state(State state) { state_ = state; }
268
269 bool enable_automatic_output_device_selection() const {
270 return enable_automatic_output_device_selection_;
271 }
272 void set_enable_automatic_output_device_selection(bool value) {
273 enable_automatic_output_device_selection_ = value;
274 }
275
276 blink::WebMediaStream* web_stream() { return &web_stream_; }
277
278 const blink::WebUserMediaRequest& request() const { return request_; }
279
280 StreamControls* stream_controls() { return &stream_controls_; }
281
282 bool is_processing_user_gesture() const {
283 return is_processing_user_gesture_;
284 }
285
286 const url::Origin& security_origin() const { return security_origin_; }
287
288 private:
289 void OnTrackStarted(MediaStreamSource* source,
290 MediaStreamRequestResult result,
291 const blink::WebString& result_name);
292
293 // Cheks if the sources for all tracks have been started and if so,
294 // invoke the |ready_callback_|. Note that the caller should expect
295 // that |this| might be deleted when the function returns.
296 void CheckAllTracksStarted();
297
298 const int request_id_;
299 State state_;
300 bool enable_automatic_output_device_selection_;
301 blink::WebMediaStream web_stream_;
302 const blink::WebUserMediaRequest request_;
303 StreamControls stream_controls_;
304 const bool is_processing_user_gesture_;
305 const url::Origin security_origin_;
306 ResourcesReady ready_callback_;
307 MediaStreamRequestResult request_result_;
308 blink::WebString request_result_name_;
309 // Sources used in this request.
310 std::vector<blink::WebMediaStreamSource> sources_;
311 std::vector<MediaStreamSource*> sources_waiting_for_callback_;
243 }; 312 };
244 313
245 UserMediaClientImpl::UserMediaClientImpl( 314 UserMediaClientImpl::UserMediaClientImpl(
246 RenderFrame* render_frame, 315 RenderFrame* render_frame,
247 PeerConnectionDependencyFactory* dependency_factory, 316 PeerConnectionDependencyFactory* dependency_factory,
248 std::unique_ptr<MediaStreamDispatcher> media_stream_dispatcher, 317 std::unique_ptr<MediaStreamDispatcher> media_stream_dispatcher,
249 const scoped_refptr<base::TaskRunner>& worker_task_runner) 318 const scoped_refptr<base::TaskRunner>& worker_task_runner)
250 : RenderFrameObserver(render_frame), 319 : RenderFrameObserver(render_frame),
251 dependency_factory_(dependency_factory), 320 dependency_factory_(dependency_factory),
252 media_stream_dispatcher_(std::move(media_stream_dispatcher)), 321 media_stream_dispatcher_(std::move(media_stream_dispatcher)),
(...skipping 25 matching lines...) Expand all
278 render_frame()->GetWebFrame() == 347 render_frame()->GetWebFrame() ==
279 static_cast<blink::WebFrame*>( 348 static_cast<blink::WebFrame*>(
280 user_media_request.ownerDocument().frame())); 349 user_media_request.ownerDocument().frame()));
281 350
282 if (RenderThreadImpl::current()) { 351 if (RenderThreadImpl::current()) {
283 RenderThreadImpl::current()->peer_connection_tracker()->TrackGetUserMedia( 352 RenderThreadImpl::current()->peer_connection_tracker()->TrackGetUserMedia(
284 user_media_request); 353 user_media_request);
285 } 354 }
286 355
287 int request_id = g_next_request_id++; 356 int request_id = g_next_request_id++;
288 std::unique_ptr<StreamControls> controls = base::MakeUnique<StreamControls>();
289 357
290 // The value returned by isProcessingUserGesture() is used by the browser to 358 // The value returned by isProcessingUserGesture() is used by the browser to
291 // make decisions about the permissions UI. Its value can be lost while 359 // make decisions about the permissions UI. Its value can be lost while
292 // switching threads, so saving its value here. 360 // switching threads, so saving its value here.
293 RequestSettings request_settings( 361 std::unique_ptr<UserMediaRequestInfo> request_info =
294 blink::WebUserGestureIndicator::isProcessingUserGesture(), 362 base::MakeUnique<UserMediaRequestInfo>(
295 static_cast<url::Origin>(user_media_request.getSecurityOrigin())); 363 request_id, user_media_request,
296 if (user_media_request.audio()) { 364 blink::WebUserGestureIndicator::isProcessingUserGesture(),
365 static_cast<url::Origin>(user_media_request.getSecurityOrigin()));
366 pending_request_infos_.push_back(std::move(request_info));
367 if (!current_request_info_) {
368 base::ThreadTaskRunnerHandle::Get()->PostTask(
369 FROM_HERE, base::Bind(&UserMediaClientImpl::MaybeProcessNextRequestInfo,
370 weak_factory_.GetWeakPtr()));
371 }
372 }
373
374 void UserMediaClientImpl::MaybeProcessNextRequestInfo() {
375 DCHECK(CalledOnValidThread());
376 if (current_request_info_ || pending_request_infos_.empty())
377 return;
378
379 current_request_info_ = std::move(pending_request_infos_.front());
380 pending_request_infos_.pop_front();
381
382 // TODO(guidou): Request audio and video capabilities in parallel.
383 if (current_request_info_->request().audio()) {
297 bool request_audio_input_devices = false; 384 bool request_audio_input_devices = false;
298 // TODO(guidou): Implement spec-compliant device selection for audio. See 385 // TODO(guidou): Implement spec-compliant device selection for audio. See
299 // http://crbug.com/623104. 386 // http://crbug.com/623104.
300 CopyConstraintsToTrackControls(user_media_request.audioConstraints(), 387 CopyConstraintsToTrackControls(
301 &controls->audio, 388 current_request_info_->request().audioConstraints(),
302 &request_audio_input_devices); 389 &current_request_info_->stream_controls()->audio,
390 &request_audio_input_devices);
303 CopyHotwordAndLocalEchoToStreamControls( 391 CopyHotwordAndLocalEchoToStreamControls(
304 user_media_request.audioConstraints(), controls.get()); 392 current_request_info_->request().audioConstraints(),
393 current_request_info_->stream_controls());
305 // Check if this input device should be used to select a matching output 394 // Check if this input device should be used to select a matching output
306 // device for audio rendering. 395 // device for audio rendering.
396 bool enable_automatic_output_device_selection = false;
307 GetConstraintValueAsBoolean( 397 GetConstraintValueAsBoolean(
308 user_media_request.audioConstraints(), 398 current_request_info_->request().audioConstraints(),
309 &blink::WebMediaTrackConstraintSet::renderToAssociatedSink, 399 &blink::WebMediaTrackConstraintSet::renderToAssociatedSink,
310 &request_settings.enable_automatic_audio_output_device_selection); 400 &enable_automatic_output_device_selection);
401 current_request_info_->set_enable_automatic_output_device_selection(
402 enable_automatic_output_device_selection);
311 403
312 if (request_audio_input_devices) { 404 if (request_audio_input_devices) {
313 GetMediaDevicesDispatcher()->EnumerateDevices( 405 GetMediaDevicesDispatcher()->EnumerateDevices(
314 true /* audio_input */, false /* video_input */, 406 true /* audio_input */, false /* video_input */,
315 false /* audio_output */, request_settings.security_origin, 407 false /* audio_output */, current_request_info_->security_origin(),
316 base::Bind(&UserMediaClientImpl::SelectAudioInputDevice, 408 base::Bind(&UserMediaClientImpl::SelectAudioInputDevice,
317 weak_factory_.GetWeakPtr(), request_id, user_media_request, 409 weak_factory_.GetWeakPtr(),
318 base::Passed(&controls), request_settings)); 410 current_request_info_->request()));
319 return; 411 return;
320 } 412 }
321 } 413 }
322 414
323 SetupVideoInput(request_id, user_media_request, std::move(controls), 415 SetupVideoInput(current_request_info_->request());
324 request_settings);
325 } 416 }
326 417
327 void UserMediaClientImpl::SelectAudioInputDevice( 418 void UserMediaClientImpl::SelectAudioInputDevice(
328 int request_id,
329 const blink::WebUserMediaRequest& user_media_request, 419 const blink::WebUserMediaRequest& user_media_request,
330 std::unique_ptr<StreamControls> controls,
331 const RequestSettings& request_settings,
332 const EnumerationResult& device_enumeration) { 420 const EnumerationResult& device_enumeration) {
333 DCHECK(CalledOnValidThread()); 421 DCHECK(CalledOnValidThread());
334 DCHECK(controls->audio.requested); 422 if (!IsCurrentRequestInfo(user_media_request))
335 DCHECK(IsDeviceSource(controls->audio.stream_source)); 423 return;
424
425 auto& audio_controls = current_request_info_->stream_controls()->audio;
426 DCHECK(audio_controls.requested);
427 DCHECK(IsDeviceSource(audio_controls.stream_source));
336 428
337 if (!PickDeviceId(user_media_request.audioConstraints(), 429 if (!PickDeviceId(user_media_request.audioConstraints(),
338 device_enumeration[MEDIA_DEVICE_TYPE_AUDIO_INPUT], 430 device_enumeration[MEDIA_DEVICE_TYPE_AUDIO_INPUT],
339 &controls->audio.device_id)) { 431 &audio_controls.device_id)) {
340 GetUserMediaRequestFailed(user_media_request, MEDIA_DEVICE_NO_HARDWARE, ""); 432 GetUserMediaRequestFailed(user_media_request, MEDIA_DEVICE_NO_HARDWARE, "");
341 return; 433 return;
342 } 434 }
343 435
344 SetupVideoInput(request_id, user_media_request, std::move(controls), 436 SetupVideoInput(user_media_request);
345 request_settings);
346 } 437 }
347 438
348 void UserMediaClientImpl::SetupVideoInput( 439 void UserMediaClientImpl::SetupVideoInput(
349 int request_id, 440 const blink::WebUserMediaRequest& user_media_request) {
350 const blink::WebUserMediaRequest& user_media_request, 441 DCHECK(CalledOnValidThread());
351 std::unique_ptr<StreamControls> controls, 442 if (!IsCurrentRequestInfo(user_media_request))
352 const RequestSettings& request_settings) { 443 return;
444
353 if (!user_media_request.video()) { 445 if (!user_media_request.video()) {
354 FinalizeRequestUserMedia(request_id, user_media_request, 446 GenerateStreamForCurrentRequestInfo();
355 std::move(controls), request_settings);
356 return; 447 return;
357 } 448 }
449 auto& video_controls = current_request_info_->stream_controls()->video;
358 InitializeTrackControls(user_media_request.videoConstraints(), 450 InitializeTrackControls(user_media_request.videoConstraints(),
359 &controls->video); 451 &video_controls);
360 if (IsDeviceSource(controls->video.stream_source)) { 452 if (IsDeviceSource(video_controls.stream_source)) {
361 GetMediaDevicesDispatcher()->GetVideoInputCapabilities( 453 GetMediaDevicesDispatcher()->GetVideoInputCapabilities(
362 request_settings.security_origin, 454 current_request_info_->security_origin(),
363 base::Bind(&UserMediaClientImpl::SelectVideoDeviceSourceSettings, 455 base::Bind(&UserMediaClientImpl::SelectVideoDeviceSourceSettings,
364 weak_factory_.GetWeakPtr(), request_id, user_media_request, 456 weak_factory_.GetWeakPtr(), user_media_request));
365 base::Passed(&controls), request_settings));
366 } else { 457 } else {
367 base::PostTaskAndReplyWithResult( 458 base::PostTaskAndReplyWithResult(
368 worker_task_runner_.get(), FROM_HERE, 459 worker_task_runner_.get(), FROM_HERE,
369 base::Bind(&SelectVideoContentCaptureSourceSettings, 460 base::Bind(&SelectVideoContentCaptureSourceSettings,
370 user_media_request.videoConstraints()), 461 user_media_request.videoConstraints()),
371 base::Bind( 462 base::Bind(
372 &UserMediaClientImpl::FinalizeSelectVideoContentSourceSettings, 463 &UserMediaClientImpl::FinalizeSelectVideoContentSourceSettings,
373 weak_factory_.GetWeakPtr(), request_id, user_media_request, 464 weak_factory_.GetWeakPtr(), user_media_request));
374 base::Passed(&controls), request_settings));
375 } 465 }
376 } 466 }
377 467
378 void UserMediaClientImpl::SelectVideoDeviceSourceSettings( 468 void UserMediaClientImpl::SelectVideoDeviceSourceSettings(
379 int request_id,
380 const blink::WebUserMediaRequest& user_media_request, 469 const blink::WebUserMediaRequest& user_media_request,
381 std::unique_ptr<StreamControls> controls,
382 const RequestSettings& request_settings,
383 std::vector<::mojom::VideoInputDeviceCapabilitiesPtr> 470 std::vector<::mojom::VideoInputDeviceCapabilitiesPtr>
384 video_input_capabilities) { 471 video_input_capabilities) {
385 DCHECK(CalledOnValidThread()); 472 DCHECK(CalledOnValidThread());
386 DCHECK(controls->video.requested); 473 if (!IsCurrentRequestInfo(user_media_request))
387 DCHECK(IsDeviceSource(controls->video.stream_source)); 474 return;
475
476 DCHECK(current_request_info_->stream_controls()->video.requested);
477 DCHECK(IsDeviceSource(
478 current_request_info_->stream_controls()->video.stream_source));
388 479
389 VideoDeviceCaptureCapabilities capabilities; 480 VideoDeviceCaptureCapabilities capabilities;
390 capabilities.device_capabilities = std::move(video_input_capabilities); 481 capabilities.device_capabilities = std::move(video_input_capabilities);
391 capabilities.power_line_capabilities = { 482 capabilities.power_line_capabilities = {
392 media::PowerLineFrequency::FREQUENCY_DEFAULT, 483 media::PowerLineFrequency::FREQUENCY_DEFAULT,
393 media::PowerLineFrequency::FREQUENCY_50HZ, 484 media::PowerLineFrequency::FREQUENCY_50HZ,
394 media::PowerLineFrequency::FREQUENCY_60HZ}; 485 media::PowerLineFrequency::FREQUENCY_60HZ};
395 capabilities.noise_reduction_capabilities = {rtc::Optional<bool>(), 486 capabilities.noise_reduction_capabilities = {rtc::Optional<bool>(),
396 rtc::Optional<bool>(true), 487 rtc::Optional<bool>(true),
397 rtc::Optional<bool>(false)}; 488 rtc::Optional<bool>(false)};
398
399 base::PostTaskAndReplyWithResult( 489 base::PostTaskAndReplyWithResult(
400 worker_task_runner_.get(), FROM_HERE, 490 worker_task_runner_.get(), FROM_HERE,
401 base::Bind(&SelectVideoDeviceCaptureSourceSettings, 491 base::Bind(&SelectVideoDeviceCaptureSourceSettings,
402 std::move(capabilities), 492 std::move(capabilities),
403 user_media_request.videoConstraints()), 493 user_media_request.videoConstraints()),
404 base::Bind(&UserMediaClientImpl::FinalizeSelectVideoDeviceSourceSettings, 494 base::Bind(&UserMediaClientImpl::FinalizeSelectVideoDeviceSourceSettings,
405 weak_factory_.GetWeakPtr(), request_id, user_media_request, 495 weak_factory_.GetWeakPtr(), user_media_request));
406 base::Passed(&controls), request_settings));
407 } 496 }
408 497
409 void UserMediaClientImpl::FinalizeSelectVideoDeviceSourceSettings( 498 void UserMediaClientImpl::FinalizeSelectVideoDeviceSourceSettings(
410 int request_id,
411 const blink::WebUserMediaRequest& user_media_request, 499 const blink::WebUserMediaRequest& user_media_request,
412 std::unique_ptr<StreamControls> controls,
413 const RequestSettings& request_settings,
414 const VideoDeviceCaptureSourceSelectionResult& selection_result) { 500 const VideoDeviceCaptureSourceSelectionResult& selection_result) {
415 DCHECK(CalledOnValidThread()); 501 DCHECK(CalledOnValidThread());
502 if (!IsCurrentRequestInfo(user_media_request))
503 return;
504
416 if (!selection_result.HasValue()) { 505 if (!selection_result.HasValue()) {
417 blink::WebString failed_constraint_name = 506 blink::WebString failed_constraint_name =
418 blink::WebString::fromASCII(selection_result.failed_constraint_name()); 507 blink::WebString::fromASCII(selection_result.failed_constraint_name());
419 MediaStreamRequestResult result = 508 MediaStreamRequestResult result =
420 failed_constraint_name.isEmpty() 509 failed_constraint_name.isEmpty()
421 ? MEDIA_DEVICE_NO_HARDWARE 510 ? MEDIA_DEVICE_NO_HARDWARE
422 : MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED; 511 : MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED;
423 GetUserMediaRequestFailed(user_media_request, result, 512 GetUserMediaRequestFailed(user_media_request, result,
424 failed_constraint_name); 513 failed_constraint_name);
425 return; 514 return;
426 } 515 }
427 controls->video.device_id = selection_result.device_id(); 516 current_request_info_->stream_controls()->video.device_id =
428 FinalizeRequestUserMedia(request_id, user_media_request, std::move(controls), 517 selection_result.device_id();
429 request_settings); 518 GenerateStreamForCurrentRequestInfo();
430 } 519 }
431 520
432 void UserMediaClientImpl::FinalizeSelectVideoContentSourceSettings( 521 void UserMediaClientImpl::FinalizeSelectVideoContentSourceSettings(
433 int request_id,
434 const blink::WebUserMediaRequest& user_media_request, 522 const blink::WebUserMediaRequest& user_media_request,
435 std::unique_ptr<StreamControls> controls,
436 const RequestSettings& request_settings,
437 const VideoContentCaptureSourceSelectionResult& selection_result) { 523 const VideoContentCaptureSourceSelectionResult& selection_result) {
438 DCHECK(CalledOnValidThread()); 524 DCHECK(CalledOnValidThread());
525 if (!IsCurrentRequestInfo(user_media_request))
526 return;
527
439 if (!selection_result.HasValue()) { 528 if (!selection_result.HasValue()) {
440 blink::WebString failed_constraint_name = 529 blink::WebString failed_constraint_name =
441 blink::WebString::fromASCII(selection_result.failed_constraint_name()); 530 blink::WebString::fromASCII(selection_result.failed_constraint_name());
442 DCHECK(!failed_constraint_name.isEmpty()); 531 DCHECK(!failed_constraint_name.isEmpty());
443 blink::WebString device_id_constraint_name = blink::WebString::fromASCII( 532 blink::WebString device_id_constraint_name = blink::WebString::fromASCII(
444 user_media_request.videoConstraints().basic().deviceId.name()); 533 user_media_request.videoConstraints().basic().deviceId.name());
445 GetUserMediaRequestFailed(user_media_request, 534 GetUserMediaRequestFailed(user_media_request,
446 MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED, 535 MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED,
447 failed_constraint_name); 536 failed_constraint_name);
448 return; 537 return;
449 } 538 }
450 controls->video.device_id = selection_result.device_id(); 539 current_request_info_->stream_controls()->video.device_id =
451 FinalizeRequestUserMedia(request_id, user_media_request, std::move(controls), 540 selection_result.device_id();
452 request_settings); 541 GenerateStreamForCurrentRequestInfo();
453 } 542 }
454 543
455 void UserMediaClientImpl::FinalizeRequestUserMedia( 544 void UserMediaClientImpl::GenerateStreamForCurrentRequestInfo() {
456 int request_id,
457 const blink::WebUserMediaRequest& user_media_request,
458 std::unique_ptr<StreamControls> controls,
459 const RequestSettings& request_settings) {
460 DCHECK(CalledOnValidThread()); 545 DCHECK(CalledOnValidThread());
546 DCHECK(current_request_info_);
461 547
462 WebRtcLogMessage( 548 WebRtcLogMessage(base::StringPrintf(
463 base::StringPrintf("MSI::requestUserMedia. request_id=%d" 549 "MSI::requestUserMedia. request_id=%d"
464 ", audio source id=%s" 550 ", audio source id=%s"
465 ", video source id=%s", 551 ", video source id=%s",
466 request_id, controls->audio.device_id.c_str(), 552 current_request_info_->request_id(),
467 controls->video.device_id.c_str())); 553 current_request_info_->stream_controls()->audio.device_id.c_str(),
554 current_request_info_->stream_controls()->video.device_id.c_str()));
468 555
469 user_media_requests_.push_back(base::MakeUnique<UserMediaRequestInfo>( 556 current_request_info_->set_state(
470 request_id, user_media_request, 557 UserMediaRequestInfo::State::SENT_FOR_GENERATION);
471 request_settings.enable_automatic_audio_output_device_selection));
472
473 media_stream_dispatcher_->GenerateStream( 558 media_stream_dispatcher_->GenerateStream(
474 request_id, weak_factory_.GetWeakPtr(), *controls, 559 current_request_info_->request_id(), weak_factory_.GetWeakPtr(),
475 request_settings.security_origin, 560 *current_request_info_->stream_controls(),
476 request_settings.is_processing_user_gesture); 561 current_request_info_->security_origin(),
562 current_request_info_->is_processing_user_gesture());
477 } 563 }
478 564
479 void UserMediaClientImpl::cancelUserMediaRequest( 565 void UserMediaClientImpl::cancelUserMediaRequest(
480 const blink::WebUserMediaRequest& user_media_request) { 566 const blink::WebUserMediaRequest& user_media_request) {
481 DCHECK(CalledOnValidThread()); 567 DCHECK(CalledOnValidThread());
482 UserMediaRequestInfo* request = FindUserMediaRequestInfo(user_media_request); 568 if (DeleteRequestInfo(user_media_request)) {
483 if (request) {
484 // We can't abort the stream generation process. 569 // We can't abort the stream generation process.
485 // Instead, erase the request. Once the stream is generated we will stop the 570 // Instead, erase the request. Once the stream is generated we will stop the
486 // stream if the request does not exist. 571 // stream if the request does not exist.
487 LogUserMediaRequestWithNoResult(MEDIA_STREAM_REQUEST_EXPLICITLY_CANCELLED); 572 LogUserMediaRequestWithNoResult(MEDIA_STREAM_REQUEST_EXPLICITLY_CANCELLED);
488 DeleteUserMediaRequestInfo(request);
489 } 573 }
490 } 574 }
491 575
492 void UserMediaClientImpl::requestMediaDevices( 576 void UserMediaClientImpl::requestMediaDevices(
493 const blink::WebMediaDevicesRequest& media_devices_request) { 577 const blink::WebMediaDevicesRequest& media_devices_request) {
494 UpdateWebRTCMethodCount(WEBKIT_GET_MEDIA_DEVICES); 578 UpdateWebRTCMethodCount(WEBKIT_GET_MEDIA_DEVICES);
495 DCHECK(CalledOnValidThread()); 579 DCHECK(CalledOnValidThread());
496 580
497 // |media_devices_request| can't be mocked, so in tests it will be empty (the 581 // |media_devices_request| can't be mocked, so in tests it will be empty (the
498 // underlying pointer is null). In order to use this function in a test we 582 // underlying pointer is null). In order to use this function in a test we
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 } 620 }
537 621
538 // Callback from MediaStreamDispatcher. 622 // Callback from MediaStreamDispatcher.
539 // The requested stream have been generated by the MediaStreamDispatcher. 623 // The requested stream have been generated by the MediaStreamDispatcher.
540 void UserMediaClientImpl::OnStreamGenerated( 624 void UserMediaClientImpl::OnStreamGenerated(
541 int request_id, 625 int request_id,
542 const std::string& label, 626 const std::string& label,
543 const StreamDeviceInfoArray& audio_array, 627 const StreamDeviceInfoArray& audio_array,
544 const StreamDeviceInfoArray& video_array) { 628 const StreamDeviceInfoArray& video_array) {
545 DCHECK(CalledOnValidThread()); 629 DCHECK(CalledOnValidThread());
546 DVLOG(1) << "UserMediaClientImpl::OnStreamGenerated stream:" << label; 630 if (!IsCurrentRequestInfo(request_id)) {
547 631 // This can happen if the request is cancelled or the frame reloads while
548 UserMediaRequestInfo* request_info = FindUserMediaRequestInfo(request_id);
549 if (!request_info) {
550 // This can happen if the request is canceled or the frame reloads while
551 // MediaStreamDispatcher is processing the request. 632 // MediaStreamDispatcher is processing the request.
552 DVLOG(1) << "Request ID not found"; 633 DVLOG(1) << "Request ID not found";
553 OnStreamGeneratedForCancelledRequest(audio_array, video_array); 634 OnStreamGeneratedForCancelledRequest(audio_array, video_array);
554 return; 635 return;
555 } 636 }
556 request_info->generated = true; 637 current_request_info_->set_state(UserMediaRequestInfo::State::GENERATED);
557 638
558 for (const auto* array : {&audio_array, &video_array}) { 639 for (const auto* array : {&audio_array, &video_array}) {
559 for (const auto& info : *array) { 640 for (const auto& info : *array) {
560 WebRtcLogMessage(base::StringPrintf("Request %d for device \"%s\"", 641 WebRtcLogMessage(base::StringPrintf("Request %d for device \"%s\"",
561 request_id, 642 request_id,
562 info.device.name.c_str())); 643 info.device.name.c_str()));
563 } 644 }
564 } 645 }
565 646
566 DCHECK(!request_info->request.isNull()); 647 DCHECK(!current_request_info_->request().isNull());
567 blink::WebVector<blink::WebMediaStreamTrack> audio_track_vector( 648 blink::WebVector<blink::WebMediaStreamTrack> audio_track_vector(
568 audio_array.size()); 649 audio_array.size());
569 CreateAudioTracks(audio_array, request_info->request.audioConstraints(), 650 CreateAudioTracks(audio_array,
570 &audio_track_vector, request_info); 651 current_request_info_->request().audioConstraints(),
652 &audio_track_vector);
571 653
572 blink::WebVector<blink::WebMediaStreamTrack> video_track_vector( 654 blink::WebVector<blink::WebMediaStreamTrack> video_track_vector(
573 video_array.size()); 655 video_array.size());
574 CreateVideoTracks(video_array, request_info->request.videoConstraints(), 656 CreateVideoTracks(video_array,
575 &video_track_vector, request_info); 657 current_request_info_->request().videoConstraints(),
658 &video_track_vector);
576 659
577 blink::WebString webkit_id = blink::WebString::fromUTF8(label); 660 blink::WebString blink_id = blink::WebString::fromUTF8(label);
578 blink::WebMediaStream* web_stream = &(request_info->web_stream); 661 current_request_info_->web_stream()->initialize(blink_id, audio_track_vector,
579 662 video_track_vector);
580 web_stream->initialize(webkit_id, audio_track_vector, video_track_vector); 663 current_request_info_->web_stream()->setExtraData(new MediaStream());
581 web_stream->setExtraData(new MediaStream());
582 664
583 // Wait for the tracks to be started successfully or to fail. 665 // Wait for the tracks to be started successfully or to fail.
584 request_info->CallbackOnTracksStarted( 666 current_request_info_->CallbackOnTracksStarted(
585 base::Bind(&UserMediaClientImpl::OnCreateNativeTracksCompleted, 667 base::Bind(&UserMediaClientImpl::OnCreateNativeTracksCompleted,
586 weak_factory_.GetWeakPtr(), label)); 668 weak_factory_.GetWeakPtr(), label));
587 } 669 }
588 670
589 void UserMediaClientImpl::OnStreamGeneratedForCancelledRequest( 671 void UserMediaClientImpl::OnStreamGeneratedForCancelledRequest(
590 const StreamDeviceInfoArray& audio_array, 672 const StreamDeviceInfoArray& audio_array,
591 const StreamDeviceInfoArray& video_array) { 673 const StreamDeviceInfoArray& video_array) {
592 // Only stop the device if the device is not used in another MediaStream. 674 // Only stop the device if the device is not used in another MediaStream.
593 for (StreamDeviceInfoArray::const_iterator device_it = audio_array.begin(); 675 for (StreamDeviceInfoArray::const_iterator device_it = audio_array.begin();
594 device_it != audio_array.end(); ++device_it) { 676 device_it != audio_array.end(); ++device_it) {
(...skipping 29 matching lines...) Expand all
624 for (auto it = pending_local_sources_.begin(); 706 for (auto it = pending_local_sources_.begin();
625 it != pending_local_sources_.end(); ++it) { 707 it != pending_local_sources_.end(); ++it) {
626 MediaStreamSource* const source_extra_data = 708 MediaStreamSource* const source_extra_data =
627 static_cast<MediaStreamSource*>((*it).getExtraData()); 709 static_cast<MediaStreamSource*>((*it).getExtraData());
628 if (source_extra_data != source) 710 if (source_extra_data != source)
629 continue; 711 continue;
630 if (result == MEDIA_DEVICE_OK) 712 if (result == MEDIA_DEVICE_OK)
631 local_sources_.push_back((*it)); 713 local_sources_.push_back((*it));
632 pending_local_sources_.erase(it); 714 pending_local_sources_.erase(it);
633 715
634 NotifyAllRequestsOfAudioSourceStarted(source, result, result_name); 716 NotifyCurrentRequestInfoOfAudioSourceStarted(source, result, result_name);
635 return; 717 return;
636 } 718 }
637 NOTREACHED(); 719 NOTREACHED();
638 } 720 }
639 721
640 void UserMediaClientImpl::NotifyAllRequestsOfAudioSourceStarted( 722 void UserMediaClientImpl::NotifyCurrentRequestInfoOfAudioSourceStarted(
641 MediaStreamSource* source, 723 MediaStreamSource* source,
642 MediaStreamRequestResult result, 724 MediaStreamRequestResult result,
643 const blink::WebString& result_name) { 725 const blink::WebString& result_name) {
644 // Since a request object that receives the OnAudioSourceStarted event, 726 // The only request possibly being processed is |current_request_info_|.
645 // might get deleted and removed from the |user_media_requests_| array while 727 if (current_request_info_)
646 // we iterate through it, we need to jump through this hoop here, copy 728 current_request_info_->OnAudioSourceStarted(source, result, result_name);
647 // pointers to the objects we're notifying and avoid using
648 // user_media_requests_ as we iterate+notify.
649 std::vector<UserMediaRequestInfo*> requests;
650 requests.reserve(user_media_requests_.size());
651 for (const auto& request : user_media_requests_)
652 requests.push_back(request.get());
653 for (auto* request : requests)
654 request->OnAudioSourceStarted(source, result, result_name);
655 } 729 }
656 730
657 void UserMediaClientImpl::FinalizeEnumerateDevices( 731 void UserMediaClientImpl::FinalizeEnumerateDevices(
658 blink::WebMediaDevicesRequest request, 732 blink::WebMediaDevicesRequest request,
659 const EnumerationResult& result) { 733 const EnumerationResult& result) {
660 DCHECK_EQ(static_cast<size_t>(NUM_MEDIA_DEVICE_TYPES), result.size()); 734 DCHECK_EQ(static_cast<size_t>(NUM_MEDIA_DEVICE_TYPES), result.size());
661 735
662 blink::WebVector<blink::WebMediaDeviceInfo> devices( 736 blink::WebVector<blink::WebMediaDeviceInfo> devices(
663 result[MEDIA_DEVICE_TYPE_AUDIO_INPUT].size() + 737 result[MEDIA_DEVICE_TYPE_AUDIO_INPUT].size() +
664 result[MEDIA_DEVICE_TYPE_VIDEO_INPUT].size() + 738 result[MEDIA_DEVICE_TYPE_VIDEO_INPUT].size() +
(...skipping 12 matching lines...) Expand all
677 751
678 EnumerateDevicesSucceded(&request, devices); 752 EnumerateDevicesSucceded(&request, devices);
679 } 753 }
680 754
681 // Callback from MediaStreamDispatcher. 755 // Callback from MediaStreamDispatcher.
682 // The requested stream failed to be generated. 756 // The requested stream failed to be generated.
683 void UserMediaClientImpl::OnStreamGenerationFailed( 757 void UserMediaClientImpl::OnStreamGenerationFailed(
684 int request_id, 758 int request_id,
685 MediaStreamRequestResult result) { 759 MediaStreamRequestResult result) {
686 DCHECK(CalledOnValidThread()); 760 DCHECK(CalledOnValidThread());
687 DVLOG(1) << "UserMediaClientImpl::OnStreamGenerationFailed(" 761 if (!IsCurrentRequestInfo(request_id)) {
688 << request_id << ")"; 762 // This can happen if the request is cancelled or the frame reloads while
689 UserMediaRequestInfo* request_info = FindUserMediaRequestInfo(request_id);
690 if (!request_info) {
691 // This can happen if the request is canceled or the frame reloads while
692 // MediaStreamDispatcher is processing the request. 763 // MediaStreamDispatcher is processing the request.
693 DVLOG(1) << "Request ID not found";
694 return; 764 return;
695 } 765 }
696 766
697 GetUserMediaRequestFailed(request_info->request, result, ""); 767 GetUserMediaRequestFailed(current_request_info_->request(), result, "");
698 DeleteUserMediaRequestInfo(request_info); 768 DeleteRequestInfo(current_request_info_->request());
699 } 769 }
700 770
701 // Callback from MediaStreamDispatcher. 771 // Callback from MediaStreamDispatcher.
702 // The browser process has stopped a device used by a MediaStream. 772 // The browser process has stopped a device used by a MediaStream.
703 void UserMediaClientImpl::OnDeviceStopped( 773 void UserMediaClientImpl::OnDeviceStopped(
704 const std::string& label, 774 const std::string& label,
705 const StreamDeviceInfo& device_info) { 775 const StreamDeviceInfo& device_info) {
706 DCHECK(CalledOnValidThread()); 776 DCHECK(CalledOnValidThread());
707 DVLOG(1) << "UserMediaClientImpl::OnDeviceStopped(" 777 DVLOG(1) << "UserMediaClientImpl::OnDeviceStopped("
708 << "{device_id = " << device_info.device.id << "})"; 778 << "{device_id = " << device_info.device.id << "})";
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
802 DCHECK(CalledOnValidThread()); 872 DCHECK(CalledOnValidThread());
803 content::MediaStreamVideoCapturerSource* ret = 873 content::MediaStreamVideoCapturerSource* ret =
804 new content::MediaStreamVideoCapturerSource(stop_callback, device, 874 new content::MediaStreamVideoCapturerSource(stop_callback, device,
805 render_frame()); 875 render_frame());
806 return ret; 876 return ret;
807 } 877 }
808 878
809 void UserMediaClientImpl::CreateVideoTracks( 879 void UserMediaClientImpl::CreateVideoTracks(
810 const StreamDeviceInfoArray& devices, 880 const StreamDeviceInfoArray& devices,
811 const blink::WebMediaConstraints& constraints, 881 const blink::WebMediaConstraints& constraints,
812 blink::WebVector<blink::WebMediaStreamTrack>* webkit_tracks, 882 blink::WebVector<blink::WebMediaStreamTrack>* webkit_tracks) {
813 UserMediaRequestInfo* request) {
814 DCHECK(CalledOnValidThread()); 883 DCHECK(CalledOnValidThread());
884 DCHECK(current_request_info_);
815 DCHECK_EQ(devices.size(), webkit_tracks->size()); 885 DCHECK_EQ(devices.size(), webkit_tracks->size());
816 886
817 for (size_t i = 0; i < devices.size(); ++i) { 887 for (size_t i = 0; i < devices.size(); ++i) {
818 blink::WebMediaStreamSource source = 888 blink::WebMediaStreamSource source =
819 InitializeVideoSourceObject(devices[i], constraints); 889 InitializeVideoSourceObject(devices[i], constraints);
820 (*webkit_tracks)[i] = 890 (*webkit_tracks)[i] =
821 request->CreateAndStartVideoTrack(source, constraints); 891 current_request_info_->CreateAndStartVideoTrack(source, constraints);
822 } 892 }
823 } 893 }
824 894
825 void UserMediaClientImpl::CreateAudioTracks( 895 void UserMediaClientImpl::CreateAudioTracks(
826 const StreamDeviceInfoArray& devices, 896 const StreamDeviceInfoArray& devices,
827 const blink::WebMediaConstraints& constraints, 897 const blink::WebMediaConstraints& constraints,
828 blink::WebVector<blink::WebMediaStreamTrack>* webkit_tracks, 898 blink::WebVector<blink::WebMediaStreamTrack>* webkit_tracks) {
829 UserMediaRequestInfo* request) {
830 DCHECK(CalledOnValidThread()); 899 DCHECK(CalledOnValidThread());
900 DCHECK(current_request_info_);
831 DCHECK_EQ(devices.size(), webkit_tracks->size()); 901 DCHECK_EQ(devices.size(), webkit_tracks->size());
832 902
833 StreamDeviceInfoArray overridden_audio_array = devices; 903 StreamDeviceInfoArray overridden_audio_array = devices;
834 if (!request->enable_automatic_output_device_selection) { 904 if (!current_request_info_->enable_automatic_output_device_selection()) {
835 // If the GetUserMedia request did not explicitly set the constraint 905 // If the GetUserMedia request did not explicitly set the constraint
836 // kMediaStreamRenderToAssociatedSink, the output device parameters must 906 // kMediaStreamRenderToAssociatedSink, the output device parameters must
837 // be removed. 907 // be removed.
838 for (auto& device_info : overridden_audio_array) { 908 for (auto& device_info : overridden_audio_array) {
839 device_info.device.matched_output_device_id = ""; 909 device_info.device.matched_output_device_id = "";
840 device_info.device.matched_output = 910 device_info.device.matched_output =
841 MediaStreamDevice::AudioDeviceParameters(); 911 MediaStreamDevice::AudioDeviceParameters();
842 } 912 }
843 } 913 }
844 914
845 for (size_t i = 0; i < overridden_audio_array.size(); ++i) { 915 for (size_t i = 0; i < overridden_audio_array.size(); ++i) {
846 bool is_pending = false; 916 bool is_pending = false;
847 blink::WebMediaStreamSource source = InitializeAudioSourceObject( 917 blink::WebMediaStreamSource source = InitializeAudioSourceObject(
848 overridden_audio_array[i], constraints, &is_pending); 918 overridden_audio_array[i], constraints, &is_pending);
849 (*webkit_tracks)[i].initialize(source); 919 (*webkit_tracks)[i].initialize(source);
850 request->StartAudioTrack((*webkit_tracks)[i], is_pending); 920 current_request_info_->StartAudioTrack((*webkit_tracks)[i], is_pending);
851 } 921 }
852 } 922 }
853 923
854 void UserMediaClientImpl::OnCreateNativeTracksCompleted( 924 void UserMediaClientImpl::OnCreateNativeTracksCompleted(
855 const std::string& label, 925 const std::string& label,
856 UserMediaRequestInfo* request, 926 UserMediaRequestInfo* request_info,
857 MediaStreamRequestResult result, 927 MediaStreamRequestResult result,
858 const blink::WebString& result_name) { 928 const blink::WebString& result_name) {
859 DCHECK(CalledOnValidThread()); 929 DCHECK(CalledOnValidThread());
860 DVLOG(1) << "UserMediaClientImpl::OnCreateNativeTracksComplete("
861 << "{request_id = " << request->request_id << "} "
862 << "{result = " << result << "})";
863
864 if (result == content::MEDIA_DEVICE_OK) { 930 if (result == content::MEDIA_DEVICE_OK) {
865 GetUserMediaRequestSucceeded(request->web_stream, request->request); 931 GetUserMediaRequestSucceeded(*request_info->web_stream(),
932 request_info->request());
866 media_stream_dispatcher_->OnStreamStarted(label); 933 media_stream_dispatcher_->OnStreamStarted(label);
867 } else { 934 } else {
868 GetUserMediaRequestFailed(request->request, result, result_name); 935 GetUserMediaRequestFailed(request_info->request(), result, result_name);
869 936
870 blink::WebVector<blink::WebMediaStreamTrack> tracks; 937 blink::WebVector<blink::WebMediaStreamTrack> tracks;
871 request->web_stream.audioTracks(tracks); 938 request_info->web_stream()->audioTracks(tracks);
872 for (auto& web_track : tracks) { 939 for (auto& web_track : tracks) {
873 MediaStreamTrack* track = MediaStreamTrack::GetTrack(web_track); 940 MediaStreamTrack* track = MediaStreamTrack::GetTrack(web_track);
874 if (track) 941 if (track)
875 track->Stop(); 942 track->Stop();
876 } 943 }
877 request->web_stream.videoTracks(tracks); 944 request_info->web_stream()->videoTracks(tracks);
878 for (auto& web_track : tracks) { 945 for (auto& web_track : tracks) {
879 MediaStreamTrack* track = MediaStreamTrack::GetTrack(web_track); 946 MediaStreamTrack* track = MediaStreamTrack::GetTrack(web_track);
880 if (track) 947 if (track)
881 track->Stop(); 948 track->Stop();
882 } 949 }
883 } 950 }
884 951
885 DeleteUserMediaRequestInfo(request); 952 DeleteRequestInfo(request_info->request());
886 } 953 }
887 954
888 void UserMediaClientImpl::OnDeviceOpened( 955 void UserMediaClientImpl::OnDeviceOpened(
889 int request_id, 956 int request_id,
890 const std::string& label, 957 const std::string& label,
891 const StreamDeviceInfo& video_device) { 958 const StreamDeviceInfo& video_device) {
892 DVLOG(1) << "UserMediaClientImpl::OnDeviceOpened(" 959 DVLOG(1) << "UserMediaClientImpl::OnDeviceOpened("
893 << request_id << ", " << label << ")"; 960 << request_id << ", " << label << ")";
894 NOTIMPLEMENTED(); 961 NOTIMPLEMENTED();
895 } 962 }
896 963
897 void UserMediaClientImpl::OnDeviceOpenFailed(int request_id) { 964 void UserMediaClientImpl::OnDeviceOpenFailed(int request_id) {
898 DVLOG(1) << "UserMediaClientImpl::VideoDeviceOpenFailed(" 965 DVLOG(1) << "UserMediaClientImpl::VideoDeviceOpenFailed("
899 << request_id << ")"; 966 << request_id << ")";
900 NOTIMPLEMENTED(); 967 NOTIMPLEMENTED();
901 } 968 }
902 969
903 void UserMediaClientImpl::DevicesChanged( 970 void UserMediaClientImpl::DevicesChanged(
904 MediaDeviceType type, 971 MediaDeviceType type,
905 const MediaDeviceInfoArray& device_infos) { 972 const MediaDeviceInfoArray& device_infos) {
906 if (!media_device_change_observer_.isNull()) 973 if (!media_device_change_observer_.isNull())
907 media_device_change_observer_.didChangeMediaDevices(); 974 media_device_change_observer_.didChangeMediaDevices();
908 } 975 }
909 976
910 void UserMediaClientImpl::GetUserMediaRequestSucceeded( 977 void UserMediaClientImpl::GetUserMediaRequestSucceeded(
911 const blink::WebMediaStream& stream, 978 const blink::WebMediaStream& stream,
912 blink::WebUserMediaRequest request_info) { 979 blink::WebUserMediaRequest request) {
913 // Completing the getUserMedia request can lead to that the RenderFrame and 980 // Completing the getUserMedia request can lead to that the RenderFrame and
914 // the UserMediaClientImpl is destroyed if the JavaScript code request the 981 // the UserMediaClientImpl is destroyed if the JavaScript code request the
915 // frame to be destroyed within the scope of the callback. Therefore, 982 // frame to be destroyed within the scope of the callback. Therefore,
916 // post a task to complete the request with a clean stack. 983 // post a task to complete the request with a clean stack.
917 base::ThreadTaskRunnerHandle::Get()->PostTask( 984 base::ThreadTaskRunnerHandle::Get()->PostTask(
918 FROM_HERE, 985 FROM_HERE,
919 base::Bind(&UserMediaClientImpl::DelayedGetUserMediaRequestSucceeded, 986 base::Bind(&UserMediaClientImpl::DelayedGetUserMediaRequestSucceeded,
920 weak_factory_.GetWeakPtr(), stream, request_info)); 987 weak_factory_.GetWeakPtr(), stream, request));
921 } 988 }
922 989
923 void UserMediaClientImpl::DelayedGetUserMediaRequestSucceeded( 990 void UserMediaClientImpl::DelayedGetUserMediaRequestSucceeded(
924 const blink::WebMediaStream& stream, 991 const blink::WebMediaStream& stream,
925 blink::WebUserMediaRequest request_info) { 992 blink::WebUserMediaRequest request) {
926 DVLOG(1) << "UserMediaClientImpl::DelayedGetUserMediaRequestSucceeded"; 993 DVLOG(1) << "UserMediaClientImpl::DelayedGetUserMediaRequestSucceeded";
927 LogUserMediaRequestResult(MEDIA_DEVICE_OK); 994 LogUserMediaRequestResult(MEDIA_DEVICE_OK);
928 request_info.requestSucceeded(stream); 995 DeleteRequestInfo(request);
996 request.requestSucceeded(stream);
929 } 997 }
930 998
931 void UserMediaClientImpl::GetUserMediaRequestFailed( 999 void UserMediaClientImpl::GetUserMediaRequestFailed(
932 blink::WebUserMediaRequest request_info, 1000 blink::WebUserMediaRequest request,
933 MediaStreamRequestResult result, 1001 MediaStreamRequestResult result,
934 const blink::WebString& result_name) { 1002 const blink::WebString& result_name) {
935 // Completing the getUserMedia request can lead to that the RenderFrame and 1003 // Completing the getUserMedia request can lead to that the RenderFrame and
936 // the UserMediaClientImpl is destroyed if the JavaScript code request the 1004 // the UserMediaClientImpl is destroyed if the JavaScript code request the
937 // frame to be destroyed within the scope of the callback. Therefore, 1005 // frame to be destroyed within the scope of the callback. Therefore,
938 // post a task to complete the request with a clean stack. 1006 // post a task to complete the request with a clean stack.
939 base::ThreadTaskRunnerHandle::Get()->PostTask( 1007 base::ThreadTaskRunnerHandle::Get()->PostTask(
940 FROM_HERE, 1008 FROM_HERE,
941 base::Bind(&UserMediaClientImpl::DelayedGetUserMediaRequestFailed, 1009 base::Bind(&UserMediaClientImpl::DelayedGetUserMediaRequestFailed,
942 weak_factory_.GetWeakPtr(), request_info, result, 1010 weak_factory_.GetWeakPtr(), request, result, result_name));
943 result_name));
944 } 1011 }
945 1012
946 void UserMediaClientImpl::DelayedGetUserMediaRequestFailed( 1013 void UserMediaClientImpl::DelayedGetUserMediaRequestFailed(
947 blink::WebUserMediaRequest request_info, 1014 blink::WebUserMediaRequest request,
948 MediaStreamRequestResult result, 1015 MediaStreamRequestResult result,
949 const blink::WebString& result_name) { 1016 const blink::WebString& result_name) {
950 LogUserMediaRequestResult(result); 1017 LogUserMediaRequestResult(result);
1018 DeleteRequestInfo(request);
951 switch (result) { 1019 switch (result) {
952 case MEDIA_DEVICE_OK: 1020 case MEDIA_DEVICE_OK:
953 case NUM_MEDIA_REQUEST_RESULTS: 1021 case NUM_MEDIA_REQUEST_RESULTS:
954 NOTREACHED(); 1022 NOTREACHED();
955 return; 1023 return;
956 case MEDIA_DEVICE_PERMISSION_DENIED: 1024 case MEDIA_DEVICE_PERMISSION_DENIED:
957 request_info.requestDenied(); 1025 request.requestDenied();
958 return; 1026 return;
959 case MEDIA_DEVICE_PERMISSION_DISMISSED: 1027 case MEDIA_DEVICE_PERMISSION_DISMISSED:
960 request_info.requestFailedUASpecific("PermissionDismissedError"); 1028 request.requestFailedUASpecific("PermissionDismissedError");
961 return; 1029 return;
962 case MEDIA_DEVICE_INVALID_STATE: 1030 case MEDIA_DEVICE_INVALID_STATE:
963 request_info.requestFailedUASpecific("InvalidStateError"); 1031 request.requestFailedUASpecific("InvalidStateError");
964 return; 1032 return;
965 case MEDIA_DEVICE_NO_HARDWARE: 1033 case MEDIA_DEVICE_NO_HARDWARE:
966 request_info.requestFailedUASpecific("DevicesNotFoundError"); 1034 request.requestFailedUASpecific("DevicesNotFoundError");
967 return; 1035 return;
968 case MEDIA_DEVICE_INVALID_SECURITY_ORIGIN: 1036 case MEDIA_DEVICE_INVALID_SECURITY_ORIGIN:
969 request_info.requestFailedUASpecific("InvalidSecurityOriginError"); 1037 request.requestFailedUASpecific("InvalidSecurityOriginError");
970 return; 1038 return;
971 case MEDIA_DEVICE_TAB_CAPTURE_FAILURE: 1039 case MEDIA_DEVICE_TAB_CAPTURE_FAILURE:
972 request_info.requestFailedUASpecific("TabCaptureError"); 1040 request.requestFailedUASpecific("TabCaptureError");
973 return; 1041 return;
974 case MEDIA_DEVICE_SCREEN_CAPTURE_FAILURE: 1042 case MEDIA_DEVICE_SCREEN_CAPTURE_FAILURE:
975 request_info.requestFailedUASpecific("ScreenCaptureError"); 1043 request.requestFailedUASpecific("ScreenCaptureError");
976 return; 1044 return;
977 case MEDIA_DEVICE_CAPTURE_FAILURE: 1045 case MEDIA_DEVICE_CAPTURE_FAILURE:
978 request_info.requestFailedUASpecific("DeviceCaptureError"); 1046 request.requestFailedUASpecific("DeviceCaptureError");
979 return; 1047 return;
980 case MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED: 1048 case MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED:
981 request_info.requestFailedConstraint(result_name); 1049 request.requestFailedConstraint(result_name);
982 return; 1050 return;
983 case MEDIA_DEVICE_TRACK_START_FAILURE: 1051 case MEDIA_DEVICE_TRACK_START_FAILURE:
984 request_info.requestFailedUASpecific("TrackStartError"); 1052 request.requestFailedUASpecific("TrackStartError");
985 return; 1053 return;
986 case MEDIA_DEVICE_NOT_SUPPORTED: 1054 case MEDIA_DEVICE_NOT_SUPPORTED:
987 request_info.requestFailedUASpecific("MediaDeviceNotSupported"); 1055 request.requestFailedUASpecific("MediaDeviceNotSupported");
988 return; 1056 return;
989 case MEDIA_DEVICE_FAILED_DUE_TO_SHUTDOWN: 1057 case MEDIA_DEVICE_FAILED_DUE_TO_SHUTDOWN:
990 request_info.requestFailedUASpecific("MediaDeviceFailedDueToShutdown"); 1058 request.requestFailedUASpecific("MediaDeviceFailedDueToShutdown");
991 return; 1059 return;
992 case MEDIA_DEVICE_KILL_SWITCH_ON: 1060 case MEDIA_DEVICE_KILL_SWITCH_ON:
993 request_info.requestFailedUASpecific("MediaDeviceKillSwitchOn"); 1061 request.requestFailedUASpecific("MediaDeviceKillSwitchOn");
994 return; 1062 return;
995 } 1063 }
996 NOTREACHED(); 1064 NOTREACHED();
997 request_info.requestFailed(); 1065 request.requestFailed();
998 } 1066 }
999 1067
1000 void UserMediaClientImpl::EnumerateDevicesSucceded( 1068 void UserMediaClientImpl::EnumerateDevicesSucceded(
1001 blink::WebMediaDevicesRequest* request, 1069 blink::WebMediaDevicesRequest* request,
1002 blink::WebVector<blink::WebMediaDeviceInfo>& devices) { 1070 blink::WebVector<blink::WebMediaDeviceInfo>& devices) {
1003 request->requestSucceeded(devices); 1071 request->requestSucceeded(devices);
1004 } 1072 }
1005 1073
1006 const blink::WebMediaStreamSource* UserMediaClientImpl::FindLocalSource( 1074 const blink::WebMediaStreamSource* UserMediaClientImpl::FindLocalSource(
1007 const LocalStreamSources& sources, 1075 const LocalStreamSources& sources,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1051 return true; 1119 return true;
1052 } 1120 }
1053 } 1121 }
1054 1122
1055 // Check if the source was pending. 1123 // Check if the source was pending.
1056 for (LocalStreamSources::iterator device_it = pending_local_sources_.begin(); 1124 for (LocalStreamSources::iterator device_it = pending_local_sources_.begin();
1057 device_it != pending_local_sources_.end(); ++device_it) { 1125 device_it != pending_local_sources_.end(); ++device_it) {
1058 if (IsSameSource(*device_it, source)) { 1126 if (IsSameSource(*device_it, source)) {
1059 MediaStreamSource* const source_extra_data = 1127 MediaStreamSource* const source_extra_data =
1060 static_cast<MediaStreamSource*>(source.getExtraData()); 1128 static_cast<MediaStreamSource*>(source.getExtraData());
1061 NotifyAllRequestsOfAudioSourceStarted( 1129 NotifyCurrentRequestInfoOfAudioSourceStarted(
1062 source_extra_data, MEDIA_DEVICE_TRACK_START_FAILURE, 1130 source_extra_data, MEDIA_DEVICE_TRACK_START_FAILURE,
1063 "Failed to access audio capture device"); 1131 "Failed to access audio capture device");
1064 pending_local_sources_.erase(device_it); 1132 pending_local_sources_.erase(device_it);
1065 return true; 1133 return true;
1066 } 1134 }
1067 } 1135 }
1068 1136
1069 return false; 1137 return false;
1070 } 1138 }
1071 1139
1072 UserMediaClientImpl::UserMediaRequestInfo* 1140 bool UserMediaClientImpl::IsCurrentRequestInfo(int request_id) const {
1073 UserMediaClientImpl::FindUserMediaRequestInfo(int request_id) {
1074 DCHECK(CalledOnValidThread()); 1141 DCHECK(CalledOnValidThread());
1075 for (auto& r : user_media_requests_) { 1142 return current_request_info_ &&
1076 if (r->request_id == request_id) 1143 current_request_info_->request_id() == request_id;
1077 return r.get();
1078 }
1079 return nullptr;
1080 } 1144 }
1081 1145
1082 UserMediaClientImpl::UserMediaRequestInfo* 1146 bool UserMediaClientImpl::IsCurrentRequestInfo(
1083 UserMediaClientImpl::FindUserMediaRequestInfo( 1147 const blink::WebUserMediaRequest& request) const {
1084 const blink::WebUserMediaRequest& request) {
1085 DCHECK(CalledOnValidThread()); 1148 DCHECK(CalledOnValidThread());
1086 for (auto& r : user_media_requests_) { 1149 return current_request_info_ && current_request_info_->request() == request;
1087 if (r->request == request)
1088 return r.get();
1089 }
1090 return nullptr;
1091 } 1150 }
1092 1151
1093 void UserMediaClientImpl::DeleteUserMediaRequestInfo( 1152 bool UserMediaClientImpl::DeleteRequestInfo(
1094 UserMediaRequestInfo* request) { 1153 const blink::WebUserMediaRequest& user_media_request) {
1095 DCHECK(CalledOnValidThread()); 1154 DCHECK(CalledOnValidThread());
1096 auto new_end = 1155 if (current_request_info_ &&
1097 std::remove_if(user_media_requests_.begin(), user_media_requests_.end(), 1156 current_request_info_->request() == user_media_request) {
1098 [&](std::unique_ptr<UserMediaRequestInfo>& r) { 1157 current_request_info_.reset();
1099 return r.get() == request; 1158 if (!pending_request_infos_.empty()) {
1100 }); 1159 base::ThreadTaskRunnerHandle::Get()->PostTask(
1101 DCHECK(new_end != user_media_requests_.end()); 1160 FROM_HERE,
1102 user_media_requests_.erase(new_end, user_media_requests_.end()); 1161 base::Bind(&UserMediaClientImpl::MaybeProcessNextRequestInfo,
1162 weak_factory_.GetWeakPtr()));
1163 }
1164 return true;
1165 }
1166
1167 for (auto it = pending_request_infos_.begin();
1168 it != pending_request_infos_.end(); ++it) {
1169 if ((*it)->request() == user_media_request) {
1170 pending_request_infos_.erase(it);
1171 return true;
1172 }
1173 }
1174
1175 return false;
1103 } 1176 }
1104 1177
1105 void UserMediaClientImpl::DeleteAllUserMediaRequests() { 1178 void UserMediaClientImpl::DeleteAllUserMediaRequests() {
1106 UserMediaRequests::iterator request_it = user_media_requests_.begin(); 1179 if (current_request_info_) {
1107 while (request_it != user_media_requests_.end()) {
1108 DVLOG(1) << "UserMediaClientImpl@" << this
1109 << "::DeleteAllUserMediaRequests: "
1110 << "Cancel user media request " << (*request_it)->request_id;
1111 // If the request is not generated, it means that a request 1180 // If the request is not generated, it means that a request
1112 // has been sent to the MediaStreamDispatcher to generate a stream 1181 // has been sent to the MediaStreamDispatcher to generate a stream
1113 // but MediaStreamDispatcher has not yet responded and we need to cancel 1182 // but MediaStreamDispatcher has not yet responded and we need to cancel
1114 // the request. 1183 // the request.
1115 if (!(*request_it)->generated) { 1184 if (current_request_info_->state() ==
1116 DCHECK(!(*request_it)->HasPendingSources()); 1185 UserMediaRequestInfo::State::GENERATED) {
1117 media_stream_dispatcher_->CancelGenerateStream( 1186 DCHECK(current_request_info_->HasPendingSources());
1118 (*request_it)->request_id, weak_factory_.GetWeakPtr());
1119 LogUserMediaRequestWithNoResult(MEDIA_STREAM_REQUEST_NOT_GENERATED);
1120 } else {
1121 DCHECK((*request_it)->HasPendingSources());
1122 LogUserMediaRequestWithNoResult( 1187 LogUserMediaRequestWithNoResult(
1123 MEDIA_STREAM_REQUEST_PENDING_MEDIA_TRACKS); 1188 MEDIA_STREAM_REQUEST_PENDING_MEDIA_TRACKS);
1189 } else {
1190 DCHECK(!current_request_info_->HasPendingSources());
1191 if (current_request_info_->state() ==
1192 UserMediaRequestInfo::State::SENT_FOR_GENERATION) {
1193 media_stream_dispatcher_->CancelGenerateStream(
1194 current_request_info_->request_id(), weak_factory_.GetWeakPtr());
1195 }
1196 LogUserMediaRequestWithNoResult(MEDIA_STREAM_REQUEST_NOT_GENERATED);
1124 } 1197 }
1125 request_it = user_media_requests_.erase(request_it); 1198 current_request_info_.reset();
1199 pending_request_infos_.clear();
1126 } 1200 }
1127 } 1201 }
1128 1202
1129 void UserMediaClientImpl::WillCommitProvisionalLoad() { 1203 void UserMediaClientImpl::WillCommitProvisionalLoad() {
1130 // Cancel all outstanding UserMediaRequests. 1204 // Cancel all outstanding UserMediaRequests.
1131 DeleteAllUserMediaRequests(); 1205 DeleteAllUserMediaRequests();
1132 1206
1133 // Loop through all current local sources and stop the sources. 1207 // Loop through all current local sources and stop the sources.
1134 LocalStreamSources::iterator sources_it = local_sources_.begin(); 1208 LocalStreamSources::iterator sources_it = local_sources_.begin();
1135 while (sources_it != local_sources_.end()) { 1209 while (sources_it != local_sources_.end()) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1174 const ::mojom::MediaDevicesDispatcherHostPtr& 1248 const ::mojom::MediaDevicesDispatcherHostPtr&
1175 UserMediaClientImpl::GetMediaDevicesDispatcher() { 1249 UserMediaClientImpl::GetMediaDevicesDispatcher() {
1176 if (!media_devices_dispatcher_) { 1250 if (!media_devices_dispatcher_) {
1177 render_frame()->GetRemoteInterfaces()->GetInterface( 1251 render_frame()->GetRemoteInterfaces()->GetInterface(
1178 mojo::MakeRequest(&media_devices_dispatcher_)); 1252 mojo::MakeRequest(&media_devices_dispatcher_));
1179 } 1253 }
1180 1254
1181 return media_devices_dispatcher_; 1255 return media_devices_dispatcher_;
1182 } 1256 }
1183 1257
1258 base::Optional<bool>
1259 UserMediaClientImpl::AutomaticOutputDeviceSelectionEnabledForCurrentRequest() {
1260 if (!current_request_info_)
1261 return base::Optional<bool>();
1262
1263 return base::Optional<bool>(
1264 current_request_info_->enable_automatic_output_device_selection());
1265 }
1266
1267 void UserMediaClientImpl::OnDestruct() {
1268 delete this;
1269 }
1270
1184 UserMediaClientImpl::UserMediaRequestInfo::UserMediaRequestInfo( 1271 UserMediaClientImpl::UserMediaRequestInfo::UserMediaRequestInfo(
1185 int request_id, 1272 int request_id,
1186 const blink::WebUserMediaRequest& request, 1273 const blink::WebUserMediaRequest& request,
1187 bool enable_automatic_output_device_selection) 1274 bool is_processing_user_gesture,
1188 : request_id(request_id), 1275 const url::Origin& security_origin)
1189 generated(false), 1276 : request_id_(request_id),
1190 enable_automatic_output_device_selection( 1277 state_(State::NOT_SENT_FOR_GENERATION),
1191 enable_automatic_output_device_selection), 1278 enable_automatic_output_device_selection_(false),
1192 request(request), 1279 request_(request),
1280 is_processing_user_gesture_(is_processing_user_gesture),
1281 security_origin_(security_origin),
1193 request_result_(MEDIA_DEVICE_OK), 1282 request_result_(MEDIA_DEVICE_OK),
1194 request_result_name_("") { 1283 request_result_name_("") {}
1195 }
1196
1197 UserMediaClientImpl::UserMediaRequestInfo::~UserMediaRequestInfo() {
1198 DVLOG(1) << "~UserMediaRequestInfo";
1199 }
1200 1284
1201 void UserMediaClientImpl::UserMediaRequestInfo::StartAudioTrack( 1285 void UserMediaClientImpl::UserMediaRequestInfo::StartAudioTrack(
1202 const blink::WebMediaStreamTrack& track, 1286 const blink::WebMediaStreamTrack& track,
1203 bool is_pending) { 1287 bool is_pending) {
1204 DCHECK(track.source().getType() == blink::WebMediaStreamSource::TypeAudio); 1288 DCHECK(track.source().getType() == blink::WebMediaStreamSource::TypeAudio);
1205 MediaStreamAudioSource* native_source = 1289 MediaStreamAudioSource* native_source =
1206 MediaStreamAudioSource::From(track.source()); 1290 MediaStreamAudioSource::From(track.source());
1207 // Add the source as pending since OnTrackStarted will expect it to be there. 1291 // Add the source as pending since OnTrackStarted will expect it to be there.
1208 sources_waiting_for_callback_.push_back(native_source); 1292 sources_waiting_for_callback_.push_back(native_source);
1209 1293
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1277 MediaStreamRequestResult result, 1361 MediaStreamRequestResult result,
1278 const blink::WebString& result_name) { 1362 const blink::WebString& result_name) {
1279 // Check if we're waiting to be notified of this source. If not, then we'll 1363 // Check if we're waiting to be notified of this source. If not, then we'll
1280 // ignore the notification. 1364 // ignore the notification.
1281 auto found = std::find(sources_waiting_for_callback_.begin(), 1365 auto found = std::find(sources_waiting_for_callback_.begin(),
1282 sources_waiting_for_callback_.end(), source); 1366 sources_waiting_for_callback_.end(), source);
1283 if (found != sources_waiting_for_callback_.end()) 1367 if (found != sources_waiting_for_callback_.end())
1284 OnTrackStarted(source, result, result_name); 1368 OnTrackStarted(source, result, result_name);
1285 } 1369 }
1286 1370
1287 void UserMediaClientImpl::OnDestruct() {
1288 delete this;
1289 }
1290
1291 } // namespace content 1371 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/user_media_client_impl.h ('k') | content/renderer/media/user_media_client_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698