Commit 9be2d95a authored by Guido Urdaneta's avatar Guido Urdaneta Committed by Commit Bot

[getUserMedia] Introduce timeout for video format queries.

This CL causes getUserMedia() to fail if requesting video formats
exceeds a timeout.
This is suspect of causing getUserMedia() hangs in some environments
such as virtual machines.

Drive-by: Add some comments, a thread check, and some extra WebRTC
logging.

Bug: 1044974
Change-Id: I87f7687c491b4a502f4dba57d2c57bc53cb81390
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2015249Reviewed-by: default avatarArmando Miraglia <armax@chromium.org>
Commit-Queue: Guido Urdaneta <guidou@chromium.org>
Cr-Commit-Position: refs/heads/master@{#734493}
parent 74db4e2a
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "media/base/audio_parameters.h" #include "media/base/audio_parameters.h"
#include "media/capture/video_capture_types.h" #include "media/capture/video_capture_types.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/common/browser_interface_broker_proxy.h"
...@@ -45,6 +46,7 @@ ...@@ -45,6 +46,7 @@
#include "third_party/blink/renderer/platform/mediastream/media_constraints.h" #include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h"
#include "third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms.h" #include "third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h" #include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/video_capture/local_video_capturer_source.h" #include "third_party/blink/renderer/platform/video_capture/local_video_capturer_source.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h" #include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
...@@ -150,12 +152,14 @@ std::string GetTrackSourceLogString(blink::MediaStreamAudioSource* source) { ...@@ -150,12 +152,14 @@ std::string GetTrackSourceLogString(blink::MediaStreamAudioSource* source) {
} }
std::string GetOnTrackStartedLogString( std::string GetOnTrackStartedLogString(
int request_id,
blink::WebPlatformMediaStreamSource* source, blink::WebPlatformMediaStreamSource* source,
MediaStreamRequestResult result) { MediaStreamRequestResult result) {
const MediaStreamDevice& device = source->device(); const MediaStreamDevice& device = source->device();
String str = String::Format("OnTrackStarted({session_id=%s}, {result=%s})", String str = String::Format(
device.session_id().ToString().c_str(), "OnTrackStarted({request_id=%d}, {session_id=%s}, {result=%s})",
MediaStreamRequestResultToString(result)); request_id, device.session_id().ToString().c_str(),
MediaStreamRequestResultToString(result));
return str.Utf8(); return str.Utf8();
} }
...@@ -314,6 +318,11 @@ Vector<blink::VideoInputDeviceCapabilities> ToVideoInputDeviceCapabilities( ...@@ -314,6 +318,11 @@ Vector<blink::VideoInputDeviceCapabilities> ToVideoInputDeviceCapabilities(
} // namespace } // namespace
// This timeout must be long enough to eliminate the possibility
// of false-positive timeouts.
const static base::TimeDelta kVideoInputFormatsTimeout =
base::TimeDelta::FromSeconds(45);
UserMediaRequestInfo::UserMediaRequestInfo( UserMediaRequestInfo::UserMediaRequestInfo(
int request_id, int request_id,
const blink::WebUserMediaRequest& web_request, const blink::WebUserMediaRequest& web_request,
...@@ -425,6 +434,19 @@ class UserMediaProcessor::RequestInfo final ...@@ -425,6 +434,19 @@ class UserMediaProcessor::RequestInfo final
return request_->is_processing_user_gesture; return request_->is_processing_user_gesture;
} }
bool all_video_input_formats_received() const {
return all_video_input_formats_received_;
}
void set_all_video_input_formats_timeout_task_handle(TaskHandle task_handle) {
all_video_input_formats_timeout_task_handle_ = std::move(task_handle);
}
void CancelAllVideoInputFormatsTimeout() {
all_video_input_formats_received_ = true;
all_video_input_formats_timeout_task_handle_.Cancel();
}
void Trace(Visitor* visitor) {} void Trace(Visitor* visitor) {}
private: private:
...@@ -446,6 +468,8 @@ class UserMediaProcessor::RequestInfo final ...@@ -446,6 +468,8 @@ class UserMediaProcessor::RequestInfo final
blink::WebMediaStream web_stream_; blink::WebMediaStream web_stream_;
StreamControls stream_controls_; StreamControls stream_controls_;
ResourcesReady ready_callback_; ResourcesReady ready_callback_;
bool all_video_input_formats_received_ = false;
TaskHandle all_video_input_formats_timeout_task_handle_;
MediaStreamRequestResult request_result_ = MediaStreamRequestResult::OK; MediaStreamRequestResult request_result_ = MediaStreamRequestResult::OK;
String request_result_name_; String request_result_name_;
// Sources used in this request. // Sources used in this request.
...@@ -519,7 +543,7 @@ void UserMediaProcessor::RequestInfo::OnTrackStarted( ...@@ -519,7 +543,7 @@ void UserMediaProcessor::RequestInfo::OnTrackStarted(
blink::WebPlatformMediaStreamSource* source, blink::WebPlatformMediaStreamSource* source,
MediaStreamRequestResult result, MediaStreamRequestResult result,
const blink::WebString& result_name) { const blink::WebString& result_name) {
SendLogMessage(GetOnTrackStartedLogString(source, result)); SendLogMessage(GetOnTrackStartedLogString(request_id(), source, result));
auto** it = std::find(sources_waiting_for_callback_.begin(), auto** it = std::find(sources_waiting_for_callback_.begin(),
sources_waiting_for_callback_.end(), source); sources_waiting_for_callback_.end(), source);
DCHECK(it != sources_waiting_for_callback_.end()); DCHECK(it != sources_waiting_for_callback_.end());
...@@ -989,13 +1013,23 @@ void UserMediaProcessor::OnStreamGenerated( ...@@ -989,13 +1013,23 @@ void UserMediaProcessor::OnStreamGenerated(
GetMediaDevicesDispatcher()->GetAllVideoInputDeviceFormats( GetMediaDevicesDispatcher()->GetAllVideoInputDeviceFormats(
video_device_id, video_device_id,
WTF::Bind(&UserMediaProcessor::GotAllVideoInputFormatsForDevice, WTF::Bind(&UserMediaProcessor::GotAllVideoInputFormatsForDevice,
WrapWeakPersistent(this), WrapWeakPersistent(this), /*success=*/true,
current_request_info_->web_request(), label, current_request_info_->web_request(), label,
video_device_id)); video_device_id));
TaskHandle timeout_task_handle = PostDelayedCancellableTask(
*task_runner_, FROM_HERE,
WTF::Bind(&UserMediaProcessor::GotAllVideoInputFormatsForDevice,
WrapWeakPersistent(this), /*success=*/false,
current_request_info_->web_request(), label, video_device_id,
Vector<media::VideoCaptureFormat>()),
kVideoInputFormatsTimeout);
current_request_info_->set_all_video_input_formats_timeout_task_handle(
std::move(timeout_task_handle));
} }
} }
void UserMediaProcessor::GotAllVideoInputFormatsForDevice( void UserMediaProcessor::GotAllVideoInputFormatsForDevice(
bool success,
const blink::WebUserMediaRequest& web_request, const blink::WebUserMediaRequest& web_request,
const String& label, const String& label,
const String& device_id, const String& device_id,
...@@ -1007,11 +1041,24 @@ void UserMediaProcessor::GotAllVideoInputFormatsForDevice( ...@@ -1007,11 +1041,24 @@ void UserMediaProcessor::GotAllVideoInputFormatsForDevice(
if (!IsCurrentRequestInfo(web_request)) if (!IsCurrentRequestInfo(web_request))
return; return;
SendLogMessage( SendLogMessage(base::StringPrintf(
base::StringPrintf("GotAllVideoInputFormatsForDevice({request_id=%d}, " "GotAllVideoInputFormatsForDevice({request_id=%d}, "
"{label=%s}, {device=[id: %s]})", "{label=%s}, {device=[id: %s]}, {success=%d})",
current_request_info_->request_id(), current_request_info_->request_id(), label.Utf8().c_str(),
label.Utf8().c_str(), device_id.Utf8().c_str())); device_id.Utf8().c_str(), success));
if (!success) {
if (!current_request_info_->all_video_input_formats_received()) {
// Fail, since the request for video input formats timed out.
GetUserMediaRequestFailed(
MediaStreamRequestResult::TRACK_START_FAILURE_VIDEO);
DeleteWebRequest(current_request_info_->web_request());
}
// If input formats were successfully received already, there is nothing
// left to do.
return;
}
current_request_info_->CancelAllVideoInputFormatsTimeout();
current_request_info_->AddNativeVideoFormats(device_id, formats); current_request_info_->AddNativeVideoFormats(device_id, formats);
if (current_request_info_->CanStartTracks()) if (current_request_info_->CanStartTracks())
StartTracks(label); StartTracks(label);
...@@ -1090,6 +1137,7 @@ void UserMediaProcessor::NotifyCurrentRequestInfoOfAudioSourceStarted( ...@@ -1090,6 +1137,7 @@ void UserMediaProcessor::NotifyCurrentRequestInfoOfAudioSourceStarted(
blink::WebPlatformMediaStreamSource* source, blink::WebPlatformMediaStreamSource* source,
MediaStreamRequestResult result, MediaStreamRequestResult result,
const String& result_name) { const String& result_name) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// The only request possibly being processed is |current_request_info_|. // The only request possibly being processed is |current_request_info_|.
if (current_request_info_) if (current_request_info_)
current_request_info_->OnAudioSourceStarted(source, result, result_name); current_request_info_->OnAudioSourceStarted(source, result, result_name);
......
...@@ -146,6 +146,7 @@ class MODULES_EXPORT UserMediaProcessor ...@@ -146,6 +146,7 @@ class MODULES_EXPORT UserMediaProcessor
const Vector<blink::MediaStreamDevice>& video_devices); const Vector<blink::MediaStreamDevice>& video_devices);
void GotAllVideoInputFormatsForDevice( void GotAllVideoInputFormatsForDevice(
bool success,
const blink::WebUserMediaRequest& web_request, const blink::WebUserMediaRequest& web_request,
const String& label, const String& label,
const String& device_id, const String& device_id,
...@@ -293,6 +294,9 @@ class MODULES_EXPORT UserMediaProcessor ...@@ -293,6 +294,9 @@ class MODULES_EXPORT UserMediaProcessor
// contains the request currently being processed. // contains the request currently being processed.
Member<RequestInfo> current_request_info_; Member<RequestInfo> current_request_info_;
MediaDevicesDispatcherCallback media_devices_dispatcher_cb_; MediaDevicesDispatcherCallback media_devices_dispatcher_cb_;
// |request_completed_cb_| is invoked when the processing of
// |current_request_info_| is completed.
base::OnceClosure request_completed_cb_; base::OnceClosure request_completed_cb_;
Member<LocalFrame> frame_; Member<LocalFrame> frame_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment