diff options
author | grunell@chromium.org <grunell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-03 11:52:47 +0000 |
---|---|---|
committer | grunell@chromium.org <grunell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-03 11:52:47 +0000 |
commit | 731c1368a3d9780b031894988ca68fd9a904c853 (patch) | |
tree | 87c9cdb8c85bfffe8ffd16df741ebaf6a24ae7f7 | |
parent | b55e344438109fa84fa43157a7f2f715684b7edf (diff) | |
download | chromium_src-731c1368a3d9780b031894988ca68fd9a904c853.zip chromium_src-731c1368a3d9780b031894988ca68fd9a904c853.tar.gz chromium_src-731c1368a3d9780b031894988ca68fd9a904c853.tar.bz2 |
Implementing uploading of a WebRTC diagnostic log.
BUG=229829
Review URL: https://chromiumcodereview.appspot.com/14329020
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@203700 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/browser_process.h | 7 | ||||
-rw-r--r-- | chrome/browser/browser_process_impl.cc | 12 | ||||
-rw-r--r-- | chrome/browser/browser_process_impl.h | 8 | ||||
-rw-r--r-- | chrome/browser/media/DEPS | 1 | ||||
-rw-r--r-- | chrome/browser/media/webrtc_log_uploader.cc | 198 | ||||
-rw-r--r-- | chrome/browser/media/webrtc_log_uploader.h | 75 | ||||
-rw-r--r-- | chrome/browser/media/webrtc_logging_handler_host.cc | 77 | ||||
-rw-r--r-- | chrome/browser/media/webrtc_logging_handler_host.h | 33 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 4 | ||||
-rw-r--r-- | chrome/test/base/testing_browser_process.cc | 6 | ||||
-rw-r--r-- | chrome/test/base/testing_browser_process.h | 4 |
11 files changed, 408 insertions, 17 deletions
diff --git a/chrome/browser/browser_process.h b/chrome/browser/browser_process.h index 004fdee..d6f8595 100644 --- a/chrome/browser/browser_process.h +++ b/chrome/browser/browser_process.h @@ -40,6 +40,9 @@ class RenderWidgetSnapshotTaker; class SafeBrowsingService; class StatusTray; class WatchDogThread; +#if defined(ENABLE_WEBRTC) +class WebRtcLogUploader; +#endif namespace chrome { class MediaFileSystemRegistry; @@ -213,6 +216,10 @@ class BrowserProcess { virtual bool created_local_state() const = 0; +#if defined(ENABLE_WEBRTC) + virtual WebRtcLogUploader* webrtc_log_uploader() = 0; +#endif + private: DISALLOW_COPY_AND_ASSIGN(BrowserProcess); }; diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index 2d7ccf9..18ae0dd 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc @@ -120,6 +120,10 @@ #include "chrome/browser/ui/app_list/app_list_service.h" #endif +#if defined(ENABLE_WEBRTC) +#include "chrome/browser/media/webrtc_log_uploader.h" +#endif + #if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) // How often to check if the persistent instance of Chrome needs to restart // to install an update. @@ -631,6 +635,14 @@ bool BrowserProcessImpl::created_local_state() const { return created_local_state_; } +#if defined(ENABLE_WEBRTC) +WebRtcLogUploader* BrowserProcessImpl::webrtc_log_uploader() { + if (!webrtc_log_uploader_.get()) + webrtc_log_uploader_.reset(new WebRtcLogUploader()); + return webrtc_log_uploader_.get(); +} +#endif + // static void BrowserProcessImpl::RegisterPrefs(PrefRegistrySimple* registry) { registry->RegisterBooleanPref(prefs::kDefaultBrowserSettingEnabled, diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h index e80b4fb..2514039 100644 --- a/chrome/browser/browser_process_impl.h +++ b/chrome/browser/browser_process_impl.h @@ -128,6 +128,9 @@ class BrowserProcessImpl : public BrowserProcess, virtual chrome::MediaFileSystemRegistry* media_file_system_registry() OVERRIDE; virtual bool created_local_state() const OVERRIDE; +#if defined(ENABLE_WEBRTC) + virtual WebRtcLogUploader* webrtc_log_uploader() OVERRIDE; +#endif static void RegisterPrefs(PrefRegistrySimple* registry); @@ -293,6 +296,11 @@ class BrowserProcessImpl : public BrowserProcess, // the callstack which released the final module reference count. base::debug::StackTrace release_last_reference_callstack_; +#if defined(ENABLE_WEBRTC) + // Lazily initialized. + scoped_ptr<WebRtcLogUploader> webrtc_log_uploader_; +#endif + DISALLOW_COPY_AND_ASSIGN(BrowserProcessImpl); }; diff --git a/chrome/browser/media/DEPS b/chrome/browser/media/DEPS index cc5cd70..05f22d2 100644 --- a/chrome/browser/media/DEPS +++ b/chrome/browser/media/DEPS @@ -1,3 +1,4 @@ include_rules = [ "+media/base", + "+third_party/zlib" ] diff --git a/chrome/browser/media/webrtc_log_uploader.cc b/chrome/browser/media/webrtc_log_uploader.cc new file mode 100644 index 0000000..763253a --- /dev/null +++ b/chrome/browser/media/webrtc_log_uploader.cc @@ -0,0 +1,198 @@ +// 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_log_uploader.h" + +#include "base/logging.h" +#include "base/shared_memory.h" +#include "base/stringprintf.h" +#include "chrome/common/chrome_version_info.h" +#include "chrome/common/partial_circular_buffer.h" +#include "content/public/browser/browser_thread.h" +#include "net/base/mime_util.h" +#include "net/base/network_delegate.h" +#include "net/proxy/proxy_config.h" +#include "net/proxy/proxy_config_service.h" +#include "net/url_request/url_fetcher.h" +#include "net/url_request/url_request_context.h" +#include "net/url_request/url_request_context_builder.h" +#include "net/url_request/url_request_context_getter.h" +#include "third_party/zlib/zlib.h" + +namespace { + +const int kLogCountLimit = 5; +const uint32 kIntermediateCompressionBufferBytes = 256 * 1024; // 256 KB + +const char kUploadURL[] = "https://clients2.google.com/cr/report"; +const char kUploadContentType[] = "multipart/form-data"; +const char kMultipartBoundary[] = + "----**--yradnuoBgoLtrapitluMklaTelgooG--**----"; + +} // namespace + +WebRtcLogUploader::WebRtcLogUploader() + : log_count_(0) { +} + +WebRtcLogUploader::~WebRtcLogUploader() { +} + +void WebRtcLogUploader::OnURLFetchComplete( + const net::URLFetcher* source) { +} + +void WebRtcLogUploader::OnURLFetchUploadProgress( + const net::URLFetcher* source, int64 current, int64 total) { +} + +bool WebRtcLogUploader::ApplyForStartLogging() { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + if (log_count_ < kLogCountLimit) { + ++log_count_; + return true; + } + return false; +} + +void WebRtcLogUploader::UploadLog(net::URLRequestContextGetter* request_context, + scoped_ptr<base::SharedMemory> shared_memory, + uint32 length, + const std::string& app_session_id, + const std::string& app_url) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); + DCHECK(shared_memory); + DCHECK(shared_memory->memory()); + + std::string post_data; + SetupMultipart(&post_data, reinterpret_cast<uint8*>(shared_memory->memory()), + length, app_session_id, app_url); + + std::string content_type = kUploadContentType; + content_type.append("; boundary="); + content_type.append(kMultipartBoundary); + + net::URLFetcher* url_fetcher = + net::URLFetcher::Create(GURL(kUploadURL), net::URLFetcher::POST, this); + url_fetcher->SetRequestContext(request_context); + url_fetcher->SetUploadData(content_type, post_data); + url_fetcher->Start(); + + content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, + base::Bind(&WebRtcLogUploader::DecreaseLogCount, base::Unretained(this))); +} + +void WebRtcLogUploader::SetupMultipart(std::string* post_data, + uint8* log_buffer, + uint32 log_buffer_length, + const std::string& app_session_id, + const std::string& app_url) { +#if defined(OS_WIN) + const char product[] = "Chrome"; +#elif defined(OS_MACOSX) + const char product[] = "Chrome_Mac"; +#elif defined(OS_LINUX) +#if !defined(ADDRESS_SANITIZER) + const char product[] = "Chrome_Linux"; +#else + const char product[] = "Chrome_Linux_ASan"; +#endif +#elif defined(OS_ANDROID) + const char product[] = "Chrome_Android"; +#elif defined(OS_CHROMEOS) + const char product[] = "Chrome_ChromeOS"; +#else + // This file should not be compiled for other platforms. + COMPILE_ASSERT(false); +#endif + net::AddMultipartValueForUpload("prod", product, kMultipartBoundary, + "", post_data); + chrome::VersionInfo version_info; + net::AddMultipartValueForUpload("ver", version_info.Version(), + kMultipartBoundary, "", post_data); + net::AddMultipartValueForUpload("guid", "0", kMultipartBoundary, + "", post_data); + net::AddMultipartValueForUpload("type", "webrtc_log", kMultipartBoundary, + "", post_data); + net::AddMultipartValueForUpload("app_session_id", app_session_id, + kMultipartBoundary, "", post_data); + net::AddMultipartValueForUpload("url", app_url, kMultipartBoundary, + "", post_data); + AddLogData(post_data, log_buffer, log_buffer_length); + net::AddMultipartFinalDelimiterForUpload(kMultipartBoundary, post_data); +} + +void WebRtcLogUploader::AddLogData(std::string* post_data, + uint8* log_buffer, + uint32 log_buffer_length) { + post_data->append("--"); + post_data->append(kMultipartBoundary); + post_data->append("\r\n"); + post_data->append("Content-Disposition: form-data; name=\"log\""); + post_data->append("; filename=\"log.gz\"\r\n"); + post_data->append("Content-Type: application/gzip\r\n\r\n"); + + CompressLog(post_data, log_buffer, log_buffer_length); + + post_data->append("\r\n"); +} + +void WebRtcLogUploader::CompressLog(std::string* post_data, + uint8* input, + uint32 input_size) { + PartialCircularBuffer read_pcb(input, input_size); + + z_stream stream = {0}; + int result = deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, + // windowBits = 15 is default, 16 is added to + // produce a gzip header + trailer. + 15 + 16, + 8, // memLevel = 8 is default. + Z_DEFAULT_STRATEGY); + DCHECK_EQ(Z_OK, result); + + uint8 intermediate_buffer[kIntermediateCompressionBufferBytes] = {0}; + ResizeForNextOutput(post_data, &stream); + uint32 read = 0; + + do { + if (stream.avail_in == 0) { + read = read_pcb.Read(&intermediate_buffer[0], + kIntermediateCompressionBufferBytes); + stream.next_in = &intermediate_buffer[0]; + stream.avail_in = read; + if (read != kIntermediateCompressionBufferBytes) + break; + } + result = deflate(&stream, Z_SYNC_FLUSH); + DCHECK_EQ(Z_OK, result); + if (stream.avail_out == 0) + ResizeForNextOutput(post_data, &stream); + } while (true); + + // Ensure we have enough room in the output buffer. Easier to always just do a + // resize than looping around and resize if needed. + if (stream.avail_out < kIntermediateCompressionBufferBytes) + ResizeForNextOutput(post_data, &stream); + + result = deflate(&stream, Z_FINISH); + DCHECK_EQ(Z_STREAM_END, result); + result = deflateEnd(&stream); + DCHECK_EQ(Z_OK, result); + + post_data->resize(post_data->size() - stream.avail_out); +} + +void WebRtcLogUploader::ResizeForNextOutput(std::string* post_data, + z_stream* stream) { + size_t old_size = post_data->size() - stream->avail_out; + post_data->resize(old_size + kIntermediateCompressionBufferBytes); + stream->next_out = reinterpret_cast<uint8*>(&(*post_data)[old_size]); + stream->avail_out = kIntermediateCompressionBufferBytes; +} + +void WebRtcLogUploader::DecreaseLogCount() { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + --log_count_; +} diff --git a/chrome/browser/media/webrtc_log_uploader.h b/chrome/browser/media/webrtc_log_uploader.h new file mode 100644 index 0000000..60225c6 --- /dev/null +++ b/chrome/browser/media/webrtc_log_uploader.h @@ -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. + +#ifndef CHROME_BROWSER_MEDIA_WEBRTC_LOG_UPLOADER_H_ +#define CHROME_BROWSER_MEDIA_WEBRTC_LOG_UPLOADER_H_ + +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "base/memory/ref_counted.h" +#include "base/platform_file.h" +#include "net/url_request/url_fetcher_delegate.h" + +namespace base { +class SharedMemory; +} + +namespace net { +class URLFetcher; +class URLRequestContextGetter; +} + +typedef struct z_stream_s z_stream; + +class WebRtcLogURLRequestContextGetter; + +// WebRtcLogUploader uploads WebRTC logs, keeps count of how many logs have +// been started and denies further logs if a limit is reached. There must only +// be one object of this type. +class WebRtcLogUploader : public net::URLFetcherDelegate { + public: + WebRtcLogUploader(); + virtual ~WebRtcLogUploader(); + + // net::URLFetcherDelegate implementation. + virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; + virtual void OnURLFetchUploadProgress(const net::URLFetcher* source, + int64 current, int64 total) OVERRIDE; + + // Returns true is number of logs limit is not reached yet. Increases log + // count if true is returned. Must be called before UploadLog(). + bool ApplyForStartLogging(); + + // Uploads log and decreases log count. May only be called if permission to + // to log has been granted by calling ApplyForStartLogging() and getting true + // in return. After UploadLog has been called, a new permission must be + // granted. + void UploadLog(net::URLRequestContextGetter* request_context, + scoped_ptr<base::SharedMemory> shared_memory, + uint32 length, + const std::string& app_session_id, + const std::string& app_url); + + private: + // Sets up a multipart body to be uploaded. The body is produced according + // to RFC 2046. + void SetupMultipart(std::string* post_data, uint8* log_buffer, + uint32 log_buffer_length, + const std::string& app_session_id, + const std::string& app_url); + + void AddLogData(std::string* post_data, uint8* log_buffer, + uint32 log_buffer_length); + void CompressLog(std::string* post_data, uint8* input, uint32 input_size); + void ResizeForNextOutput(std::string* post_data, z_stream* stream); + void DecreaseLogCount(); + + int log_count_; + + DISALLOW_COPY_AND_ASSIGN(WebRtcLogUploader); +}; + +#endif // CHROME_BROWSER_MEDIA_WEBRTC_LOG_UPLOADER_H_ diff --git a/chrome/browser/media/webrtc_logging_handler_host.cc b/chrome/browser/media/webrtc_logging_handler_host.cc index c04a28a..25c972a 100644 --- a/chrome/browser/media/webrtc_logging_handler_host.cc +++ b/chrome/browser/media/webrtc_logging_handler_host.cc @@ -6,23 +6,32 @@ #include "base/bind.h" #include "base/logging.h" +#include "base/prefs/pref_service.h" +#include "base/shared_memory.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/media/webrtc_log_uploader.h" #include "chrome/common/media/webrtc_logging_messages.h" +#include "chrome/common/pref_names.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/content_browser_client.h" +#include "content/public/browser/render_process_host.h" +#include "net/url_request/url_request_context_getter.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() {} -WebRtcLoggingHandlerHost::~WebRtcLoggingHandlerHost() { -} +WebRtcLoggingHandlerHost::~WebRtcLoggingHandlerHost() {} void WebRtcLoggingHandlerHost::OnChannelClosing() { + UploadLog(); content::BrowserMessageFilter::OnChannelClosing(); } @@ -45,22 +54,72 @@ bool WebRtcLoggingHandlerHost::OnMessageReceived(const IPC::Message& message, 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())); + app_session_id_ = app_session_id; + app_url_ = app_url; + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( + &WebRtcLoggingHandlerHost::OpenLogIfAllowed, this)); +} + +void WebRtcLoggingHandlerHost::OpenLogIfAllowed() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + bool enabled = false; + + // If the user permits metrics reporting / crash uploading with the checkbox + // in the prefs, we allow uploading automatically. We disable uploading + // completely for non-official builds. +#if defined(GOOGLE_CHROME_BUILD) +#if defined(OS_CHROMEOS) + chromeos::CrosSettings::Get()->GetBoolean(chromeos::kStatsReportingPref, + &enabled); +#else + enabled = g_browser_process->local_state()->GetBoolean( + prefs::kMetricsReportingEnabled); +#endif // #if defined(OS_CHROMEOS) +#endif // defined(GOOGLE_CHROME_BUILD) + if (!enabled) + return; + + if (!g_browser_process->webrtc_log_uploader()->ApplyForStartLogging()) + return; + + system_request_context_ = g_browser_process->system_request_context(); + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( + &WebRtcLoggingHandlerHost::DoOpenLog, this)); +} + +void WebRtcLoggingHandlerHost::DoOpenLog() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + DCHECK(!shared_memory_); + + shared_memory_.reset(new base::SharedMemory()); - if (!shared_memory_.CreateAndMapAnonymous(kWebRtcLogSize)) { + 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(), + 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)); } + +void WebRtcLoggingHandlerHost::UploadLog() { + if (!shared_memory_) + return; + + BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind( + &WebRtcLogUploader::UploadLog, + base::Unretained(g_browser_process->webrtc_log_uploader()), + system_request_context_, + Passed(&shared_memory_), + kWebRtcLogSize, + app_session_id_, + app_url_)); +} diff --git a/chrome/browser/media/webrtc_logging_handler_host.h b/chrome/browser/media/webrtc_logging_handler_host.h index 2b735a8..5f67c1f 100644 --- a/chrome/browser/media/webrtc_logging_handler_host.h +++ b/chrome/browser/media/webrtc_logging_handler_host.h @@ -6,31 +6,48 @@ #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" +namespace base { +class SharedMemory; +} // namespace base + +namespace net { +class URLRequestContextGetter; +} // namespace net + +class RenderProcessHost; + // WebRtcLoggingHandlerHost handles operations regarding the WebRTC logging: -// opening and closing shared memory buffer that the handler in the renderer -// process writes to. +// - Opens a shared memory buffer that the handler in the render process +// writes to. +// - Detects when channel, i.e. renderer, is going away and triggers uploading +// the log. class WebRtcLoggingHandlerHost : public content::BrowserMessageFilter { public: WebRtcLoggingHandlerHost(); private: + friend class content::BrowserThread; + friend class base::DeleteHelper<WebRtcLoggingHandlerHost>; + + virtual ~WebRtcLoggingHandlerHost(); + // 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>; + void OnOpenLog(const std::string& app_session_id, const std::string& app_url); - virtual ~WebRtcLoggingHandlerHost(); + void OpenLogIfAllowed(); + void DoOpenLog(); - void OnOpenLog(const std::string& app_session_id, const std::string& app_url); + void UploadLog(); - base::SharedMemory shared_memory_; + scoped_refptr<net::URLRequestContextGetter> system_request_context_; + scoped_ptr<base::SharedMemory> shared_memory_; std::string app_session_id_; std::string app_url_; diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index b162342..4a61c41 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -970,6 +970,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_log_uploader.cc', + 'browser/media/webrtc_log_uploader.h', 'browser/media/webrtc_logging_handler_host.cc', 'browser/media/webrtc_logging_handler_host.h', 'browser/media_galleries/fileapi/filtering_file_enumerator.cc', @@ -3075,6 +3077,8 @@ }], ['enable_webrtc==0', { 'sources!': [ + 'browser/media/webrtc_log_uploader.cc', + 'browser/media/webrtc_log_uploader.h', 'browser/media/webrtc_logging_handler_host.cc', 'browser/media/webrtc_logging_handler_host.h', ] diff --git a/chrome/test/base/testing_browser_process.cc b/chrome/test/base/testing_browser_process.cc index 75cc12c..a6a1c43 100644 --- a/chrome/test/base/testing_browser_process.cc +++ b/chrome/test/base/testing_browser_process.cc @@ -324,6 +324,12 @@ bool TestingBrowserProcess::created_local_state() const { return (local_state_ != NULL); } +#if defined(ENABLE_WEBRTC) +WebRtcLogUploader* TestingBrowserProcess::webrtc_log_uploader() { + return NULL; +} +#endif + void TestingBrowserProcess::SetBookmarkPromptController( BookmarkPromptController* controller) { #if !defined(OS_IOS) diff --git a/chrome/test/base/testing_browser_process.h b/chrome/test/base/testing_browser_process.h index 3f07bec..300f192 100644 --- a/chrome/test/base/testing_browser_process.h +++ b/chrome/test/base/testing_browser_process.h @@ -107,6 +107,10 @@ class TestingBrowserProcess : public BrowserProcess { media_file_system_registry() OVERRIDE; virtual bool created_local_state() const OVERRIDE; +#if defined(ENABLE_WEBRTC) + virtual WebRtcLogUploader* webrtc_log_uploader() OVERRIDE; +#endif + // Set the local state for tests. Consumer is responsible for cleaning it up // afterwards (using ScopedTestingLocalState, for example). void SetLocalState(PrefService* local_state); |