summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorvrk@chromium.org <vrk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-29 16:35:27 +0000
committervrk@chromium.org <vrk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-29 16:35:27 +0000
commite7b9b356a756d0fba4529f11c05cc12e55bf4552 (patch)
tree3ef9f673e30b9f14ee18cdc9bc03a0e8b38d964b /content
parentb8452b57b91e954a1f8177e56a93a2e877359726 (diff)
downloadchromium_src-e7b9b356a756d0fba4529f11c05cc12e55bf4552.zip
chromium_src-e7b9b356a756d0fba4529f11c05cc12e55bf4552.tar.gz
chromium_src-e7b9b356a756d0fba4529f11c05cc12e55bf4552.tar.bz2
Reland CL to implement browser-side logging to WebRtc log.
This reverts commit d95595eb5145e310baf692f359f9488faf73750d, and it fixes the original bug where |requests_| was being accessed from the UI thread. BUG=338848,332261 Review URL: https://codereview.chromium.org/140633004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@247697 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-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.cc121
-rw-r--r--content/browser/renderer_host/media/media_stream_manager.h18
-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
19 files changed, 216 insertions, 31 deletions
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 4c84918..74ecd80 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..88a1aa1 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,44 @@ 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()) {
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&MediaStreamManager::AddLogMessageOnIOThread,
+ base::Unretained(content::BrowserMainLoop::GetInstance()
+ ->media_stream_manager()),
+ 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 +1056,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 +1459,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 +1536,65 @@ 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::AddLogMessageOnIOThread(const std::string& message) {
+ // Get render process ids on the IO thread.
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ // 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);
+ }
+
+ // MediaStreamManager is a singleton in BrowserMainLoop, which owns the UI
+ // thread. MediaStreamManager has the same lifetime as the UI thread, so it is
+ // safe to use base::Unretained.
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&MediaStreamManager::AddLogMessageOnUIThread,
+ base::Unretained(this),
+ requesting_process_ids,
+ message));
+}
+
+void MediaStreamManager::AddLogMessageOnUIThread(
+ const std::set<int>& requesting_process_ids,
+ 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));
+
+ 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..88f02e1 100644
--- a/content/browser/renderer_host/media/media_stream_manager.h
+++ b/content/browser/renderer_host/media/media_stream_manager.h
@@ -24,6 +24,7 @@
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_MANAGER_H_
#include <map>
+#include <set>
#include <string>
#include "base/basictypes.h"
@@ -185,6 +186,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 AddLogMessageOnIOThread(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();
@@ -310,6 +320,12 @@ class CONTENT_EXPORT MediaStreamManager
void TranslateDeviceIdToSourceId(DeviceRequest* request,
MediaStreamDevice* device);
+ // Helper method that sends log messages to the render processes in
+ // |render_process_ids|, to be used by the webrtcLoggingPrivate API if
+ // requested.
+ void AddLogMessageOnUIThread(const std::set<int>& render_process_ids,
+ const std::string& message);
+
// Finds and returns the device id corresponding to the given
// |source_id|. Returns true if there was a raw device id that matched the
// given |source_id|, false if nothing matched it.
@@ -339,7 +355,7 @@ class CONTENT_EXPORT MediaStreamManager
// AudioInputDeviceManager, in order to only enumerate when necessary.
int active_enumeration_ref_count_[NUM_MEDIA_TYPES];
- // All non-closed request.
+ // All non-closed request. Must be accessed on IO thread.
DeviceRequests requests_;
// Hold a pointer to the IO loop to check we delete the device thread and
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.