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

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: Fixed pre-submit warnings/errors (including adding bzip2 to content/browser DEPS). Created 7 years, 7 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/logging.h"
16 #include "base/prefs/pref_service.h"
17 #include "chrome/browser/browser_process.h"
18 #include "chrome/common/cloud_print/cloud_print_helpers.h"
19 #include "chrome/common/pref_names.h"
20 //#include "content/common/partial_circular_buffer.h"
21 #include "content/public/browser/browser_thread.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 namespace {
29
30 const uint32 kIntermediateCompressionBufferSize = 0.5 * 1024 * 1024; // 0.5 MB
31
32 const char kTempUploadFile[] = "/tmp/chromium-webrtc-log-upload";
33 const char kUploadURL[] = "https://clients2.google.com/cr/report";
34 const char kUploadContentType[] = "multipart/form-data";
35 const char kMultipartBoundary[] =
36 "----**--yradnuoBgoLtrapitluMklaTelgooG--**----";
37
38 const uint32 kFileCopyBufferSize = 128 * 1024; // 128 KB
39
40 // Config getter that always returns direct settings.
41 class ProxyConfigServiceDirect : public net::ProxyConfigService {
42 public:
43 // ProxyConfigService implementation.
44 virtual void AddObserver(Observer* observer) OVERRIDE {}
45 virtual void RemoveObserver(Observer* observer) OVERRIDE {}
46 virtual ConfigAvailability GetLatestProxyConfig(
47 net::ProxyConfig* config) OVERRIDE {
48 *config = net::ProxyConfig::CreateDirect();
49 return CONFIG_VALID;
50 }
51 };
52
53 } // namespace
54
55 class WebRtcLogURLRequestContextGetter :
56 public net::URLRequestContextGetter {
57 public:
58 WebRtcLogURLRequestContextGetter() {}
59
60 // net::URLRequestContextGetter implementation.
61 virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE {
62 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
63
64 if (!url_request_context_) {
65 net::URLRequestContextBuilder builder;
66 #if defined(OS_LINUX) || defined(OS_ANDROID)
67 builder.set_proxy_config_service(new ProxyConfigServiceDirect());
68 #endif
69 url_request_context_.reset(builder.Build());
70 }
71 CHECK(url_request_context_.get());
72
73 return url_request_context_.get();
74 }
75
76 virtual scoped_refptr<base::SingleThreadTaskRunner>
77 GetNetworkTaskRunner() const OVERRIDE {
78 return content::BrowserThread::GetMessageLoopProxyForThread(
79 content::BrowserThread::IO);
80 }
81
82 private:
83 virtual ~WebRtcLogURLRequestContextGetter() {}
84
85 // NULL if not yet initialized. Otherwise, it is the URLRequestContext
86 // instance that was lazily created by GetURLRequestContext().
87 // Access only from the IO thread.
88 scoped_ptr<net::URLRequestContext> url_request_context_;
89
90 DISALLOW_COPY_AND_ASSIGN(WebRtcLogURLRequestContextGetter);
91 };
92
93
94 WebRtcLogUploadManager::WebRtcLogUploadManager()
95 : multipart_file_(base::kInvalidPlatformFileValue) {
96 }
97
98 WebRtcLogUploadManager::~WebRtcLogUploadManager() {
99 }
100
101 void WebRtcLogUploadManager::OnURLFetchComplete(
102 const net::URLFetcher* source) {
103 std::vector<net::URLFetcher*>::iterator it;
104 for (it = url_fetchers_.begin(); it != url_fetchers_.end(); ++it) {
105 if (*it == source) {
106 url_fetchers_.erase(it);
107 break;
108 }
109 }
110 delete source;
111 }
112
113 void WebRtcLogUploadManager::OnURLFetchUploadProgress(
114 const net::URLFetcher* source, int64 current, int64 total) {
115 }
116
117 void WebRtcLogUploadManager::UploadLog(base::PlatformFile log_file) {
118 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
119 /*
120 DCHECK(shared_memory);
121 DCHECK(shared_memory->memory());
122
123 scoped_ptr<base::SharedMemory> scoped_shared_memory(shared_memory);
124
125 uint8 compressed[length];
126 uint32 compressed_size = sizeof(compressed); //content::kWebRtcLogSize;
127 ReadAndCompressLog(reinterpret_cast<uint8*>(scoped_shared_memory->memory()),
128 length, compressed, &compressed_size);
129 */
130 SetupUpload(log_file);
131
132 if (!request_context_getter_)
133 request_context_getter_ = new WebRtcLogURLRequestContextGetter();
134
135 std::string content_type = kUploadContentType;
136 content_type.append("; boundary=");
137 content_type.append(kMultipartBoundary);
138
139 net::URLFetcher* url_fetcher =
140 net::URLFetcher::Create(GURL(kUploadURL), net::URLFetcher::POST, this);
141 url_fetcher->SetRequestContext(request_context_getter_);
142 url_fetcher->SetUploadFilePath(
143 content_type, base::FilePath(kTempUploadFile),
144 content::BrowserThread::GetMessageLoopProxyForThread(
145 content::BrowserThread::FILE));
146 url_fetcher->Start();
147 url_fetchers_.push_back(url_fetcher);
148 }
149
150 /*
151 void WebRtcLogUploadManager::ReadAndCompressLog(uint8* input,
152 uint32 input_size,
153 uint8* output,
154 uint32* output_size) {
155 content::PartialCircularBuffer read_pcb(input, input_size);
156
157 bz_stream stream = {0};
158 int result = BZ2_bzCompressInit(&stream, 6, 0, 0);
159 DCHECK(result == BZ_OK);
160
161 scoped_ptr<uint8[]> intermediate_buffer(
162 new uint8[kIntermediateCompressionBufferSize]);
163 memset(intermediate_buffer.get(), 0, kIntermediateCompressionBufferSize);
164 uint32 read = read_pcb.Read(intermediate_buffer.get(),
165 kIntermediateCompressionBufferSize);
166 stream.next_in = reinterpret_cast<char*>(&intermediate_buffer.get()[0]);
167 stream.avail_in = read;
168
169 while (read == kIntermediateCompressionBufferSize) {
170 stream.next_out =
171 reinterpret_cast<char*>(&((output)[stream.total_out_lo32]));
172 stream.avail_out = *output_size - stream.total_out_lo32;
173 result = BZ2_bzCompress(&stream, BZ_RUN);
174 DCHECK(result == BZ_OK);
175 read = read_pcb.Read(intermediate_buffer.get(),
176 kIntermediateCompressionBufferSize);
177 }
178
179 stream.avail_in = read;
180 do {
181 stream.next_out =
182 reinterpret_cast<char*>(&((output)[stream.total_out_lo32]));
183 stream.avail_out = *output_size - stream.total_out_lo32;
184 result = BZ2_bzCompress(&stream, BZ_FINISH);
185 } while (result == BZ_FINISH_OK);
186 DCHECK(result == BZ_STREAM_END);
187
188 result = BZ2_bzCompressEnd(&stream);
189 DCHECK(result == BZ_OK);
190
191 *output_size = stream.total_out_lo32;
192 }
193 */
194
195 void WebRtcLogUploadManager::SetupUpload(base::PlatformFile log_file) {
196 /*
197 file_stream_.reset(new net::FileStream(NULL));
198 int open_flags = base::PLATFORM_FILE_CREATE_ALWAYS |
199 base::PLATFORM_FILE_WRITE;
200 file_stream_->OpenSync(base::FilePath(kTempUploadFile),
201 open_flags);
202 */
203
204 int flags = base::PLATFORM_FILE_CREATE_ALWAYS |
205 base::PLATFORM_FILE_WRITE /*|
206 base::PLATFORM_FILE_DELETE_ON_CLOSE*/;
207 bool created = false;
208 base::PlatformFileError error = base::PLATFORM_FILE_OK;
209 multipart_file_ =
210 CreatePlatformFile(base::FilePath(kTempUploadFile), flags,
211 &created, &error);
212 DCHECK(created);
213 DCHECK(error == base::PLATFORM_FILE_OK);
214
215 // TODO(grunell): Correct product name.
216 AddPairString("prod", "Chrome");
217 // TODO(grunell): Correct version.
218 AddPairString("ver", "0.0.1.1-dev-test");
219 AddPairString("type", "log");
220
221 AddUrlChunks();
222
223 AddLogData(log_file);
224
225 std::stringstream ss;
226 ss << "--" << kMultipartBoundary << "--" << "\r\n";
227 base::WritePlatformFileAtCurrentPos(
228 multipart_file_, ss.str().data(), ss.str().size());
229
230 // TODO(grunell): Close file?
231 }
232
233 void WebRtcLogUploadManager::AddPairString(const std::string& key,
234 const std::string& value) {
235 // TODO(grunell): Break out the function in cloud print.
236 std::string str;
237 cloud_print::AddMultipartValueForUpload(
238 key, value, kMultipartBoundary, "", &str);
239 // file_stream_->WriteSync(str.c_str(), str.size());
240 base::WritePlatformFileAtCurrentPos(multipart_file_, str.c_str(), str.size());
241 }
242
243 void WebRtcLogUploadManager::AddUrlChunks() {
244 // TODO(grunell): Implement.
245 }
246
247 void WebRtcLogUploadManager::AddLogData(base::PlatformFile log_file) {
248 std::stringstream ss;
249 ss << "--" << kMultipartBoundary << "\r\n";
250 ss << "Content-Disposition: form-data; name=\"log\"";
251 ss << "; filename=\"log.bz2\"" << "\r\n";
252 ss << "Content-Type: application/x-bzip" << "\r\n";
253 ss << "\r\n";
254 // file_stream_->WriteSync(ss.str().data(), ss.str().size());
255 base::WritePlatformFileAtCurrentPos(
256 multipart_file_, ss.str().data(), ss.str().size());
257
258 // file_stream_->WriteSync(reinterpret_cast<const char*>(log_data),
259 // log_data_size);
260 // Copy the log file contents
261 char buffer[kFileCopyBufferSize] = {0};
262 int read = 0;
263 int written = 0;
264 int acc_written = 0;
265 do {
266 read = base::ReadPlatformFileAtCurrentPos(log_file, &buffer[0],
267 sizeof(buffer));
268 DCHECK_GE(read, 0);
269 written = base::WritePlatformFileAtCurrentPos(multipart_file_, &buffer[0],
270 read);
271 DCHECK_GE(written, 0);
272 DCHECK_EQ(read, written);
273 acc_written += written;
274 } while (read > 0);
275
276 LOG(ERROR) << "TOTAL WRITTEN = " << acc_written;
277
278 std::string end_str = "\r\n";
279 // file_stream_->WriteSync(end_str.c_str(), end_str.size());
280 base::WritePlatformFileAtCurrentPos(
281 multipart_file_, end_str.c_str(), end_str.size());
282 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698