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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/webrtc_log_upload_manager.h"
6
7 #if defined(USE_SYSTEM_LIBBZ2)
8 #include <bzlib.h>
9 #else
10 #include "third_party/bzip2/bzlib.h"
11 #endif
12
13 #include "base/bind.h"
14 #include "base/command_line.h"
15 #include "base/prefs/pref_service.h"
16 #include "base/logging.h"
17 #include "chrome/browser/browser_process.h"
Jói 2013/04/26 12:55:10 Where is this used?
18 #include "chrome/common/cloud_print/cloud_print_helpers.h"
19 #include "chrome/common/pref_names.h"
20 #include "content/browser/browser_thread_impl.h"
21 #include "content/common/partial_circular_buffer.h"
22 #include "googleurl/src/gurl.h"
23 #include "net/base/file_stream.h"
24 #include "net/proxy/proxy_config_service.h"
25 #include "net/url_request/url_fetcher.h"
26 #include "net/url_request/url_request_context_builder.h"
27
28 const uint32 kIntermediateCompressionBufferSize = 0.5 * 1024 * 1024; // 0.5 MB
29
30 const char kTempUploadFile[] = "/tmp/chromium-upload-webrtc-log";
31 const char kUploadURL[] = "https://clients2.google.com/cr/report";
32 const char kUploadContentType[] = "multipart/form-data";
33 const char kMultipartBoundary[] =
34 "----**--yradnuoBgoLtrapitluMklaTelgooG--**----";
35
36 namespace {
37
38 // Config getter that always returns direct settings.
39 class ProxyConfigServiceDirect : public net::ProxyConfigService {
40 public:
41 // ProxyConfigService implementation.
42 virtual void AddObserver(Observer* observer) OVERRIDE {}
43 virtual void RemoveObserver(Observer* observer) OVERRIDE {}
44 virtual ConfigAvailability GetLatestProxyConfig(
45 net::ProxyConfig* config) OVERRIDE {
46 *config = net::ProxyConfig::CreateDirect();
47 return CONFIG_VALID;
48 }
49 };
50
51 } // namespace
52
53 class WebRtcLogURLRequestContextGetter :
54 public net::URLRequestContextGetter {
55 public:
56 WebRtcLogURLRequestContextGetter() {}
57
58 // net::URLRequestContextGetter implementation.
59 virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE {
60 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
61
62 if (!url_request_context_) {
63 net::URLRequestContextBuilder builder;
64 #if defined(OS_LINUX) || defined(OS_ANDROID)
65 builder.set_proxy_config_service(new ProxyConfigServiceDirect());
66 #endif
67 url_request_context_.reset(builder.Build());
68 }
69 CHECK(url_request_context_.get());
70
71 return url_request_context_.get();
72 }
73
74 virtual scoped_refptr<base::SingleThreadTaskRunner>
75 GetNetworkTaskRunner() const OVERRIDE {
76 return content::BrowserThread::GetMessageLoopProxyForThread(
77 content::BrowserThread::IO);
78 }
79
80 private:
81 virtual ~WebRtcLogURLRequestContextGetter() {}
82
83 // NULL if not yet initialized. Otherwise, it is the URLRequestContext
84 // instance that was lazily created by GetURLRequestContext().
85 // Access only from the IO thread.
86 scoped_ptr<net::URLRequestContext> url_request_context_;
87
88 DISALLOW_COPY_AND_ASSIGN(WebRtcLogURLRequestContextGetter);
89 };
90
91
92 WebRtcLogUploadManager::WebRtcLogUploadManager() {
93 }
94
95 WebRtcLogUploadManager::~WebRtcLogUploadManager() {
96 }
97
98 void WebRtcLogUploadManager::OnURLFetchComplete(
99 const net::URLFetcher* source) {
100 std::vector<net::URLFetcher*>::iterator it;
101 for (it = url_fetchers_.begin(); it != url_fetchers_.end(); ++it) {
102 if (*it == source) {
103 url_fetchers_.erase(it);
104 break;
105 }
106 }
107 delete source;
108 }
109
110 void WebRtcLogUploadManager::OnURLFetchUploadProgress(
111 const net::URLFetcher* source, int64 current, int64 total) {
112 }
113
114 void WebRtcLogUploadManager::UploadLog(base::SharedMemory* shared_memory,
115 uint32 length) {
116 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
117 DCHECK(shared_memory);
118 DCHECK(shared_memory->memory());
119
120 scoped_ptr<base::SharedMemory> scoped_shared_memory(shared_memory);
121
122 uint8 compressed[length];
123 uint32 compressed_size = sizeof(compressed); //content::kWebRtcLogSize;
124 ReadAndCompressLog(reinterpret_cast<uint8*>(scoped_shared_memory->memory()),
125 length, compressed, &compressed_size);
126
127 SetupUpload(compressed, compressed_size);
128
129 if (!request_context_getter_)
130 request_context_getter_ = new WebRtcLogURLRequestContextGetter();
131
132 std::string content_type = kUploadContentType;
133 content_type.append("; boundary=");
134 content_type.append(kMultipartBoundary);
135
136 net::URLFetcher* url_fetcher =
137 net::URLFetcher::Create(GURL(kUploadURL), net::URLFetcher::POST, this);
138 // url_fetcher_.reset(
139 // net::URLFetcher::Create(GURL(kUploadURL), net::URLFetcher::POST, this));
140 url_fetcher->SetRequestContext(request_context_getter_);
141 url_fetcher->SetUploadFilePath(
142 content_type, base::FilePath(kTempUploadFile),
143 content::BrowserThread::GetMessageLoopProxyForThread(
144 content::BrowserThread::FILE));
145 url_fetcher->Start();
146 url_fetchers_.push_back(url_fetcher);
147 }
148
149 void WebRtcLogUploadManager::ReadAndCompressLog(uint8* input,
150 uint32 input_size,
151 uint8* output,
152 uint32* output_size) {
153 content::PartialCircularBuffer read_pcb(input, input_size);
154
155 bz_stream stream = {0};
156 int result = BZ2_bzCompressInit(&stream, 6, 0, 0);
157 DCHECK(result == BZ_OK);
158
159 scoped_ptr<uint8[]> intermediate_buffer(
160 new uint8[kIntermediateCompressionBufferSize]);
161 memset(intermediate_buffer.get(), 0, kIntermediateCompressionBufferSize);
162 uint32 read = read_pcb.Read(intermediate_buffer.get(),
163 kIntermediateCompressionBufferSize);
164 stream.next_in = reinterpret_cast<char*>(&intermediate_buffer.get()[0]);
165 stream.avail_in = read;
166
167 while (read == kIntermediateCompressionBufferSize) {
168 stream.next_out =
169 reinterpret_cast<char*>(&((output)[stream.total_out_lo32]));
170 stream.avail_out = *output_size - stream.total_out_lo32;
171 result = BZ2_bzCompress(&stream, BZ_RUN);
172 DCHECK(result == BZ_OK);
173 read = read_pcb.Read(intermediate_buffer.get(),
174 kIntermediateCompressionBufferSize);
175 }
176
177 stream.avail_in = read;
178 do {
179 stream.next_out =
180 reinterpret_cast<char*>(&((output)[stream.total_out_lo32]));
181 stream.avail_out = *output_size - stream.total_out_lo32;
182 result = BZ2_bzCompress(&stream, BZ_FINISH);
183 } while (result == BZ_FINISH_OK);
184 DCHECK(result == BZ_STREAM_END);
185
186 result = BZ2_bzCompressEnd(&stream);
187 DCHECK(result == BZ_OK);
188
189 *output_size = stream.total_out_lo32;
190 }
191
192 void WebRtcLogUploadManager::SetupUpload(uint8* log_data,
193 uint32 log_data_size) {
194 file_stream_.reset(new net::FileStream(NULL));
195 int open_flags = base::PLATFORM_FILE_CREATE_ALWAYS |
196 base::PLATFORM_FILE_WRITE;
197 file_stream_->OpenSync(base::FilePath(kTempUploadFile),
198 open_flags);
199
200 // TODO(grunell): Correct product name.
201 AddPairString("prod", "Chrome");
202 // TODO(grunell): Correct version.
203 AddPairString("ver", "0.0.1.1-dev-test");
204 AddPairString("type", "log");
205
206 AddUrlChunks();
207
208 AddLogData(log_data, log_data_size);
209
210 std::stringstream ss;
211 ss << "--" << kMultipartBoundary << "--" << "\r\n";
212 file_stream_->WriteSync(ss.str().data(), ss.str().size());
213 }
214
215 void WebRtcLogUploadManager::AddPairString(const std::string& key,
216 const std::string& value) {
217 // 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
218 std::string str;
219 cloud_print::AddMultipartValueForUpload(
220 key, value, kMultipartBoundary, "", &str);
221 file_stream_->WriteSync(str.c_str(), str.size());
222 }
223
224 void WebRtcLogUploadManager::AddUrlChunks() {
225 // TODO(grunell): Implement.
226 }
227
228 void WebRtcLogUploadManager::AddLogData(uint8* log_data,
229 uint32 log_data_size) {
230 std::stringstream ss;
231 ss << "--" << kMultipartBoundary << "\r\n";
232 ss << "Content-Disposition: form-data; name=\"log\"";
233 ss << "; filename=\"log.bz2\"" << "\r\n";
234 ss << "Content-Type: application/x-bzip" << "\r\n";
235 ss << "\r\n";
236 file_stream_->WriteSync(ss.str().data(), ss.str().size());
237
238 file_stream_->WriteSync(reinterpret_cast<const char*>(log_data),
239 log_data_size);
240
241 std::string end_str = "\r\n";
242 file_stream_->WriteSync(end_str.c_str(), end_str.size());
243 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698