diff options
author | vrk@chromium.org <vrk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-26 10:05:30 +0000 |
---|---|---|
committer | vrk@chromium.org <vrk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-26 10:05:30 +0000 |
commit | c0f49b71f44e156f615ec0e6db64a0d864b02af7 (patch) | |
tree | a37c8ab1bfa4d1f81e52558eb22326ebe723a8ed | |
parent | f9adbc8dd62b000870d7ecb94707dbb3525d455d (diff) | |
download | chromium_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
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_; |