Merge "Add select widget inspired by material design."
diff --git a/BUILD b/BUILD
index 9b50375..49778a3 100644
--- a/BUILD
+++ b/BUILD
@@ -3824,6 +3824,7 @@
],
deps = [
":protos_perfetto_common_protos",
+ ":protos_perfetto_trace_android_protos",
":protos_perfetto_trace_gpu_protos",
":protos_perfetto_trace_profiling_protos",
":protos_perfetto_trace_track_event_protos",
@@ -3835,6 +3836,7 @@
name = "protos_perfetto_trace_interned_data_zero",
deps = [
":protos_perfetto_common_zero",
+ ":protos_perfetto_trace_android_zero",
":protos_perfetto_trace_gpu_zero",
":protos_perfetto_trace_interned_data_protos",
":protos_perfetto_trace_profiling_zero",
diff --git a/protos/perfetto/config/android/network_trace_config.proto b/protos/perfetto/config/android/network_trace_config.proto
index f58f280..ad5196b 100644
--- a/protos/perfetto/config/android/network_trace_config.proto
+++ b/protos/perfetto/config/android/network_trace_config.proto
@@ -27,4 +27,28 @@
// The minimum polling rate is 100ms (values below this are ignored).
// Introduced in Android 14 (U).
optional uint32 poll_ms = 1;
+
+ // The aggregation_threshold is the number of packets at which an event will
+ // switch from per-packet details to aggregate details. For example, a value
+ // of 50 means that if a particular event (grouped by the unique combinations
+ // of metadata fields: {interface, direction, uid, etc}) has fewer than 50
+ // packets, the exact timestamp and length are recorded for each packet. If
+ // there were 50 or more packets in an event, it would only record the total
+ // duration, packets, and length. A value of zero or unspecified will always
+ /// record per-packet details. A value of 1 always records aggregate details.
+ optional uint32 aggregation_threshold = 2;
+
+ // Specifies the maximum number of packet contexts to intern at a time. This
+ // prevents the interning table from growing too large and controls whether
+ // interning is enabled or disabled (a value of zero disables interning and
+ // is the default). When a data sources interning table reaches this amount,
+ // packet contexts will be inlined into NetworkPacketEvents.
+ optional uint32 intern_limit = 3;
+
+ // The following fields specify whether certain fields should be dropped from
+ // the output. Dropping fields improves normalization results, reduces the
+ // size of the interning table, and slightly reduces event size.
+ optional bool drop_local_port = 4;
+ optional bool drop_remote_port = 5;
+ optional bool drop_tcp_flags = 6;
}
diff --git a/protos/perfetto/config/perfetto_config.proto b/protos/perfetto/config/perfetto_config.proto
index 2504541..3673dd0 100644
--- a/protos/perfetto/config/perfetto_config.proto
+++ b/protos/perfetto/config/perfetto_config.proto
@@ -430,6 +430,30 @@
// The minimum polling rate is 100ms (values below this are ignored).
// Introduced in Android 14 (U).
optional uint32 poll_ms = 1;
+
+ // The aggregation_threshold is the number of packets at which an event will
+ // switch from per-packet details to aggregate details. For example, a value
+ // of 50 means that if a particular event (grouped by the unique combinations
+ // of metadata fields: {interface, direction, uid, etc}) has fewer than 50
+ // packets, the exact timestamp and length are recorded for each packet. If
+ // there were 50 or more packets in an event, it would only record the total
+ // duration, packets, and length. A value of zero or unspecified will always
+ /// record per-packet details. A value of 1 always records aggregate details.
+ optional uint32 aggregation_threshold = 2;
+
+ // Specifies the maximum number of packet contexts to intern at a time. This
+ // prevents the interning table from growing too large and controls whether
+ // interning is enabled or disabled (a value of zero disables interning and
+ // is the default). When a data sources interning table reaches this amount,
+ // packet contexts will be inlined into NetworkPacketEvents.
+ optional uint32 intern_limit = 3;
+
+ // The following fields specify whether certain fields should be dropped from
+ // the output. Dropping fields improves normalization results, reduces the
+ // size of the interning table, and slightly reduces event size.
+ optional bool drop_local_port = 4;
+ optional bool drop_remote_port = 5;
+ optional bool drop_tcp_flags = 6;
}
// End of protos/perfetto/config/android/network_trace_config.proto
diff --git a/protos/perfetto/trace/android/network_trace.proto b/protos/perfetto/trace/android/network_trace.proto
index d1c43a2..5fcd28b 100644
--- a/protos/perfetto/trace/android/network_trace.proto
+++ b/protos/perfetto/trace/android/network_trace.proto
@@ -33,7 +33,9 @@
// The name of the interface if available (e.g. 'rmnet0').
optional string interface = 2;
- // The length of the packet in bytes (wire_size - L2_header_size).
+ // The length of the packet in bytes (wire_size - L2_header_size). Ignored
+ // when using NetworkPacketEvent as the ctx in either NetworkPacketBundle or
+ // NetworkPacketContext.
optional uint32 length = 3;
// The Linux user id associated with the packet's socket.
@@ -54,3 +56,36 @@
// The remote udp/tcp port of the packet.
optional uint32 remote_port = 9;
}
+
+// NetworkPacketBundle bundles one or more packets sharing the same attributes.
+message NetworkPacketBundle {
+ oneof packet_context {
+ // The intern id for looking up the associated packet context.
+ uint64 iid = 1;
+
+ // The inlined context for events in this bundle.
+ NetworkPacketEvent ctx = 2;
+ }
+
+ // The timestamp of the i-th packet encoded as the nanoseconds since the
+ // enclosing TracePacket's timestamp.
+ repeated uint64 packet_timestamps = 3 [packed = true];
+
+ // The length of the i-th packet in bytes (wire_size - L2_header_size).
+ repeated uint32 packet_lengths = 4 [packed = true];
+
+ // Total number of packets in the bundle (when above aggregation_threshold).
+ optional uint32 total_packets = 5;
+
+ // Duration between first and last packet (when above aggregation_threshold).
+ optional uint64 total_duration = 6;
+
+ // Total packet length in bytes (when above aggregation_threshold).
+ optional uint64 total_length = 7;
+}
+
+// An internable packet context.
+message NetworkPacketContext {
+ optional uint64 iid = 1;
+ optional NetworkPacketEvent ctx = 2;
+}
diff --git a/protos/perfetto/trace/interned_data/BUILD.gn b/protos/perfetto/trace/interned_data/BUILD.gn
index 580bb5b..66436c5 100644
--- a/protos/perfetto/trace/interned_data/BUILD.gn
+++ b/protos/perfetto/trace/interned_data/BUILD.gn
@@ -17,6 +17,7 @@
perfetto_proto_library("@TYPE@") {
sources = [ "interned_data.proto" ]
deps = [
+ "../android:@TYPE@",
"../gpu:@TYPE@",
"../profiling:@TYPE@",
"../track_event:@TYPE@",
diff --git a/protos/perfetto/trace/interned_data/interned_data.proto b/protos/perfetto/trace/interned_data/interned_data.proto
index 59103a7..9b6db47 100644
--- a/protos/perfetto/trace/interned_data/interned_data.proto
+++ b/protos/perfetto/trace/interned_data/interned_data.proto
@@ -16,6 +16,7 @@
syntax = "proto2";
+import "protos/perfetto/trace/android/network_trace.proto";
import "protos/perfetto/trace/gpu/gpu_render_stage_event.proto";
import "protos/perfetto/trace/track_event/chrome_histogram_sample.proto";
import "protos/perfetto/trace/track_event/debug_annotation.proto";
@@ -53,7 +54,7 @@
// emitted proactively in advance of referring to them in later packets.
//
// Next reserved id: 8 (up to 15).
-// Next id: 30.
+// Next id: 31.
message InternedData {
// TODO(eseckler): Replace iid fields inside interned messages with
// map<iid, message> type fields in InternedData.
@@ -114,4 +115,7 @@
// Interned string values in the DebugAnnotation proto.
repeated InternedString debug_annotation_string_values = 29;
+
+ // Interned packet context for android.network_packets.
+ repeated NetworkPacketContext packet_context = 30;
}
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index 4912220..7dc8589 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -430,6 +430,30 @@
// The minimum polling rate is 100ms (values below this are ignored).
// Introduced in Android 14 (U).
optional uint32 poll_ms = 1;
+
+ // The aggregation_threshold is the number of packets at which an event will
+ // switch from per-packet details to aggregate details. For example, a value
+ // of 50 means that if a particular event (grouped by the unique combinations
+ // of metadata fields: {interface, direction, uid, etc}) has fewer than 50
+ // packets, the exact timestamp and length are recorded for each packet. If
+ // there were 50 or more packets in an event, it would only record the total
+ // duration, packets, and length. A value of zero or unspecified will always
+ /// record per-packet details. A value of 1 always records aggregate details.
+ optional uint32 aggregation_threshold = 2;
+
+ // Specifies the maximum number of packet contexts to intern at a time. This
+ // prevents the interning table from growing too large and controls whether
+ // interning is enabled or disabled (a value of zero disables interning and
+ // is the default). When a data sources interning table reaches this amount,
+ // packet contexts will be inlined into NetworkPacketEvents.
+ optional uint32 intern_limit = 3;
+
+ // The following fields specify whether certain fields should be dropped from
+ // the output. Dropping fields improves normalization results, reduces the
+ // size of the interning table, and slightly reduces event size.
+ optional bool drop_local_port = 4;
+ optional bool drop_remote_port = 5;
+ optional bool drop_tcp_flags = 6;
}
// End of protos/perfetto/config/android/network_trace_config.proto
@@ -3708,7 +3732,9 @@
// The name of the interface if available (e.g. 'rmnet0').
optional string interface = 2;
- // The length of the packet in bytes (wire_size - L2_header_size).
+ // The length of the packet in bytes (wire_size - L2_header_size). Ignored
+ // when using NetworkPacketEvent as the ctx in either NetworkPacketBundle or
+ // NetworkPacketContext.
optional uint32 length = 3;
// The Linux user id associated with the packet's socket.
@@ -3730,6 +3756,39 @@
optional uint32 remote_port = 9;
}
+// NetworkPacketBundle bundles one or more packets sharing the same attributes.
+message NetworkPacketBundle {
+ oneof packet_context {
+ // The intern id for looking up the associated packet context.
+ uint64 iid = 1;
+
+ // The inlined context for events in this bundle.
+ NetworkPacketEvent ctx = 2;
+ }
+
+ // The timestamp of the i-th packet encoded as the nanoseconds since the
+ // enclosing TracePacket's timestamp.
+ repeated uint64 packet_timestamps = 3 [packed = true];
+
+ // The length of the i-th packet in bytes (wire_size - L2_header_size).
+ repeated uint32 packet_lengths = 4 [packed = true];
+
+ // Total number of packets in the bundle (when above aggregation_threshold).
+ optional uint32 total_packets = 5;
+
+ // Duration between first and last packet (when above aggregation_threshold).
+ optional uint64 total_duration = 6;
+
+ // Total packet length in bytes (when above aggregation_threshold).
+ optional uint64 total_length = 7;
+}
+
+// An internable packet context.
+message NetworkPacketContext {
+ optional uint64 iid = 1;
+ optional NetworkPacketEvent ctx = 2;
+}
+
// End of protos/perfetto/trace/android/network_trace.proto
// Begin of protos/perfetto/trace/android/packages_list.proto
@@ -9899,7 +9958,7 @@
// emitted proactively in advance of referring to them in later packets.
//
// Next reserved id: 8 (up to 15).
-// Next id: 30.
+// Next id: 31.
message InternedData {
// TODO(eseckler): Replace iid fields inside interned messages with
// map<iid, message> type fields in InternedData.
@@ -9960,6 +10019,9 @@
// Interned string values in the DebugAnnotation proto.
repeated InternedString debug_annotation_string_values = 29;
+
+ // Interned packet context for android.network_packets.
+ repeated NetworkPacketContext packet_context = 30;
}
// End of protos/perfetto/trace/interned_data/interned_data.proto
@@ -11804,7 +11866,7 @@
// See the [Buffers and Dataflow](/docs/concepts/buffers.md) doc for details.
//
// Next reserved id: 14 (up to 15).
-// Next id: 92.
+// Next id: 93.
message TracePacket {
// The timestamp of the TracePacket.
// By default this timestamps refers to the trace clock (CLOCK_BOOTTIME on
@@ -11913,6 +11975,9 @@
// Represents a single packet sent or received by the network.
NetworkPacketEvent network_packet = 88;
+ // Represents one or more packets sent or received by the network.
+ NetworkPacketBundle network_packet_bundle = 92;
+
// The "range of interest" for track events. See the message definition
// comments for more details.
TrackEventRangeOfInterest track_event_range_of_interest = 90;
diff --git a/protos/perfetto/trace/trace_packet.proto b/protos/perfetto/trace/trace_packet.proto
index c5c2de5..bb20291 100644
--- a/protos/perfetto/trace/trace_packet.proto
+++ b/protos/perfetto/trace/trace_packet.proto
@@ -94,7 +94,7 @@
// See the [Buffers and Dataflow](/docs/concepts/buffers.md) doc for details.
//
// Next reserved id: 14 (up to 15).
-// Next id: 92.
+// Next id: 93.
message TracePacket {
// The timestamp of the TracePacket.
// By default this timestamps refers to the trace clock (CLOCK_BOOTTIME on
@@ -203,6 +203,9 @@
// Represents a single packet sent or received by the network.
NetworkPacketEvent network_packet = 88;
+ // Represents one or more packets sent or received by the network.
+ NetworkPacketBundle network_packet_bundle = 92;
+
// The "range of interest" for track events. See the message definition
// comments for more details.
TrackEventRangeOfInterest track_event_range_of_interest = 90;
diff --git a/python/perfetto/trace_processor/protos.py b/python/perfetto/trace_processor/protos.py
index 4d0c40e..ea13297 100644
--- a/python/perfetto/trace_processor/protos.py
+++ b/python/perfetto/trace_processor/protos.py
@@ -43,6 +43,8 @@
def create_message_factory(message_type):
message_desc = self.descriptor_pool.FindMessageTypeByName(message_type)
+ if hasattr(message_factory, 'GetMessageClass'):
+ return message_factory.GetMessageClass(message_desc)
return message_factory.MessageFactory().GetPrototype(message_desc)
# Create proto messages to correctly communicate with the RPC API by sending
diff --git a/test/cts/heapprofd_java_test_cts.cc b/test/cts/heapprofd_java_test_cts.cc
index 40c4aa6..6435f76 100644
--- a/test/cts/heapprofd_java_test_cts.cc
+++ b/test/cts/heapprofd_java_test_cts.cc
@@ -146,10 +146,13 @@
helper.StartTracing(trace_config);
StartAppActivity(app_name, "JavaOomActivity", "target.app.running", &task_runner,
/*delay_ms=*/100);
+ task_runner.RunUntilCheckpoint("target.app.running", 10000 /*ms*/);
- helper.WaitForTracingDisabled();
- helper.ReadData();
- helper.WaitForReadData();
+ if (SupportsOomHeapDump()) {
+ helper.WaitForTracingDisabled();
+ helper.ReadData();
+ helper.WaitForReadData();
+ }
PERFETTO_CHECK(IsAppRunning(app_name));
StopApp(app_name, "new.app.stopped", &task_runner);
diff --git a/tools/gen_amalgamated_sql.py b/tools/gen_amalgamated_sql.py
index 1ac0ab0..a726002 100755
--- a/tools/gen_amalgamated_sql.py
+++ b/tools/gen_amalgamated_sql.py
@@ -64,8 +64,10 @@
};
'''
-def filename_to_variable(filename):
- return "k" + "".join([x.capitalize() for x in filename.split("_")])
+
+def filename_to_variable(filename: str):
+ return "k" + "".join(
+ [x.capitalize() for x in filename.replace(os.path.sep, '_').split("_")])
def main():
@@ -114,8 +116,7 @@
# Create the C++ variable for each SQL file.
for path, sql in sql_outputs.items():
- name = os.path.basename(path)
- variable = filename_to_variable(os.path.splitext(name)[0])
+ variable = filename_to_variable(os.path.splitext(path)[0])
output.write('\nconst char {}[] = '.format(variable))
# MSVC doesn't like string literals that are individually longer than 16k.
# However it's still fine "if" "we" "concatenate" "many" "of" "them".
@@ -135,8 +136,7 @@
# Create mapping of filename to variable name for each variable.
output.write("\nconst FileToSql kFileToSql[] = {")
for path in sql_outputs.keys():
- name = os.path.basename(path)
- variable = filename_to_variable(os.path.splitext(name)[0])
+ variable = filename_to_variable(os.path.splitext(path)[0])
# This is for Windows which has \ as a path separator.
path = path.replace("\\", "/")
diff --git a/ui/src/assets/details.scss b/ui/src/assets/details.scss
index 034a967..00919b8 100644
--- a/ui/src/assets/details.scss
+++ b/ui/src/assets/details.scss
@@ -198,27 +198,6 @@
display: inline-flex;
justify-content: flex-end;
}
- button {
- width: fit-content;
- height: 20px;
- padding: 3px;
- padding-top: 0;
- margin: 2px;
- font-size: 12px;
- opacity: 0.5;
- &.download {
- opacity: 1;
- padding-top: 3px;
- height: 21px;
- }
- &.chosen {
- opacity: 1;
- }
- .material-icons {
- font-size: 15px;
- margin-right: 3px;
- }
- }
.title {
justify-self: start;
margin-left: 5px;
@@ -280,19 +259,6 @@
table-layout: auto;
}
- button {
- background-color: #262f3c;
- color: #fff;
- font-size: 0.875rem;
- padding-left: 1rem;
- padding-right: 1rem;
- padding-top: 0.5rem;
- padding-bottom: 0.5rem;
- border-radius: 0.25rem;
- margin-top: 12px;
- margin-left: 10px;
- }
-
.slice-details-latency-panel {
// This panel is set to relative to make this panel a positioned element
// This is to allow the absolute text panels below to be positioned relative
diff --git a/ui/src/common/protos.ts b/ui/src/common/protos.ts
index 1fa770d..9443a00 100644
--- a/ui/src/common/protos.ts
+++ b/ui/src/common/protos.ts
@@ -25,6 +25,8 @@
import ChromeConfig = protos.perfetto.protos.ChromeConfig;
import TrackEventConfig = protos.perfetto.protos.TrackEventConfig;
import ConsumerPort = protos.perfetto.protos.ConsumerPort;
+import NetworkPacketTraceConfig =
+ protos.perfetto.protos.NetworkPacketTraceConfig;
import NativeContinuousDumpConfig =
protos.perfetto.protos.HeapprofdConfig.ContinuousDumpConfig;
import JavaContinuousDumpConfig =
@@ -112,6 +114,7 @@
JavaHprofConfig,
MeminfoCounters,
NativeContinuousDumpConfig,
+ NetworkPacketTraceConfig,
ProcessStatsConfig,
PerfettoMetatrace,
ReadBuffersRequest,
diff --git a/ui/src/common/recordingV2/recording_config_utils.ts b/ui/src/common/recordingV2/recording_config_utils.ts
index 6a329b3..2840b3c 100644
--- a/ui/src/common/recordingV2/recording_config_utils.ts
+++ b/ui/src/common/recordingV2/recording_config_utils.ts
@@ -28,6 +28,7 @@
JavaHprofConfig,
MeminfoCounters,
NativeContinuousDumpConfig,
+ NetworkPacketTraceConfig,
ProcessStatsConfig,
SysStatsConfig,
TraceConfig,
@@ -368,6 +369,25 @@
}
}
+ if (uiCfg.androidNetworkTracing) {
+ if (targetInfo.targetType !== 'CHROME') {
+ const net = new TraceConfig.DataSource();
+ net.config = new DataSourceConfig();
+ net.config.name = 'android.network_packets';
+ net.config.networkPacketTraceConfig = new NetworkPacketTraceConfig();
+ net.config.networkPacketTraceConfig.pollMs =
+ uiCfg.androidNetworkTracingPollMs;
+ protoCfg.dataSources.push(net);
+
+ // Record package info so that Perfetto can display the package name for
+ // network packet events based on the event uid.
+ const pkg = new TraceConfig.DataSource();
+ pkg.config = new DataSourceConfig();
+ pkg.config.name = 'android.packages_list';
+ protoCfg.dataSources.push(pkg);
+ }
+ }
+
if (uiCfg.chromeLogs) {
chromeCategories.add('log');
}
diff --git a/ui/src/controller/record_config_types.ts b/ui/src/controller/record_config_types.ts
index fc306b2..a23acfd 100644
--- a/ui/src/controller/record_config_types.ts
+++ b/ui/src/controller/record_config_types.ts
@@ -53,6 +53,8 @@
androidLogBuffers: arrayOf(str()),
androidFrameTimeline: bool(),
androidGameInterventionList: bool(),
+ androidNetworkTracing: bool(),
+ androidNetworkTracingPollMs: num(250),
cpuCoarse: bool(),
cpuCoarsePollMs: num(1000),
diff --git a/ui/src/frontend/flamegraph_panel.ts b/ui/src/frontend/flamegraph_panel.ts
index 278ebda..e46be91 100644
--- a/ui/src/frontend/flamegraph_panel.ts
+++ b/ui/src/frontend/flamegraph_panel.ts
@@ -40,6 +40,7 @@
import {Router} from './router';
import {getCurrentTrace} from './sidebar';
import {convertTraceToPprofAndDownload} from './trace_converter';
+import {Button} from './widgets/button';
interface FlamegraphDetailsPanelAttrs {}
@@ -135,17 +136,14 @@
// Required to stop hot-key handling:
onkeydown: (e: Event) => e.stopPropagation(),
}),
- this.profileType === ProfileType.NATIVE_HEAP_PROFILE ||
- this.profileType === ProfileType.JAVA_HEAP_SAMPLES ?
- m('button.download',
- {
- onclick: () => {
- this.downloadPprof();
- },
+ (this.profileType === ProfileType.NATIVE_HEAP_PROFILE ||
+ this.profileType === ProfileType.JAVA_HEAP_SAMPLES) &&
+ m(Button, {
+ icon: 'file_download',
+ onclick: () => {
+ this.downloadPprof();
},
- m('i.material-icons', 'file_download'),
- 'Download profile') :
- null,
+ }),
]),
]),
m(`div[style=height:${height}px]`),
@@ -330,19 +328,16 @@
private static buildButtonComponent(
viewingOption: FlamegraphStateViewingOption, text: string) {
- const buttonsClass =
- (globals.state.currentFlamegraphState &&
- globals.state.currentFlamegraphState.viewingOption === viewingOption) ?
- '.chosen' :
- '';
- return m(
- `button${buttonsClass}`,
- {
- onclick: () => {
- globals.dispatch(
- Actions.changeViewFlamegraphState({viewingOption}));
- },
- },
- text);
+ const active =
+ (globals.state.currentFlamegraphState !== null &&
+ globals.state.currentFlamegraphState.viewingOption === viewingOption);
+ return m(Button, {
+ label: text,
+ active,
+ minimal: true,
+ onclick: () => {
+ globals.dispatch(Actions.changeViewFlamegraphState({viewingOption}));
+ },
+ });
}
}
diff --git a/ui/src/frontend/recording/android_settings.ts b/ui/src/frontend/recording/android_settings.ts
index 2536a69..7f9a6e5 100644
--- a/ui/src/frontend/recording/android_settings.ts
+++ b/ui/src/frontend/recording/android_settings.ts
@@ -21,6 +21,8 @@
DropdownAttrs,
Probe,
ProbeAttrs,
+ Slider,
+ SliderAttrs,
Textarea,
TextareaAttrs,
Toggle,
@@ -172,6 +174,23 @@
Requires Android 13 (T) or above.`,
setEnabled: (cfg, val) => cfg.androidGameInterventionList = val,
isEnabled: (cfg) => cfg.androidGameInterventionList,
- } as ProbeAttrs));
+ } as ProbeAttrs),
+ m(Probe,
+ {
+ title: 'Network Tracing',
+ img: '',
+ descr: `Records detailed information on network packets.
+ Requires Android 14 (U) or above.`,
+ setEnabled: (cfg, val) => cfg.androidNetworkTracing = val,
+ isEnabled: (cfg) => cfg.androidNetworkTracing,
+ } as ProbeAttrs,
+ m(Slider, {
+ title: 'Poll interval',
+ cssClass: '.thin',
+ values: [100, 250, 500, 1000, 2500],
+ unit: 'ms',
+ set: (cfg, val) => cfg.androidNetworkTracingPollMs = val,
+ get: (cfg) => cfg.androidNetworkTracingPollMs,
+ } as SliderAttrs)));
}
}