Chromium Code Reviews| Index: content/browser/tracing/tracing_controller_impl.cc |
| diff --git a/content/browser/tracing/tracing_controller_impl.cc b/content/browser/tracing/tracing_controller_impl.cc |
| index bc2eb6ea2f6d08911a05027ac525673e46d70562..08f35ecf059b9d565d20f6a1daf404932c810090 100644 |
| --- a/content/browser/tracing/tracing_controller_impl.cc |
| +++ b/content/browser/tracing/tracing_controller_impl.cc |
| @@ -45,6 +45,12 @@ namespace { |
| base::LazyInstance<TracingControllerImpl>::Leaky g_controller = |
| LAZY_INSTANCE_INITIALIZER; |
| +const char kChromeTracingAgentName[] = "chrome"; |
| +#if defined(OS_CHROMEOS) |
| +const char kCrOSTracingAgentName[] = "cros"; |
| +#endif |
| +const char kETWTracingAgentName[] = "etw"; |
| +const char kChromeTraceLabel[] = "traceEvents"; |
| std::string GetNetworkTypeString() { |
| switch (net::NetworkChangeNotifier::GetConnectionType()) { |
| @@ -145,14 +151,8 @@ TracingControllerImpl::TracingControllerImpl() |
| approximate_event_count_(0), |
| pending_memory_dump_ack_count_(0), |
| failed_memory_dump_count_(0), |
| - // Tracing may have been enabled by ContentMainRunner if kTraceStartup |
| - // is specified in command line. |
| -#if defined(OS_CHROMEOS) || defined(OS_WIN) |
| - is_system_tracing_(false), |
| -#endif |
| is_tracing_(false), |
| - is_monitoring_(false), |
| - is_power_tracing_(false) { |
| + is_monitoring_(false) { |
| base::trace_event::MemoryDumpManager::GetInstance()->Initialize( |
| this /* delegate */, true /* is_coordinator */); |
| @@ -210,10 +210,12 @@ bool TracingControllerImpl::StartTracing( |
| const TraceConfig& trace_config, |
| const StartTracingDoneCallback& callback) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| + DCHECK(additional_tracing_agents_.empty()); |
| if (!can_start_tracing()) |
| return false; |
| is_tracing_ = true; |
| + start_tracing_done_callback_ = callback; |
| #if defined(OS_ANDROID) |
| if (pending_get_categories_done_callback_.is_null()) |
| @@ -221,46 +223,30 @@ bool TracingControllerImpl::StartTracing( |
| #endif |
| if (trace_config.IsSystraceEnabled()) { |
| - DCHECK(!is_power_tracing_); |
| - is_power_tracing_ = PowerTracingAgent::GetInstance()->StartTracing(); |
| + if (PowerTracingAgent::GetInstance()->StartAgentTracing(trace_config)) |
| + additional_tracing_agents_.push_back(PowerTracingAgent::GetInstance()); |
| #if defined(OS_CHROMEOS) |
| - DCHECK(!is_system_tracing_); |
| - chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()-> |
| - StartSystemTracing(); |
| - is_system_tracing_ = true; |
| + if (chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()-> |
| + StartAgentTracing(trace_config)) { |
| + additional_tracing_agents_.push_back( |
| + chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()); |
| + } |
|
stevenjb
2015/12/14 18:22:40
Can this be:
DebugDaemonClient debug_daemon = chro
Zhen Wang
2015/12/14 21:03:57
Done.
|
| #elif defined(OS_WIN) |
| - DCHECK(!is_system_tracing_); |
| - is_system_tracing_ = |
| - EtwSystemEventConsumer::GetInstance()->StartSystemTracing(); |
| + if (EtwSystemEventConsumer::GetInstance()->StartAgentTracing( |
| + trace_config)) { |
| + additional_tracing_agents_.push_back( |
| + EtwSystemEventConsumer::GetInstance()); |
| + } |
| #endif |
| } |
| // TraceLog may have been enabled in startup tracing before threads are ready. |
| if (TraceLog::GetInstance()->IsEnabled()) |
| return true; |
| - |
| - base::Closure on_start_tracing_done_callback = |
| - base::Bind(&TracingControllerImpl::OnStartTracingDone, |
| - base::Unretained(this), |
| - trace_config, callback); |
| - if (!BrowserThread::PostTask( |
| - BrowserThread::FILE, FROM_HERE, |
| - base::Bind(&TracingControllerImpl::SetEnabledOnFileThread, |
| - base::Unretained(this), trace_config, |
| - base::trace_event::TraceLog::RECORDING_MODE, |
| - on_start_tracing_done_callback))) { |
| - // BrowserThread::PostTask fails if the threads haven't been created yet, |
| - // so it should be safe to just use TraceLog::SetEnabled directly. |
| - base::trace_event::TraceLog::GetInstance()->SetEnabled( |
| - trace_config, base::trace_event::TraceLog::RECORDING_MODE); |
| - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| - on_start_tracing_done_callback); |
| - } |
| - |
| - return true; |
| + return StartAgentTracing(trace_config); |
| } |
| -void TracingControllerImpl::OnStartTracingDone( |
| +void TracingControllerImpl::OnStartAgentTracingDone( |
| const TraceConfig& trace_config, |
| const StartTracingDoneCallback& callback) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| @@ -325,63 +311,23 @@ void TracingControllerImpl::OnStopTracingDone() { |
| pending_stop_tracing_ack_count_ = trace_message_filters_.size() + 1; |
| pending_stop_tracing_filters_ = trace_message_filters_; |
| -#if defined(OS_CHROMEOS) || defined(OS_WIN) |
| - if (is_system_tracing_) { |
| - // Disable system tracing. |
| - is_system_tracing_ = false; |
| - ++pending_stop_tracing_ack_count_; |
| - |
| + pending_stop_tracing_ack_count_ += additional_tracing_agents_.size(); |
| + for (auto it : additional_tracing_agents_) { |
| #if defined(OS_CHROMEOS) |
| - scoped_refptr<base::TaskRunner> task_runner = |
| - BrowserThread::GetBlockingPool(); |
| - chromeos::DBusThreadManager::Get() |
| - ->GetDebugDaemonClient() |
| - ->RequestStopSystemTracing( |
| - task_runner, |
| - base::Bind(&TracingControllerImpl::OnEndSystemTracingAcked, |
| - base::Unretained(this))); |
| -#elif defined(OS_WIN) |
| - EtwSystemEventConsumer::GetInstance()->StopSystemTracing( |
| - base::Bind(&TracingControllerImpl::OnEndSystemTracingAcked, |
| - base::Unretained(this))); |
| + if (it->GetTracingAgentName() == kCrOSTracingAgentName) { |
|
stevenjb
2015/12/14 18:22:40
This is awkward. See note above.
Zhen Wang
2015/12/14 21:03:57
Done.
|
| + scoped_refptr<base::TaskRunner> task_runner = |
| + BrowserThread::GetBlockingPool(); |
| + static_cast<chromeos::DebugDaemonClient*>( |
| + it)->SetStopAgentTracingTaskRunner(task_runner); |
| + } |
| #endif |
| - } |
| -#endif // defined(OS_CHROMEOS) || defined(OS_WIN) |
| - |
| - if (is_power_tracing_) { |
| - is_power_tracing_ = false; |
| - ++pending_stop_tracing_ack_count_; |
| - PowerTracingAgent::GetInstance()->StopTracing( |
| - base::Bind(&TracingControllerImpl::OnEndPowerTracingAcked, |
| + it->StopAgentTracing( |
| + base::Bind(&TracingControllerImpl::OnEndAgentTracingAcked, |
| base::Unretained(this))); |
| } |
| + additional_tracing_agents_.clear(); |
| - // Handle special case of zero child processes by immediately flushing the |
| - // trace log. Once the flush has completed the caller will be notified that |
| - // tracing has ended. |
| - if (pending_stop_tracing_ack_count_ == 1) { |
| - // Flush/cancel asynchronously now, because we don't have any children to |
| - // wait for. |
| - if (trace_data_sink_) { |
| - TraceLog::GetInstance()->Flush( |
| - base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected, |
| - base::Unretained(this)), |
| - true); |
| - } else { |
| - TraceLog::GetInstance()->CancelTracing( |
| - base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected, |
| - base::Unretained(this))); |
| - } |
| - } |
| - |
| - // Notify all child processes. |
| - for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin(); |
| - it != trace_message_filters_.end(); ++it) { |
| - if (trace_data_sink_) |
| - it->get()->SendEndTracing(); |
| - else |
| - it->get()->SendCancelTracing(); |
| - } |
| + StopAgentTracing(StopAgentTracingCallback()); |
| } |
| bool TracingControllerImpl::StartMonitoring( |
| @@ -738,39 +684,26 @@ void TracingControllerImpl::OnStopTracingAcked( |
| } |
| } |
| -void TracingControllerImpl::OnEndPowerTracingAcked( |
| - const scoped_refptr<base::RefCountedString>& events_str_ptr) { |
| - DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| - |
| - if (trace_data_sink_.get()) { |
| - std::string json_string = base::GetQuotedJSONString(events_str_ptr->data()); |
| - trace_data_sink_->SetPowerTrace(json_string); |
| - } |
| - std::vector<std::string> category_groups; |
| - OnStopTracingAcked(NULL, category_groups); |
| -} |
| - |
| -#if defined(OS_CHROMEOS) || defined(OS_WIN) |
| -void TracingControllerImpl::OnEndSystemTracingAcked( |
| +void TracingControllerImpl::OnEndAgentTracingAcked( |
| + const std::string& agent_name, |
| + const std::string& events_label, |
| const scoped_refptr<base::RefCountedString>& events_str_ptr) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| if (trace_data_sink_.get()) { |
| -#if defined(OS_WIN) |
| - // The Windows kernel events are kept into a JSon format stored as string |
| - // and must not be escaped. |
| - std::string json_string = events_str_ptr->data(); |
| -#else |
| - std::string json_string = |
| - base::GetQuotedJSONString(events_str_ptr->data()); |
| -#endif |
| - trace_data_sink_->SetSystemTrace(json_string); |
| + std::string json_string; |
| + if (agent_name == kETWTracingAgentName) { |
| + // The Windows kernel events are kept into a JSON format stored as string |
| + // and must not be escaped. |
| + json_string = events_str_ptr->data(); |
| + } else { |
| + json_string = base::GetQuotedJSONString(events_str_ptr->data()); |
| + } |
| + trace_data_sink_->AddAgentTrace(events_label, json_string); |
| } |
| - DCHECK(!is_system_tracing_); |
| std::vector<std::string> category_groups; |
| OnStopTracingAcked(NULL, category_groups); |
| } |
| -#endif |
| void TracingControllerImpl::OnCaptureMonitoringSnapshotAcked( |
| TraceMessageFilter* trace_message_filter) { |
| @@ -924,6 +857,86 @@ void TracingControllerImpl::UnregisterTracingUI(TracingUI* tracing_ui) { |
| tracing_uis_.erase(it); |
| } |
| +std::string TracingControllerImpl::GetTracingAgentName() { |
| + return kChromeTracingAgentName; |
| +} |
| + |
| +std::string TracingControllerImpl::GetTraceEventLabel() { |
| + return kChromeTraceLabel; |
| +} |
| + |
| +bool TracingControllerImpl::StartAgentTracing( |
| + const base::trace_event::TraceConfig& trace_config) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| + |
| + base::Closure on_start_tracing_done_callback = |
| + base::Bind(&TracingControllerImpl::OnStartAgentTracingDone, |
| + base::Unretained(this), |
| + trace_config, start_tracing_done_callback_); |
| + if (!BrowserThread::PostTask( |
| + BrowserThread::FILE, FROM_HERE, |
| + base::Bind(&TracingControllerImpl::SetEnabledOnFileThread, |
| + base::Unretained(this), trace_config, |
| + base::trace_event::TraceLog::RECORDING_MODE, |
| + on_start_tracing_done_callback))) { |
| + // BrowserThread::PostTask fails if the threads haven't been created yet, |
| + // so it should be safe to just use TraceLog::SetEnabled directly. |
| + base::trace_event::TraceLog::GetInstance()->SetEnabled( |
| + trace_config, base::trace_event::TraceLog::RECORDING_MODE); |
| + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| + on_start_tracing_done_callback); |
| + } |
| + |
| + return true; |
| +} |
| + |
| +void TracingControllerImpl::StopAgentTracing( |
| + const StopAgentTracingCallback& callback) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| + // Handle special case of zero child processes by immediately flushing the |
| + // trace log. Once the flush has completed the caller will be notified that |
| + // tracing has ended. |
| + if (pending_stop_tracing_ack_count_ == 1) { |
| + // Flush/cancel asynchronously now, because we don't have any children to |
| + // wait for. |
| + if (trace_data_sink_) { |
| + TraceLog::GetInstance()->Flush( |
| + base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected, |
| + base::Unretained(this)), |
| + true); |
| + } else { |
| + TraceLog::GetInstance()->CancelTracing( |
| + base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected, |
| + base::Unretained(this))); |
| + } |
| + } |
| + |
| + // Notify all child processes. |
| + for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin(); |
| + it != trace_message_filters_.end(); ++it) { |
|
stevenjb
2015/12/14 18:22:40
for (auto it : trace_message_filters_)
Zhen Wang
2015/12/14 21:03:57
Done.
|
| + if (trace_data_sink_) |
| + it->get()->SendEndTracing(); |
| + else |
| + it->get()->SendCancelTracing(); |
| + } |
| +} |
| + |
| +bool TracingControllerImpl::SupportsExplicitClockSync() { |
| + // TODO(zhenw): return true after implementing explicit clock sync. |
| + return false; |
| +} |
| + |
| +void TracingControllerImpl::RecordClockSyncMarker( |
| + int sync_id, |
| + const RecordClockSyncMarkerCallback& callback) { |
| + DCHECK(SupportsExplicitClockSync()); |
| + // TODO(zhenw): implement explicit clock sync. |
| +} |
| + |
| +void TracingControllerImpl::IssueClockSyncMarker() { |
| + // TODO(zhenw): implement explicit clock sync. |
| +} |
| + |
| void TracingControllerImpl::RequestGlobalMemoryDump( |
| const base::trace_event::MemoryDumpRequestArgs& args, |
| const base::trace_event::MemoryDumpCallback& callback) { |