Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4932)

Unified Diff: chrome/browser/webrtc_log_upload_manager.cc

Issue 14329020: Implementing uploading of a WebRTC diagnostic log. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/webrtc_log_upload_manager.cc
diff --git a/chrome/browser/webrtc_log_upload_manager.cc b/chrome/browser/webrtc_log_upload_manager.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b646af0401dd73dac16a8640b3968c07d7b94ede
--- /dev/null
+++ b/chrome/browser/webrtc_log_upload_manager.cc
@@ -0,0 +1,243 @@
+// Copyright (c) 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/webrtc_log_upload_manager.h"
+
+#if defined(USE_SYSTEM_LIBBZ2)
+#include <bzlib.h>
+#else
+#include "third_party/bzip2/bzlib.h"
+#endif
+
+#include "base/bind.h"
+#include "base/command_line.h"
+#include "base/prefs/pref_service.h"
+#include "base/logging.h"
+#include "chrome/browser/browser_process.h"
Jói 2013/04/26 12:55:10 Where is this used?
+#include "chrome/common/cloud_print/cloud_print_helpers.h"
+#include "chrome/common/pref_names.h"
+#include "content/browser/browser_thread_impl.h"
+#include "content/common/partial_circular_buffer.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/file_stream.h"
+#include "net/proxy/proxy_config_service.h"
+#include "net/url_request/url_fetcher.h"
+#include "net/url_request/url_request_context_builder.h"
+
+const uint32 kIntermediateCompressionBufferSize = 0.5 * 1024 * 1024; // 0.5 MB
+
+const char kTempUploadFile[] = "/tmp/chromium-upload-webrtc-log";
+const char kUploadURL[] = "https://clients2.google.com/cr/report";
+const char kUploadContentType[] = "multipart/form-data";
+const char kMultipartBoundary[] =
+ "----**--yradnuoBgoLtrapitluMklaTelgooG--**----";
+
+namespace {
+
+// Config getter that always returns direct settings.
+class ProxyConfigServiceDirect : public net::ProxyConfigService {
+ public:
+ // ProxyConfigService implementation.
+ virtual void AddObserver(Observer* observer) OVERRIDE {}
+ virtual void RemoveObserver(Observer* observer) OVERRIDE {}
+ virtual ConfigAvailability GetLatestProxyConfig(
+ net::ProxyConfig* config) OVERRIDE {
+ *config = net::ProxyConfig::CreateDirect();
+ return CONFIG_VALID;
+ }
+};
+
+} // namespace
+
+class WebRtcLogURLRequestContextGetter :
+ public net::URLRequestContextGetter {
+ public:
+ WebRtcLogURLRequestContextGetter() {}
+
+ // net::URLRequestContextGetter implementation.
+ virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+
+ if (!url_request_context_) {
+ net::URLRequestContextBuilder builder;
+#if defined(OS_LINUX) || defined(OS_ANDROID)
+ builder.set_proxy_config_service(new ProxyConfigServiceDirect());
+#endif
+ url_request_context_.reset(builder.Build());
+ }
+ CHECK(url_request_context_.get());
+
+ return url_request_context_.get();
+ }
+
+ virtual scoped_refptr<base::SingleThreadTaskRunner>
+ GetNetworkTaskRunner() const OVERRIDE {
+ return content::BrowserThread::GetMessageLoopProxyForThread(
+ content::BrowserThread::IO);
+ }
+
+ private:
+ virtual ~WebRtcLogURLRequestContextGetter() {}
+
+ // NULL if not yet initialized. Otherwise, it is the URLRequestContext
+ // instance that was lazily created by GetURLRequestContext().
+ // Access only from the IO thread.
+ scoped_ptr<net::URLRequestContext> url_request_context_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcLogURLRequestContextGetter);
+};
+
+
+WebRtcLogUploadManager::WebRtcLogUploadManager() {
+}
+
+WebRtcLogUploadManager::~WebRtcLogUploadManager() {
+}
+
+void WebRtcLogUploadManager::OnURLFetchComplete(
+ const net::URLFetcher* source) {
+ std::vector<net::URLFetcher*>::iterator it;
+ for (it = url_fetchers_.begin(); it != url_fetchers_.end(); ++it) {
+ if (*it == source) {
+ url_fetchers_.erase(it);
+ break;
+ }
+ }
+ delete source;
+}
+
+void WebRtcLogUploadManager::OnURLFetchUploadProgress(
+ const net::URLFetcher* source, int64 current, int64 total) {
+}
+
+void WebRtcLogUploadManager::UploadLog(base::SharedMemory* shared_memory,
+ uint32 length) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
+ DCHECK(shared_memory);
+ DCHECK(shared_memory->memory());
+
+ scoped_ptr<base::SharedMemory> scoped_shared_memory(shared_memory);
+
+ uint8 compressed[length];
+ uint32 compressed_size = sizeof(compressed); //content::kWebRtcLogSize;
+ ReadAndCompressLog(reinterpret_cast<uint8*>(scoped_shared_memory->memory()),
+ length, compressed, &compressed_size);
+
+ SetupUpload(compressed, compressed_size);
+
+ if (!request_context_getter_)
+ request_context_getter_ = new WebRtcLogURLRequestContextGetter();
+
+ 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_.reset(
+// net::URLFetcher::Create(GURL(kUploadURL), net::URLFetcher::POST, this));
+ url_fetcher->SetRequestContext(request_context_getter_);
+ url_fetcher->SetUploadFilePath(
+ content_type, base::FilePath(kTempUploadFile),
+ content::BrowserThread::GetMessageLoopProxyForThread(
+ content::BrowserThread::FILE));
+ url_fetcher->Start();
+ url_fetchers_.push_back(url_fetcher);
+}
+
+void WebRtcLogUploadManager::ReadAndCompressLog(uint8* input,
+ uint32 input_size,
+ uint8* output,
+ uint32* output_size) {
+ content::PartialCircularBuffer read_pcb(input, input_size);
+
+ bz_stream stream = {0};
+ int result = BZ2_bzCompressInit(&stream, 6, 0, 0);
+ DCHECK(result == BZ_OK);
+
+ scoped_ptr<uint8[]> intermediate_buffer(
+ new uint8[kIntermediateCompressionBufferSize]);
+ memset(intermediate_buffer.get(), 0, kIntermediateCompressionBufferSize);
+ uint32 read = read_pcb.Read(intermediate_buffer.get(),
+ kIntermediateCompressionBufferSize);
+ stream.next_in = reinterpret_cast<char*>(&intermediate_buffer.get()[0]);
+ stream.avail_in = read;
+
+ while (read == kIntermediateCompressionBufferSize) {
+ stream.next_out =
+ reinterpret_cast<char*>(&((output)[stream.total_out_lo32]));
+ stream.avail_out = *output_size - stream.total_out_lo32;
+ result = BZ2_bzCompress(&stream, BZ_RUN);
+ DCHECK(result == BZ_OK);
+ read = read_pcb.Read(intermediate_buffer.get(),
+ kIntermediateCompressionBufferSize);
+ }
+
+ stream.avail_in = read;
+ do {
+ stream.next_out =
+ reinterpret_cast<char*>(&((output)[stream.total_out_lo32]));
+ stream.avail_out = *output_size - stream.total_out_lo32;
+ result = BZ2_bzCompress(&stream, BZ_FINISH);
+ } while (result == BZ_FINISH_OK);
+ DCHECK(result == BZ_STREAM_END);
+
+ result = BZ2_bzCompressEnd(&stream);
+ DCHECK(result == BZ_OK);
+
+ *output_size = stream.total_out_lo32;
+}
+
+void WebRtcLogUploadManager::SetupUpload(uint8* log_data,
+ uint32 log_data_size) {
+ file_stream_.reset(new net::FileStream(NULL));
+ int open_flags = base::PLATFORM_FILE_CREATE_ALWAYS |
+ base::PLATFORM_FILE_WRITE;
+ file_stream_->OpenSync(base::FilePath(kTempUploadFile),
+ open_flags);
+
+ // TODO(grunell): Correct product name.
+ AddPairString("prod", "Chrome");
+ // TODO(grunell): Correct version.
+ AddPairString("ver", "0.0.1.1-dev-test");
+ AddPairString("type", "log");
+
+ AddUrlChunks();
+
+ AddLogData(log_data, log_data_size);
+
+ std::stringstream ss;
+ ss << "--" << kMultipartBoundary << "--" << "\r\n";
+ file_stream_->WriteSync(ss.str().data(), ss.str().size());
+}
+
+void WebRtcLogUploadManager::AddPairString(const std::string& key,
+ const std::string& value) {
+ // TODO(grunell): Break out the function in cloud print.
Jói 2013/04/26 12:55:10 Yeah, you definitely shouldn't be including stuff
+ std::string str;
+ cloud_print::AddMultipartValueForUpload(
+ key, value, kMultipartBoundary, "", &str);
+ file_stream_->WriteSync(str.c_str(), str.size());
+}
+
+void WebRtcLogUploadManager::AddUrlChunks() {
+ // TODO(grunell): Implement.
+}
+
+void WebRtcLogUploadManager::AddLogData(uint8* log_data,
+ uint32 log_data_size) {
+ std::stringstream ss;
+ ss << "--" << kMultipartBoundary << "\r\n";
+ ss << "Content-Disposition: form-data; name=\"log\"";
+ ss << "; filename=\"log.bz2\"" << "\r\n";
+ ss << "Content-Type: application/x-bzip" << "\r\n";
+ ss << "\r\n";
+ file_stream_->WriteSync(ss.str().data(), ss.str().size());
+
+ file_stream_->WriteSync(reinterpret_cast<const char*>(log_data),
+ log_data_size);
+
+ std::string end_str = "\r\n";
+ file_stream_->WriteSync(end_str.c_str(), end_str.size());
+}

Powered by Google App Engine
This is Rietveld 408576698