summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvrk@chromium.org <vrk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-26 10:05:30 +0000
committervrk@chromium.org <vrk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-26 10:05:30 +0000
commitc0f49b71f44e156f615ec0e6db64a0d864b02af7 (patch)
treea37c8ab1bfa4d1f81e52558eb22326ebe723a8ed
parentf9adbc8dd62b000870d7ecb94707dbb3525d455d (diff)
downloadchromium_src-c0f49b71f44e156f615ec0e6db64a0d864b02af7.zip
chromium_src-c0f49b71f44e156f615ec0e6db64a0d864b02af7.tar.gz
chromium_src-c0f49b71f44e156f615ec0e6db64a0d864b02af7.tar.bz2
Implement browser-side logging to WebRtc log
This adds a logging callback to RenderProcessHost and also adds logging for device enumeration in the browser process. BUG=332261 Review URL: https://codereview.chromium.org/140843007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@247164 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chrome_content_browser_client.cc2
-rw-r--r--chrome/browser/media/webrtc_logging_handler_host.cc15
-rw-r--r--chrome/browser/media/webrtc_logging_handler_host.h7
-rw-r--r--content/browser/renderer_host/media/audio_input_renderer_host.cc6
-rw-r--r--content/browser/renderer_host/media/desktop_capture_device.cc5
-rw-r--r--content/browser/renderer_host/media/desktop_capture_device_aura.cc2
-rw-r--r--content/browser/renderer_host/media/desktop_capture_device_aura_unittest.cc4
-rw-r--r--content/browser/renderer_host/media/desktop_capture_device_unittest.cc8
-rw-r--r--content/browser/renderer_host/media/media_stream_manager.cc98
-rw-r--r--content/browser/renderer_host/media/media_stream_manager.h9
-rw-r--r--content/browser/renderer_host/media/video_capture_controller.cc7
-rw-r--r--content/browser/renderer_host/media/video_capture_controller_unittest.cc4
-rw-r--r--content/browser/renderer_host/media/video_capture_device_impl.cc26
-rw-r--r--content/browser/renderer_host/media/video_capture_device_impl.h4
-rw-r--r--content/browser/renderer_host/media/video_capture_manager.cc2
-rw-r--r--content/browser/renderer_host/media/web_contents_video_capture_device.cc2
-rw-r--r--content/browser/renderer_host/media/web_contents_video_capture_device_unittest.cc2
-rw-r--r--content/browser/renderer_host/render_process_host_impl.cc13
-rw-r--r--content/browser/renderer_host/render_process_host_impl.h11
-rw-r--r--content/public/browser/render_process_host.h6
-rw-r--r--content/public/test/mock_render_process_host.cc4
-rw-r--r--content/public/test/mock_render_process_host.h2
-rw-r--r--media/video/capture/android/video_capture_device_android.cc2
-rw-r--r--media/video/capture/linux/video_capture_device_linux.cc2
-rw-r--r--media/video/capture/mac/video_capture_device_mac.mm2
-rw-r--r--media/video/capture/video_capture_device.h4
-rw-r--r--media/video/capture/video_capture_device_unittest.cc2
-rw-r--r--media/video/capture/win/video_capture_device_mf_win.cc6
-rw-r--r--media/video/capture/win/video_capture_device_win.cc4
-rw-r--r--media/video/capture/win/video_capture_device_win.h2
30 files changed, 222 insertions, 41 deletions
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 94a6ae7..5a671a2 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -921,6 +921,8 @@ void ChromeContentBrowserClient::RenderProcessWillLaunch(
#if defined(ENABLE_WEBRTC)
WebRtcLoggingHandlerHost* webrtc_logging_handler_host =
new WebRtcLoggingHandlerHost(profile);
+ host->SetWebRtcLogMessageCallback(base::Bind(
+ &WebRtcLoggingHandlerHost::LogMessage, webrtc_logging_handler_host));
host->AddFilter(webrtc_logging_handler_host);
host->SetUserData(host, new base::UserDataAdapter<WebRtcLoggingHandlerHost>(
webrtc_logging_handler_host));
diff --git a/chrome/browser/media/webrtc_logging_handler_host.cc b/chrome/browser/media/webrtc_logging_handler_host.cc
index 611bc52..31759bb 100644
--- a/chrome/browser/media/webrtc_logging_handler_host.cc
+++ b/chrome/browser/media/webrtc_logging_handler_host.cc
@@ -203,6 +203,14 @@ void WebRtcLoggingHandlerHost::DiscardLog(const GenericDoneCallback& callback) {
FireGenericDoneCallback(&discard_callback, true, "");
}
+void WebRtcLoggingHandlerHost::LogMessage(const std::string& message) {
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(
+ &WebRtcLoggingHandlerHost::AddLogMessageFromBrowser, this, message));
+}
+
void WebRtcLoggingHandlerHost::OnChannelClosing() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
if (logging_state_ == STARTED || logging_state_ == STOPPED) {
@@ -234,6 +242,13 @@ bool WebRtcLoggingHandlerHost::OnMessageReceived(const IPC::Message& message,
return handled;
}
+void WebRtcLoggingHandlerHost::AddLogMessageFromBrowser(
+ const std::string& message) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ if (logging_state_ == STARTED)
+ LogToCircularBuffer(message);
+}
+
void WebRtcLoggingHandlerHost::OnAddLogMessage(const std::string& message) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
if (logging_state_ == STARTED || logging_state_ == STOPPING)
diff --git a/chrome/browser/media/webrtc_logging_handler_host.h b/chrome/browser/media/webrtc_logging_handler_host.h
index 5f7f5a4..3ce35cb 100644
--- a/chrome/browser/media/webrtc_logging_handler_host.h
+++ b/chrome/browser/media/webrtc_logging_handler_host.h
@@ -61,6 +61,9 @@ class WebRtcLoggingHandlerHost : public content::BrowserMessageFilter {
// called on the IO thread.
void DiscardLog(const GenericDoneCallback& callback);
+ // Adds a message to the log.
+ void LogMessage(const std::string& message);
+
// May be called on any thread. |upload_log_on_render_close_| is used
// for decision making and it's OK if it changes before the execution based
// on that decision has finished.
@@ -99,9 +102,13 @@ class WebRtcLoggingHandlerHost : public content::BrowserMessageFilter {
virtual bool OnMessageReceived(const IPC::Message& message,
bool* message_was_ok) OVERRIDE;
+ // Handles log message requests from both renderer process.
void OnAddLogMessage(const std::string& message);
void OnLoggingStoppedInRenderer();
+ // Handles log message requests from browser process.
+ void AddLogMessageFromBrowser(const std::string& message);
+
void StartLoggingIfAllowed();
void DoStartLogging();
void LogMachineInfo();
diff --git a/content/browser/renderer_host/media/audio_input_renderer_host.cc b/content/browser/renderer_host/media/audio_input_renderer_host.cc
index ec61944..93ed16c 100644
--- a/content/browser/renderer_host/media/audio_input_renderer_host.cc
+++ b/content/browser/renderer_host/media/audio_input_renderer_host.cc
@@ -176,6 +176,8 @@ void AudioInputRendererHost::DoSendRecordingMessage(
void AudioInputRendererHost::DoHandleError(
media::AudioInputController* controller) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ MediaStreamManager::SendMessageToNativeLog(
+ "The AudioInputController signalled an error.");
AudioEntry* entry = LookupByController(controller);
if (!entry)
@@ -310,6 +312,8 @@ void AudioInputRendererHost::OnCreateStream(
entry->stream_id = stream_id;
audio_entries_.insert(std::make_pair(stream_id, entry.release()));
+ MediaStreamManager::SendMessageToNativeLog(
+ "Audio input stream created successfully.");
audio_log_->OnCreated(stream_id, audio_params, device_id, std::string());
}
@@ -349,6 +353,8 @@ void AudioInputRendererHost::OnSetVolume(int stream_id, double volume) {
}
void AudioInputRendererHost::SendErrorMessage(int stream_id) {
+ MediaStreamManager::SendMessageToNativeLog(
+ "An error occurred in AudioInputRendererHost.");
Send(new AudioInputMsg_NotifyStreamStateChanged(
stream_id, media::AudioInputIPCDelegate::kError));
}
diff --git a/content/browser/renderer_host/media/desktop_capture_device.cc b/content/browser/renderer_host/media/desktop_capture_device.cc
index d09131b..7c78df0 100644
--- a/content/browser/renderer_host/media/desktop_capture_device.cc
+++ b/content/browser/renderer_host/media/desktop_capture_device.cc
@@ -165,8 +165,9 @@ void DesktopCaptureDevice::Core::OnCaptureCompleted(
capture_in_progress_ = false;
if (!frame) {
- LOG(ERROR) << "Failed to capture a frame.";
- client_->OnError();
+ std::string log("Failed to capture a frame.");
+ LOG(ERROR) << log;
+ client_->OnError(log);
return;
}
diff --git a/content/browser/renderer_host/media/desktop_capture_device_aura.cc b/content/browser/renderer_host/media/desktop_capture_device_aura.cc
index 03e9c89..7d9e7d9 100644
--- a/content/browser/renderer_host/media/desktop_capture_device_aura.cc
+++ b/content/browser/renderer_host/media/desktop_capture_device_aura.cc
@@ -405,7 +405,7 @@ void DesktopVideoCaptureMachine::OnWindowDestroyed(aura::Window* window) {
Stop(base::Bind(&base::DoNothing));
- oracle_proxy_->ReportError();
+ oracle_proxy_->ReportError("OnWindowDestroyed()");
}
void DesktopVideoCaptureMachine::OnCompositingEnded(
diff --git a/content/browser/renderer_host/media/desktop_capture_device_aura_unittest.cc b/content/browser/renderer_host/media/desktop_capture_device_aura_unittest.cc
index 2dd75f7..e6abac3 100644
--- a/content/browser/renderer_host/media/desktop_capture_device_aura_unittest.cc
+++ b/content/browser/renderer_host/media/desktop_capture_device_aura_unittest.cc
@@ -32,7 +32,7 @@ class MockDeviceClient : public media::VideoCaptureDevice::Client {
MOCK_METHOD2(ReserveOutputBuffer,
scoped_refptr<Buffer>(media::VideoFrame::Format format,
const gfx::Size& dimensions));
- MOCK_METHOD0(OnError, void());
+ MOCK_METHOD1(OnError, void(const std::string& reason));
MOCK_METHOD5(OnIncomingCapturedFrame,
void(const uint8* data,
int length,
@@ -99,7 +99,7 @@ TEST_F(DesktopCaptureDeviceAuraTest, StartAndStop) {
content::DesktopMediaID::RegisterAuraWindow(root_window())));
scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
- EXPECT_CALL(*client, OnError()).Times(0);
+ EXPECT_CALL(*client, OnError(_)).Times(0);
media::VideoCaptureParams capture_params;
capture_params.requested_format.frame_size.SetSize(640, 480);
diff --git a/content/browser/renderer_host/media/desktop_capture_device_unittest.cc b/content/browser/renderer_host/media/desktop_capture_device_unittest.cc
index 90ac57b..c51172a 100644
--- a/content/browser/renderer_host/media/desktop_capture_device_unittest.cc
+++ b/content/browser/renderer_host/media/desktop_capture_device_unittest.cc
@@ -43,7 +43,7 @@ class MockDeviceClient : public media::VideoCaptureDevice::Client {
MOCK_METHOD2(ReserveOutputBuffer,
scoped_refptr<Buffer>(media::VideoFrame::Format format,
const gfx::Size& dimensions));
- MOCK_METHOD0(OnError, void());
+ MOCK_METHOD1(OnError, void(const std::string& reason));
MOCK_METHOD5(OnIncomingCapturedFrame,
void(const uint8* data,
int length,
@@ -164,7 +164,7 @@ TEST_F(DesktopCaptureDeviceTest, MAYBE_Capture) {
int frame_size;
scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
- EXPECT_CALL(*client, OnError()).Times(0);
+ EXPECT_CALL(*client, OnError(_)).Times(0);
EXPECT_CALL(*client, OnIncomingCapturedFrame(_, _, _, _, _))
.WillRepeatedly(
DoAll(SaveArg<1>(&frame_size),
@@ -204,7 +204,7 @@ TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeConstantResolution) {
int frame_size;
scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
- EXPECT_CALL(*client, OnError()).Times(0);
+ EXPECT_CALL(*client, OnError(_)).Times(0);
EXPECT_CALL(*client, OnIncomingCapturedFrame(_, _, _, _, _))
.WillRepeatedly(
DoAll(SaveArg<1>(&frame_size),
@@ -251,7 +251,7 @@ TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeVariableResolution) {
base::WaitableEvent done_event(false, false);
scoped_ptr<MockDeviceClient> client(new MockDeviceClient());
- EXPECT_CALL(*client, OnError()).Times(0);
+ EXPECT_CALL(*client, OnError(_)).Times(0);
EXPECT_CALL(*client, OnIncomingCapturedFrame(_, _, _, _, _))
.WillRepeatedly(
DoAll(SaveArg<4>(&format),
diff --git a/content/browser/renderer_host/media/media_stream_manager.cc b/content/browser/renderer_host/media/media_stream_manager.cc
index 6ed73ca..6832d62 100644
--- a/content/browser/renderer_host/media/media_stream_manager.cc
+++ b/content/browser/renderer_host/media/media_stream_manager.cc
@@ -13,18 +13,22 @@
#include "base/logging.h"
#include "base/rand_util.h"
#include "base/run_loop.h"
+#include "base/strings/stringprintf.h"
#include "base/threading/thread.h"
+#include "content/browser/browser_main_loop.h"
#include "content/browser/renderer_host/media/audio_input_device_manager.h"
#include "content/browser/renderer_host/media/device_request_message_filter.h"
#include "content/browser/renderer_host/media/media_stream_requester.h"
#include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
#include "content/browser/renderer_host/media/video_capture_manager.h"
#include "content/browser/renderer_host/media/web_contents_capture_util.h"
+#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/media_device_id.h"
#include "content/public/browser/media_observer.h"
#include "content/public/browser/media_request_state.h"
+#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/media_stream_request.h"
#include "media/audio/audio_manager_base.h"
@@ -103,6 +107,39 @@ void ParseStreamType(const StreamOptions& options,
}
}
+// Private helper method for SendMessageToNativeLog() that obtains the global
+// MediaStreamManager instance on the UI thread before sending |message| to the
+// webrtcLoggingPrivate API.
+void DoAddLogMessage(const std::string& message) {
+ // Must be on the UI thread to access BrowserMainLoop.
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ // May be null in tests.
+ // TODO(vrk): Handle this more elegantly by having native log messages become
+ // no-ops until MediaStreamManager is aware that a renderer process has
+ // started logging. crbug.com/333894
+ if (content::BrowserMainLoop::GetInstance()) {
+ content::BrowserMainLoop::GetInstance()->
+ media_stream_manager()->AddLogMessageOnUIThread(message);
+ }
+}
+
+// Private helper method to generate a string for the log message that lists the
+// human readable names of |devices|.
+std::string GetLogMessageString(MediaStreamType stream_type,
+ const StreamDeviceInfoArray& devices) {
+ std::string output_string =
+ base::StringPrintf("Getting devices for stream type %d:\n", stream_type);
+ if (devices.empty()) {
+ output_string += "No devices found.";
+ } else {
+ for (StreamDeviceInfoArray::const_iterator it = devices.begin();
+ it != devices.end(); ++it) {
+ output_string += " " + it->device.name + "\n";
+ }
+ }
+ return output_string;
+}
+
} // namespace
@@ -1014,6 +1051,20 @@ void MediaStreamManager::SetupRequest(const std::string& label) {
// Enumerate the devices if there is no valid device lists to be used.
StartEnumeration(request);
return;
+ } else {
+ // Cache is valid, so log the cached devices for MediaStream requests.
+ if (request->request_type == MEDIA_GENERATE_STREAM) {
+ std::string log_message("Using cached devices for request.\n");
+ if (audio_type != MEDIA_NO_SERVICE) {
+ log_message +=
+ GetLogMessageString(audio_type, audio_enumeration_cache_.devices);
+ }
+ if (video_type != MEDIA_NO_SERVICE) {
+ log_message +=
+ GetLogMessageString(video_type, video_enumeration_cache_.devices);
+ }
+ SendMessageToNativeLog(log_message);
+ }
}
if (!SetupDeviceCaptureRequest(request)) {
@@ -1403,7 +1454,11 @@ void MediaStreamManager::DevicesEnumerated(
MediaStreamType stream_type, const StreamDeviceInfoArray& devices) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
DVLOG(1) << "DevicesEnumerated("
- << ", {stream_type = " << stream_type << "})";
+ << "{stream_type = " << stream_type << "})" << std::endl;
+
+ std::string log_message = "New device enumeration result:\n" +
+ GetLogMessageString(stream_type, devices);
+ SendMessageToNativeLog(log_message);
// Only cache the device list when the device list has been changed.
bool need_update_clients = false;
@@ -1476,6 +1531,47 @@ void MediaStreamManager::DevicesEnumerated(
DCHECK_GE(active_enumeration_ref_count_[stream_type], 0);
}
+// static
+void MediaStreamManager::SendMessageToNativeLog(const std::string& message) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(DoAddLogMessage, message));
+}
+
+void MediaStreamManager::AddLogMessageOnUIThread(const std::string& message) {
+#if defined(OS_ANDROID)
+ // It appears android_aosp is being built with ENABLE_WEBRTC=0, since it does
+ // not find RenderProcessHostImpl::WebRtcLogMessage. Logging is not enabled on
+ // Android anyway, so make this function a no-op.
+ // TODO(vrk): Figure out what's going on here and fix.
+ return;
+#else
+ // Must be on the UI thread to access RenderProcessHost from process ID.
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ // Grab all unique process ids that request a MediaStream or have a
+ // MediaStream running.
+ std::set<int> requesting_process_ids;
+ for (DeviceRequests::const_iterator it = requests_.begin();
+ it != requests_.end(); ++it) {
+ DeviceRequest* request = it->second;
+ if (request->request_type == MEDIA_GENERATE_STREAM)
+ requesting_process_ids.insert(request->requesting_process_id);
+ }
+
+ for (std::set<int>::const_iterator it = requesting_process_ids.begin();
+ it != requesting_process_ids.end(); ++it) {
+ // Log the message to all renderers that are requesting a MediaStream or
+ // have a MediaStream running.
+ content::RenderProcessHostImpl* render_process_host_impl =
+ static_cast<content::RenderProcessHostImpl*>(
+ content::RenderProcessHost::FromID(*it));
+ if (render_process_host_impl)
+ render_process_host_impl->WebRtcLogMessage(message);
+ }
+#endif
+}
+
void MediaStreamManager::HandleAccessRequestResponse(
const std::string& label,
const MediaStreamDevices& devices) {
diff --git a/content/browser/renderer_host/media/media_stream_manager.h b/content/browser/renderer_host/media/media_stream_manager.h
index eefab6b..8c2edc4 100644
--- a/content/browser/renderer_host/media/media_stream_manager.h
+++ b/content/browser/renderer_host/media/media_stream_manager.h
@@ -185,6 +185,15 @@ class CONTENT_EXPORT MediaStreamManager
// too late. (see http://crbug.com/247525#c14).
virtual void WillDestroyCurrentMessageLoop() OVERRIDE;
+ // Sends log messages to the render processes making device requests, to be
+ // used by the webrtcLoggingPrivate API if requested.
+ void AddLogMessageOnUIThread(const std::string& message);
+
+ // Adds |message| to native logs for outstanding device requests, for use by
+ // render processes requesting logging from webrtcLoggingPrivate API. Safe to
+ // call from any thread.
+ static void SendMessageToNativeLog(const std::string& message);
+
protected:
// Used for testing.
MediaStreamManager();
diff --git a/content/browser/renderer_host/media/video_capture_controller.cc b/content/browser/renderer_host/media/video_capture_controller.cc
index f23f50f..5dff5c2 100644
--- a/content/browser/renderer_host/media/video_capture_controller.cc
+++ b/content/browser/renderer_host/media/video_capture_controller.cc
@@ -121,7 +121,7 @@ class VideoCaptureController::VideoCaptureDeviceClient
const gfx::Size& dimensions,
base::TimeTicks timestamp,
int frame_rate) OVERRIDE;
- virtual void OnError() OVERRIDE;
+ virtual void OnError(const std::string& reason) OVERRIDE;
private:
scoped_refptr<Buffer> DoReserveOutputBuffer(media::VideoFrame::Format format,
@@ -428,7 +428,10 @@ void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedBuffer(
timestamp));
}
-void VideoCaptureController::VideoCaptureDeviceClient::OnError() {
+void VideoCaptureController::VideoCaptureDeviceClient::OnError(
+ const std::string& reason) {
+ MediaStreamManager::SendMessageToNativeLog(
+ "Error on video capture: " + reason);
BrowserThread::PostTask(BrowserThread::IO,
FROM_HERE,
base::Bind(&VideoCaptureController::DoErrorOnIOThread, controller_));
diff --git a/content/browser/renderer_host/media/video_capture_controller_unittest.cc b/content/browser/renderer_host/media/video_capture_controller_unittest.cc
index 1852a71..b4de263 100644
--- a/content/browser/renderer_host/media/video_capture_controller_unittest.cc
+++ b/content/browser/renderer_host/media/video_capture_controller_unittest.cc
@@ -407,7 +407,7 @@ TEST_F(VideoCaptureControllerTest, ErrorBeforeDeviceCreation) {
// Start with one client.
controller_->AddClient(
route_id, client_a_.get(), base::kNullProcessHandle, 100, session_100);
- device_->OnError();
+ device_->OnError("Test Error");
EXPECT_CALL(*client_a_, DoError(route_id)).Times(1);
base::RunLoop().RunUntilIdle();
Mock::VerifyAndClearExpectations(client_a_.get());
@@ -462,7 +462,7 @@ TEST_F(VideoCaptureControllerTest, ErrorAfterDeviceCreation) {
device_->ReserveOutputBuffer(media::VideoFrame::I420, dims);
ASSERT_TRUE(buffer);
- device_->OnError();
+ device_->OnError("Test error");
device_->OnIncomingCapturedBuffer(buffer,
media::VideoFrame::I420,
dims,
diff --git a/content/browser/renderer_host/media/video_capture_device_impl.cc b/content/browser/renderer_host/media/video_capture_device_impl.cc
index 045eda6..88e5ab5 100644
--- a/content/browser/renderer_host/media/video_capture_device_impl.cc
+++ b/content/browser/renderer_host/media/video_capture_device_impl.cc
@@ -155,10 +155,10 @@ void ThreadSafeCaptureOracle::Stop() {
client_.reset();
}
-void ThreadSafeCaptureOracle::ReportError() {
+void ThreadSafeCaptureOracle::ReportError(const std::string& reason) {
base::AutoLock guard(lock_);
if (client_)
- client_->OnError();
+ client_->OnError(reason);
}
void ThreadSafeCaptureOracle::DidCaptureFrame(
@@ -196,16 +196,19 @@ void VideoCaptureDeviceImpl::AllocateAndStart(
}
if (params.requested_format.frame_rate <= 0) {
- DVLOG(1) << "invalid frame_rate: " << params.requested_format.frame_rate;
- client->OnError();
+ std::string error_msg = base::StringPrintf(
+ "invalid frame_rate: %d", params.requested_format.frame_rate);
+ DVLOG(1) << error_msg;
+ client->OnError(error_msg);
return;
}
if (params.requested_format.frame_size.width() < kMinFrameWidth ||
params.requested_format.frame_size.height() < kMinFrameHeight) {
- DVLOG(1) << "invalid frame size: "
- << params.requested_format.frame_size.ToString();
- client->OnError();
+ std::string error_msg =
+ "invalid frame size: " + params.requested_format.frame_size.ToString();
+ DVLOG(1) << error_msg;
+ client->OnError(error_msg);
return;
}
@@ -252,8 +255,9 @@ void VideoCaptureDeviceImpl::StopAndDeAllocate() {
void VideoCaptureDeviceImpl::CaptureStarted(bool success) {
DCHECK(thread_checker_.CalledOnValidThread());
if (!success) {
- DVLOG(1) << "Failed to start capture machine.";
- Error();
+ std::string reason("Failed to start capture machine.");
+ DVLOG(1) << reason;
+ Error(reason);
}
}
@@ -291,14 +295,14 @@ void VideoCaptureDeviceImpl::TransitionStateTo(State next_state) {
state_ = next_state;
}
-void VideoCaptureDeviceImpl::Error() {
+void VideoCaptureDeviceImpl::Error(const std::string& reason) {
DCHECK(thread_checker_.CalledOnValidThread());
if (state_ == kIdle)
return;
if (oracle_proxy_)
- oracle_proxy_->ReportError();
+ oracle_proxy_->ReportError(reason);
StopAndDeAllocate();
TransitionStateTo(kError);
diff --git a/content/browser/renderer_host/media/video_capture_device_impl.h b/content/browser/renderer_host/media/video_capture_device_impl.h
index 56bf1e0..87d4c19 100644
--- a/content/browser/renderer_host/media/video_capture_device_impl.h
+++ b/content/browser/renderer_host/media/video_capture_device_impl.h
@@ -71,7 +71,7 @@ class ThreadSafeCaptureOracle
void Stop();
// Signal an error to the client.
- void ReportError();
+ void ReportError(const std::string& reason);
private:
friend class base::RefCountedThreadSafe<ThreadSafeCaptureOracle>;
@@ -165,7 +165,7 @@ class CONTENT_EXPORT VideoCaptureDeviceImpl
void CaptureStarted(bool success);
// Stops capturing and notifies client_ of an error state.
- void Error();
+ void Error(const std::string& reason);
// Tracks that all activity occurs on the media stream manager's thread.
base::ThreadChecker thread_checker_;
diff --git a/content/browser/renderer_host/media/video_capture_manager.cc b/content/browser/renderer_host/media/video_capture_manager.cc
index ace6565..28242f4 100644
--- a/content/browser/renderer_host/media/video_capture_manager.cc
+++ b/content/browser/renderer_host/media/video_capture_manager.cc
@@ -213,7 +213,7 @@ void VideoCaptureManager::DoStartDeviceOnDeviceThread(
}
if (!video_capture_device) {
- device_client->OnError();
+ device_client->OnError("Could not create capture device");
return;
}
diff --git a/content/browser/renderer_host/media/web_contents_video_capture_device.cc b/content/browser/renderer_host/media/web_contents_video_capture_device.cc
index 535111b..95333fc 100644
--- a/content/browser/renderer_host/media/web_contents_video_capture_device.cc
+++ b/content/browser/renderer_host/media/web_contents_video_capture_device.cc
@@ -700,7 +700,7 @@ void WebContentsCaptureMachine::WebContentsDestroyed(
subscription_.reset();
web_contents->DecrementCapturerCount();
- oracle_proxy_->ReportError();
+ oracle_proxy_->ReportError("WebContentsDestroyed()");
}
RenderWidgetHost* WebContentsCaptureMachine::GetTarget() {
diff --git a/content/browser/renderer_host/media/web_contents_video_capture_device_unittest.cc b/content/browser/renderer_host/media/web_contents_video_capture_device_unittest.cc
index 39b427b..5787d2b 100644
--- a/content/browser/renderer_host/media/web_contents_video_capture_device_unittest.cc
+++ b/content/browser/renderer_host/media/web_contents_video_capture_device_unittest.cc
@@ -361,7 +361,7 @@ class StubClient : public media::VideoCaptureDevice::Client {
color_callback_.Run((SkColorSetRGB(yuv[0], yuv[1], yuv[2])));
}
- virtual void OnError() OVERRIDE {
+ virtual void OnError(const std::string& reason) OVERRIDE {
error_callback_.Run();
}
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index 14c0cd2..60881ea 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1516,6 +1516,11 @@ void RenderProcessHostImpl::DisableAecDump() {
base::Bind(&RenderProcessHostImpl::SendDisableAecDumpToRenderer,
weak_factory_.GetWeakPtr()));
}
+
+void RenderProcessHostImpl::SetWebRtcLogMessageCallback(
+ base::Callback<void(const std::string&)> callback) {
+ webrtc_log_message_callback_ = callback;
+}
#endif
IPC::ChannelProxy* RenderProcessHostImpl::GetChannel() {
@@ -1882,6 +1887,14 @@ void RenderProcessHostImpl::EndFrameSubscription(int route_id) {
route_id));
}
+#if defined(ENABLE_WEBRTC)
+void RenderProcessHostImpl::WebRtcLogMessage(const std::string& message) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (!webrtc_log_message_callback_.is_null())
+ webrtc_log_message_callback_.Run(message);
+}
+#endif
+
void RenderProcessHostImpl::OnShutdownRequest() {
// Don't shut down if there are active RenderViews, or if there are pending
// RenderViews being swapped back in.
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h
index 73522cb..a2d8df5 100644
--- a/content/browser/renderer_host/render_process_host_impl.h
+++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -124,6 +124,8 @@ class CONTENT_EXPORT RenderProcessHostImpl
#if defined(ENABLE_WEBRTC)
virtual void EnableAecDump(const base::FilePath& file) OVERRIDE;
virtual void DisableAecDump() OVERRIDE;
+ virtual void SetWebRtcLogMessageCallback(
+ base::Callback<void(const std::string&)> callback) OVERRIDE;
#endif
// IPC::Sender via RenderProcessHost.
@@ -165,6 +167,11 @@ class CONTENT_EXPORT RenderProcessHostImpl
return make_scoped_refptr(geolocation_dispatcher_host_);
}
+#if defined(ENABLE_WEBRTC)
+ // Fires the webrtc log message callback with |message|, if callback is set.
+ void WebRtcLogMessage(const std::string& message);
+#endif
+
// Register/unregister the host identified by the host id in the global host
// list.
static void RegisterHost(int host_id, RenderProcessHost* host);
@@ -389,6 +396,10 @@ class CONTENT_EXPORT RenderProcessHostImpl
// Message filter for geolocation messages.
GeolocationDispatcherHost* geolocation_dispatcher_host_;
+#if defined(ENABLE_WEBRTC)
+ base::Callback<void(const std::string&)> webrtc_log_message_callback_;
+#endif
+
// Lives on the browser's ChildThread.
base::WeakPtrFactory<RenderProcessHostImpl> weak_factory_;
diff --git a/content/public/browser/render_process_host.h b/content/public/browser/render_process_host.h
index 436108a..faa42eb 100644
--- a/content/public/browser/render_process_host.h
+++ b/content/public/browser/render_process_host.h
@@ -215,6 +215,12 @@ class CONTENT_EXPORT RenderProcessHost : public IPC::Sender,
#if defined(ENABLE_WEBRTC)
virtual void EnableAecDump(const base::FilePath& file) = 0;
virtual void DisableAecDump() = 0;
+
+ // When set, |callback| receives log messages regarding, for example. media
+ // devices (webcams, mics, etc) that were initially requested in the render
+ // process associated with this RenderProcessHost.
+ virtual void SetWebRtcLogMessageCallback(
+ base::Callback<void(const std::string&)> callback) = 0;
#endif
// Static management functions -----------------------------------------------
diff --git a/content/public/test/mock_render_process_host.cc b/content/public/test/mock_render_process_host.cc
index 1fc3eab..5e67bf8 100644
--- a/content/public/test/mock_render_process_host.cc
+++ b/content/public/test/mock_render_process_host.cc
@@ -257,6 +257,10 @@ void MockRenderProcessHost::EnableAecDump(const base::FilePath& file) {
void MockRenderProcessHost::DisableAecDump() {
}
+
+void MockRenderProcessHost::SetWebRtcLogMessageCallback(
+ base::Callback<void(const std::string&)> callback) {
+}
#endif
bool MockRenderProcessHost::OnMessageReceived(const IPC::Message& msg) {
diff --git a/content/public/test/mock_render_process_host.h b/content/public/test/mock_render_process_host.h
index d76fa66..d3c9739 100644
--- a/content/public/test/mock_render_process_host.h
+++ b/content/public/test/mock_render_process_host.h
@@ -78,6 +78,8 @@ class MockRenderProcessHost : public RenderProcessHost {
#if defined(ENABLE_WEBRTC)
virtual void EnableAecDump(const base::FilePath& file) OVERRIDE;
virtual void DisableAecDump() OVERRIDE;
+ virtual void SetWebRtcLogMessageCallback(
+ base::Callback<void(const std::string&)> callback) OVERRIDE;
#endif
// IPC::Sender via RenderProcessHost.
diff --git a/media/video/capture/android/video_capture_device_android.cc b/media/video/capture/android/video_capture_device_android.cc
index 54ca9de..cbf5005 100644
--- a/media/video/capture/android/video_capture_device_android.cc
+++ b/media/video/capture/android/video_capture_device_android.cc
@@ -259,7 +259,7 @@ void VideoCaptureDeviceAndroid::SetErrorState(const std::string& reason) {
base::AutoLock lock(lock_);
state_ = kError;
}
- client_->OnError();
+ client_->OnError(reason);
}
} // namespace media
diff --git a/media/video/capture/linux/video_capture_device_linux.cc b/media/video/capture/linux/video_capture_device_linux.cc
index a6f85d5..7155ae23 100644
--- a/media/video/capture/linux/video_capture_device_linux.cc
+++ b/media/video/capture/linux/video_capture_device_linux.cc
@@ -607,7 +607,7 @@ void VideoCaptureDeviceLinux::SetErrorState(const std::string& reason) {
v4l2_thread_.message_loop() == base::MessageLoop::current());
DVLOG(1) << reason;
state_ = kError;
- client_->OnError();
+ client_->OnError(reason);
}
} // namespace media
diff --git a/media/video/capture/mac/video_capture_device_mac.mm b/media/video/capture/mac/video_capture_device_mac.mm
index 97e4363..8ff066f 100644
--- a/media/video/capture/mac/video_capture_device_mac.mm
+++ b/media/video/capture/mac/video_capture_device_mac.mm
@@ -322,7 +322,7 @@ void VideoCaptureDeviceMac::SetErrorState(const std::string& reason) {
DCHECK(task_runner_->BelongsToCurrentThread());
DLOG(ERROR) << reason;
state_ = kError;
- client_->OnError();
+ client_->OnError(reason);
}
bool VideoCaptureDeviceMac::UpdateCaptureResolution() {
diff --git a/media/video/capture/video_capture_device.h b/media/video/capture/video_capture_device.h
index c02dcc1..a3cabad 100644
--- a/media/video/capture/video_capture_device.h
+++ b/media/video/capture/video_capture_device.h
@@ -180,8 +180,8 @@ class MEDIA_EXPORT VideoCaptureDevice {
int frame_rate) = 0;
// An error has occurred that cannot be handled and VideoCaptureDevice must
- // be StopAndDeAllocate()-ed.
- virtual void OnError() = 0;
+ // be StopAndDeAllocate()-ed. |reason| is a text description of the error.
+ virtual void OnError(const std::string& reason) = 0;
};
// Creates a VideoCaptureDevice object.
diff --git a/media/video/capture/video_capture_device_unittest.cc b/media/video/capture/video_capture_device_unittest.cc
index 6a765e1..735a96a 100644
--- a/media/video/capture/video_capture_device_unittest.cc
+++ b/media/video/capture/video_capture_device_unittest.cc
@@ -69,7 +69,7 @@ class MockClient : public media::VideoCaptureDevice::Client {
explicit MockClient(base::Callback<void(const VideoCaptureFormat&)> frame_cb)
: main_thread_(base::MessageLoopProxy::current()), frame_cb_(frame_cb) {}
- virtual void OnError() OVERRIDE {
+ virtual void OnError(const std::string& error_message) OVERRIDE {
OnErr();
}
diff --git a/media/video/capture/win/video_capture_device_mf_win.cc b/media/video/capture/win/video_capture_device_mf_win.cc
index f4007fa..de199c2 100644
--- a/media/video/capture/win/video_capture_device_mf_win.cc
+++ b/media/video/capture/win/video_capture_device_mf_win.cc
@@ -9,6 +9,7 @@
#include "base/lazy_instance.h"
#include "base/memory/ref_counted.h"
+#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h"
#include "base/synchronization/waitable_event.h"
#include "base/win/scoped_co_mem.h"
@@ -432,9 +433,10 @@ void VideoCaptureDeviceMFWin::OnIncomingCapturedFrame(
}
void VideoCaptureDeviceMFWin::OnError(HRESULT hr) {
- DLOG(ERROR) << "VideoCaptureDeviceMFWin: " << std::hex << hr;
+ std::string log_msg = base::StringPrintf("VideoCaptureDeviceMFWin: %x", hr);
+ DLOG(ERROR) << log_msg;
if (client_.get())
- client_->OnError();
+ client_->OnError(log_msg);
}
} // namespace media
diff --git a/media/video/capture/win/video_capture_device_win.cc b/media/video/capture/win/video_capture_device_win.cc
index 48dd3da..13d4d48 100644
--- a/media/video/capture/win/video_capture_device_win.cc
+++ b/media/video/capture/win/video_capture_device_win.cc
@@ -590,10 +590,10 @@ bool VideoCaptureDeviceWin::CreateCapabilityMap() {
return !capabilities_.empty();
}
-void VideoCaptureDeviceWin::SetErrorState(const char* reason) {
+void VideoCaptureDeviceWin::SetErrorState(const std::string& reason) {
DCHECK(CalledOnValidThread());
DVLOG(1) << reason;
state_ = kError;
- client_->OnError();
+ client_->OnError(reason);
}
} // namespace media
diff --git a/media/video/capture/win/video_capture_device_win.h b/media/video/capture/win/video_capture_device_win.h
index 164c01c..8c9e546 100644
--- a/media/video/capture/win/video_capture_device_win.h
+++ b/media/video/capture/win/video_capture_device_win.h
@@ -59,7 +59,7 @@ class VideoCaptureDeviceWin
virtual void FrameReceived(const uint8* buffer, int length);
bool CreateCapabilityMap();
- void SetErrorState(const char* reason);
+ void SetErrorState(const std::string& reason);
Name device_name_;
InternalState state_;