Index: content/browser/webrtc_log_manager.cc |
diff --git a/content/browser/webrtc_log_manager.cc b/content/browser/webrtc_log_manager.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..798144b259d81c1168a44f143839867b0670a65c |
--- /dev/null |
+++ b/content/browser/webrtc_log_manager.cc |
@@ -0,0 +1,140 @@ |
+// 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 "content/browser/webrtc_log_manager.h" |
+ |
+#if defined(USE_SYSTEM_LIBBZ2) |
+#include <bzlib.h> |
+#else |
+#include "third_party/bzip2/bzlib.h" |
+#endif |
+ |
+#include "base/shared_memory.h" |
+#include "content/common/partial_circular_buffer.h" |
+#include "content/public/browser/browser_thread.h" |
+#include "content/public/browser/content_browser_client.h" |
+ |
+namespace content { |
+ |
+namespace { |
+// TODO(grunell): Smaller size? |
+const uint32 kIntermediateCompressionBufferSize = 0.5 * 1024 * 1024; // 0.5 MB |
+//const uint32 kIntermediateCompressionBufferSize = 10 * 1024; // 10 KB |
+} // namespace |
+ |
+WebRtcLogManager::WebRtcLogManager() { |
+} |
+ |
+WebRtcLogManager::~WebRtcLogManager() { |
+} |
+ |
+WebRtcLogManager* WebRtcLogManager::GetInstance() { |
+ return Singleton<WebRtcLogManager>::get(); |
+} |
+ |
+void WebRtcLogManager::UploadLog(base::SharedMemory* shared_memory, |
+ uint32 length, |
+ base::PlatformFile file) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
+ DCHECK(shared_memory); |
+ DCHECK(shared_memory->memory()); |
+ |
+ // We have taken ownership of |shared_memory|, make sure it's deleted when |
+ // we're done. |
+ scoped_ptr<base::SharedMemory> scoped_shared_memory(shared_memory); |
+ |
+ ReadAndCompressLog(reinterpret_cast<uint8*>(scoped_shared_memory->memory()), |
+ length, file); |
+ DCHECK_EQ(0, base::SeekPlatformFile(file, base::PLATFORM_FILE_FROM_BEGIN, 0)); |
+ |
+ GetContentClient()->browser()->UploadWebRtcLog(file); |
+} |
+ |
+void WebRtcLogManager::ReadAndCompressLog(uint8* input, |
Jói
2013/05/02 16:47:31
It almost seems strange that the content layer wou
Henrik Grunell
2013/05/03 07:59:36
I definitely like to have this in the embedder. Th
|
+ uint32 input_size, |
+ base::PlatformFile output_file) { |
+ const bool debug_print = false; |
+ |
+ if (debug_print) LOG(ERROR) << "*** DUMPING LOG BUFFER BEGIN ***"; |
+ |
+ PartialCircularBuffer read_pcb(input, input_size); |
+ |
+ // TODO(grunell): Maybe better to write directly to file with BZ2_bzWrite? |
+ bz_stream stream = {0}; |
+ int result = BZ2_bzCompressInit(&stream, 6, 0, 0); |
+ DCHECK(result == BZ_OK); |
+ |
+ scoped_ptr<uint8[]> intermediate_buffer( |
+ new uint8[kIntermediateCompressionBufferSize]); |
+ scoped_ptr<uint8[]> compressed( |
+ new uint8[kIntermediateCompressionBufferSize]); |
+ memset(intermediate_buffer.get(), 0, kIntermediateCompressionBufferSize); |
+ memset(compressed.get(), 0, kIntermediateCompressionBufferSize); |
+ uint32 read = read_pcb.Read(intermediate_buffer.get(), |
+ kIntermediateCompressionBufferSize); |
+ |
+ if (debug_print) { |
+ std::string tmp( |
+ reinterpret_cast<char*>(&intermediate_buffer.get()[0]), read); |
+ LOG(ERROR) << "Data (" << read << "):" << '\n' << tmp; |
+ } |
+ |
+ stream.next_in = reinterpret_cast<char*>(&intermediate_buffer.get()[0]); |
+ stream.avail_in = read; |
+ char* compressed_char_ptr = reinterpret_cast<char*>(&compressed.get()[0]); |
+ |
+ // Keeps track of written output. |
+ unsigned int last_total_out = stream.total_out_lo32; |
+ |
+ while (read == kIntermediateCompressionBufferSize) { |
+ stream.next_out = compressed_char_ptr; |
+ stream.avail_out = kIntermediateCompressionBufferSize; |
+ result = BZ2_bzCompress(&stream, BZ_RUN); |
+ if (debug_print) { |
+ LOG(ERROR) << "RESULT = " << result << ", read = " << read; |
+ LOG(ERROR) << "avail_in = " << stream.avail_in |
+ << ", total_in_lo32 = " << stream.total_in_lo32; |
+ LOG(ERROR) << "avail_out = " << stream.avail_out |
+ << ", total_out_lo32 = " << stream.total_out_lo32; |
+ } |
+ DCHECK(result == BZ_RUN_OK); |
+ base::WritePlatformFileAtCurrentPos(output_file, compressed_char_ptr, |
+ stream.total_out_lo32 - last_total_out); |
+ last_total_out = stream.total_out_lo32; |
+ read = read_pcb.Read(intermediate_buffer.get(), |
+ kIntermediateCompressionBufferSize); |
+ stream.next_in = reinterpret_cast<char*>(&intermediate_buffer.get()[0]); |
+ stream.avail_in = read; |
+ |
+ if (debug_print) { |
+ std::string tmp( |
+ reinterpret_cast<char*>(&intermediate_buffer.get()[0]), read); |
+ LOG(ERROR) << "Data (" << read << "):" << '\n' << tmp; |
+ } |
+ } |
+ |
+ do { |
+ stream.next_out = compressed_char_ptr; |
+ stream.avail_out = kIntermediateCompressionBufferSize; |
+ result = BZ2_bzCompress(&stream, BZ_FINISH); |
+ if (debug_print) { |
+ LOG(ERROR) << "RESULT = " << result << ", read = " << read; |
+ LOG(ERROR) << "avail_in = " << stream.avail_in |
+ << ", total_in_lo32 = " << stream.total_in_lo32; |
+ LOG(ERROR) << "avail_out = " << stream.avail_out |
+ << ", total_out_lo32 = " << stream.total_out_lo32; |
+ } |
+ base::WritePlatformFileAtCurrentPos(output_file, compressed_char_ptr, |
+ stream.total_out_lo32 - last_total_out); |
+ last_total_out = stream.total_out_lo32; |
+ } while (result == BZ_FINISH_OK); |
+ DCHECK(result == BZ_STREAM_END); |
+ |
+ result = BZ2_bzCompressEnd(&stream); |
+ DCHECK(result == BZ_OK); |
+ |
+ if (debug_print) LOG(ERROR) << "*** DUMPING LOG BUFFER END ***"; |
+} |
+ |
+} // namespace content |