summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorgrunell@chromium.org <grunell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-31 23:58:31 +0000
committergrunell@chromium.org <grunell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-31 23:58:31 +0000
commit6ef98b5a0dabccfe9271697efee657316693cbee (patch)
tree7e219b96acacdbaab8c6e7d84e136a36df0a0362 /chrome
parent66d5ac0c4ff1e95e240d076c798300435891b58b (diff)
downloadchromium_src-6ef98b5a0dabccfe9271697efee657316693cbee.zip
chromium_src-6ef98b5a0dabccfe9271697efee657316693cbee.tar.gz
chromium_src-6ef98b5a0dabccfe9271697efee657316693cbee.tar.bz2
Moving WebRTC logging related files from content to chrome.
BUG=229829 Review URL: https://chromiumcodereview.appspot.com/15741003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@203516 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/chrome_content_browser_client.cc7
-rw-r--r--chrome/browser/media/webrtc_logging_handler_host.cc66
-rw-r--r--chrome/browser/media/webrtc_logging_handler_host.h40
-rw-r--r--chrome/chrome_browser.gypi12
-rw-r--r--chrome/chrome_common.gypi8
-rw-r--r--chrome/chrome_renderer.gypi12
-rw-r--r--chrome/chrome_tests_unit.gypi7
-rw-r--r--chrome/common/common_message_generator.h4
-rw-r--r--chrome/common/media/webrtc_logging_messages.h28
-rw-r--r--chrome/common/partial_circular_buffer.cc162
-rw-r--r--chrome/common/partial_circular_buffer.h65
-rw-r--r--chrome/common/partial_circular_buffer_unittest.cc134
-rw-r--r--chrome/renderer/chrome_content_renderer_client.cc12
-rw-r--r--chrome/renderer/chrome_content_renderer_client.h7
-rw-r--r--chrome/renderer/media/webrtc_logging_handler_impl.cc75
-rw-r--r--chrome/renderer/media/webrtc_logging_handler_impl.h56
-rw-r--r--chrome/renderer/media/webrtc_logging_handler_impl_unittest.cc46
-rw-r--r--chrome/renderer/media/webrtc_logging_message_filter.cc88
-rw-r--r--chrome/renderer/media/webrtc_logging_message_filter.h63
19 files changed, 887 insertions, 5 deletions
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 568351e..393fec0 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -181,6 +181,10 @@
#include "chrome/browser/media_galleries/fileapi/media_file_system_mount_point_provider.h"
#endif
+#if defined(ENABLE_WEBRTC)
+#include "chrome/browser/media/webrtc_logging_handler_host.h"
+#endif
+
using base::FileDescriptor;
using content::AccessTokenStore;
using content::BrowserChildProcessHostIterator;
@@ -723,6 +727,9 @@ void ChromeContentBrowserClient::RenderProcessHostCreated(
new prerender::PrerenderMessageFilter(id, profile));
host->GetChannel()->AddFilter(new ValidationMessageMessageFilter(id));
host->GetChannel()->AddFilter(new TtsMessageFilter(id, profile));
+#if defined(ENABLE_WEBRTC)
+ host->GetChannel()->AddFilter(new WebRtcLoggingHandlerHost());
+#endif
host->Send(new ChromeViewMsg_SetIsIncognitoProcess(
profile->IsOffTheRecord()));
diff --git a/chrome/browser/media/webrtc_logging_handler_host.cc b/chrome/browser/media/webrtc_logging_handler_host.cc
new file mode 100644
index 0000000..c04a28a
--- /dev/null
+++ b/chrome/browser/media/webrtc_logging_handler_host.cc
@@ -0,0 +1,66 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/media/webrtc_logging_handler_host.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "chrome/common/media/webrtc_logging_messages.h"
+
+using content::BrowserThread;
+
+#if defined(OS_ANDROID)
+const size_t kWebRtcLogSize = 1 * 1024 * 1024; // 1 MB
+#else
+const size_t kWebRtcLogSize = 6 * 1024 * 1024; // 6 MB
+#endif
+
+WebRtcLoggingHandlerHost::WebRtcLoggingHandlerHost() {
+}
+
+WebRtcLoggingHandlerHost::~WebRtcLoggingHandlerHost() {
+}
+
+void WebRtcLoggingHandlerHost::OnChannelClosing() {
+ content::BrowserMessageFilter::OnChannelClosing();
+}
+
+void WebRtcLoggingHandlerHost::OnDestruct() const {
+ BrowserThread::DeleteOnIOThread::Destruct(this);
+}
+
+bool WebRtcLoggingHandlerHost::OnMessageReceived(const IPC::Message& message,
+ bool* message_was_ok) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP_EX(WebRtcLoggingHandlerHost, message, *message_was_ok)
+ IPC_MESSAGE_HANDLER(WebRtcLoggingMsg_OpenLog, OnOpenLog)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP_EX()
+
+ return handled;
+}
+
+void WebRtcLoggingHandlerHost::OnOpenLog(const std::string& app_session_id,
+ const std::string& app_url) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK(!base::SharedMemory::IsHandleValid(shared_memory_.handle()));
+
+ if (!shared_memory_.CreateAndMapAnonymous(kWebRtcLogSize)) {
+ DLOG(ERROR) << "Failed to create shared memory.";
+ Send(new WebRtcLoggingMsg_OpenLogFailed());
+ return;
+ }
+
+ base::SharedMemoryHandle foreign_memory_handle;
+ if (!shared_memory_.ShareToProcess(peer_handle(),
+ &foreign_memory_handle)) {
+ Send(new WebRtcLoggingMsg_OpenLogFailed());
+ return;
+ }
+
+ app_session_id_ = app_session_id;
+ app_url_ = app_url;
+ Send(new WebRtcLoggingMsg_LogOpened(foreign_memory_handle, kWebRtcLogSize));
+}
diff --git a/chrome/browser/media/webrtc_logging_handler_host.h b/chrome/browser/media/webrtc_logging_handler_host.h
new file mode 100644
index 0000000..2b735a8
--- /dev/null
+++ b/chrome/browser/media/webrtc_logging_handler_host.h
@@ -0,0 +1,40 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_MEDIA_WEBRTC_LOGGING_HANDLER_HOST_H_
+#define CHROME_BROWSER_MEDIA_WEBRTC_LOGGING_HANDLER_HOST_H_
+
+#include "base/basictypes.h"
+#include "base/shared_memory.h"
+#include "content/public/browser/browser_message_filter.h"
+
+// WebRtcLoggingHandlerHost handles operations regarding the WebRTC logging:
+// opening and closing shared memory buffer that the handler in the renderer
+// process writes to.
+class WebRtcLoggingHandlerHost : public content::BrowserMessageFilter {
+ public:
+ WebRtcLoggingHandlerHost();
+
+ private:
+ // BrowserMessageFilter implementation.
+ virtual void OnChannelClosing() OVERRIDE;
+ virtual void OnDestruct() const OVERRIDE;
+ virtual bool OnMessageReceived(const IPC::Message& message,
+ bool* message_was_ok) OVERRIDE;
+
+ friend class content::BrowserThread;
+ friend class base::DeleteHelper<WebRtcLoggingHandlerHost>;
+
+ virtual ~WebRtcLoggingHandlerHost();
+
+ void OnOpenLog(const std::string& app_session_id, const std::string& app_url);
+
+ base::SharedMemory shared_memory_;
+ std::string app_session_id_;
+ std::string app_url_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcLoggingHandlerHost);
+};
+
+#endif // CHROME_BROWSER_MEDIA_WEBRTC_LOGGING_HANDLER_HOST_H_
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index f6a3b1d..2c1fa67 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -973,6 +973,8 @@
'browser/media/media_stream_devices_controller.h',
'browser/media/media_stream_infobar_delegate.cc',
'browser/media/media_stream_infobar_delegate.h',
+ 'browser/media/webrtc_logging_handler_host.cc',
+ 'browser/media/webrtc_logging_handler_host.h',
'browser/media_galleries/fileapi/filtering_file_enumerator.cc',
'browser/media_galleries/fileapi/filtering_file_enumerator.h',
'browser/media_galleries/fileapi/itunes_finder.cc',
@@ -3068,11 +3070,11 @@
['exclude', '^browser/managed_mode/'],
]
}],
- ['enable_webrtc==1', {
- 'dependencies': [
- '../third_party/libjingle/libjingle.gyp:libjingle_webrtc',
- '../third_party/libjingle/libjingle.gyp:libpeerconnection',
- ],
+ ['enable_webrtc==0', {
+ 'sources!': [
+ 'browser/media/webrtc_logging_handler_host.cc',
+ 'browser/media/webrtc_logging_handler_host.h',
+ ]
}],
],
'target_conditions': [
diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi
index 58c0057..429cc9c 100644
--- a/chrome/chrome_common.gypi
+++ b/chrome/chrome_common.gypi
@@ -352,6 +352,7 @@
'common/mac/objc_method_swizzle.mm',
'common/mac/objc_zombie.h',
'common/mac/objc_zombie.mm',
+ 'common/media/webrtc_logging_messages.h',
'common/metrics/entropy_provider.cc',
'common/metrics/entropy_provider.h',
'common/metrics/metrics_log_base.cc',
@@ -380,6 +381,8 @@
'common/omaha_query_params/omaha_query_params.h',
'common/omnibox_focus_state.h',
'common/one_click_signin_messages.h',
+ 'common/partial_circular_buffer.cc',
+ 'common/partial_circular_buffer.h',
'common/pepper_flash.cc',
'common/pepper_flash.h',
'common/pref_names_util.cc',
@@ -573,6 +576,11 @@
'<(DEPTH)/base/third_party/nspr/nspr.gyp:nspr',
],
}],
+ ['enable_webrtc==0', {
+ 'sources!': [
+ 'common/media/webrtc_logging_messages.h',
+ ]
+ }],
],
'target_conditions': [
['OS == "ios"', {
diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi
index 032f414..653c1e1 100644
--- a/chrome/chrome_renderer.gypi
+++ b/chrome/chrome_renderer.gypi
@@ -145,6 +145,10 @@
'renderer/isolated_world_ids.h',
'renderer/loadtimes_extension_bindings.cc',
'renderer/loadtimes_extension_bindings.h',
+ 'renderer/media/webrtc_logging_handler_impl.cc',
+ 'renderer/media/webrtc_logging_handler_impl.h',
+ 'renderer/media/webrtc_logging_message_filter.cc',
+ 'renderer/media/webrtc_logging_message_filter.h',
'renderer/net/net_error_helper.cc',
'renderer/net/net_error_helper.h',
'renderer/net/predictor_queue.cc',
@@ -348,6 +352,14 @@
['exclude', '^renderer/safe_browsing/'],
],
}],
+ ['enable_webrtc==0', {
+ 'sources!': [
+ 'renderer/media/webrtc_logging_handler_impl.cc',
+ 'renderer/media/webrtc_logging_handler_impl.h',
+ 'renderer/media/webrtc_logging_message_filter.cc',
+ 'renderer/media/webrtc_logging_message_filter.h',
+ ],
+ }],
['OS=="mac"', {
'dependencies': [
'../third_party/mach_override/mach_override.gyp:mach_override',
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index 915cb64..b98e7c8 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -1671,6 +1671,7 @@
'common/multi_process_lock_unittest.cc',
'common/net/net_error_tracker_unittest.cc',
'common/net/x509_certificate_model_unittest.cc',
+ 'common/partial_circular_buffer_unittest.cc',
'common/pref_names_util_unittest.cc',
'common/service_process_util_unittest.cc',
'common/switch_utils_unittest.cc',
@@ -1687,6 +1688,7 @@
'renderer/extensions/json_schema_unittest.cc',
'renderer/extensions/module_system_unittest.cc',
'renderer/extensions/renderer_permissions_policy_delegate_unittest.cc',
+ 'renderer/media/webrtc_logging_handler_impl_unittest.cc',
'renderer/net/predictor_queue_unittest.cc',
'renderer/net/renderer_predictor_unittest.cc',
'renderer/plugins/plugin_uma_unittest.cc',
@@ -2049,6 +2051,11 @@
'browser/ui/startup/session_crashed_infobar_delegate_unittest.cc',
],
}],
+ ['enable_webrtc==0', {
+ 'sources!': [
+ 'renderer/media/webrtc_logging_handler_impl_unittest.cc',
+ ],
+ }],
['chromeos==1', {
'sources!': [
'browser/password_manager/native_backend_gnome_x_unittest.cc',
diff --git a/chrome/common/common_message_generator.h b/chrome/common/common_message_generator.h
index de8ab77..dce23eb 100644
--- a/chrome/common/common_message_generator.h
+++ b/chrome/common/common_message_generator.h
@@ -17,3 +17,7 @@
#include "chrome/common/spellcheck_messages.h"
#include "chrome/common/tts_messages.h"
#include "chrome/common/validation_message_messages.h"
+
+#if defined(ENABLE_WEBRTC)
+#include "chrome/common/media/webrtc_logging_messages.h"
+#endif
diff --git a/chrome/common/media/webrtc_logging_messages.h b/chrome/common/media/webrtc_logging_messages.h
new file mode 100644
index 0000000..5bcf8f9
--- /dev/null
+++ b/chrome/common/media/webrtc_logging_messages.h
@@ -0,0 +1,28 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// IPC messages for WebRTC logging.
+// Multiply-included message file, hence no include guard.
+
+#include "base/shared_memory.h"
+#include "ipc/ipc_message_macros.h"
+
+#define IPC_MESSAGE_START WebRtcLoggingMsgStart
+
+// Messages sent from the renderer to the browser.
+
+// Request to open a log.
+IPC_MESSAGE_CONTROL2(WebRtcLoggingMsg_OpenLog,
+ std::string /* app_session_id */,
+ std::string /* app_url */)
+
+// Messages sent from the browser to the renderer.
+
+// Notification that a log could not be opened.
+IPC_MESSAGE_CONTROL0(WebRtcLoggingMsg_OpenLogFailed)
+
+// Notification that a log has been opened.
+IPC_MESSAGE_CONTROL2(WebRtcLoggingMsg_LogOpened,
+ base::SharedMemoryHandle /* handle */,
+ uint32 /* length */)
diff --git a/chrome/common/partial_circular_buffer.cc b/chrome/common/partial_circular_buffer.cc
new file mode 100644
index 0000000..f6e0b70
--- /dev/null
+++ b/chrome/common/partial_circular_buffer.cc
@@ -0,0 +1,162 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/common/partial_circular_buffer.h"
+
+#include <algorithm>
+
+#include "base/logging.h"
+
+namespace {
+
+inline uint32 Min3(uint32 a, uint32 b, uint32 c) {
+ return std::min(a, std::min(b, c));
+}
+
+} // namespace
+
+PartialCircularBuffer::PartialCircularBuffer(void* buffer,
+ uint32 buffer_size)
+ : buffer_data_(reinterpret_cast<BufferData*>(buffer)),
+ memory_buffer_size_(buffer_size),
+ data_size_(0),
+ position_(0),
+ total_read_(0) {
+ uint32 header_size =
+ buffer_data_->data - reinterpret_cast<uint8*>(buffer_data_);
+ data_size_ = memory_buffer_size_ - header_size;
+
+ DCHECK(buffer_data_);
+ DCHECK_GE(memory_buffer_size_, header_size);
+ DCHECK_LE(buffer_data_->total_written, data_size_);
+ DCHECK_LT(buffer_data_->wrap_position, data_size_);
+ DCHECK_LT(buffer_data_->end_position, data_size_);
+}
+
+PartialCircularBuffer::PartialCircularBuffer(void* buffer,
+ uint32 buffer_size,
+ uint32 wrap_position)
+ : buffer_data_(reinterpret_cast<BufferData*>(buffer)),
+ memory_buffer_size_(buffer_size),
+ data_size_(0),
+ position_(0),
+ total_read_(0) {
+ uint32 header_size =
+ buffer_data_->data - reinterpret_cast<uint8*>(buffer_data_);
+ data_size_ = memory_buffer_size_ - header_size;
+
+ DCHECK(buffer_data_);
+ DCHECK_GE(memory_buffer_size_, header_size);
+ DCHECK_LT(wrap_position, data_size_);
+
+ buffer_data_->total_written = 0;
+ buffer_data_->wrap_position = wrap_position;
+ buffer_data_->end_position = 0;
+}
+
+uint32 PartialCircularBuffer::Read(void* buffer, uint32 buffer_size) {
+ DCHECK(buffer_data_);
+ if (total_read_ >= buffer_data_->total_written)
+ return 0;
+
+ uint8* buffer_uint8 = reinterpret_cast<uint8*>(buffer);
+ uint32 read = 0;
+
+ // Read from beginning part.
+ if (position_ < buffer_data_->wrap_position) {
+ uint32 to_wrap_pos = buffer_data_->wrap_position - position_;
+ uint32 to_eow = buffer_data_->total_written - total_read_;
+ uint32 to_read = Min3(buffer_size, to_wrap_pos, to_eow);
+ memcpy(buffer_uint8, buffer_data_->data + position_, to_read);
+ position_ += to_read;
+ total_read_ += to_read;
+ read += to_read;
+ if (position_ == buffer_data_->wrap_position &&
+ buffer_data_->total_written == data_size_) {
+ // We've read all the beginning part, set the position to the middle part.
+ // (The second condition above checks if the wrapping part is filled, i.e.
+ // writing has wrapped.)
+ position_ = buffer_data_->end_position;
+ }
+ if (read >= buffer_size) {
+ DCHECK_EQ(read, buffer_size);
+ return read;
+ }
+ if (read >= to_eow) {
+ DCHECK_EQ(read, to_eow);
+ DCHECK_EQ(total_read_, buffer_data_->total_written);
+ return read;
+ }
+ }
+
+ // Read from middle part.
+ DCHECK_GE(position_, buffer_data_->wrap_position);
+ if (position_ >= buffer_data_->end_position) {
+ uint32 remaining_buffer_size = buffer_size - read;
+ uint32 to_eof = data_size_ - position_;
+ uint32 to_eow = buffer_data_->total_written - total_read_;
+ uint32 to_read = Min3(remaining_buffer_size, to_eof, to_eow);
+ memcpy(buffer_uint8 + read, buffer_data_->data + position_, to_read);
+ position_ += to_read;
+ total_read_ += to_read;
+ read += to_read;
+ if (position_ == data_size_) {
+ // We've read all the middle part, set position to the end part.
+ position_ = buffer_data_->wrap_position;
+ }
+ if (read >= buffer_size) {
+ DCHECK_EQ(read, buffer_size);
+ return read;
+ }
+ if (total_read_ >= buffer_data_->total_written) {
+ DCHECK_EQ(total_read_, buffer_data_->total_written);
+ return read;
+ }
+ }
+
+ // Read from end part.
+ DCHECK_GE(position_, buffer_data_->wrap_position);
+ DCHECK_LT(position_, buffer_data_->end_position);
+ uint32 remaining_buffer_size = buffer_size - read;
+ uint32 to_eob = buffer_data_->end_position - position_;
+ uint32 to_eow = buffer_data_->total_written - total_read_;
+ uint32 to_read = Min3(remaining_buffer_size, to_eob, to_eow);
+ memcpy(buffer_uint8 + read, buffer_data_->data + position_, to_read);
+ position_ += to_read;
+ total_read_ += to_read;
+ read += to_read;
+ DCHECK_LE(read, buffer_size);
+ DCHECK_LE(total_read_, buffer_data_->total_written);
+ return read;
+}
+
+void PartialCircularBuffer::Write(const void* buffer, uint32 buffer_size) {
+ DCHECK(buffer_data_);
+ uint32 position_before_write = position_;
+
+ uint32 to_eof = data_size_ - position_;
+ uint32 to_write = std::min(buffer_size, to_eof);
+ DoWrite(buffer_data_->data + position_, buffer, to_write);
+ if (position_ >= data_size_) {
+ DCHECK_EQ(position_, data_size_);
+ position_ = buffer_data_->wrap_position;
+ }
+
+ if (to_write < buffer_size) {
+ uint32 remainder_to_write = buffer_size - to_write;
+ DCHECK_LT(position_, position_before_write);
+ DCHECK_LE(position_ + remainder_to_write, position_before_write);
+ DoWrite(buffer_data_->data + position_,
+ reinterpret_cast<const uint8*>(buffer) + to_write,
+ remainder_to_write);
+ }
+}
+
+void PartialCircularBuffer::DoWrite(void* dest, const void* src, uint32 num) {
+ memcpy(dest, src, num);
+ position_ += num;
+ buffer_data_->total_written =
+ std::min(buffer_data_->total_written + num, data_size_);
+ buffer_data_->end_position = position_;
+}
diff --git a/chrome/common/partial_circular_buffer.h b/chrome/common/partial_circular_buffer.h
new file mode 100644
index 0000000..582487c
--- /dev/null
+++ b/chrome/common/partial_circular_buffer.h
@@ -0,0 +1,65 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_COMMON_PARTIAL_CIRCULAR_BUFFER_H_
+#define CHROME_COMMON_PARTIAL_CIRCULAR_BUFFER_H_
+
+#include "base/basictypes.h"
+#include "base/gtest_prod_util.h"
+
+// A wrapper around a memory buffer that allows circular read and write with a
+// selectable wrapping position. Buffer layout (after wrap; H is header):
+// -----------------------------------------------------------
+// | H | Beginning | End | Middle |
+// -----------------------------------------------------------
+// ^---- Non-wrapping -----^ ^--------- Wrapping ----------^
+// The non-wrapping part is never overwritten. The wrapping part will be
+// circular. The very first part is the header (see the BufferData struct
+// below). It consists of the following information:
+// - Length written to the buffer (not including header).
+// - Wrapping position.
+// - End position of buffer. (If the last byte is at x, this will be x + 1.)
+// Users of wrappers around the same underlying buffer must ensure that writing
+// is finished before reading is started.
+class PartialCircularBuffer {
+ public:
+ // Use for reading. |buffer_size| is in bytes and must be larger than the
+ // header size (see above).
+ PartialCircularBuffer(void* buffer, uint32 buffer_size);
+
+ // Use for writing. |buffer_size| is in bytes and must be larger than the
+ // header size (see above).
+ PartialCircularBuffer(void* buffer,
+ uint32 buffer_size,
+ uint32 wrap_position);
+
+ uint32 Read(void* buffer, uint32 buffer_size);
+ void Write(const void* buffer, uint32 buffer_size);
+
+ private:
+ friend class PartialCircularBufferTest;
+
+#pragma pack(push)
+#pragma pack(4)
+ struct BufferData {
+ uint32 total_written;
+ uint32 wrap_position;
+ uint32 end_position;
+ uint8 data[1];
+ };
+#pragma pack(pop)
+
+ void DoWrite(void* dest, const void* src, uint32 num);
+
+ // Used for reading and writing.
+ BufferData* buffer_data_;
+ uint32 memory_buffer_size_;
+ uint32 data_size_;
+ uint32 position_;
+
+ // Used for reading.
+ uint32 total_read_;
+};
+
+#endif // CHROME_COMMON_PARTIAL_CIRCULAR_BUFFER_H_
diff --git a/chrome/common/partial_circular_buffer_unittest.cc b/chrome/common/partial_circular_buffer_unittest.cc
new file mode 100644
index 0000000..f176e82
--- /dev/null
+++ b/chrome/common/partial_circular_buffer_unittest.cc
@@ -0,0 +1,134 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// The test buffer data is 52 bytes, wrap position is set to 20 (this is
+// arbitrarily chosen). The total buffer size is allocated dynamically based on
+// the actual header size. This gives:
+// Header of some size, non-wrapping part 20 bytes, wrapping part 32 bytes.
+// As input data, a 14 byte array is used and repeatedly written. It's chosen
+// not to be an integer factor smaller than the wrapping part. This ensures that
+// the wrapped data isn't repeated at the same position.
+// Note that desipte the number of wraps (if one or more), the reference output
+// data is the same since the offset at each wrap is always the same.
+
+#include "base/memory/scoped_ptr.h"
+#include "chrome/common/partial_circular_buffer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+const uint32 kWrapPosition = 20;
+const uint8 kInputData[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
+const uint8 kOutputRefDataWrap[] =
+ // The 20 bytes in the non-wrapping part.
+ {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 1, 2, 3, 4, 5, 6,
+ // The 32 bytes in wrapping part.
+ 11, 12, 13, 14,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
+
+class PartialCircularBufferTest : public testing::Test {
+ public:
+ PartialCircularBufferTest() {
+ PartialCircularBuffer::BufferData test_struct;
+ buffer_header_size_ =
+ &test_struct.data[0] - reinterpret_cast<uint8*>(&test_struct);
+
+ buffer_.reset(new uint8[buffer_header_size_ + sizeof(kOutputRefDataWrap)]);
+ pcb_write_.reset(new PartialCircularBuffer(
+ buffer_.get(),
+ buffer_header_size_ + sizeof(kOutputRefDataWrap),
+ kWrapPosition));
+ }
+
+ void WriteToBuffer(int num) {
+ for (int i = 0; i < num; ++i)
+ pcb_write_->Write(kInputData, sizeof(kInputData));
+ }
+
+ void InitReadBuffer() {
+ pcb_read_.reset(new PartialCircularBuffer(
+ buffer_.get(), buffer_header_size_ + sizeof(kOutputRefDataWrap)));
+ }
+
+ protected:
+ scoped_ptr<PartialCircularBuffer> pcb_write_;
+ scoped_ptr<PartialCircularBuffer> pcb_read_;
+ scoped_ptr<uint8[]> buffer_;
+ uint32 buffer_header_size_;
+
+ DISALLOW_COPY_AND_ASSIGN(PartialCircularBufferTest);
+};
+
+TEST_F(PartialCircularBufferTest, NoWrapBeginningPartOnly) {
+ WriteToBuffer(1);
+ InitReadBuffer();
+
+ uint8 output_data[sizeof(kInputData)] = {0};
+ EXPECT_EQ(sizeof(output_data),
+ pcb_read_->Read(output_data, sizeof(output_data)));
+
+ EXPECT_EQ(0, memcmp(kInputData, output_data, sizeof(kInputData)));
+
+ EXPECT_EQ(0u, pcb_read_->Read(output_data, sizeof(output_data)));
+}
+
+TEST_F(PartialCircularBufferTest, NoWrapBeginningAndEndParts) {
+ WriteToBuffer(2);
+ InitReadBuffer();
+
+ uint8 output_data[2 * sizeof(kInputData)] = {0};
+ EXPECT_EQ(sizeof(output_data),
+ pcb_read_->Read(output_data, sizeof(output_data)));
+
+ const uint8 output_ref_data[2 * sizeof(kInputData)] =
+ {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
+ EXPECT_EQ(0, memcmp(output_ref_data, output_data, sizeof(output_data)));
+
+ EXPECT_EQ(0u, pcb_read_->Read(output_data, sizeof(output_data)));
+}
+
+TEST_F(PartialCircularBufferTest, WrapOnce) {
+ WriteToBuffer(4);
+ InitReadBuffer();
+
+ uint8 output_data[sizeof(kOutputRefDataWrap)] = {0};
+ EXPECT_EQ(sizeof(output_data),
+ pcb_read_->Read(output_data, sizeof(output_data)));
+
+ EXPECT_EQ(0, memcmp(kOutputRefDataWrap, output_data, sizeof(output_data)));
+
+ EXPECT_EQ(0u, pcb_read_->Read(output_data, sizeof(output_data)));
+}
+
+TEST_F(PartialCircularBufferTest, WrapTwice) {
+ WriteToBuffer(7);
+ InitReadBuffer();
+
+ uint8 output_data[sizeof(kOutputRefDataWrap)] = {0};
+ EXPECT_EQ(sizeof(output_data),
+ pcb_read_->Read(output_data, sizeof(output_data)));
+
+ EXPECT_EQ(0, memcmp(kOutputRefDataWrap, output_data, sizeof(output_data)));
+
+ EXPECT_EQ(0u, pcb_read_->Read(output_data, sizeof(output_data)));
+}
+
+TEST_F(PartialCircularBufferTest, WrapOnceSmallerOutputBuffer) {
+ WriteToBuffer(4);
+ InitReadBuffer();
+
+ uint8 output_data[sizeof(kOutputRefDataWrap)] = {0};
+ const uint32 size_per_read = 16;
+ uint32 read = 0;
+ for (; read + size_per_read <= sizeof(output_data); read += size_per_read) {
+ EXPECT_EQ(size_per_read,
+ pcb_read_->Read(output_data + read, size_per_read));
+ }
+ EXPECT_EQ(sizeof(output_data) - read,
+ pcb_read_->Read(output_data + read, size_per_read));
+
+ EXPECT_EQ(0, memcmp(kOutputRefDataWrap, output_data, sizeof(output_data)));
+
+ EXPECT_EQ(0u, pcb_read_->Read(output_data, sizeof(output_data)));
+}
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index 14c0cd0..092b48f 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -100,6 +100,10 @@
#include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR.
+#if defined(ENABLE_WEBRTC)
+#include "chrome/renderer/media/webrtc_logging_message_filter.h"
+#endif
+
using autofill::AutofillAgent;
using autofill::PasswordAutofillAgent;
using autofill::PasswordGenerationManager;
@@ -223,6 +227,10 @@ void ChromeContentRendererClient::RenderThreadStarted() {
phishing_classifier_.reset(safe_browsing::PhishingClassifierFilter::Create());
#endif
prerender_dispatcher_.reset(new prerender::PrerenderDispatcher());
+#if defined(ENABLE_WEBRTC)
+ webrtc_logging_message_filter_ = new WebRtcLoggingMessageFilter(
+ content::RenderThread::Get()->GetIOMessageLoopProxy());
+#endif
RenderThread* thread = RenderThread::Get();
@@ -235,6 +243,10 @@ void ChromeContentRendererClient::RenderThreadStarted() {
thread->AddObserver(visited_link_slave_.get());
thread->AddObserver(prerender_dispatcher_.get());
+#if defined(ENABLE_WEBRTC)
+ thread->AddFilter(webrtc_logging_message_filter_.get());
+#endif
+
thread->RegisterExtension(extensions_v8::ExternalExtension::Get());
thread->RegisterExtension(extensions_v8::LoadTimesExtension::Get());
diff --git a/chrome/renderer/chrome_content_renderer_client.h b/chrome/renderer/chrome_content_renderer_client.h
index 02f620b..4edcfb8 100644
--- a/chrome/renderer/chrome_content_renderer_client.h
+++ b/chrome/renderer/chrome_content_renderer_client.h
@@ -48,6 +48,10 @@ namespace WebKit {
class WebSecurityOrigin;
}
+#if defined(ENABLE_WEBRTC)
+class WebRtcLoggingMessageFilter;
+#endif
+
namespace chrome {
class ChromeContentRendererClient : public content::ContentRendererClient {
@@ -184,6 +188,9 @@ class ChromeContentRendererClient : public content::ContentRendererClient {
scoped_ptr<visitedlink::VisitedLinkSlave> visited_link_slave_;
scoped_ptr<safe_browsing::PhishingClassifierFilter> phishing_classifier_;
scoped_ptr<prerender::PrerenderDispatcher> prerender_dispatcher_;
+#if defined(ENABLE_WEBRTC)
+ scoped_refptr<WebRtcLoggingMessageFilter> webrtc_logging_message_filter_;
+#endif
};
} // namespace chrome
diff --git a/chrome/renderer/media/webrtc_logging_handler_impl.cc b/chrome/renderer/media/webrtc_logging_handler_impl.cc
new file mode 100644
index 0000000..b46ec73
--- /dev/null
+++ b/chrome/renderer/media/webrtc_logging_handler_impl.cc
@@ -0,0 +1,75 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/renderer/media/webrtc_logging_handler_impl.h"
+
+#include "base/logging.h"
+#include "base/message_loop_proxy.h"
+#include "chrome/common/partial_circular_buffer.h"
+#include "chrome/renderer/media/webrtc_logging_message_filter.h"
+
+WebRtcLoggingHandlerImpl::WebRtcLoggingHandlerImpl(
+ const scoped_refptr<base::MessageLoopProxy>& io_message_loop,
+ WebRtcLoggingMessageFilter* message_filter)
+ : io_message_loop_(io_message_loop),
+ message_filter_(message_filter),
+ log_initialized_(false) {
+ content::InitWebRtcLoggingDelegate(this);
+}
+
+WebRtcLoggingHandlerImpl::~WebRtcLoggingHandlerImpl() {
+ DCHECK(CalledOnValidThread());
+}
+
+void WebRtcLoggingHandlerImpl::InitLogging(const std::string& app_session_id,
+ const std::string& app_url) {
+ DCHECK(CalledOnValidThread());
+
+ if (!log_initialized_) {
+ log_initialized_ = true;
+ message_filter_->InitLogging(app_session_id, app_url);
+ }
+}
+
+void WebRtcLoggingHandlerImpl::LogMessage(const std::string& message) {
+ if (!CalledOnValidThread()) {
+ io_message_loop_->PostTask(
+ FROM_HERE, base::Bind(
+ &WebRtcLoggingHandlerImpl::LogMessage,
+ base::Unretained(this),
+ message));
+ return;
+ }
+
+ if (circular_buffer_) {
+ circular_buffer_->Write(message.c_str(), message.length());
+ const char eol = '\n';
+ circular_buffer_->Write(&eol, 1);
+ }
+}
+
+void WebRtcLoggingHandlerImpl::OnFilterRemoved() {
+ DCHECK(CalledOnValidThread());
+ message_filter_ = NULL;
+}
+
+void WebRtcLoggingHandlerImpl::OnLogOpened(
+ base::SharedMemoryHandle handle,
+ uint32 length) {
+ DCHECK(CalledOnValidThread());
+
+ shared_memory_.reset(new base::SharedMemory(handle, false));
+ CHECK(shared_memory_->Map(length));
+ circular_buffer_.reset(
+ new PartialCircularBuffer(shared_memory_->memory(),
+ length,
+ length / 2));
+}
+
+void WebRtcLoggingHandlerImpl::OnOpenLogFailed() {
+ DCHECK(CalledOnValidThread());
+ DLOG(ERROR) << "Could not open log.";
+ // TODO(grunell): Implement.
+ NOTIMPLEMENTED();
+}
diff --git a/chrome/renderer/media/webrtc_logging_handler_impl.h b/chrome/renderer/media/webrtc_logging_handler_impl.h
new file mode 100644
index 0000000..5a98143
--- /dev/null
+++ b/chrome/renderer/media/webrtc_logging_handler_impl.h
@@ -0,0 +1,56 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_RENDERER_MEDIA_WEBRTC_LOGGING_HANDLER_IMPL_H_
+#define CHROME_RENDERER_MEDIA_WEBRTC_LOGGING_HANDLER_IMPL_H_
+
+#include <string>
+
+#include "base/shared_memory.h"
+#include "content/public/renderer/webrtc_log_message_delegate.h"
+#include "ipc/ipc_channel_proxy.h"
+
+namespace base {
+class MessageLoopProxy;
+}
+
+class PartialCircularBuffer;
+class WebRtcLoggingMessageFilter;
+
+// WebRtcLoggingHandlerImpl handles WebRTC logging. There is one object per
+// render process, owned by WebRtcLoggingMessageFilter. It communicates with
+// WebRtcLoggingHandlerHost and receives logging messages from libjingle and
+// writes them to a shared memory buffer.
+class WebRtcLoggingHandlerImpl
+ : public content::WebRtcLogMessageDelegate,
+ public base::NonThreadSafe {
+ public:
+ WebRtcLoggingHandlerImpl(
+ const scoped_refptr<base::MessageLoopProxy>& io_message_loop,
+ WebRtcLoggingMessageFilter* message_filter);
+
+ virtual ~WebRtcLoggingHandlerImpl();
+
+ // content::WebRtcLogMessageDelegate implementation.
+ virtual void InitLogging(const std::string& app_session_id,
+ const std::string& app_url) OVERRIDE;
+ virtual void LogMessage(const std::string& message) OVERRIDE;
+
+ void OnFilterRemoved();
+
+ void OnLogOpened(base::SharedMemoryHandle handle, uint32 length);
+ void OnOpenLogFailed();
+
+ private:
+ scoped_refptr<base::MessageLoopProxy> io_message_loop_;
+ scoped_ptr<base::SharedMemory> shared_memory_;
+ scoped_ptr<PartialCircularBuffer> circular_buffer_;
+
+ WebRtcLoggingMessageFilter* message_filter_;
+ bool log_initialized_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcLoggingHandlerImpl);
+};
+
+#endif // CHROME_RENDERER_MEDIA_WEBRTC_LOGGING_HANDLER_IMPL_H_
diff --git a/chrome/renderer/media/webrtc_logging_handler_impl_unittest.cc b/chrome/renderer/media/webrtc_logging_handler_impl_unittest.cc
new file mode 100644
index 0000000..b12f622
--- /dev/null
+++ b/chrome/renderer/media/webrtc_logging_handler_impl_unittest.cc
@@ -0,0 +1,46 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+
+#include "base/process_util.h"
+#include "chrome/common/partial_circular_buffer.h"
+#include "chrome/renderer/media/webrtc_logging_handler_impl.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+TEST(WebRtcLoggingHandlerImplTest, Basic) {
+ const uint32 kTestLogSize = 1024; // 1 KB
+ const char kTestString[] = "abcdefghijklmnopqrstuvwxyz";
+
+ base::MessageLoop message_loop(base::MessageLoop::TYPE_IO);
+
+ scoped_ptr<WebRtcLoggingHandlerImpl> logging_handler(
+ new WebRtcLoggingHandlerImpl(message_loop.message_loop_proxy(), NULL));
+
+ base::SharedMemory shared_memory;
+ ASSERT_TRUE(shared_memory.CreateAndMapAnonymous(kTestLogSize));
+ base::SharedMemoryHandle new_handle;
+ ASSERT_TRUE(shared_memory.ShareToProcess(base::GetCurrentProcessHandle(),
+ &new_handle));
+ logging_handler->OnLogOpened(new_handle, kTestLogSize);
+
+ logging_handler->LogMessage(kTestString);
+ logging_handler->LogMessage(kTestString);
+
+ PartialCircularBuffer read_pcb(
+ reinterpret_cast<uint8*>(shared_memory.memory()), kTestLogSize);
+
+ // Size is calculated as (sizeof(kTestString) - 1 for terminating null
+ // + 1 for eol added for each log message in LogMessage) * 2 + 1 for
+ // terminating null.
+ char read_buffer[sizeof(kTestString) * 2 + 1] = {0};
+
+ uint32 read = read_pcb.Read(read_buffer, sizeof(read_buffer));
+ EXPECT_EQ(sizeof(read_buffer) - 1, read);
+ std::string ref_output = kTestString;
+ ref_output.append("\n");
+ ref_output.append(kTestString);
+ ref_output.append("\n");
+ EXPECT_STREQ(ref_output.c_str(), read_buffer);
+}
diff --git a/chrome/renderer/media/webrtc_logging_message_filter.cc b/chrome/renderer/media/webrtc_logging_message_filter.cc
new file mode 100644
index 0000000..f12c695
--- /dev/null
+++ b/chrome/renderer/media/webrtc_logging_message_filter.cc
@@ -0,0 +1,88 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/renderer/media/webrtc_logging_message_filter.h"
+
+#include "base/logging.h"
+#include "base/message_loop_proxy.h"
+#include "chrome/common/media/webrtc_logging_messages.h"
+#include "chrome/renderer/media/webrtc_logging_handler_impl.h"
+#include "ipc/ipc_logging.h"
+
+WebRtcLoggingMessageFilter::WebRtcLoggingMessageFilter(
+ const scoped_refptr<base::MessageLoopProxy>& io_message_loop)
+ : logging_handler_(NULL),
+ io_message_loop_(io_message_loop),
+ channel_(NULL) {
+ io_message_loop_->PostTask(
+ FROM_HERE, base::Bind(
+ &WebRtcLoggingMessageFilter::CreateLoggingHandler,
+ base::Unretained(this)));
+}
+
+WebRtcLoggingMessageFilter::~WebRtcLoggingMessageFilter() {
+}
+
+bool WebRtcLoggingMessageFilter::OnMessageReceived(
+ const IPC::Message& message) {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(WebRtcLoggingMessageFilter, message)
+ IPC_MESSAGE_HANDLER(WebRtcLoggingMsg_LogOpened, OnLogOpened)
+ IPC_MESSAGE_HANDLER(WebRtcLoggingMsg_OpenLogFailed, OnOpenLogFailed)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void WebRtcLoggingMessageFilter::OnFilterAdded(IPC::Channel* channel) {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ channel_ = channel;
+}
+
+void WebRtcLoggingMessageFilter::OnFilterRemoved() {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ channel_ = NULL;
+ logging_handler_->OnFilterRemoved();
+}
+
+void WebRtcLoggingMessageFilter::OnChannelClosing() {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ channel_ = NULL;
+ logging_handler_->OnFilterRemoved();
+}
+
+void WebRtcLoggingMessageFilter::InitLogging(
+ const std::string& app_session_id,
+ const std::string& app_url) {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ Send(new WebRtcLoggingMsg_OpenLog(app_session_id, app_url));
+}
+
+void WebRtcLoggingMessageFilter::CreateLoggingHandler() {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ logging_handler_ = new WebRtcLoggingHandlerImpl(io_message_loop_, this);
+}
+
+void WebRtcLoggingMessageFilter::OnLogOpened(
+ base::SharedMemoryHandle handle,
+ uint32 length) {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ logging_handler_->OnLogOpened(handle, length);
+}
+
+void WebRtcLoggingMessageFilter::OnOpenLogFailed() {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ logging_handler_->OnOpenLogFailed();
+}
+
+void WebRtcLoggingMessageFilter::Send(IPC::Message* message) {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ if (!channel_) {
+ DLOG(ERROR) << "IPC channel not available.";
+ delete message;
+ } else {
+ channel_->Send(message);
+ }
+}
diff --git a/chrome/renderer/media/webrtc_logging_message_filter.h b/chrome/renderer/media/webrtc_logging_message_filter.h
new file mode 100644
index 0000000..4466a1cd
--- /dev/null
+++ b/chrome/renderer/media/webrtc_logging_message_filter.h
@@ -0,0 +1,63 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_RENDERER_MEDIA_WEBRTC_LOGGING_MESSAGE_FILTER_H_
+#define CHROME_RENDERER_MEDIA_WEBRTC_LOGGING_MESSAGE_FILTER_H_
+
+#include "base/shared_memory.h"
+#include "ipc/ipc_channel_proxy.h"
+
+namespace base {
+class MessageLoopProxy;
+}
+
+class WebRtcLoggingHandlerImpl;
+
+// Filter for WebRTC logging messages. Sits between WebRtcLoggingHandlerImpl
+// (renderer process) and WebRtcLoggingHandlerHost (browser process). Must be
+// called on the IO thread.
+class WebRtcLoggingMessageFilter
+ : public IPC::ChannelProxy::MessageFilter {
+ public:
+ explicit WebRtcLoggingMessageFilter(
+ const scoped_refptr<base::MessageLoopProxy>& io_message_loop);
+
+ virtual void InitLogging(const std::string& app_session_id,
+ const std::string& app_url);
+
+ const scoped_refptr<base::MessageLoopProxy>& io_message_loop() {
+ return io_message_loop_;
+ }
+
+ protected:
+ virtual ~WebRtcLoggingMessageFilter();
+
+ private:
+ // IPC::ChannelProxy::MessageFilter implementation.
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+ virtual void OnFilterAdded(IPC::Channel* channel) OVERRIDE;
+ virtual void OnFilterRemoved() OVERRIDE;
+ virtual void OnChannelClosing() OVERRIDE;
+
+ void CreateLoggingHandler();
+
+ void OnLogOpened(base::SharedMemoryHandle handle, uint32 length);
+ void OnOpenLogFailed();
+
+ void Send(IPC::Message* message);
+
+ // Owned by this class. The only other pointer to it is in libjingle's logging
+ // file. That's a global pointer used on different threads, so we will leak
+ // this object when we go away to ensure that it outlives any log messages
+ // coming from libjingle.
+ WebRtcLoggingHandlerImpl* logging_handler_;
+
+ scoped_refptr<base::MessageLoopProxy> io_message_loop_;
+
+ IPC::Channel* channel_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcLoggingMessageFilter);
+};
+
+#endif // CHROME_RENDERER_MEDIA_WEBRTC_LOGGING_MESSAGE_FILTER_H_