Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Unified Diff: content/browser/tracing/tracing_controller_impl.cc

Issue 2833873003: WIP: The tracing service prototype
Patch Set: sync Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 4af29736a8684de53267b9d40276ea9c84767749..620630f86dc1202b026e995074a8449b48de7226 100644
--- a/content/browser/tracing/tracing_controller_impl.cc
+++ b/content/browser/tracing/tracing_controller_impl.cc
@@ -16,6 +16,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted_memory.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
#include "base/sys_info.h"
#include "base/threading/sequenced_worker_pool.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -36,6 +37,8 @@
#include "content/public/common/content_switches.h"
#include "gpu/config/gpu_info.h"
#include "net/base/network_change_notifier.h"
+#include "services/resource_coordinator/tracing/coordinator_impl.h"
+#include "services/service_manager/public/cpp/connector.h"
#include "v8/include/v8-version-string.h"
#if (defined(OS_POSIX) && defined(USE_UDEV)) || defined(OS_WIN) || \
@@ -67,74 +70,29 @@ namespace {
base::LazyInstance<TracingControllerImpl>::Leaky g_controller =
LAZY_INSTANCE_INITIALIZER;
-const char kChromeTracingAgentName[] = "chrome";
-const char kETWTracingAgentName[] = "etw";
-const char kArcTracingAgentName[] = "arc";
-const char kChromeTraceLabel[] = "traceEvents";
-
-const int kStartTracingTimeoutSeconds = 30;
-const int kIssueClockSyncTimeoutSeconds = 30;
-const int kStopTracingRetryTimeMilliseconds = 100;
-
-std::string GetNetworkTypeString() {
- switch (net::NetworkChangeNotifier::GetConnectionType()) {
- case net::NetworkChangeNotifier::CONNECTION_ETHERNET:
- return "Ethernet";
- case net::NetworkChangeNotifier::CONNECTION_WIFI:
- return "WiFi";
- case net::NetworkChangeNotifier::CONNECTION_2G:
- return "2G";
- case net::NetworkChangeNotifier::CONNECTION_3G:
- return "3G";
- case net::NetworkChangeNotifier::CONNECTION_4G:
- return "4G";
- case net::NetworkChangeNotifier::CONNECTION_NONE:
- return "None";
- case net::NetworkChangeNotifier::CONNECTION_BLUETOOTH:
- return "Bluetooth";
- case net::NetworkChangeNotifier::CONNECTION_UNKNOWN:
- default:
- break;
- }
- return "Unknown";
-}
-
-std::string GetClockString() {
- switch (base::TimeTicks::GetClock()) {
- case base::TimeTicks::Clock::LINUX_CLOCK_MONOTONIC:
- return "LINUX_CLOCK_MONOTONIC";
- case base::TimeTicks::Clock::IOS_CF_ABSOLUTE_TIME_MINUS_KERN_BOOTTIME:
- return "IOS_CF_ABSOLUTE_TIME_MINUS_KERN_BOOTTIME";
- case base::TimeTicks::Clock::MAC_MACH_ABSOLUTE_TIME:
- return "MAC_MACH_ABSOLUTE_TIME";
- case base::TimeTicks::Clock::WIN_QPC:
- return "WIN_QPC";
- case base::TimeTicks::Clock::WIN_ROLLOVER_PROTECTED_TIME_GET_TIME:
- return "WIN_ROLLOVER_PROTECTED_TIME_GET_TIME";
- }
-
- NOTREACHED();
- return std::string();
-}
-
} // namespace
TracingController* TracingController::GetInstance() {
return TracingControllerImpl::GetInstance();
}
-TracingControllerImpl::TracingControllerImpl()
- : pending_start_tracing_ack_count_(0),
- pending_stop_tracing_ack_count_(0),
- pending_trace_log_status_ack_count_(0),
- maximum_trace_buffer_usage_(0),
- approximate_event_count_(0),
- pending_clock_sync_ack_count_(0),
- enabled_tracing_modes_(0) {
+TracingControllerImpl::TracingControllerImpl() {
// Deliberately leaked, like this class.
base::FileTracing::SetProvider(new FileTracingProviderImpl);
}
+void TracingControllerImpl::Initialize(service_manager::Connector* connector) {
+ if (connector) {
+ connector->BindInterface("tracing", &coordinator_);
+ return;
+ }
+ // If connector is null, the coordinator must be running in this process.
+ resource_coordinator::tracing::CoordinatorImpl* coordinator =
+ resource_coordinator::tracing::CoordinatorImpl::GetInstance();
+ DCHECK(coordinator);
+ coordinator->BindCoordinatorRequest(mojo::MakeRequest(&coordinator_));
+}
+
TracingControllerImpl::~TracingControllerImpl() {
// This is a Leaky instance.
NOTREACHED();
@@ -148,257 +106,74 @@ bool TracingControllerImpl::GetCategories(
const GetCategoriesDoneCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- // Known categories come back from child processes with the EndTracingAck
- // message. So to get known categories, just begin and end tracing immediately
- // afterwards. This will ping all the child processes for categories.
- pending_get_categories_done_callback_ = callback;
- if (!StartTracing(TraceConfig("*", ""), StartTracingDoneCallback())) {
- pending_get_categories_done_callback_.Reset();
- return false;
- }
-
- bool ok = StopTracing(NULL);
- DCHECK(ok);
+ coordinator_->GetCategories(
+ base::BindRepeating(&TracingControllerImpl::GetCategoriesDone,
+ base::Unretained(this), callback));
return true;
}
-void TracingControllerImpl::SetEnabledOnFileThread(
- const TraceConfig& trace_config,
- const base::Closure& callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::FILE);
-
- TraceLog::GetInstance()->SetEnabled(trace_config, enabled_tracing_modes_);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
-}
-
-void TracingControllerImpl::SetDisabledOnFileThread(
- const base::Closure& callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::FILE);
-
- DCHECK(enabled_tracing_modes_);
- TraceLog::GetInstance()->SetDisabled(enabled_tracing_modes_);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
+void TracingControllerImpl::GetCategoriesDone(
+ const GetCategoriesDoneCallback& callback,
+ const std::string& categories) {
+ const std::vector<std::string> split = base::SplitString(
+ categories, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+ std::set<std::string> category_set;
+ for (const auto& category : split) {
+ category_set.insert(category);
+ }
+ callback.Run(category_set);
}
bool TracingControllerImpl::StartTracing(
const TraceConfig& trace_config,
const StartTracingDoneCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK(additional_tracing_agents_.empty());
-
- // TODO(ssid): Introduce a priority for tracing agents to handle multiple
- // start and stop requests, crbug.com/705087.
- if (!can_start_tracing())
- return false;
- start_tracing_done_callback_ = callback;
- trace_config_.reset(new base::trace_event::TraceConfig(trace_config));
- enabled_tracing_modes_ = TraceLog::RECORDING_MODE;
- if (!trace_config_->event_filters().empty())
- enabled_tracing_modes_ |= TraceLog::FILTERING_MODE;
- metadata_.reset(new base::DictionaryValue());
- pending_start_tracing_ack_count_ = 0;
-
-#if defined(OS_ANDROID)
- if (pending_get_categories_done_callback_.is_null())
- TraceLog::GetInstance()->AddClockSyncMetadataEvent();
-#endif
-
- if (trace_config.IsSystraceEnabled()) {
-#if defined(ENABLE_POWER_TRACING)
- PowerTracingAgent::GetInstance()->StartAgentTracing(
- trace_config,
- base::Bind(&TracingControllerImpl::OnStartAgentTracingAcked,
- base::Unretained(this)));
- ++pending_start_tracing_ack_count_;
-#endif
-
-#if defined(OS_CHROMEOS)
- chromeos::DebugDaemonClient* debug_daemon =
- chromeos::DBusThreadManager::Get()->GetDebugDaemonClient();
- if (debug_daemon) {
- debug_daemon->StartAgentTracing(
- trace_config,
- base::Bind(&TracingControllerImpl::OnStartAgentTracingAcked,
- base::Unretained(this)));
- ++pending_start_tracing_ack_count_;
- }
-
- ArcTracingAgent::GetInstance()->StartAgentTracing(
- trace_config,
- base::Bind(&TracingControllerImpl::OnStartAgentTracingAcked,
- base::Unretained(this)));
- ++pending_start_tracing_ack_count_;
-#elif defined(OS_WIN)
- EtwTracingAgent::GetInstance()->StartAgentTracing(
- trace_config,
- base::Bind(&TracingControllerImpl::OnStartAgentTracingAcked,
- base::Unretained(this)));
- ++pending_start_tracing_ack_count_;
-#endif
- }
-
- // TraceLog may have been enabled in startup tracing before threads are ready.
- if (TraceLog::GetInstance()->IsEnabled())
- return true;
-
- StartAgentTracing(trace_config,
- base::Bind(&TracingControllerImpl::OnStartAgentTracingAcked,
- base::Unretained(this)));
- ++pending_start_tracing_ack_count_;
-
- // Set a deadline to ensure all agents ack within a reasonable time frame.
- start_tracing_timer_.Start(
- FROM_HERE, base::TimeDelta::FromSeconds(kStartTracingTimeoutSeconds),
- base::Bind(&TracingControllerImpl::OnAllTracingAgentsStarted,
- base::Unretained(this)));
+ is_tracing_ = true;
+ mojo::DataPipe data_pipe;
+ coordinator_->StartTracing(std::move(data_pipe.producer_handle),
+ trace_config.ToString());
+ drainer_.reset(new mojo::common::DataPipeDrainer(
+ this, std::move(data_pipe.consumer_handle)));
+ if (!callback.is_null())
+ callback.Run();
return true;
}
-void TracingControllerImpl::OnAllTracingAgentsStarted() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- TRACE_EVENT_API_ADD_METADATA_EVENT(
- TraceLog::GetCategoryGroupEnabled("__metadata"),
- "IsTimeTicksHighResolution", "value",
- base::TimeTicks::IsHighResolution());
-
- // Notify all child processes.
- for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin();
- it != trace_message_filters_.end(); ++it) {
- it->get()->SendBeginTracing(*trace_config_);
- }
-
- if (!start_tracing_done_callback_.is_null())
- start_tracing_done_callback_.Run();
-
- start_tracing_done_callback_.Reset();
-}
-
-void TracingControllerImpl::AddMetadata(const base::DictionaryValue& data) {
- if (metadata_)
- metadata_->MergeDictionary(&data);
-}
-
bool TracingControllerImpl::StopTracing(
const scoped_refptr<TraceDataSink>& trace_data_sink) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (!can_stop_tracing())
- return false;
-
- // If we're still waiting to start tracing, try again after a delay.
- if (start_tracing_timer_.IsRunning()) {
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE,
- base::Bind(base::IgnoreResult(&TracingControllerImpl::StopTracing),
- base::Unretained(this), trace_data_sink),
- base::TimeDelta::FromMilliseconds(kStopTracingRetryTimeMilliseconds));
- return true;
- }
-
- if (trace_data_sink) {
- MetadataFilterPredicate metadata_filter;
- if (TraceLog::GetInstance()->GetCurrentTraceConfig()
- .IsArgumentFilterEnabled()) {
- std::unique_ptr<TracingDelegate> delegate(
- GetContentClient()->browser()->GetTracingDelegate());
- if (delegate)
- metadata_filter = delegate->GetMetadataFilterPredicate();
- }
- AddFilteredMetadata(trace_data_sink.get(), GenerateTracingMetadataDict(),
- metadata_filter);
- AddFilteredMetadata(trace_data_sink.get(), std::move(metadata_),
- metadata_filter);
- } else {
- metadata_.reset();
- }
-
trace_data_sink_ = trace_data_sink;
- trace_config_.reset();
-
- // Issue clock sync marker before actually stopping tracing.
- // StopTracingAfterClockSync() will be called after clock sync is done.
- IssueClockSyncMarker();
-
+ coordinator_->StopAndFlush();
return true;
}
-void TracingControllerImpl::StopTracingAfterClockSync() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- // |pending_clock_sync_ack_count_| could be non-zero if clock sync times out.
- pending_clock_sync_ack_count_ = 0;
-
- // Disable local trace early to avoid traces during end-tracing process from
- // interfering with the process.
- base::Closure on_stop_tracing_done_callback = base::Bind(
- &TracingControllerImpl::OnStopTracingDone, base::Unretained(this));
- BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
- base::Bind(&TracingControllerImpl::SetDisabledOnFileThread,
- base::Unretained(this),
- on_stop_tracing_done_callback));
-}
-
-void TracingControllerImpl::OnStopTracingDone() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
-#if defined(OS_ANDROID)
- if (pending_get_categories_done_callback_.is_null())
- TraceLog::GetInstance()->AddClockSyncMetadataEvent();
-#endif
-
- // Count myself (local trace) in pending_stop_tracing_ack_count_,
- // acked below.
- pending_stop_tracing_ack_count_ = trace_message_filters_.size() + 1;
- pending_stop_tracing_filters_ = trace_message_filters_;
-
- pending_stop_tracing_ack_count_ += additional_tracing_agents_.size();
- for (auto* it : additional_tracing_agents_) {
- it->StopAgentTracing(
- base::Bind(&TracingControllerImpl::OnEndAgentTracingAcked,
- base::Unretained(this)));
- }
- additional_tracing_agents_.clear();
-
- StopAgentTracing(StopAgentTracingCallback());
-}
-
bool TracingControllerImpl::GetTraceBufferUsage(
const GetTraceBufferUsageCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (!can_get_trace_buffer_usage() || callback.is_null())
- return false;
-
- pending_trace_buffer_usage_callback_ = callback;
-
- // Count myself in pending_trace_log_status_ack_count_, acked below.
- pending_trace_log_status_ack_count_ = trace_message_filters_.size() + 1;
- pending_trace_log_status_filters_ = trace_message_filters_;
- maximum_trace_buffer_usage_ = 0;
- approximate_event_count_ = 0;
-
- base::trace_event::TraceLogStatus status =
- TraceLog::GetInstance()->GetStatus();
- // Call OnTraceLogStatusReply unconditionally for the browser process.
- // This will result in immediate execution of the callback if there are no
- // child processes.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&TracingControllerImpl::OnTraceLogStatusReply,
- base::Unretained(this), nullptr, status));
-
- // Notify all child processes.
- for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin();
- it != trace_message_filters_.end(); ++it) {
- it->get()->SendGetTraceLogStatus();
- }
+ coordinator_->RequestBufferUsage(
+ base::BindRepeating(&TracingControllerImpl::GetTraceBufferUsageDone,
+ base::Unretained(this), callback));
return true;
}
+void TracingControllerImpl::AddMetadata(const base::DictionaryValue& metadata) {
+ if (metadata_)
+ metadata_->MergeDictionary(&metadata);
+}
+
bool TracingControllerImpl::IsTracing() const {
- return !!enabled_tracing_modes_;
+ return is_tracing_;
+}
+
+void TracingControllerImpl::GetTraceBufferUsageDone(
+ const GetTraceBufferUsageCallback& callback,
+ bool success,
+ float percent_full,
+ uint32_t approximate_count) {
+ callback.Run(percent_full, approximate_count);
}
void TracingControllerImpl::AddTraceMessageFilter(
@@ -420,11 +195,6 @@ void TracingControllerImpl::AddTraceMessageFilter(
#endif
trace_message_filters_.insert(trace_message_filter);
- if (can_stop_tracing()) {
- trace_message_filter->SendBeginTracing(
- TraceLog::GetInstance()->GetCurrentTraceConfig());
- }
-
for (auto& observer : trace_message_filter_observers_)
observer.OnTraceMessageFilterAdded(trace_message_filter);
}
@@ -445,237 +215,9 @@ void TracingControllerImpl::RemoveTraceMessageFilter(
trace_message_filter->peer_pid());
#endif
- // If a filter is removed while a response from that filter is pending then
- // simulate the response. Otherwise the response count will be wrong and the
- // completion callback will never be executed.
- if (pending_stop_tracing_ack_count_ > 0) {
- TraceMessageFilterSet::const_iterator it =
- pending_stop_tracing_filters_.find(trace_message_filter);
- if (it != pending_stop_tracing_filters_.end()) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&TracingControllerImpl::OnStopTracingAcked,
- base::Unretained(this),
- base::RetainedRef(trace_message_filter),
- std::vector<std::string>()));
- }
- }
- if (pending_trace_log_status_ack_count_ > 0) {
- TraceMessageFilterSet::const_iterator it =
- pending_trace_log_status_filters_.find(trace_message_filter);
- if (it != pending_trace_log_status_filters_.end()) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&TracingControllerImpl::OnTraceLogStatusReply,
- base::Unretained(this),
- base::RetainedRef(trace_message_filter),
- base::trace_event::TraceLogStatus()));
- }
- }
trace_message_filters_.erase(trace_message_filter);
}
-void TracingControllerImpl::AddTracingAgent(const std::string& agent_name) {
-#if defined(OS_CHROMEOS)
- auto* debug_daemon =
- chromeos::DBusThreadManager::Get()->GetDebugDaemonClient();
- if (agent_name == debug_daemon->GetTracingAgentName()) {
- additional_tracing_agents_.push_back(debug_daemon);
- debug_daemon->SetStopAgentTracingTaskRunner(
- BrowserThread::GetBlockingPool());
- return;
- }
-
- if (agent_name == kArcTracingAgentName) {
- additional_tracing_agents_.push_back(ArcTracingAgent::GetInstance());
- return;
- }
-#elif defined(OS_WIN)
- auto* etw_agent = EtwTracingAgent::GetInstance();
- if (agent_name == etw_agent->GetTracingAgentName()) {
- additional_tracing_agents_.push_back(etw_agent);
- return;
- }
-#endif
-
-#if defined(ENABLE_POWER_TRACING)
- auto* power_agent = PowerTracingAgent::GetInstance();
- if (agent_name == power_agent->GetTracingAgentName()) {
- additional_tracing_agents_.push_back(power_agent);
- return;
- }
-#endif
-
- DCHECK(agent_name == kChromeTracingAgentName);
-}
-
-void TracingControllerImpl::OnStartAgentTracingAcked(
- const std::string& agent_name,
- bool success) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- // Don't taken any further action if the ack came after the deadline.
- if (!start_tracing_timer_.IsRunning())
- return;
-
- if (success)
- AddTracingAgent(agent_name);
-
- if (--pending_start_tracing_ack_count_ == 0) {
- start_tracing_timer_.Stop();
- OnAllTracingAgentsStarted();
- }
-}
-
-void TracingControllerImpl::OnStopTracingAcked(
- TraceMessageFilter* trace_message_filter,
- const std::vector<std::string>& known_category_groups) {
- if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(
- &TracingControllerImpl::OnStopTracingAcked, base::Unretained(this),
- base::RetainedRef(trace_message_filter), known_category_groups));
- return;
- }
-
- // Merge known_category_groups with known_category_groups_
- known_category_groups_.insert(known_category_groups.begin(),
- known_category_groups.end());
-
- if (pending_stop_tracing_ack_count_ == 0)
- return;
-
- if (trace_message_filter &&
- !pending_stop_tracing_filters_.erase(trace_message_filter)) {
- // The response from the specified message filter has already been received.
- return;
- }
-
- if (--pending_stop_tracing_ack_count_ == 1) {
- // All acks from subprocesses have been received. Now flush the local trace.
- // During or after this call, our OnLocalTraceDataCollected will be
- // called with the last of the local trace data.
- 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)));
- }
- return;
- }
-
- if (pending_stop_tracing_ack_count_ != 0)
- return;
-
- // All acks (including from the subprocesses and the local trace) have been
- // received.
- enabled_tracing_modes_ = 0;
-
- // Trigger callback if one is set.
- if (!pending_get_categories_done_callback_.is_null()) {
- pending_get_categories_done_callback_.Run(known_category_groups_);
- pending_get_categories_done_callback_.Reset();
- } else if (trace_data_sink_.get()) {
- trace_data_sink_->Close();
- trace_data_sink_ = NULL;
- }
-}
-
-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() && events_str_ptr &&
- !events_str_ptr->data().empty()) {
- if (agent_name == kETWTracingAgentName) {
- // The Windows kernel events are kept into a JSON format stored as string
- // and must not be escaped.
- trace_data_sink_->AddAgentTrace(events_label, events_str_ptr->data());
- } else if (agent_name == kArcTracingAgentName) {
- // The ARC events are kept into a JSON format stored as string
- // and must not be escaped.
- trace_data_sink_->AddTraceChunk(events_str_ptr->data());
- } else {
- trace_data_sink_->AddAgentTrace(
- events_label, base::GetQuotedJSONString(events_str_ptr->data()));
- }
- }
- std::vector<std::string> category_groups;
- OnStopTracingAcked(NULL, category_groups);
-}
-
-void TracingControllerImpl::OnTraceDataCollected(
- const scoped_refptr<base::RefCountedString>& events_str_ptr) {
- // OnTraceDataCollected may be called from any browser thread, either by the
- // local event trace system or from child processes via TraceMessageFilter.
- if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&TracingControllerImpl::OnTraceDataCollected,
- base::Unretained(this), events_str_ptr));
- return;
- }
-
- if (trace_data_sink_.get())
- trace_data_sink_->AddTraceChunk(events_str_ptr->data());
-}
-
-void TracingControllerImpl::OnLocalTraceDataCollected(
- const scoped_refptr<base::RefCountedString>& events_str_ptr,
- bool has_more_events) {
- if (events_str_ptr->data().size())
- OnTraceDataCollected(events_str_ptr);
-
- if (has_more_events)
- return;
-
- // Simulate an StopTracingAcked for the local trace.
- std::vector<std::string> category_groups;
- TraceLog::GetInstance()->GetKnownCategoryGroups(&category_groups);
- OnStopTracingAcked(NULL, category_groups);
-}
-
-void TracingControllerImpl::OnTraceLogStatusReply(
- TraceMessageFilter* trace_message_filter,
- const base::trace_event::TraceLogStatus& status) {
- if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&TracingControllerImpl::OnTraceLogStatusReply,
- base::Unretained(this),
- base::RetainedRef(trace_message_filter), status));
- return;
- }
-
- if (pending_trace_log_status_ack_count_ == 0)
- return;
-
- if (trace_message_filter &&
- !pending_trace_log_status_filters_.erase(trace_message_filter)) {
- // The response from the specified message filter has already been received.
- return;
- }
-
- float percent_full = static_cast<float>(
- static_cast<double>(status.event_count) / status.event_capacity);
- maximum_trace_buffer_usage_ =
- std::max(maximum_trace_buffer_usage_, percent_full);
- approximate_event_count_ += status.event_count;
-
- if (--pending_trace_log_status_ack_count_ == 0) {
- // Trigger callback if one is set.
- pending_trace_buffer_usage_callback_.Run(maximum_trace_buffer_usage_,
- approximate_event_count_);
- pending_trace_buffer_usage_callback_.Reset();
- }
-}
-
void TracingControllerImpl::RegisterTracingUI(TracingUI* tracing_ui) {
DCHECK(tracing_uis_.find(tracing_ui) == tracing_uis_.end());
tracing_uis_.insert(tracing_ui);
@@ -687,238 +229,6 @@ void TracingControllerImpl::UnregisterTracingUI(TracingUI* tracing_ui) {
tracing_uis_.erase(it);
}
-std::string TracingControllerImpl::GetTracingAgentName() {
- return kChromeTracingAgentName;
-}
-
-std::string TracingControllerImpl::GetTraceEventLabel() {
- return kChromeTraceLabel;
-}
-
-void TracingControllerImpl::StartAgentTracing(
- const base::trace_event::TraceConfig& trace_config,
- const StartAgentTracingCallback& callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- base::Closure on_agent_started =
- base::Bind(callback, kChromeTracingAgentName, true);
- if (!BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- base::Bind(&TracingControllerImpl::SetEnabledOnFileThread,
- base::Unretained(this), trace_config,
- on_agent_started))) {
- // BrowserThread::PostTask fails if the threads haven't been created yet,
- // so it should be safe to just use TraceLog::SetEnabled directly.
- TraceLog::GetInstance()->SetEnabled(trace_config, enabled_tracing_modes_);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, on_agent_started);
- }
-}
-
-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 (auto it : trace_message_filters_) {
- if (trace_data_sink_)
- it->SendEndTracing();
- else
- it->SendCancelTracing();
- }
-}
-
-bool TracingControllerImpl::SupportsExplicitClockSync() {
- return true;
-}
-
-void TracingControllerImpl::RecordClockSyncMarker(
- const std::string& sync_id,
- const RecordClockSyncMarkerCallback& callback) {
- DCHECK(SupportsExplicitClockSync());
-
- TRACE_EVENT_CLOCK_SYNC_RECEIVER(sync_id);
-}
-
-void TracingControllerImpl::IssueClockSyncMarker() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK_EQ(0, pending_clock_sync_ack_count_);
-
- for (auto* it : additional_tracing_agents_) {
- if (it->SupportsExplicitClockSync()) {
- it->RecordClockSyncMarker(
- base::GenerateGUID(),
- base::Bind(&TracingControllerImpl::OnClockSyncMarkerRecordedByAgent,
- base::Unretained(this)));
- pending_clock_sync_ack_count_++;
- }
- }
-
- // If no clock sync is needed, stop tracing right away. Otherwise, schedule
- // to stop tracing after timeout.
- if (pending_clock_sync_ack_count_ == 0) {
- StopTracingAfterClockSync();
- } else {
- clock_sync_timer_.Start(
- FROM_HERE, base::TimeDelta::FromSeconds(kIssueClockSyncTimeoutSeconds),
- this, &TracingControllerImpl::StopTracingAfterClockSync);
- }
-}
-
-void TracingControllerImpl::OnClockSyncMarkerRecordedByAgent(
- const std::string& sync_id,
- const base::TimeTicks& issue_ts,
- const base::TimeTicks& issue_end_ts) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- // TODO(charliea): Change this function so that it can accept a boolean
- // success indicator instead of having to rely on sentinel issue_ts and
- // issue_end_ts values to signal failure.
- if (!(issue_ts == base::TimeTicks() || issue_end_ts == base::TimeTicks()))
- TRACE_EVENT_CLOCK_SYNC_ISSUER(sync_id, issue_ts, issue_end_ts);
-
- // Timer is not running means that clock sync already timed out.
- if (!clock_sync_timer_.IsRunning())
- return;
-
- // Stop tracing only if all agents report back.
- if (--pending_clock_sync_ack_count_ == 0) {
- clock_sync_timer_.Stop();
- StopTracingAfterClockSync();
- }
-}
-
-void TracingControllerImpl::AddFilteredMetadata(
- TracingController::TraceDataSink* sink,
- std::unique_ptr<base::DictionaryValue> metadata,
- const MetadataFilterPredicate& filter) {
- if (filter.is_null()) {
- sink->AddMetadata(std::move(metadata));
- return;
- }
- std::unique_ptr<base::DictionaryValue> filtered_metadata(
- new base::DictionaryValue);
- for (base::DictionaryValue::Iterator it(*metadata); !it.IsAtEnd();
- it.Advance()) {
- if (filter.Run(it.key()))
- filtered_metadata->Set(it.key(), it.value().DeepCopy());
- else
- filtered_metadata->SetString(it.key(), "__stripped__");
- }
- sink->AddMetadata(std::move(filtered_metadata));
-}
-
-std::unique_ptr<base::DictionaryValue>
-TracingControllerImpl::GenerateTracingMetadataDict() const {
- // It's important that this function creates a new metadata dict and returns
- // it rather than directly populating the metadata_ member, as the data may
- // need filtering in some cases.
- std::unique_ptr<base::DictionaryValue> metadata_dict(
- new base::DictionaryValue());
-
- metadata_dict->SetString("network-type", GetNetworkTypeString());
- metadata_dict->SetString("product-version", GetContentClient()->GetProduct());
- metadata_dict->SetString("v8-version", V8_VERSION_STRING);
- metadata_dict->SetString("user-agent", GetContentClient()->GetUserAgent());
-
- // OS
-#if defined(OS_CHROMEOS)
- metadata_dict->SetString("os-name", "CrOS");
- int32_t major_version;
- int32_t minor_version;
- int32_t bugfix_version;
- // OperatingSystemVersion only has a POSIX implementation which returns the
- // wrong versions for CrOS.
- base::SysInfo::OperatingSystemVersionNumbers(&major_version, &minor_version,
- &bugfix_version);
- metadata_dict->SetString(
- "os-version", base::StringPrintf("%d.%d.%d", major_version, minor_version,
- bugfix_version));
-#else
- metadata_dict->SetString("os-name", base::SysInfo::OperatingSystemName());
- metadata_dict->SetString("os-version",
- base::SysInfo::OperatingSystemVersion());
-#endif
- metadata_dict->SetString("os-arch",
- base::SysInfo::OperatingSystemArchitecture());
-
- // CPU
- base::CPU cpu;
- metadata_dict->SetInteger("cpu-family", cpu.family());
- metadata_dict->SetInteger("cpu-model", cpu.model());
- metadata_dict->SetInteger("cpu-stepping", cpu.stepping());
- metadata_dict->SetInteger("num-cpus", base::SysInfo::NumberOfProcessors());
- metadata_dict->SetInteger("physical-memory",
- base::SysInfo::AmountOfPhysicalMemoryMB());
-
- std::string cpu_brand = cpu.cpu_brand();
- // Workaround for crbug.com/249713.
- // TODO(oysteine): Remove workaround when bug is fixed.
- size_t null_pos = cpu_brand.find('\0');
- if (null_pos != std::string::npos)
- cpu_brand.erase(null_pos);
- metadata_dict->SetString("cpu-brand", cpu_brand);
-
- // GPU
- gpu::GPUInfo gpu_info = content::GpuDataManager::GetInstance()->GetGPUInfo();
-
-#if !defined(OS_ANDROID)
- metadata_dict->SetInteger("gpu-venid", gpu_info.gpu.vendor_id);
- metadata_dict->SetInteger("gpu-devid", gpu_info.gpu.device_id);
-#endif
-
- metadata_dict->SetString("gpu-driver", gpu_info.driver_version);
- metadata_dict->SetString("gpu-psver", gpu_info.pixel_shader_version);
- metadata_dict->SetString("gpu-vsver", gpu_info.vertex_shader_version);
-
-#if defined(OS_MACOSX)
- metadata_dict->SetString("gpu-glver", gpu_info.gl_version);
-#elif defined(OS_POSIX)
- metadata_dict->SetString("gpu-gl-vendor", gpu_info.gl_vendor);
- metadata_dict->SetString("gpu-gl-renderer", gpu_info.gl_renderer);
-#endif
-
- std::unique_ptr<TracingDelegate> delegate(
- GetContentClient()->browser()->GetTracingDelegate());
- if (delegate)
- delegate->GenerateMetadataDict(metadata_dict.get());
-
- metadata_dict->SetString("clock-domain", GetClockString());
- metadata_dict->SetBoolean("highres-ticks",
- base::TimeTicks::IsHighResolution());
-
- metadata_dict->SetString("trace-config", trace_config_->ToString());
-
- metadata_dict->SetString(
- "command_line",
- base::CommandLine::ForCurrentProcess()->GetCommandLineString());
-
- base::Time::Exploded ctime;
- base::Time::Now().UTCExplode(&ctime);
- std::string time_string = base::StringPrintf(
- "%u-%u-%u %d:%d:%d", ctime.year, ctime.month, ctime.day_of_month,
- ctime.hour, ctime.minute, ctime.second);
- metadata_dict->SetString("trace-capture-datetime", time_string);
-
- return metadata_dict;
-}
-
void TracingControllerImpl::AddTraceMessageFilterObserver(
TraceMessageFilterObserver* observer) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -937,4 +247,20 @@ void TracingControllerImpl::RemoveTraceMessageFilterObserver(
observer->OnTraceMessageFilterRemoved(filter.get());
}
+void TracingControllerImpl::OnDataAvailable(const void* data,
+ size_t num_bytes) {
+ if (trace_data_sink_.get()) {
+ const std::string chunk(static_cast<const char*>(data), num_bytes);
+ trace_data_sink_->AddTraceChunk(chunk);
+ }
+}
+
+void TracingControllerImpl::OnDataComplete() {
+ is_tracing_ = false;
+ if (trace_data_sink_.get()) {
+ trace_data_sink_->Close();
+ trace_data_sink_ = NULL;
+ }
+}
+
} // namespace content
« no previous file with comments | « content/browser/tracing/tracing_controller_impl.h ('k') | content/browser/tracing/tracing_controller_impl_data_sinks.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698