OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/feedback/tracing_manager.h" | 5 #include "components/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" | 8 #include "base/memory/ref_counted_memory.h" |
11 #include "base/message_loop/message_loop_proxy.h" | 9 #include "base/message_loop/message_loop_proxy.h" |
12 #include "components/feedback/feedback_util.h" | 10 #include "components/feedback/feedback_util.h" |
13 #include "content/public/browser/tracing_controller.h" | 11 #include "content/public/browser/tracing_controller.h" |
14 | 12 |
15 namespace { | 13 namespace { |
| 14 |
| 15 class StringTraceDataSink : public content::TracingController::TraceDataSink { |
| 16 public: |
| 17 typedef base::Callback<void(const std::string&)> CompletionCallback; |
| 18 |
| 19 explicit StringTraceDataSink(CompletionCallback callback) |
| 20 : completion_callback_(callback) { |
| 21 } |
| 22 |
| 23 // TracingController::TraceDataSink implementation |
| 24 virtual void AddTraceChunk(const std::string& chunk) OVERRIDE { |
| 25 if (!trace_.empty()) |
| 26 trace_ += ","; |
| 27 trace_ += chunk; |
| 28 } |
| 29 virtual void SetSystemTrace(const std::string& data) OVERRIDE { |
| 30 system_trace_ = data; |
| 31 } |
| 32 virtual void Close() OVERRIDE { |
| 33 std::string result = "{\"traceEvents\":[" + trace_ + "]"; |
| 34 if (!system_trace_.empty()) |
| 35 result += ",\"systemTraceEvents\":[" + system_trace_ + "]"; |
| 36 result += "}"; |
| 37 |
| 38 completion_callback_.Run(result); |
| 39 delete this; |
| 40 } |
| 41 |
| 42 private: |
| 43 virtual ~StringTraceDataSink() {} |
| 44 |
| 45 std::string trace_; |
| 46 std::string system_trace_; |
| 47 CompletionCallback completion_callback_; |
| 48 }; |
| 49 |
| 50 |
16 // Only once trace manager can exist at a time. | 51 // Only once trace manager can exist at a time. |
17 TracingManager* g_tracing_manager = NULL; | 52 TracingManager* g_tracing_manager = NULL; |
18 // Trace IDs start at 1 and increase. | 53 // Trace IDs start at 1 and increase. |
19 int g_next_trace_id = 1; | 54 int g_next_trace_id = 1; |
20 // Name of the file to store the tracing data as. | 55 // Name of the file to store the tracing data as. |
21 const base::FilePath::CharType kTracingFilename[] = | 56 const base::FilePath::CharType kTracingFilename[] = |
22 FILE_PATH_LITERAL("tracing.json"); | 57 FILE_PATH_LITERAL("tracing.json"); |
23 } | 58 } |
24 | 59 |
25 TracingManager::TracingManager() | 60 TracingManager::TracingManager() |
(...skipping 10 matching lines...) Expand all Loading... |
36 } | 71 } |
37 | 72 |
38 int TracingManager::RequestTrace() { | 73 int TracingManager::RequestTrace() { |
39 // Return the current trace if one is being collected. | 74 // Return the current trace if one is being collected. |
40 if (current_trace_id_) | 75 if (current_trace_id_) |
41 return current_trace_id_; | 76 return current_trace_id_; |
42 | 77 |
43 current_trace_id_ = g_next_trace_id; | 78 current_trace_id_ = g_next_trace_id; |
44 ++g_next_trace_id; | 79 ++g_next_trace_id; |
45 content::TracingController::GetInstance()->DisableRecording( | 80 content::TracingController::GetInstance()->DisableRecording( |
46 base::FilePath(), | 81 new StringTraceDataSink(base::Bind(&TracingManager::OnTraceDataCollected, |
47 base::Bind(&TracingManager::OnTraceDataCollected, | 82 weak_ptr_factory_.GetWeakPtr()))); |
48 weak_ptr_factory_.GetWeakPtr())); | |
49 return current_trace_id_; | 83 return current_trace_id_; |
50 } | 84 } |
51 | 85 |
52 bool TracingManager::GetTraceData(int id, const TraceDataCallback& callback) { | 86 bool TracingManager::GetTraceData(int id, const TraceDataCallback& callback) { |
53 // If a trace is being collected currently, send it via callback when | 87 // If a trace is being collected currently, send it via callback when |
54 // complete. | 88 // complete. |
55 if (current_trace_id_) { | 89 if (current_trace_id_) { |
56 // Only allow one trace data request at a time. | 90 // Only allow one trace data request at a time. |
57 if (trace_callback_.is_null()) { | 91 if (trace_callback_.is_null()) { |
58 trace_callback_ = callback; | 92 trace_callback_ = callback; |
(...skipping 30 matching lines...) Expand all Loading... |
89 } | 123 } |
90 } | 124 } |
91 | 125 |
92 void TracingManager::StartTracing() { | 126 void TracingManager::StartTracing() { |
93 content::TracingController::GetInstance()->EnableRecording( | 127 content::TracingController::GetInstance()->EnableRecording( |
94 base::debug::CategoryFilter(), | 128 base::debug::CategoryFilter(), |
95 base::debug::TraceOptions(), | 129 base::debug::TraceOptions(), |
96 content::TracingController::EnableRecordingDoneCallback()); | 130 content::TracingController::EnableRecordingDoneCallback()); |
97 } | 131 } |
98 | 132 |
99 void TracingManager::OnTraceDataCollected(const base::FilePath& path) { | 133 void TracingManager::OnTraceDataCollected(const std::string& trace_data) { |
100 if (!current_trace_id_) | 134 if (!current_trace_id_) |
101 return; | 135 return; |
102 | 136 |
103 std::string data; | |
104 if (!base::ReadFileToString(path, &data)) { | |
105 LOG(ERROR) << "Failed to read trace data from: " << path.value(); | |
106 return; | |
107 } | |
108 base::DeleteFile(path, false); | |
109 | |
110 std::string output_val; | 137 std::string output_val; |
111 feedback_util::ZipString( | 138 feedback_util::ZipString( |
112 base::FilePath(kTracingFilename), data, &output_val); | 139 base::FilePath(kTracingFilename), trace_data, &output_val); |
113 | 140 |
114 scoped_refptr<base::RefCountedString> output( | 141 scoped_refptr<base::RefCountedString> output( |
115 base::RefCountedString::TakeString(&output_val)); | 142 base::RefCountedString::TakeString(&output_val)); |
116 | 143 |
117 trace_data_[current_trace_id_] = output; | 144 trace_data_[current_trace_id_] = output; |
118 | 145 |
119 if (!trace_callback_.is_null()) { | 146 if (!trace_callback_.is_null()) { |
120 trace_callback_.Run(output); | 147 trace_callback_.Run(output); |
121 trace_callback_.Reset(); | 148 trace_callback_.Reset(); |
122 } | 149 } |
(...skipping 11 matching lines...) Expand all Loading... |
134 // static | 161 // static |
135 scoped_ptr<TracingManager> TracingManager::Create() { | 162 scoped_ptr<TracingManager> TracingManager::Create() { |
136 if (g_tracing_manager) | 163 if (g_tracing_manager) |
137 return scoped_ptr<TracingManager>(); | 164 return scoped_ptr<TracingManager>(); |
138 return scoped_ptr<TracingManager>(new TracingManager()); | 165 return scoped_ptr<TracingManager>(new TracingManager()); |
139 } | 166 } |
140 | 167 |
141 TracingManager* TracingManager::Get() { | 168 TracingManager* TracingManager::Get() { |
142 return g_tracing_manager; | 169 return g_tracing_manager; |
143 } | 170 } |
OLD | NEW |