OLD | NEW |
(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/feedback/tracing_manager.h" |
| 6 |
| 7 #include "base/bind.h" |
| 8 #include "base/prefs/pref_service.h" |
| 9 #include "chrome/browser/browser_process.h" |
| 10 #include "chrome/browser/feedback/feedback_util.h" |
| 11 #include "chrome/common/pref_names.h" |
| 12 #include "content/public/browser/trace_controller.h" |
| 13 |
| 14 namespace { |
| 15 // Only once trace manager can exist at a time. |
| 16 TracingManager* g_tracing_manager = NULL; |
| 17 // Trace IDs start at 1 and increase. |
| 18 int g_next_trace_id = 1; |
| 19 } |
| 20 |
| 21 TracingManager::TracingManager() |
| 22 : current_trace_id_(0), |
| 23 weak_ptr_factory_(this) { |
| 24 DCHECK(!g_tracing_manager); |
| 25 g_tracing_manager = this; |
| 26 StartTracing(); |
| 27 } |
| 28 |
| 29 TracingManager::~TracingManager() { |
| 30 DCHECK(g_tracing_manager == this); |
| 31 g_tracing_manager = NULL; |
| 32 } |
| 33 |
| 34 int TracingManager::RequestTrace() { |
| 35 // Return the current trace if one is being collected. |
| 36 if (current_trace_id_) |
| 37 return current_trace_id_; |
| 38 |
| 39 current_trace_id_ = g_next_trace_id; |
| 40 ++g_next_trace_id; |
| 41 content::TraceController::GetInstance()->EndTracingAsync(this); |
| 42 return current_trace_id_; |
| 43 } |
| 44 |
| 45 bool TracingManager::GetTraceData(int id, const TraceDataCallback& callback) { |
| 46 // If a trace is being collected currently, send it via callback when |
| 47 // complete. |
| 48 if (current_trace_id_) { |
| 49 // Only allow one trace data request at a time. |
| 50 if (trace_callback_.is_null()) { |
| 51 trace_callback_ = callback; |
| 52 return true; |
| 53 } else { |
| 54 return false; |
| 55 } |
| 56 } else { |
| 57 std::map<int, scoped_refptr<base::RefCountedString> >::iterator data = |
| 58 trace_data_.find(id); |
| 59 if (data == trace_data_.end()) |
| 60 return false; |
| 61 |
| 62 // Always return the data asychronously, so the behavior is consistant. |
| 63 base::MessageLoopProxy::current()->PostTask( |
| 64 FROM_HERE, |
| 65 base::Bind(callback, data->second)); |
| 66 return true; |
| 67 } |
| 68 } |
| 69 |
| 70 void TracingManager::DiscardTraceData(int id) { |
| 71 trace_data_.erase(id); |
| 72 |
| 73 // If the trace is discarded before it is complete, clean up the accumulators. |
| 74 if (id == current_trace_id_) { |
| 75 current_trace_id_ = 0; |
| 76 data_ = ""; |
| 77 |
| 78 // If the trace has already been requested, provide an empty string. |
| 79 if (!trace_callback_.is_null()) { |
| 80 trace_callback_.Run(scoped_refptr<base::RefCountedString>()); |
| 81 trace_callback_.Reset(); |
| 82 } |
| 83 } |
| 84 } |
| 85 |
| 86 void TracingManager::StartTracing() { |
| 87 content::TraceController::GetInstance()->BeginTracing( |
| 88 this, "-test_*", |
| 89 base::debug::TraceLog::RECORD_CONTINUOUSLY); |
| 90 } |
| 91 |
| 92 void TracingManager::OnEndTracingComplete() { |
| 93 if (!current_trace_id_) |
| 94 return; |
| 95 |
| 96 std::string output_val; |
| 97 FeedbackUtil::ZipString(data_, &output_val); |
| 98 |
| 99 scoped_refptr<base::RefCountedString> output; |
| 100 output->TakeString(&output_val); |
| 101 |
| 102 trace_data_[current_trace_id_] = output; |
| 103 |
| 104 if (!trace_callback_.is_null()) { |
| 105 trace_callback_.Run(output); |
| 106 trace_callback_.Reset(); |
| 107 } |
| 108 |
| 109 current_trace_id_ = 0; |
| 110 data_ = ""; |
| 111 |
| 112 // Tracing has to be restarted asynchronous, so the TracingController can |
| 113 // clean up. |
| 114 base::MessageLoopProxy::current()->PostTask( |
| 115 FROM_HERE, |
| 116 base::Bind(&TracingManager::StartTracing, |
| 117 weak_ptr_factory_.GetWeakPtr())); |
| 118 } |
| 119 |
| 120 void TracingManager::OnTraceDataCollected( |
| 121 const scoped_refptr<base::RefCountedString>& trace_fragment) { |
| 122 if (current_trace_id_) |
| 123 data_ += trace_fragment->data(); |
| 124 } |
| 125 |
| 126 // static |
| 127 scoped_ptr<TracingManager> TracingManager::Create() { |
| 128 if (g_tracing_manager) |
| 129 return scoped_ptr<TracingManager>(); |
| 130 return scoped_ptr<TracingManager>(new TracingManager()); |
| 131 } |
| 132 |
| 133 TracingManager* TracingManager::Get() { |
| 134 return g_tracing_manager; |
| 135 } |
OLD | NEW |