1*635a8641SAndroid Build Coastguard Worker // Copyright 2016 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker #include "base/trace_event/blame_context.h"
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #include "base/strings/stringprintf.h"
8*635a8641SAndroid Build Coastguard Worker #include "base/trace_event/trace_event.h"
9*635a8641SAndroid Build Coastguard Worker #include "base/trace_event/trace_event_argument.h"
10*635a8641SAndroid Build Coastguard Worker
11*635a8641SAndroid Build Coastguard Worker namespace base {
12*635a8641SAndroid Build Coastguard Worker namespace trace_event {
13*635a8641SAndroid Build Coastguard Worker
BlameContext(const char * category,const char * name,const char * type,const char * scope,int64_t id,const BlameContext * parent_context)14*635a8641SAndroid Build Coastguard Worker BlameContext::BlameContext(const char* category,
15*635a8641SAndroid Build Coastguard Worker const char* name,
16*635a8641SAndroid Build Coastguard Worker const char* type,
17*635a8641SAndroid Build Coastguard Worker const char* scope,
18*635a8641SAndroid Build Coastguard Worker int64_t id,
19*635a8641SAndroid Build Coastguard Worker const BlameContext* parent_context)
20*635a8641SAndroid Build Coastguard Worker : category_(category),
21*635a8641SAndroid Build Coastguard Worker name_(name),
22*635a8641SAndroid Build Coastguard Worker type_(type),
23*635a8641SAndroid Build Coastguard Worker scope_(scope),
24*635a8641SAndroid Build Coastguard Worker id_(id),
25*635a8641SAndroid Build Coastguard Worker parent_scope_(parent_context ? parent_context->scope() : nullptr),
26*635a8641SAndroid Build Coastguard Worker parent_id_(parent_context ? parent_context->id() : 0),
27*635a8641SAndroid Build Coastguard Worker category_group_enabled_(nullptr),
28*635a8641SAndroid Build Coastguard Worker weak_factory_(this) {
29*635a8641SAndroid Build Coastguard Worker DCHECK(!parent_context || !std::strcmp(name_, parent_context->name()))
30*635a8641SAndroid Build Coastguard Worker << "Parent blame context must have the same name";
31*635a8641SAndroid Build Coastguard Worker }
32*635a8641SAndroid Build Coastguard Worker
~BlameContext()33*635a8641SAndroid Build Coastguard Worker BlameContext::~BlameContext() {
34*635a8641SAndroid Build Coastguard Worker DCHECK(thread_checker_.CalledOnValidThread());
35*635a8641SAndroid Build Coastguard Worker DCHECK(WasInitialized());
36*635a8641SAndroid Build Coastguard Worker TRACE_EVENT_API_ADD_TRACE_EVENT(
37*635a8641SAndroid Build Coastguard Worker TRACE_EVENT_PHASE_DELETE_OBJECT, category_group_enabled_, type_, scope_,
38*635a8641SAndroid Build Coastguard Worker id_, 0, nullptr, nullptr, nullptr, nullptr, TRACE_EVENT_FLAG_HAS_ID);
39*635a8641SAndroid Build Coastguard Worker trace_event::TraceLog::GetInstance()->RemoveAsyncEnabledStateObserver(this);
40*635a8641SAndroid Build Coastguard Worker }
41*635a8641SAndroid Build Coastguard Worker
Enter()42*635a8641SAndroid Build Coastguard Worker void BlameContext::Enter() {
43*635a8641SAndroid Build Coastguard Worker DCHECK(WasInitialized());
44*635a8641SAndroid Build Coastguard Worker TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_ENTER_CONTEXT,
45*635a8641SAndroid Build Coastguard Worker category_group_enabled_, name_, scope_, id_,
46*635a8641SAndroid Build Coastguard Worker 0 /* num_args */, nullptr, nullptr, nullptr,
47*635a8641SAndroid Build Coastguard Worker nullptr, TRACE_EVENT_FLAG_HAS_ID);
48*635a8641SAndroid Build Coastguard Worker }
49*635a8641SAndroid Build Coastguard Worker
Leave()50*635a8641SAndroid Build Coastguard Worker void BlameContext::Leave() {
51*635a8641SAndroid Build Coastguard Worker DCHECK(WasInitialized());
52*635a8641SAndroid Build Coastguard Worker TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_LEAVE_CONTEXT,
53*635a8641SAndroid Build Coastguard Worker category_group_enabled_, name_, scope_, id_,
54*635a8641SAndroid Build Coastguard Worker 0 /* num_args */, nullptr, nullptr, nullptr,
55*635a8641SAndroid Build Coastguard Worker nullptr, TRACE_EVENT_FLAG_HAS_ID);
56*635a8641SAndroid Build Coastguard Worker }
57*635a8641SAndroid Build Coastguard Worker
TakeSnapshot()58*635a8641SAndroid Build Coastguard Worker void BlameContext::TakeSnapshot() {
59*635a8641SAndroid Build Coastguard Worker DCHECK(thread_checker_.CalledOnValidThread());
60*635a8641SAndroid Build Coastguard Worker DCHECK(WasInitialized());
61*635a8641SAndroid Build Coastguard Worker if (!*category_group_enabled_)
62*635a8641SAndroid Build Coastguard Worker return;
63*635a8641SAndroid Build Coastguard Worker std::unique_ptr<trace_event::TracedValue> snapshot(
64*635a8641SAndroid Build Coastguard Worker new trace_event::TracedValue);
65*635a8641SAndroid Build Coastguard Worker AsValueInto(snapshot.get());
66*635a8641SAndroid Build Coastguard Worker static const char* const kArgName = "snapshot";
67*635a8641SAndroid Build Coastguard Worker const int kNumArgs = 1;
68*635a8641SAndroid Build Coastguard Worker unsigned char arg_types[1] = {TRACE_VALUE_TYPE_CONVERTABLE};
69*635a8641SAndroid Build Coastguard Worker std::unique_ptr<trace_event::ConvertableToTraceFormat> arg_values[1] = {
70*635a8641SAndroid Build Coastguard Worker std::move(snapshot)};
71*635a8641SAndroid Build Coastguard Worker TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_SNAPSHOT_OBJECT,
72*635a8641SAndroid Build Coastguard Worker category_group_enabled_, type_, scope_, id_,
73*635a8641SAndroid Build Coastguard Worker kNumArgs, &kArgName, arg_types, nullptr,
74*635a8641SAndroid Build Coastguard Worker arg_values, TRACE_EVENT_FLAG_HAS_ID);
75*635a8641SAndroid Build Coastguard Worker }
76*635a8641SAndroid Build Coastguard Worker
OnTraceLogEnabled()77*635a8641SAndroid Build Coastguard Worker void BlameContext::OnTraceLogEnabled() {
78*635a8641SAndroid Build Coastguard Worker DCHECK(WasInitialized());
79*635a8641SAndroid Build Coastguard Worker TakeSnapshot();
80*635a8641SAndroid Build Coastguard Worker }
81*635a8641SAndroid Build Coastguard Worker
OnTraceLogDisabled()82*635a8641SAndroid Build Coastguard Worker void BlameContext::OnTraceLogDisabled() {}
83*635a8641SAndroid Build Coastguard Worker
AsValueInto(trace_event::TracedValue * state)84*635a8641SAndroid Build Coastguard Worker void BlameContext::AsValueInto(trace_event::TracedValue* state) {
85*635a8641SAndroid Build Coastguard Worker DCHECK(WasInitialized());
86*635a8641SAndroid Build Coastguard Worker if (!parent_id_)
87*635a8641SAndroid Build Coastguard Worker return;
88*635a8641SAndroid Build Coastguard Worker state->BeginDictionary("parent");
89*635a8641SAndroid Build Coastguard Worker state->SetString("id_ref", StringPrintf("0x%" PRIx64, parent_id_));
90*635a8641SAndroid Build Coastguard Worker state->SetString("scope", parent_scope_);
91*635a8641SAndroid Build Coastguard Worker state->EndDictionary();
92*635a8641SAndroid Build Coastguard Worker }
93*635a8641SAndroid Build Coastguard Worker
Initialize()94*635a8641SAndroid Build Coastguard Worker void BlameContext::Initialize() {
95*635a8641SAndroid Build Coastguard Worker DCHECK(thread_checker_.CalledOnValidThread());
96*635a8641SAndroid Build Coastguard Worker category_group_enabled_ =
97*635a8641SAndroid Build Coastguard Worker TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_);
98*635a8641SAndroid Build Coastguard Worker TRACE_EVENT_API_ADD_TRACE_EVENT(
99*635a8641SAndroid Build Coastguard Worker TRACE_EVENT_PHASE_CREATE_OBJECT, category_group_enabled_, type_, scope_,
100*635a8641SAndroid Build Coastguard Worker id_, 0, nullptr, nullptr, nullptr, nullptr, TRACE_EVENT_FLAG_HAS_ID);
101*635a8641SAndroid Build Coastguard Worker trace_event::TraceLog::GetInstance()->AddAsyncEnabledStateObserver(
102*635a8641SAndroid Build Coastguard Worker weak_factory_.GetWeakPtr());
103*635a8641SAndroid Build Coastguard Worker TakeSnapshot();
104*635a8641SAndroid Build Coastguard Worker }
105*635a8641SAndroid Build Coastguard Worker
WasInitialized() const106*635a8641SAndroid Build Coastguard Worker bool BlameContext::WasInitialized() const {
107*635a8641SAndroid Build Coastguard Worker return category_group_enabled_ != nullptr;
108*635a8641SAndroid Build Coastguard Worker }
109*635a8641SAndroid Build Coastguard Worker
110*635a8641SAndroid Build Coastguard Worker } // namespace trace_event
111*635a8641SAndroid Build Coastguard Worker } // namespace base
112