Merge "Trace Redaction - Common Redact FTrace Event Modifications" into main
diff --git a/Android.bp b/Android.bp
index 403ffaa..928eee1 100644
--- a/Android.bp
+++ b/Android.bp
@@ -5694,6 +5694,7 @@
"protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
"protos/perfetto/trace/chrome/chrome_metadata.proto",
"protos/perfetto/trace/chrome/chrome_trace_event.proto",
+ "protos/perfetto/trace/chrome/chrome_trigger.proto",
"protos/perfetto/trace/chrome/v8.proto",
],
}
@@ -5713,6 +5714,7 @@
"external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.gen.cc",
"external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.gen.cc",
"external/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.gen.cc",
+ "external/perfetto/protos/perfetto/trace/chrome/chrome_trigger.gen.cc",
"external/perfetto/protos/perfetto/trace/chrome/v8.gen.cc",
],
}
@@ -5732,6 +5734,7 @@
"external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.gen.h",
"external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.gen.h",
"external/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.gen.h",
+ "external/perfetto/protos/perfetto/trace/chrome/chrome_trigger.gen.h",
"external/perfetto/protos/perfetto/trace/chrome/v8.gen.h",
],
export_include_dirs: [
@@ -5747,6 +5750,7 @@
"protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
"protos/perfetto/trace/chrome/chrome_metadata.proto",
"protos/perfetto/trace/chrome/chrome_trace_event.proto",
+ "protos/perfetto/trace/chrome/chrome_trigger.proto",
"protos/perfetto/trace/chrome/v8.proto",
],
}
@@ -5765,6 +5769,7 @@
"external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pb.cc",
"external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.pb.cc",
"external/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.pb.cc",
+ "external/perfetto/protos/perfetto/trace/chrome/chrome_trigger.pb.cc",
"external/perfetto/protos/perfetto/trace/chrome/v8.pb.cc",
],
}
@@ -5783,6 +5788,7 @@
"external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pb.h",
"external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.pb.h",
"external/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.pb.h",
+ "external/perfetto/protos/perfetto/trace/chrome/chrome_trigger.pb.h",
"external/perfetto/protos/perfetto/trace/chrome/v8.pb.h",
],
export_include_dirs: [
@@ -5798,6 +5804,7 @@
"protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
"protos/perfetto/trace/chrome/chrome_metadata.proto",
"protos/perfetto/trace/chrome/chrome_trace_event.proto",
+ "protos/perfetto/trace/chrome/chrome_trigger.proto",
"protos/perfetto/trace/chrome/v8.proto",
],
}
@@ -5817,6 +5824,7 @@
"external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pbzero.cc",
"external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.pbzero.cc",
"external/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.pbzero.cc",
+ "external/perfetto/protos/perfetto/trace/chrome/chrome_trigger.pbzero.cc",
"external/perfetto/protos/perfetto/trace/chrome/v8.pbzero.cc",
],
}
@@ -5836,6 +5844,7 @@
"external/perfetto/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pbzero.h",
"external/perfetto/protos/perfetto/trace/chrome/chrome_metadata.pbzero.h",
"external/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.pbzero.h",
+ "external/perfetto/protos/perfetto/trace/chrome/chrome_trigger.pbzero.h",
"external/perfetto/protos/perfetto/trace/chrome/v8.pbzero.h",
],
export_include_dirs: [
@@ -5919,6 +5928,7 @@
"protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
"protos/perfetto/trace/chrome/chrome_metadata.proto",
"protos/perfetto/trace/chrome/chrome_trace_event.proto",
+ "protos/perfetto/trace/chrome/chrome_trigger.proto",
"protos/perfetto/trace/chrome/v8.proto",
"protos/perfetto/trace/clock_snapshot.proto",
"protos/perfetto/trace/etw/etw.proto",
@@ -13803,6 +13813,7 @@
"protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
"protos/perfetto/trace/chrome/chrome_metadata.proto",
"protos/perfetto/trace/chrome/chrome_trace_event.proto",
+ "protos/perfetto/trace/chrome/chrome_trigger.proto",
"protos/perfetto/trace/chrome/v8.proto",
"protos/perfetto/trace/clock_snapshot.proto",
"protos/perfetto/trace/etw/etw.proto",
diff --git a/BUILD b/BUILD
index 032036c..2e137b7 100644
--- a/BUILD
+++ b/BUILD
@@ -4646,6 +4646,7 @@
"protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto",
"protos/perfetto/trace/chrome/chrome_metadata.proto",
"protos/perfetto/trace/chrome/chrome_trace_event.proto",
+ "protos/perfetto/trace/chrome/chrome_trigger.proto",
"protos/perfetto/trace/chrome/v8.proto",
],
visibility = [
diff --git a/include/perfetto/base/build_config.h b/include/perfetto/base/build_config.h
index a0e6bb9..5f7a7bd 100644
--- a/include/perfetto/base/build_config.h
+++ b/include/perfetto/base/build_config.h
@@ -139,6 +139,12 @@
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ARCH_CPU_ARM64() 0
#endif
+#if defined(__x86_64__) || defined(_M_X64)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ARCH_CPU_X86_64() 1
+#else
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ARCH_CPU_X86_64() 0
+#endif
+
// perfetto_build_flags.h contains the tweakable build flags defined via GN.
// - In GN builds (e.g., standalone, chromium, v8) this file is generated at
// build time via the gen_rule //gn/gen_buildflags.
diff --git a/include/perfetto/base/time.h b/include/perfetto/base/time.h
index 3e5b101..13e575c 100644
--- a/include/perfetto/base/time.h
+++ b/include/perfetto/base/time.h
@@ -37,6 +37,14 @@
#include <emscripten/emscripten.h>
#endif
+#if PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_X86_64)
+#if PERFETTO_BUILDFLAG(PERFETTO_COMPILER_MSVC)
+#include <intrin.h>
+#else
+#include <x86intrin.h>
+#endif
+#endif
+
namespace perfetto {
namespace base {
@@ -272,6 +280,12 @@
return TimeGm(&tms);
}
+#if PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_X86_64)
+inline uint64_t Rdtsc() {
+ return static_cast<uint64_t>(__rdtsc());
+}
+#endif
+
std::optional<int32_t> GetTimezoneOffsetMins();
} // namespace base
diff --git a/protos/perfetto/common/builtin_clock.proto b/protos/perfetto/common/builtin_clock.proto
index dba9ec9..6b1ecc1 100644
--- a/protos/perfetto/common/builtin_clock.proto
+++ b/protos/perfetto/common/builtin_clock.proto
@@ -26,11 +26,8 @@
BUILTIN_CLOCK_MONOTONIC_COARSE = 4;
BUILTIN_CLOCK_MONOTONIC_RAW = 5;
BUILTIN_CLOCK_BOOTTIME = 6;
+ BUILTIN_CLOCK_TSC = 9;
BUILTIN_CLOCK_MAX_ID = 63;
reserved 7, 8;
-
- // An internal CL (ag/16521245) has taken this for BUILTIN_CLOCK_TSC.
- // That might get upstreamed later on. Avoid diverging on this ID in future.
- reserved 9;
}
diff --git a/protos/perfetto/config/perfetto_config.proto b/protos/perfetto/config/perfetto_config.proto
index 6623597..2fd3c55 100644
--- a/protos/perfetto/config/perfetto_config.proto
+++ b/protos/perfetto/config/perfetto_config.proto
@@ -339,13 +339,10 @@
BUILTIN_CLOCK_MONOTONIC_COARSE = 4;
BUILTIN_CLOCK_MONOTONIC_RAW = 5;
BUILTIN_CLOCK_BOOTTIME = 6;
+ BUILTIN_CLOCK_TSC = 9;
BUILTIN_CLOCK_MAX_ID = 63;
reserved 7, 8;
-
- // An internal CL (ag/16521245) has taken this for BUILTIN_CLOCK_TSC.
- // That might get upstreamed later on. Avoid diverging on this ID in future.
- reserved 9;
}
// End of protos/perfetto/common/builtin_clock.proto
diff --git a/protos/perfetto/trace/chrome/BUILD.gn b/protos/perfetto/trace/chrome/BUILD.gn
index 0df6b88..b9599aa 100644
--- a/protos/perfetto/trace/chrome/BUILD.gn
+++ b/protos/perfetto/trace/chrome/BUILD.gn
@@ -19,6 +19,7 @@
"chrome_benchmark_metadata.proto",
"chrome_metadata.proto",
"chrome_trace_event.proto",
+ "chrome_trigger.proto",
"v8.proto",
]
}
diff --git a/protos/perfetto/trace/chrome/chrome_trace_packet.proto b/protos/perfetto/trace/chrome/chrome_trace_packet.proto
index ae0201d..17f1e68 100644
--- a/protos/perfetto/trace/chrome/chrome_trace_packet.proto
+++ b/protos/perfetto/trace/chrome/chrome_trace_packet.proto
@@ -28,6 +28,7 @@
import "protos/perfetto/common/trace_stats.proto";
import "protos/perfetto/config/trace_config.proto";
import "protos/perfetto/trace/chrome/chrome_trace_event.proto";
+import "protos/perfetto/trace/chrome/chrome_trigger.proto";
import "protos/perfetto/trace/clock_snapshot.proto";
import "protos/perfetto/trace/interned_data/interned_data.proto";
import "protos/perfetto/trace/profiling/profile_packet.proto";
@@ -52,6 +53,7 @@
ThreadDescriptor thread_descriptor = 44;
StreamingProfilePacket streaming_profile_packet = 54;
ProfiledFrameSymbols profiled_frame_symbols = 55;
+ ChromeTrigger chrome_trigger = 109;
// The original trace config.
TraceConfig trace_config = 33;
diff --git a/protos/perfetto/trace/chrome/chrome_trigger.proto b/protos/perfetto/trace/chrome/chrome_trigger.proto
new file mode 100644
index 0000000..9662e92
--- /dev/null
+++ b/protos/perfetto/trace/chrome/chrome_trigger.proto
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+syntax = "proto2";
+
+package perfetto.protos;
+
+// When a TracingSession receives a trigger it records the boot time
+// nanoseconds in the TracePacket's timestamp field. We emit this data so
+// filtering can be done on triggers received in the trace.
+message ChromeTrigger {
+ // Name of the trigger which was received.
+ optional string trigger_name = 1;
+ // MD5 hash of the trigger name.
+ optional string trigger_hash = 2;
+}
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index c8b4c9e..4988bfd 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -339,13 +339,10 @@
BUILTIN_CLOCK_MONOTONIC_COARSE = 4;
BUILTIN_CLOCK_MONOTONIC_RAW = 5;
BUILTIN_CLOCK_BOOTTIME = 6;
+ BUILTIN_CLOCK_TSC = 9;
BUILTIN_CLOCK_MAX_ID = 63;
reserved 7, 8;
-
- // An internal CL (ag/16521245) has taken this for BUILTIN_CLOCK_TSC.
- // That might get upstreamed later on. Avoid diverging on this ID in future.
- reserved 9;
}
// End of protos/perfetto/common/builtin_clock.proto
@@ -6001,6 +5998,20 @@
// End of protos/perfetto/trace/chrome/chrome_trace_event.proto
+// Begin of protos/perfetto/trace/chrome/chrome_trigger.proto
+
+// When a TracingSession receives a trigger it records the boot time
+// nanoseconds in the TracePacket's timestamp field. We emit this data so
+// filtering can be done on triggers received in the trace.
+message ChromeTrigger {
+ // Name of the trigger which was received.
+ optional string trigger_name = 1;
+ // MD5 hash of the trigger name.
+ optional string trigger_hash = 2;
+}
+
+// End of protos/perfetto/trace/chrome/chrome_trigger.proto
+
// Begin of protos/perfetto/trace/chrome/v8.proto
// These are the protos for the V8 data source.
@@ -14680,7 +14691,7 @@
// See the [Buffers and Dataflow](/docs/concepts/buffers.md) doc for details.
//
// Next reserved id: 14 (up to 15).
-// Next id: 108.
+// Next id: 109.
message TracePacket {
// The timestamp of the TracePacket.
// By default this timestamps refers to the trace clock (CLOCK_BOOTTIME on
@@ -14721,6 +14732,7 @@
AndroidLogPacket android_log = 39;
SystemInfo system_info = 45;
Trigger trigger = 46;
+ ChromeTrigger chrome_trigger = 109;
PackagesList packages_list = 47;
ChromeBenchmarkMetadata chrome_benchmark_metadata = 48;
PerfettoMetatrace perfetto_metatrace = 49;
diff --git a/protos/perfetto/trace/trace_packet.proto b/protos/perfetto/trace/trace_packet.proto
index 2547824..93fb7d3 100644
--- a/protos/perfetto/trace/trace_packet.proto
+++ b/protos/perfetto/trace/trace_packet.proto
@@ -37,6 +37,7 @@
import "protos/perfetto/trace/chrome/chrome_benchmark_metadata.proto";
import "protos/perfetto/trace/chrome/chrome_metadata.proto";
import "protos/perfetto/trace/chrome/chrome_trace_event.proto";
+import "protos/perfetto/trace/chrome/chrome_trigger.proto";
import "protos/perfetto/trace/chrome/v8.proto";
import "protos/perfetto/trace/clock_snapshot.proto";
import "protos/perfetto/trace/etw/etw_event_bundle.proto";
@@ -102,7 +103,7 @@
// See the [Buffers and Dataflow](/docs/concepts/buffers.md) doc for details.
//
// Next reserved id: 14 (up to 15).
-// Next id: 108.
+// Next id: 109.
message TracePacket {
// The timestamp of the TracePacket.
// By default this timestamps refers to the trace clock (CLOCK_BOOTTIME on
@@ -143,6 +144,7 @@
AndroidLogPacket android_log = 39;
SystemInfo system_info = 45;
Trigger trigger = 46;
+ ChromeTrigger chrome_trigger = 109;
PackagesList packages_list = 47;
ChromeBenchmarkMetadata chrome_benchmark_metadata = 48;
PerfettoMetatrace perfetto_metatrace = 49;
diff --git a/src/base/http/http_server.cc b/src/base/http/http_server.cc
index 2efe9f7..bf99e25 100644
--- a/src/base/http/http_server.cc
+++ b/src/base/http/http_server.cc
@@ -60,7 +60,7 @@
SockType::kStream);
bool ipv4_listening = sock4_ && sock4_->is_listening();
if (!ipv4_listening) {
- PERFETTO_PLOG("Failed to listen on IPv4 socket");
+ PERFETTO_PLOG("Failed to listen on IPv4 socket: \"%s\"", ipv4_addr.c_str());
sock4_.reset();
}
@@ -68,7 +68,7 @@
SockType::kStream);
bool ipv6_listening = sock6_ && sock6_->is_listening();
if (!ipv6_listening) {
- PERFETTO_PLOG("Failed to listen on IPv6 socket");
+ PERFETTO_PLOG("Failed to listen on IPv6 socket: \"%s\"", ipv6_addr.c_str());
sock6_.reset();
}
}
diff --git a/src/trace_processor/importers/proto/metadata_module.cc b/src/trace_processor/importers/proto/metadata_module.cc
index 3374043..9f2cb30 100644
--- a/src/trace_processor/importers/proto/metadata_module.cc
+++ b/src/trace_processor/importers/proto/metadata_module.cc
@@ -26,6 +26,7 @@
#include "src/trace_processor/util/protozero_to_text.h"
#include "protos/perfetto/config/trace_config.pbzero.h"
+#include "protos/perfetto/trace/chrome/chrome_trigger.pbzero.h"
#include "protos/perfetto/trace/trace_packet.pbzero.h"
#include "protos/perfetto/trace/trace_uuid.pbzero.h"
#include "protos/perfetto/trace/trigger.pbzero.h"
@@ -87,11 +88,14 @@
int64_t ts,
const TracePacketData&,
uint32_t field_id) {
+ // We handle triggers at parse time rather at tokenization because
+ // we add slices to tables which need to happen post-sorting.
if (field_id == TracePacket::kTriggerFieldNumber) {
- // We handle triggers at parse time rather at tokenization because
- // we add slices to tables which need to happen post-sorting.
ParseTrigger(ts, decoder.trigger());
}
+ if (field_id == TracePacket::kChromeTriggerFieldNumber) {
+ ParseChromeTrigger(ts, decoder.chrome_trigger());
+ }
}
void MetadataModule::ParseTrigger(int64_t ts, ConstBytes blob) {
@@ -116,6 +120,20 @@
});
}
+void MetadataModule::ParseChromeTrigger(int64_t ts, ConstBytes blob) {
+ protos::pbzero::ChromeTrigger::Decoder trigger(blob.data, blob.size);
+ StringId cat_id = kNullStringId;
+ TrackId track_id = context_->track_tracker->GetOrCreateTriggerTrack();
+ StringId name_id;
+ if (trigger.has_trigger_name()) {
+ name_id = context_->storage->InternString(trigger.trigger_name());
+ } else {
+ name_id = context_->storage->InternString(trigger.trigger_hash());
+ }
+ context_->slice_tracker->Scoped(ts, track_id, cat_id, name_id,
+ /* duration = */ 0);
+}
+
void MetadataModule::ParseTraceUuid(ConstBytes blob) {
// If both the TraceUuid packet and TraceConfig.trace_uuid_msb/lsb are set,
// the former (which is emitted first) takes precedence. This is because the
diff --git a/src/trace_processor/importers/proto/metadata_module.h b/src/trace_processor/importers/proto/metadata_module.h
index 49e0384..31cbd42 100644
--- a/src/trace_processor/importers/proto/metadata_module.h
+++ b/src/trace_processor/importers/proto/metadata_module.h
@@ -47,6 +47,7 @@
private:
void ParseTrigger(int64_t ts, ConstBytes);
+ void ParseChromeTrigger(int64_t ts, ConstBytes);
void ParseTraceUuid(ConstBytes);
TraceProcessorContext* context_;
diff --git a/src/traced/probes/ftrace/ftrace_config_muxer.cc b/src/traced/probes/ftrace/ftrace_config_muxer.cc
index 97969be..3e2b9ab 100644
--- a/src/traced/probes/ftrace/ftrace_config_muxer.cc
+++ b/src/traced/probes/ftrace/ftrace_config_muxer.cc
@@ -625,12 +625,12 @@
// Set up the rest of the tracefs state, without starting it.
// Notes:
// * resizing buffers can be quite slow (up to hundreds of ms).
- // * resizing buffers doesn't clear their existing contents, which matters
- // to the preserve_ftrace_buffer option.
+ // * resizing buffers may truncate existing contents if the new size is
+ // smaller, which matters to the preserve_ftrace_buffer option.
if (!request.preserve_ftrace_buffer()) {
SetupClock(request);
+ SetupBufferSize(request);
}
- SetupBufferSize(request);
}
std::set<GroupAndName> events = GetFtraceEvents(request, table_);
diff --git a/src/traced/probes/ftrace/ftrace_config_muxer_unittest.cc b/src/traced/probes/ftrace/ftrace_config_muxer_unittest.cc
index d5d7f05..3ef5635 100644
--- a/src/traced/probes/ftrace/ftrace_config_muxer_unittest.cc
+++ b/src/traced/probes/ftrace/ftrace_config_muxer_unittest.cc
@@ -1385,5 +1385,28 @@
ASSERT_FALSE(model.SetupConfig(/* id= */ 73, config));
}
+TEST_F(FtraceConfigMuxerTest, PreserveFtraceBufferNotSetBufferSizeKb) {
+ auto fake_table = CreateFakeTable();
+ NiceMock<MockFtraceProcfs> ftrace;
+ FtraceConfigMuxer model(&ftrace, fake_table.get(), GetSyscallTable(), {},
+ /* secondary_instance= */ false);
+
+ FtraceConfig config = CreateFtraceConfig({"sched/sched_switch"});
+
+ config.set_preserve_ftrace_buffer(true);
+ EXPECT_CALL(ftrace, ReadOneCharFromFile("/root/tracing_on"))
+ .WillOnce(Return('1'));
+ ON_CALL(ftrace, ReadFileIntoString("/root/trace_clock"))
+ .WillByDefault(Return("[local] global boot"));
+ EXPECT_CALL(ftrace, ReadFileIntoString("/root/trace_clock"))
+ .Times(AnyNumber());
+ EXPECT_CALL(ftrace, WriteToFile("/root/buffer_size_kb", _)).Times(0);
+ EXPECT_CALL(ftrace,
+ WriteToFile("/root/events/sched/sched_switch/enable", "1"));
+
+ FtraceConfigId id = 44;
+ ASSERT_TRUE(model.SetupConfig(id, config));
+}
+
} // namespace
} // namespace perfetto
diff --git a/src/tracing/core/clock_snapshots.cc b/src/tracing/core/clock_snapshots.cc
index 98fe7c5..a4fe6c0 100644
--- a/src/tracing/core/clock_snapshots.cc
+++ b/src/tracing/core/clock_snapshots.cc
@@ -66,6 +66,12 @@
ClockReading(protos::pbzero::BUILTIN_CLOCK_MONOTONIC, wall_time_ns));
#endif
+#if PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_X86_64)
+ // X86-specific but OS-independent TSC clocksource
+ snapshot_data.push_back(
+ ClockReading(protos::pbzero::BUILTIN_CLOCK_TSC, base::Rdtsc()));
+#endif // PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_X86_64)
+
return snapshot_data;
}
diff --git a/ui/src/common/actions.ts b/ui/src/common/actions.ts
index 4f16d80..f99ae5c 100644
--- a/ui/src/common/actions.ts
+++ b/ui/src/common/actions.ts
@@ -256,7 +256,7 @@
args: {
name: string;
id: string;
- summaryTrackKey: string;
+ summaryTrackKey?: string;
collapsed: boolean;
fixedOrdering?: boolean;
},
@@ -265,7 +265,8 @@
name: args.name,
id: args.id,
collapsed: args.collapsed,
- tracks: [args.summaryTrackKey],
+ tracks: [],
+ summaryTrack: args.summaryTrackKey,
fixedOrdering: args.fixedOrdering,
};
},
diff --git a/ui/src/common/actions_unittest.ts b/ui/src/common/actions_unittest.ts
index 56c204c..b31d2ae 100644
--- a/ui/src/common/actions_unittest.ts
+++ b/ui/src/common/actions_unittest.ts
@@ -133,8 +133,8 @@
});
});
- expect(afterTrackAdd.trackGroups['123-123-123'].tracks[0]).toBe('s');
- expect(afterTrackAdd.trackGroups['123-123-123'].tracks[1]).toBe('1');
+ expect(afterTrackAdd.trackGroups['123-123-123'].summaryTrack).toBe('s');
+ expect(afterTrackAdd.trackGroups['123-123-123'].tracks[0]).toBe('1');
});
test('reorder tracks', () => {
@@ -346,7 +346,7 @@
// High Priority tracks should be sorted before Low Priority tracks:
// 'b' appears twice because it's the summary track
- expect(after.trackGroups['g'].tracks).toEqual(['a', 'b', 'b']);
+ expect(after.trackGroups['g'].tracks).toEqual(['a', 'b']);
});
test('sortTracksByPriorityAndKindAndName', () => {
@@ -406,7 +406,6 @@
expect(after.trackGroups['g'].tracks).toEqual([
'a',
'b',
- 'b',
'c',
'd',
'e',
@@ -456,7 +455,7 @@
StateActions.sortThreadTracks(draft, {});
});
- expect(after.trackGroups['g'].tracks).toEqual(['a', 'a', 'c', 'b']);
+ expect(after.trackGroups['g'].tracks).toEqual(['a', 'c', 'b']);
});
test('perf samples open flamegraph', () => {
diff --git a/ui/src/common/state.ts b/ui/src/common/state.ts
index 43f205e..396df65 100644
--- a/ui/src/common/state.ts
+++ b/ui/src/common/state.ts
@@ -148,7 +148,8 @@
// 49. Remove currentTab, which is only relevant to TabsV1.
// 50. Remove ftrace filter state.
// 51. Changed structure of FlamegraphState.expandedCallsiteByViewingOption.
-export const STATE_VERSION = 51;
+// 52. Update track group state - don't make the summary track the first track.
+export const STATE_VERSION = 52;
export const SCROLLING_TRACK_GROUP = 'ScrollingTracks';
@@ -290,6 +291,7 @@
collapsed: boolean;
tracks: string[]; // Child track ids.
fixedOrdering?: boolean; // Render tracks without sorting.
+ summaryTrack: string | undefined;
}
export interface EngineConfig {
diff --git a/ui/src/controller/track_decider.ts b/ui/src/controller/track_decider.ts
index 06e6823..3f942e9 100644
--- a/ui/src/controller/track_decider.ts
+++ b/ui/src/controller/track_decider.ts
@@ -41,7 +41,6 @@
ACTUAL_FRAMES_SLICE_TRACK_KIND,
EXPECTED_FRAMES_SLICE_TRACK_KIND,
} from '../tracks/frames';
-import {NULL_TRACK_URI} from '../tracks/null_track';
import {decideTracks as screenshotDecideTracks} from '../tracks/screenshots';
import {THREAD_STATE_TRACK_KIND} from '../tracks/thread_state';
@@ -233,19 +232,8 @@
parentIdToGroupId.set(parentTrackId, trackGroup);
const parentName = getTrackName({name: rawParentName, kind});
-
- const summaryTrackKey = uuidv4();
- this.tracksToAdd.push({
- uri: NULL_TRACK_URI,
- key: summaryTrackKey,
- trackSortKey: PrimaryTrackSortKey.NULL_TRACK,
- trackGroup: undefined,
- name: parentName,
- });
-
this.addTrackGroupActions.push(
Actions.addTrackGroup({
- summaryTrackKey: summaryTrackKey,
name: parentName,
id: trackGroup,
collapsed: true,
@@ -406,18 +394,7 @@
for (const [key, value] of devMap) {
const groupName = group + key;
- const summaryTrackKey = uuidv4();
-
- this.tracksToAdd.push({
- uri: NULL_TRACK_URI,
- key: summaryTrackKey,
- trackSortKey: PrimaryTrackSortKey.NULL_TRACK,
- name: groupName,
- trackGroup: undefined,
- });
-
const addGroup = Actions.addTrackGroup({
- summaryTrackKey,
name: groupName,
id: value,
collapsed: true,
@@ -456,18 +433,7 @@
for (const [key, value] of devMap) {
const groupName = key;
- const summaryTrackKey = uuidv4();
-
- this.tracksToAdd.push({
- uri: NULL_TRACK_URI,
- key: summaryTrackKey,
- trackSortKey: PrimaryTrackSortKey.NULL_TRACK,
- name: groupName,
- trackGroup: undefined,
- });
-
const addGroup = Actions.addTrackGroup({
- summaryTrackKey,
name: groupName,
id: value,
collapsed: true,
@@ -492,9 +458,6 @@
) {
continue;
}
- if (track.uri === NULL_TRACK_URI) {
- continue;
- }
if (groupUuid === undefined) {
groupUuid = uuidv4();
}
@@ -503,17 +466,7 @@
}
if (groupUuid !== undefined) {
- const summaryTrackKey = uuidv4();
- this.tracksToAdd.push({
- uri: NULL_TRACK_URI,
- key: summaryTrackKey,
- trackSortKey: PrimaryTrackSortKey.NULL_TRACK,
- name: groupName,
- trackGroup: undefined,
- });
-
const addGroup = Actions.addTrackGroup({
- summaryTrackKey,
name: groupName,
id: groupUuid,
collapsed: true,
@@ -540,9 +493,6 @@
) {
continue;
}
- if (track.uri === NULL_TRACK_URI) {
- continue;
- }
let allowlisted = false;
for (const regex of ALLOWLIST_REGEXES) {
allowlisted = allowlisted || regex.test(track.name);
@@ -557,17 +507,7 @@
}
if (groupUuid !== undefined) {
- const summaryTrackKey = uuidv4();
- this.tracksToAdd.push({
- uri: NULL_TRACK_URI,
- key: summaryTrackKey,
- trackSortKey: PrimaryTrackSortKey.NULL_TRACK,
- name: groupName,
- trackGroup: undefined,
- });
-
const addGroup = Actions.addTrackGroup({
- summaryTrackKey,
name: groupName,
id: groupUuid,
collapsed: true,
@@ -587,9 +527,6 @@
) {
continue;
}
- if (track.uri === NULL_TRACK_URI) {
- continue;
- }
if (groupUuid === undefined) {
groupUuid = uuidv4();
}
@@ -598,17 +535,7 @@
}
if (groupUuid !== undefined) {
- const summaryTrackKey = uuidv4();
- this.tracksToAdd.push({
- uri: NULL_TRACK_URI,
- key: summaryTrackKey,
- trackSortKey: PrimaryTrackSortKey.NULL_TRACK,
- name: groupName,
- trackGroup: undefined,
- });
-
const addGroup = Actions.addTrackGroup({
- summaryTrackKey: summaryTrackKey,
name: groupName,
id: groupUuid,
collapsed: true,
@@ -962,7 +889,7 @@
});
// Map From [name] -> [uuid, key]
- const groupMap = new Map<string, [string, string]>();
+ const groupMap = new Map<string, string>();
for (; it.valid(); it.next()) {
if (it.name == null || it.uid == null) {
@@ -975,16 +902,7 @@
const groupUuid = `uid-track-group${rawName}`;
if (groupMap.get(rawName) === undefined) {
- const summaryTrackKey = uuidv4();
- this.tracksToAdd.push({
- uri: NULL_TRACK_URI,
- trackSortKey: PrimaryTrackSortKey.NULL_TRACK,
- name: `UID Tracks`,
- trackGroup: undefined,
- key: summaryTrackKey,
- });
-
- groupMap.set(rawName, [groupUuid, summaryTrackKey]);
+ groupMap.set(rawName, groupUuid);
}
this.tracksToAdd.push({
@@ -995,12 +913,11 @@
});
}
- for (const [name, [groupUuid, summaryTrackKey]] of groupMap) {
+ for (const [name, groupUuid] of groupMap) {
const addGroup = Actions.addTrackGroup({
name: name,
id: groupUuid,
collapsed: true,
- summaryTrackKey,
});
this.addTrackGroupActions.push(addGroup);
}
@@ -1589,25 +1506,12 @@
if (uuid) {
groupUuid = uuid;
} else {
- console.log(`Creating group "${groupName}"`);
-
- // Add the summary track
- const summaryTrackKey = uuidv4();
- this.tracksToAdd.push({
- uri: NULL_TRACK_URI,
- trackSortKey: PrimaryTrackSortKey.NULL_TRACK,
- name: groupName,
- trackGroup: undefined,
- key: summaryTrackKey,
- });
-
// Add the group
groupUuid = uuidv4();
const addGroup = Actions.addTrackGroup({
name: groupName,
id: groupUuid,
collapsed: true,
- summaryTrackKey,
fixedOrdering: true,
});
this.addTrackGroupActions.push(addGroup);
diff --git a/ui/src/frontend/viewer_page.ts b/ui/src/frontend/viewer_page.ts
index 34d1752..73decc9 100644
--- a/ui/src/frontend/viewer_page.ts
+++ b/ui/src/frontend/viewer_page.ts
@@ -226,24 +226,31 @@
);
for (const group of Object.values(globals.state.trackGroups)) {
- const key = group.tracks[0];
- const trackBundle = this.resolveTrack(key);
- const headerPanel = new TrackGroupPanel({
- trackGroupId: group.id,
- key: `trackgroup-${group.id}`,
- trackFSM: trackBundle.trackFSM,
- labels: trackBundle.labels,
- tags: trackBundle.tags,
- collapsed: group.collapsed,
- title: group.name,
- });
+ const key = group.summaryTrack;
+ let headerPanel;
+ if (key) {
+ const trackBundle = this.resolveTrack(key);
+ headerPanel = new TrackGroupPanel({
+ trackGroupId: group.id,
+ key: `trackgroup-${group.id}`,
+ trackFSM: trackBundle.trackFSM,
+ labels: trackBundle.labels,
+ tags: trackBundle.tags,
+ collapsed: group.collapsed,
+ title: group.name,
+ });
+ } else {
+ headerPanel = new TrackGroupPanel({
+ trackGroupId: group.id,
+ key: `trackgroup-${group.id}`,
+ collapsed: group.collapsed,
+ title: group.name,
+ });
+ }
const childTracks: Panel[] = [];
- // The first track is the summary track, and is displayed as part of the
- // group panel, we don't want to display it twice so we start from 1.
if (!group.collapsed) {
- for (let i = 1; i < group.tracks.length; ++i) {
- const key = group.tracks[i];
+ for (const key of group.tracks) {
const trackBundle = this.resolveTrack(key);
const panel = new TrackPanel({
trackKey: key,
diff --git a/ui/src/tracks/chrome_scroll_jank/index.ts b/ui/src/tracks/chrome_scroll_jank/index.ts
index 212c3fa..41917bb 100644
--- a/ui/src/tracks/chrome_scroll_jank/index.ts
+++ b/ui/src/tracks/chrome_scroll_jank/index.ts
@@ -26,11 +26,9 @@
PluginContext,
PluginContextTrace,
PluginDescriptor,
- PrimaryTrackSortKey,
} from '../../public';
import {Engine, EngineProxy} from '../../trace_processor/engine';
import {CustomSqlDetailsPanelConfig} from '../custom_sql_table_slices';
-import {NULL_TRACK_URI} from '../null_track';
import {ChromeTasksScrollJankTrack} from './chrome_tasks_scroll_jank_track';
import {EventLatencySliceDetailsPanel} from './event_latency_details_panel';
@@ -138,20 +136,10 @@
const eventLatencies = await addLatencyTracks();
result.tracksToAdd = result.tracksToAdd.concat(eventLatencies.tracksToAdd);
- const summaryTrackKey = uuidv4();
- result.tracksToAdd.push({
- uri: NULL_TRACK_URI,
- trackSortKey: PrimaryTrackSortKey.ASYNC_SLICE_TRACK,
- name: '', // TODO(stevegolton): We should probably put some name here.
- trackGroup: undefined,
- key: summaryTrackKey,
- });
-
const addTrackGroup = Actions.addTrackGroup({
name: 'Chrome Scroll Jank',
id: SCROLL_JANK_GROUP_ID,
collapsed: false,
- summaryTrackKey,
fixedOrdering: true,
});
diff --git a/ui/src/tracks/null_track/index.ts b/ui/src/tracks/null_track/index.ts
deleted file mode 100644
index 540550e..0000000
--- a/ui/src/tracks/null_track/index.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (C) 2022 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import {
- Plugin,
- PluginContext,
- PluginContextTrace,
- PluginDescriptor,
- Track,
-} from '../../public';
-
-export const NULL_TRACK_URI = 'perfetto.NullTrack';
-export const NULL_TRACK_KIND = 'NullTrack';
-
-export class NullTrack implements Track {
- getHeight(): number {
- return 30;
- }
-
- render(): void {}
-}
-
-class NullTrackPlugin implements Plugin {
- onActivate(_ctx: PluginContext): void {}
-
- async onTraceLoad(ctx: PluginContextTrace): Promise<void> {
- // TODO(stevegolton): This is not the right way to handle blank tracks,
- // instead we should probably just render some blank element at render time
- // if no track uri is supplied.
- ctx.registerTrack({
- uri: NULL_TRACK_URI,
- displayName: 'Null Track',
- kind: NULL_TRACK_KIND,
- trackFactory: () => new NullTrack(),
- });
- }
-}
-
-export const plugin: PluginDescriptor = {
- pluginId: 'perfetto.NullTrack',
- plugin: NullTrackPlugin,
-};