Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 #include <utility> | 4 #include <utility> |
| 5 | 5 |
| 6 #include "base/bind.h" | 6 #include "base/bind.h" |
| 7 #include "base/files/file_util.h" | 7 #include "base/files/file_util.h" |
| 8 #include "base/json/json_writer.h" | 8 #include "base/json/json_writer.h" |
| 9 #include "base/macros.h" | 9 #include "base/macros.h" |
| 10 #include "base/strings/pattern.h" | 10 #include "base/strings/pattern.h" |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 22 class StringTraceDataEndpoint : public TraceDataEndpoint { | 22 class StringTraceDataEndpoint : public TraceDataEndpoint { |
| 23 public: | 23 public: |
| 24 typedef base::Callback<void(std::unique_ptr<const base::DictionaryValue>, | 24 typedef base::Callback<void(std::unique_ptr<const base::DictionaryValue>, |
| 25 base::RefCountedString*)> | 25 base::RefCountedString*)> |
| 26 CompletionCallback; | 26 CompletionCallback; |
| 27 | 27 |
| 28 explicit StringTraceDataEndpoint(CompletionCallback callback) | 28 explicit StringTraceDataEndpoint(CompletionCallback callback) |
| 29 : completion_callback_(callback) {} | 29 : completion_callback_(callback) {} |
| 30 | 30 |
| 31 void ReceiveTraceFinalContents( | 31 void ReceiveTraceFinalContents( |
| 32 std::unique_ptr<const base::DictionaryValue> metadata, | 32 std::unique_ptr<const base::DictionaryValue> metadata) override { |
| 33 const std::string& contents) override { | 33 std::string tmp = trace_.str(); |
| 34 std::string tmp = contents; | 34 trace_.str(""); |
|
oystein (OOO til 10th of July)
2016/07/14 22:04:33
nit: Should technically also do trace_.clear() in
| |
| 35 scoped_refptr<base::RefCountedString> str = | 35 scoped_refptr<base::RefCountedString> str = |
| 36 base::RefCountedString::TakeString(&tmp); | 36 base::RefCountedString::TakeString(&tmp); |
| 37 | 37 |
| 38 BrowserThread::PostTask( | 38 BrowserThread::PostTask( |
| 39 BrowserThread::UI, FROM_HERE, | 39 BrowserThread::UI, FROM_HERE, |
| 40 base::Bind(completion_callback_, base::Passed(std::move(metadata)), | 40 base::Bind(completion_callback_, base::Passed(std::move(metadata)), |
| 41 base::RetainedRef(str))); | 41 base::RetainedRef(str))); |
| 42 } | 42 } |
| 43 | 43 |
| 44 void ReceiveTraceChunk(const std::string& chunk) override { trace_ << chunk; } | |
| 45 | |
| 44 private: | 46 private: |
| 45 ~StringTraceDataEndpoint() override {} | 47 ~StringTraceDataEndpoint() override {} |
| 46 | 48 |
| 47 CompletionCallback completion_callback_; | 49 CompletionCallback completion_callback_; |
| 50 std::ostringstream trace_; | |
| 48 | 51 |
| 49 DISALLOW_COPY_AND_ASSIGN(StringTraceDataEndpoint); | 52 DISALLOW_COPY_AND_ASSIGN(StringTraceDataEndpoint); |
| 50 }; | 53 }; |
| 51 | 54 |
| 52 class FileTraceDataEndpoint : public TraceDataEndpoint { | 55 class FileTraceDataEndpoint : public TraceDataEndpoint { |
| 53 public: | 56 public: |
| 54 explicit FileTraceDataEndpoint(const base::FilePath& trace_file_path, | 57 explicit FileTraceDataEndpoint(const base::FilePath& trace_file_path, |
| 55 const base::Closure& callback) | 58 const base::Closure& callback) |
| 56 : file_path_(trace_file_path), | 59 : file_path_(trace_file_path), |
| 57 completion_callback_(callback), | 60 completion_callback_(callback), |
| 58 file_(NULL) {} | 61 file_(NULL) {} |
| 59 | 62 |
| 60 void ReceiveTraceChunk(const std::string& chunk) override { | 63 void ReceiveTraceChunk(const std::string& chunk) override { |
| 61 std::string tmp = chunk; | 64 std::string tmp = chunk; |
| 62 scoped_refptr<base::RefCountedString> chunk_ptr = | 65 scoped_refptr<base::RefCountedString> chunk_ptr = |
| 63 base::RefCountedString::TakeString(&tmp); | 66 base::RefCountedString::TakeString(&tmp); |
| 64 BrowserThread::PostTask( | 67 BrowserThread::PostTask( |
| 65 BrowserThread::FILE, FROM_HERE, | 68 BrowserThread::FILE, FROM_HERE, |
| 66 base::Bind(&FileTraceDataEndpoint::ReceiveTraceChunkOnFileThread, this, | 69 base::Bind(&FileTraceDataEndpoint::ReceiveTraceChunkOnFileThread, this, |
| 67 chunk_ptr)); | 70 chunk_ptr)); |
| 68 } | 71 } |
| 69 | 72 |
| 70 void ReceiveTraceFinalContents(std::unique_ptr<const base::DictionaryValue>, | 73 void ReceiveTraceFinalContents( |
| 71 const std::string& contents) override { | 74 std::unique_ptr<const base::DictionaryValue>) override { |
| 72 BrowserThread::PostTask( | 75 BrowserThread::PostTask( |
| 73 BrowserThread::FILE, FROM_HERE, | 76 BrowserThread::FILE, FROM_HERE, |
| 74 base::Bind(&FileTraceDataEndpoint::CloseOnFileThread, this)); | 77 base::Bind(&FileTraceDataEndpoint::CloseOnFileThread, this)); |
| 75 } | 78 } |
| 76 | 79 |
| 77 private: | 80 private: |
| 78 ~FileTraceDataEndpoint() override { DCHECK(file_ == NULL); } | 81 ~FileTraceDataEndpoint() override { DCHECK(file_ == NULL); } |
| 79 | 82 |
| 80 void ReceiveTraceChunkOnFileThread( | 83 void ReceiveTraceChunkOnFileThread( |
| 81 const scoped_refptr<base::RefCountedString> chunk) { | 84 const scoped_refptr<base::RefCountedString> chunk) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 131 const std::map<std::string, std::string>& GetAgentTrace() const; | 134 const std::map<std::string, std::string>& GetAgentTrace() const; |
| 132 std::unique_ptr<base::DictionaryValue> TakeMetadata(); | 135 std::unique_ptr<base::DictionaryValue> TakeMetadata(); |
| 133 | 136 |
| 134 private: | 137 private: |
| 135 std::map<std::string, std::string> additional_tracing_agent_trace_; | 138 std::map<std::string, std::string> additional_tracing_agent_trace_; |
| 136 std::unique_ptr<base::DictionaryValue> metadata_; | 139 std::unique_ptr<base::DictionaryValue> metadata_; |
| 137 | 140 |
| 138 DISALLOW_COPY_AND_ASSIGN(TraceDataSinkImplBase); | 141 DISALLOW_COPY_AND_ASSIGN(TraceDataSinkImplBase); |
| 139 }; | 142 }; |
| 140 | 143 |
| 141 class StringTraceDataSink : public TraceDataSinkImplBase { | 144 class JSONTraceDataSink : public TraceDataSinkImplBase { |
| 142 public: | 145 public: |
| 143 explicit StringTraceDataSink(scoped_refptr<TraceDataEndpoint> endpoint) | 146 explicit JSONTraceDataSink(scoped_refptr<TraceDataEndpoint> endpoint) |
| 144 : endpoint_(endpoint) {} | 147 : endpoint_(endpoint), first_chunk_(true) {} |
| 145 | 148 |
| 146 void AddTraceChunk(const std::string& chunk) override { | 149 void AddTraceChunk(const std::string& chunk) override { |
| 147 std::string trace_string; | 150 std::string trace_string; |
| 148 if (trace_.empty()) | 151 if (first_chunk_) |
| 149 trace_string = "{\"" + std::string(kChromeTraceLabel) + "\":["; | 152 trace_string = "{\"" + std::string(kChromeTraceLabel) + "\":["; |
| 150 else | 153 else |
| 151 trace_string = ","; | 154 trace_string = ","; |
| 152 trace_string += chunk; | 155 trace_string += chunk; |
| 156 first_chunk_ = false; | |
| 153 | 157 |
| 154 AddTraceChunkAndPassToEndpoint(trace_string); | 158 endpoint_->ReceiveTraceChunk(trace_string); |
| 155 } | |
| 156 | |
| 157 void AddTraceChunkAndPassToEndpoint(const std::string& chunk) { | |
| 158 trace_ += chunk; | |
| 159 | |
| 160 endpoint_->ReceiveTraceChunk(chunk); | |
| 161 } | 159 } |
| 162 | 160 |
| 163 void Close() override { | 161 void Close() override { |
| 164 AddTraceChunkAndPassToEndpoint("]"); | 162 endpoint_->ReceiveTraceChunk("]"); |
| 165 | 163 |
| 166 for (auto const &it : GetAgentTrace()) | 164 for (auto const &it : GetAgentTrace()) |
| 167 AddTraceChunkAndPassToEndpoint(",\"" + it.first + "\": " + it.second); | 165 endpoint_->ReceiveTraceChunk(",\"" + it.first + "\": " + it.second); |
| 168 | 166 |
| 169 std::unique_ptr<base::DictionaryValue> metadata(TakeMetadata()); | 167 std::unique_ptr<base::DictionaryValue> metadata(TakeMetadata()); |
| 170 std::string metadataJSON; | 168 std::string metadataJSON; |
| 171 | 169 |
| 172 if (base::JSONWriter::Write(*metadata, &metadataJSON) && | 170 if (base::JSONWriter::Write(*metadata, &metadataJSON) && |
| 173 !metadataJSON.empty()) { | 171 !metadataJSON.empty()) { |
| 174 AddTraceChunkAndPassToEndpoint( | 172 endpoint_->ReceiveTraceChunk(",\"" + std::string(kMetadataTraceLabel) + |
| 175 ",\"" + std::string(kMetadataTraceLabel) + "\": " + metadataJSON); | 173 "\": " + metadataJSON); |
| 176 } | 174 } |
| 177 | 175 |
| 178 AddTraceChunkAndPassToEndpoint("}"); | 176 endpoint_->ReceiveTraceChunk("}"); |
| 179 | 177 endpoint_->ReceiveTraceFinalContents(std::move(metadata)); |
| 180 endpoint_->ReceiveTraceFinalContents(std::move(metadata), trace_); | |
| 181 } | 178 } |
| 182 | 179 |
| 183 private: | 180 private: |
| 184 ~StringTraceDataSink() override {} | 181 ~JSONTraceDataSink() override {} |
| 185 | 182 |
| 186 scoped_refptr<TraceDataEndpoint> endpoint_; | 183 scoped_refptr<TraceDataEndpoint> endpoint_; |
| 187 std::string trace_; | 184 bool first_chunk_; |
|
oystein (OOO til 10th of July)
2016/07/14 22:04:33
nit: has_received_first_chunk_ (and inverted check
| |
| 188 | 185 DISALLOW_COPY_AND_ASSIGN(JSONTraceDataSink); |
| 189 DISALLOW_COPY_AND_ASSIGN(StringTraceDataSink); | |
| 190 }; | 186 }; |
| 191 | 187 |
| 192 class CompressedStringTraceDataSink : public TraceDataSinkImplBase { | 188 class CompressedStringTraceDataSink : public TraceDataSinkImplBase { |
| 193 public: | 189 public: |
| 194 explicit CompressedStringTraceDataSink( | 190 explicit CompressedStringTraceDataSink( |
| 195 scoped_refptr<TraceDataEndpoint> endpoint) | 191 scoped_refptr<TraceDataEndpoint> endpoint) |
| 196 : endpoint_(endpoint), already_tried_open_(false) {} | 192 : endpoint_(endpoint), already_tried_open_(false), first_chunk_(true) {} |
| 197 | 193 |
| 198 void AddTraceChunk(const std::string& chunk) override { | 194 void AddTraceChunk(const std::string& chunk) override { |
| 199 std::string tmp = chunk; | 195 std::string tmp = chunk; |
| 200 scoped_refptr<base::RefCountedString> chunk_ptr = | 196 scoped_refptr<base::RefCountedString> chunk_ptr = |
| 201 base::RefCountedString::TakeString(&tmp); | 197 base::RefCountedString::TakeString(&tmp); |
| 202 BrowserThread::PostTask( | 198 BrowserThread::PostTask( |
| 203 BrowserThread::FILE, FROM_HERE, | 199 BrowserThread::FILE, FROM_HERE, |
| 204 base::Bind(&CompressedStringTraceDataSink::AddTraceChunkOnFileThread, | 200 base::Bind(&CompressedStringTraceDataSink::AddTraceChunkOnFileThread, |
| 205 this, chunk_ptr)); | 201 this, chunk_ptr)); |
| 206 } | 202 } |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 234 MAX_WBITS + 16, | 230 MAX_WBITS + 16, |
| 235 8, // memLevel = 8 is default. | 231 8, // memLevel = 8 is default. |
| 236 Z_DEFAULT_STRATEGY); | 232 Z_DEFAULT_STRATEGY); |
| 237 return result == 0; | 233 return result == 0; |
| 238 } | 234 } |
| 239 | 235 |
| 240 void AddTraceChunkOnFileThread( | 236 void AddTraceChunkOnFileThread( |
| 241 const scoped_refptr<base::RefCountedString> chunk_ptr) { | 237 const scoped_refptr<base::RefCountedString> chunk_ptr) { |
| 242 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 238 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 243 std::string trace; | 239 std::string trace; |
| 244 if (compressed_trace_data_.empty()) | 240 if (first_chunk_) |
| 245 trace = "{\"" + std::string(kChromeTraceLabel) + "\":["; | 241 trace = "{\"" + std::string(kChromeTraceLabel) + "\":["; |
| 246 else | 242 else |
| 247 trace = ","; | 243 trace = ","; |
| 244 first_chunk_ = false; | |
| 248 trace += chunk_ptr->data(); | 245 trace += chunk_ptr->data(); |
| 249 AddTraceChunkAndCompressOnFileThread(trace, false); | 246 AddTraceChunkAndCompressOnFileThread(trace, false); |
| 250 } | 247 } |
| 251 | 248 |
| 252 void AddTraceChunkAndCompressOnFileThread(const std::string& chunk, | 249 void AddTraceChunkAndCompressOnFileThread(const std::string& chunk, |
| 253 bool finished) { | 250 bool finished) { |
| 254 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 251 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 255 if (!OpenZStreamOnFileThread()) | 252 if (!OpenZStreamOnFileThread()) |
| 256 return; | 253 return; |
| 257 | 254 |
| 258 const int kChunkSize = 0x4000; | 255 const int kChunkSize = 0x4000; |
| 259 | 256 |
| 260 char buffer[kChunkSize]; | 257 char buffer[kChunkSize]; |
| 261 int err; | 258 int err; |
| 262 stream_->avail_in = chunk.size(); | 259 stream_->avail_in = chunk.size(); |
| 263 stream_->next_in = (unsigned char*)chunk.data(); | 260 stream_->next_in = (unsigned char*)chunk.data(); |
| 264 do { | 261 do { |
| 265 stream_->avail_out = kChunkSize; | 262 stream_->avail_out = kChunkSize; |
| 266 stream_->next_out = (unsigned char*)buffer; | 263 stream_->next_out = (unsigned char*)buffer; |
| 267 err = deflate(stream_.get(), finished ? Z_FINISH : Z_NO_FLUSH); | 264 err = deflate(stream_.get(), finished ? Z_FINISH : Z_NO_FLUSH); |
| 268 if (err != Z_OK && (err != Z_STREAM_END && finished)) { | 265 if (err != Z_OK && (err != Z_STREAM_END && finished)) { |
| 269 stream_.reset(); | 266 stream_.reset(); |
| 270 return; | 267 return; |
| 271 } | 268 } |
| 272 | 269 |
| 273 int bytes = kChunkSize - stream_->avail_out; | 270 int bytes = kChunkSize - stream_->avail_out; |
| 274 if (bytes) { | 271 if (bytes) { |
| 275 std::string compressed_chunk = std::string(buffer, bytes); | 272 std::string compressed_chunk = std::string(buffer, bytes); |
| 276 compressed_trace_data_ += compressed_chunk; | |
| 277 endpoint_->ReceiveTraceChunk(compressed_chunk); | 273 endpoint_->ReceiveTraceChunk(compressed_chunk); |
| 278 } | 274 } |
| 279 } while (stream_->avail_out == 0); | 275 } while (stream_->avail_out == 0); |
| 280 } | 276 } |
| 281 | 277 |
| 282 void CloseOnFileThread() { | 278 void CloseOnFileThread() { |
| 283 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 279 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 284 if (!OpenZStreamOnFileThread()) | 280 if (!OpenZStreamOnFileThread()) |
| 285 return; | 281 return; |
| 286 | 282 |
| 287 if (compressed_trace_data_.empty()) { | 283 if (first_chunk_) { |
| 288 AddTraceChunkAndCompressOnFileThread( | 284 AddTraceChunkAndCompressOnFileThread( |
| 289 "{\"" + std::string(kChromeTraceLabel) + "\":[", false); | 285 "{\"" + std::string(kChromeTraceLabel) + "\":[", false); |
| 290 } | 286 } |
| 291 AddTraceChunkAndCompressOnFileThread("]", false); | 287 AddTraceChunkAndCompressOnFileThread("]", false); |
| 292 | 288 |
| 293 for (auto const &it : GetAgentTrace()) { | 289 for (auto const &it : GetAgentTrace()) { |
| 294 AddTraceChunkAndCompressOnFileThread( | 290 AddTraceChunkAndCompressOnFileThread( |
| 295 ",\"" + it.first + "\": " + it.second, false); | 291 ",\"" + it.first + "\": " + it.second, false); |
| 296 } | 292 } |
| 297 | 293 |
| 298 std::unique_ptr<base::DictionaryValue> metadata(TakeMetadata()); | 294 std::unique_ptr<base::DictionaryValue> metadata(TakeMetadata()); |
| 299 std::string metadataJSON; | 295 std::string metadataJSON; |
| 300 if (base::JSONWriter::Write(*metadata, &metadataJSON) && | 296 if (base::JSONWriter::Write(*metadata, &metadataJSON) && |
| 301 !metadataJSON.empty()) { | 297 !metadataJSON.empty()) { |
| 302 AddTraceChunkAndCompressOnFileThread( | 298 AddTraceChunkAndCompressOnFileThread( |
| 303 ",\"" + std::string(kMetadataTraceLabel) + "\": " + metadataJSON, | 299 ",\"" + std::string(kMetadataTraceLabel) + "\": " + metadataJSON, |
| 304 false); | 300 false); |
| 305 } | 301 } |
| 306 AddTraceChunkAndCompressOnFileThread("}", true); | 302 AddTraceChunkAndCompressOnFileThread("}", true); |
| 307 | 303 |
| 308 deflateEnd(stream_.get()); | 304 deflateEnd(stream_.get()); |
| 309 stream_.reset(); | 305 stream_.reset(); |
| 310 | 306 |
| 311 endpoint_->ReceiveTraceFinalContents(std::move(metadata), | 307 endpoint_->ReceiveTraceFinalContents(std::move(metadata)); |
| 312 compressed_trace_data_); | |
| 313 } | 308 } |
| 314 | 309 |
| 315 scoped_refptr<TraceDataEndpoint> endpoint_; | 310 scoped_refptr<TraceDataEndpoint> endpoint_; |
| 316 std::unique_ptr<z_stream> stream_; | 311 std::unique_ptr<z_stream> stream_; |
| 317 bool already_tried_open_; | 312 bool already_tried_open_; |
| 318 std::string compressed_trace_data_; | 313 bool first_chunk_; |
| 319 | 314 |
| 320 DISALLOW_COPY_AND_ASSIGN(CompressedStringTraceDataSink); | 315 DISALLOW_COPY_AND_ASSIGN(CompressedStringTraceDataSink); |
| 321 }; | 316 }; |
| 322 | 317 |
| 323 } // namespace | 318 } // namespace |
| 324 | 319 |
| 325 TracingController::TraceDataSink::TraceDataSink() {} | 320 TracingController::TraceDataSink::TraceDataSink() {} |
| 326 TracingController::TraceDataSink::~TraceDataSink() {} | 321 TracingController::TraceDataSink::~TraceDataSink() {} |
| 327 | 322 |
| 328 void TraceDataSinkImplBase::AddAgentTrace(const std::string& trace_label, | 323 void TraceDataSinkImplBase::AddAgentTrace(const std::string& trace_label, |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 343 } | 338 } |
| 344 | 339 |
| 345 std::unique_ptr<base::DictionaryValue> TraceDataSinkImplBase::TakeMetadata() { | 340 std::unique_ptr<base::DictionaryValue> TraceDataSinkImplBase::TakeMetadata() { |
| 346 return std::move(metadata_); | 341 return std::move(metadata_); |
| 347 } | 342 } |
| 348 | 343 |
| 349 scoped_refptr<TracingController::TraceDataSink> | 344 scoped_refptr<TracingController::TraceDataSink> |
| 350 TracingController::CreateStringSink( | 345 TracingController::CreateStringSink( |
| 351 const base::Callback<void(std::unique_ptr<const base::DictionaryValue>, | 346 const base::Callback<void(std::unique_ptr<const base::DictionaryValue>, |
| 352 base::RefCountedString*)>& callback) { | 347 base::RefCountedString*)>& callback) { |
| 353 return new StringTraceDataSink(new StringTraceDataEndpoint(callback)); | 348 return new JSONTraceDataSink(new StringTraceDataEndpoint(callback)); |
| 354 } | 349 } |
| 355 | 350 |
| 356 scoped_refptr<TracingController::TraceDataSink> | 351 scoped_refptr<TracingController::TraceDataSink> |
| 357 TracingController::CreateFileSink(const base::FilePath& file_path, | 352 TracingController::CreateFileSink(const base::FilePath& file_path, |
| 358 const base::Closure& callback) { | 353 const base::Closure& callback) { |
| 359 return new StringTraceDataSink( | 354 return new JSONTraceDataSink(new FileTraceDataEndpoint(file_path, callback)); |
| 360 new FileTraceDataEndpoint(file_path, callback)); | |
| 361 } | 355 } |
| 362 | 356 |
| 363 scoped_refptr<TracingController::TraceDataSink> | 357 scoped_refptr<TracingController::TraceDataSink> |
| 364 TracingControllerImpl::CreateCompressedStringSink( | 358 TracingControllerImpl::CreateCompressedStringSink( |
| 365 scoped_refptr<TraceDataEndpoint> endpoint) { | 359 scoped_refptr<TraceDataEndpoint> endpoint) { |
| 366 return new CompressedStringTraceDataSink(endpoint); | 360 return new CompressedStringTraceDataSink(endpoint); |
| 367 } | 361 } |
| 368 | 362 |
| 369 scoped_refptr<TraceDataEndpoint> TracingControllerImpl::CreateCallbackEndpoint( | 363 scoped_refptr<TraceDataEndpoint> TracingControllerImpl::CreateCallbackEndpoint( |
| 370 const base::Callback<void(std::unique_ptr<const base::DictionaryValue>, | 364 const base::Callback<void(std::unique_ptr<const base::DictionaryValue>, |
| 371 base::RefCountedString*)>& callback) { | 365 base::RefCountedString*)>& callback) { |
| 372 return new StringTraceDataEndpoint(callback); | 366 return new StringTraceDataEndpoint(callback); |
| 373 } | 367 } |
| 374 | 368 |
| 375 } // namespace content | 369 } // namespace content |
| OLD | NEW |