Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 | 4 |
| 5 #include "chrome/browser/feedback/tracing_manager.h" | 5 #include "chrome/browser/feedback/tracing_manager.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/file_util.h" | |
| 9 #include "base/location.h" | |
| 10 #include "base/memory/ref_counted_memory.h" | |
| 11 #include "base/message_loop/message_loop_proxy.h" | |
| 8 #include "base/prefs/pref_service.h" | 12 #include "base/prefs/pref_service.h" |
| 9 #include "chrome/browser/browser_process.h" | 13 #include "chrome/browser/browser_process.h" |
| 10 #include "chrome/browser/feedback/feedback_util.h" | 14 #include "chrome/browser/feedback/feedback_util.h" |
| 11 #include "chrome/common/pref_names.h" | 15 #include "chrome/common/pref_names.h" |
| 12 #include "content/public/browser/trace_controller.h" | 16 #include "content/public/browser/tracing_controller.h" |
| 13 | 17 |
| 14 namespace { | 18 namespace { |
| 15 // Only once trace manager can exist at a time. | 19 // Only once trace manager can exist at a time. |
| 16 TracingManager* g_tracing_manager = NULL; | 20 TracingManager* g_tracing_manager = NULL; |
| 17 // Trace IDs start at 1 and increase. | 21 // Trace IDs start at 1 and increase. |
| 18 int g_next_trace_id = 1; | 22 int g_next_trace_id = 1; |
| 19 // Name of the file to store the tracing data as. | |
| 20 const base::FilePath::CharType kTracingFilename[] = | |
| 21 FILE_PATH_LITERAL("tracing.json"); | |
| 22 } | 23 } |
| 23 | 24 |
| 24 TracingManager::TracingManager() | 25 TracingManager::TracingManager() |
| 25 : current_trace_id_(0), | 26 : current_trace_id_(0), |
| 26 weak_ptr_factory_(this) { | 27 weak_ptr_factory_(this) { |
| 27 DCHECK(!g_tracing_manager); | 28 DCHECK(!g_tracing_manager); |
| 28 g_tracing_manager = this; | 29 g_tracing_manager = this; |
| 29 StartTracing(); | 30 StartTracing(); |
| 30 } | 31 } |
| 31 | 32 |
| 32 TracingManager::~TracingManager() { | 33 TracingManager::~TracingManager() { |
| 33 DCHECK(g_tracing_manager == this); | 34 DCHECK(g_tracing_manager == this); |
| 34 g_tracing_manager = NULL; | 35 g_tracing_manager = NULL; |
| 35 } | 36 } |
| 36 | 37 |
| 37 int TracingManager::RequestTrace() { | 38 int TracingManager::RequestTrace() { |
| 38 // Return the current trace if one is being collected. | 39 // Return the current trace if one is being collected. |
| 39 if (current_trace_id_) | 40 if (current_trace_id_) |
| 40 return current_trace_id_; | 41 return current_trace_id_; |
| 41 | 42 |
| 42 current_trace_id_ = g_next_trace_id; | 43 current_trace_id_ = g_next_trace_id; |
| 43 ++g_next_trace_id; | 44 ++g_next_trace_id; |
| 44 content::TraceController::GetInstance()->EndTracingAsync(this); | 45 content::TracingController::GetInstance()->DisableRecording( |
| 46 base::FilePath(), | |
| 47 base::Bind(&TracingManager::OnTraceDataCollected, | |
| 48 base::Unretained(this))); | |
| 45 return current_trace_id_; | 49 return current_trace_id_; |
| 46 } | 50 } |
| 47 | 51 |
| 48 bool TracingManager::GetTraceData(int id, const TraceDataCallback& callback) { | 52 bool TracingManager::GetTraceData(int id, const TraceDataCallback& callback) { |
| 49 // If a trace is being collected currently, send it via callback when | 53 // If a trace is being collected currently, send it via callback when |
| 50 // complete. | 54 // complete. |
| 51 if (current_trace_id_) { | 55 if (current_trace_id_) { |
| 52 // Only allow one trace data request at a time. | 56 // Only allow one trace data request at a time. |
| 53 if (trace_callback_.is_null()) { | 57 if (trace_callback_.is_null()) { |
| 54 trace_callback_ = callback; | 58 trace_callback_ = callback; |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 69 return true; | 73 return true; |
| 70 } | 74 } |
| 71 } | 75 } |
| 72 | 76 |
| 73 void TracingManager::DiscardTraceData(int id) { | 77 void TracingManager::DiscardTraceData(int id) { |
| 74 trace_data_.erase(id); | 78 trace_data_.erase(id); |
| 75 | 79 |
| 76 // If the trace is discarded before it is complete, clean up the accumulators. | 80 // If the trace is discarded before it is complete, clean up the accumulators. |
| 77 if (id == current_trace_id_) { | 81 if (id == current_trace_id_) { |
| 78 current_trace_id_ = 0; | 82 current_trace_id_ = 0; |
| 79 data_ = ""; | |
| 80 | 83 |
| 81 // If the trace has already been requested, provide an empty string. | 84 // If the trace has already been requested, provide an empty string. |
| 82 if (!trace_callback_.is_null()) { | 85 if (!trace_callback_.is_null()) { |
| 83 trace_callback_.Run(scoped_refptr<base::RefCountedString>()); | 86 trace_callback_.Run(scoped_refptr<base::RefCountedString>()); |
| 84 trace_callback_.Reset(); | 87 trace_callback_.Reset(); |
| 85 } | 88 } |
| 86 } | 89 } |
| 87 } | 90 } |
| 88 | 91 |
| 89 void TracingManager::StartTracing() { | 92 void TracingManager::StartTracing() { |
| 90 content::TraceController::GetInstance()->BeginTracing( | 93 content::TracingController::GetInstance()->EnableRecording( |
| 91 this, "-test_*", | 94 "", content::TracingController::DEFAULT_OPTIONS, |
| 92 base::debug::TraceLog::RECORD_CONTINUOUSLY); | 95 content::TracingController::EnableRecordingDoneCallback()); |
| 93 } | 96 } |
| 94 | 97 |
| 95 void TracingManager::OnEndTracingComplete() { | 98 void TracingManager::OnTraceDataCollected(const base::FilePath& path) { |
| 96 if (!current_trace_id_) | 99 if (!current_trace_id_) |
| 97 return; | 100 return; |
| 98 | 101 |
| 99 data_ = std::string("[") + data_ + "]"; | |
| 100 | |
| 101 std::string output_val; | 102 std::string output_val; |
| 102 feedback_util::ZipString( | 103 feedback_util::ZipFile(path, &output_val); |
| 103 base::FilePath(kTracingFilename), data_, &output_val); | 104 base::DeleteFile(path, false); |
|
Zachary Kuznia
2013/11/15 23:21:36
Is there a reason you delete the file both here an
Xianzhu
2013/11/15 23:25:33
ZipFile deletes the temporary zip file, and here i
| |
| 104 | 105 |
| 105 scoped_refptr<base::RefCountedString> output( | 106 scoped_refptr<base::RefCountedString> output( |
| 106 base::RefCountedString::TakeString(&output_val)); | 107 base::RefCountedString::TakeString(&output_val)); |
| 107 | 108 |
| 108 trace_data_[current_trace_id_] = output; | 109 trace_data_[current_trace_id_] = output; |
| 109 | 110 |
| 110 if (!trace_callback_.is_null()) { | 111 if (!trace_callback_.is_null()) { |
| 111 trace_callback_.Run(output); | 112 trace_callback_.Run(output); |
| 112 trace_callback_.Reset(); | 113 trace_callback_.Reset(); |
| 113 } | 114 } |
| 114 | 115 |
| 115 current_trace_id_ = 0; | 116 current_trace_id_ = 0; |
| 116 data_ = ""; | |
| 117 | 117 |
| 118 // Tracing has to be restarted asynchronous, so the TracingController can | 118 // Tracing has to be restarted asynchronous, so the TracingController can |
| 119 // clean up. | 119 // clean up. |
| 120 base::MessageLoopProxy::current()->PostTask( | 120 base::MessageLoopProxy::current()->PostTask( |
| 121 FROM_HERE, | 121 FROM_HERE, |
| 122 base::Bind(&TracingManager::StartTracing, | 122 base::Bind(&TracingManager::StartTracing, |
| 123 weak_ptr_factory_.GetWeakPtr())); | 123 weak_ptr_factory_.GetWeakPtr())); |
| 124 } | 124 } |
| 125 | 125 |
| 126 void TracingManager::OnTraceDataCollected( | |
| 127 const scoped_refptr<base::RefCountedString>& trace_fragment) { | |
| 128 if (current_trace_id_) { | |
| 129 if (!data_.empty()) | |
| 130 data_ += ","; | |
| 131 data_ += trace_fragment->data(); | |
| 132 } | |
| 133 } | |
| 134 | |
| 135 // static | 126 // static |
| 136 scoped_ptr<TracingManager> TracingManager::Create() { | 127 scoped_ptr<TracingManager> TracingManager::Create() { |
| 137 if (g_tracing_manager) | 128 if (g_tracing_manager) |
| 138 return scoped_ptr<TracingManager>(); | 129 return scoped_ptr<TracingManager>(); |
| 139 return scoped_ptr<TracingManager>(new TracingManager()); | 130 return scoped_ptr<TracingManager>(new TracingManager()); |
| 140 } | 131 } |
| 141 | 132 |
| 142 TracingManager* TracingManager::Get() { | 133 TracingManager* TracingManager::Get() { |
| 143 return g_tracing_manager; | 134 return g_tracing_manager; |
| 144 } | 135 } |
| OLD | NEW |