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

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

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